2 * Copyright (c) 2016 Cisco and/or its affiliates.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
7 * http://www.apache.org/licenses/LICENSE-2.0
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
20 lb_vip_command_fn (vlib_main_t * vm,
21 unformat_input_t * input, vlib_cli_command_t * cmd)
23 unformat_input_t _line_input, *line_input = &_line_input;
24 ip46_address_t prefix;
31 lb_vip_type_t type = 0;
32 clib_error_t *error = 0;
34 if (!unformat_user (input, unformat_line_input, line_input))
37 if (!unformat(line_input, "%U", unformat_ip46_prefix, &prefix, &plen, IP46_TYPE_ANY)) {
38 error = clib_error_return (0, "invalid vip prefix: '%U'",
39 format_unformat_error, line_input);
43 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
45 if (unformat(line_input, "new_len %d", &new_len))
47 else if (unformat(line_input, "del"))
49 else if (unformat(line_input, "encap gre4"))
50 encap = LB_ENCAP_TYPE_GRE4;
51 else if (unformat(line_input, "encap gre6"))
52 encap = LB_ENCAP_TYPE_GRE6;
53 else if (unformat(line_input, "encap l3dsr"))
54 encap = LB_ENCAP_TYPE_L3DSR;
55 else if (unformat(line_input, "dscp %d", &dscp))
58 error = clib_error_return (0, "parse error: '%U'",
59 format_unformat_error, line_input);
64 if ((encap != LB_ENCAP_TYPE_L3DSR) && (dscp != ~0) )
66 error = clib_error_return (0, "lb_vip_add error: "
67 "should not configure dscp for none L3DSR.");
71 if ((encap == LB_ENCAP_TYPE_L3DSR) && (dscp >= 64 ) )
73 error = clib_error_return (0, "lb_vip_add error: "
74 "dscp for L3DSR should be less than 64.");
78 if (ip46_prefix_is_ip4(&prefix, plen)) {
79 if (encap == LB_ENCAP_TYPE_GRE4)
80 type = LB_VIP_TYPE_IP4_GRE4;
81 else if (encap == LB_ENCAP_TYPE_GRE6)
82 type = LB_VIP_TYPE_IP4_GRE6;
83 else if (encap == LB_ENCAP_TYPE_L3DSR)
84 type = LB_VIP_TYPE_IP4_L3DSR;
86 if (encap == LB_ENCAP_TYPE_GRE4)
87 type = LB_VIP_TYPE_IP6_GRE4;
88 else if (encap == LB_ENCAP_TYPE_GRE6)
89 type = LB_VIP_TYPE_IP6_GRE6;
92 lb_garbage_collection();
96 if ((ret = lb_vip_add(&prefix, plen, type, (u8)(dscp & 0x3F), new_len, &index))) {
97 error = clib_error_return (0, "lb_vip_add error %d", ret);
100 vlib_cli_output(vm, "lb_vip_add ok %d", index);
103 if ((ret = lb_vip_find_index(&prefix, plen, &index))) {
104 error = clib_error_return (0, "lb_vip_find_index error %d", ret);
106 } else if ((ret = lb_vip_del(index))) {
107 error = clib_error_return (0, "lb_vip_del error %d", ret);
113 unformat_free (line_input);
118 VLIB_CLI_COMMAND (lb_vip_command, static) =
121 .short_help = "lb vip <prefix> [encap (gre6|gre4|l3dsr)] [dscp <n>] [new_len <n>] [del]",
122 .function = lb_vip_command_fn,
125 static clib_error_t *
126 lb_as_command_fn (vlib_main_t * vm,
127 unformat_input_t * input, vlib_cli_command_t * cmd)
129 unformat_input_t _line_input, *line_input = &_line_input;
130 ip46_address_t vip_prefix, as_addr;
132 ip46_address_t *as_array = 0;
136 clib_error_t *error = 0;
138 if (!unformat_user (input, unformat_line_input, line_input))
141 if (!unformat(line_input, "%U", unformat_ip46_prefix, &vip_prefix, &vip_plen, IP46_TYPE_ANY)) {
142 error = clib_error_return (0, "invalid as address: '%U'",
143 format_unformat_error, line_input);
147 if ((ret = lb_vip_find_index(&vip_prefix, vip_plen, &vip_index))) {
148 error = clib_error_return (0, "lb_vip_find_index error %d", ret);
152 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
154 if (unformat(line_input, "%U", unformat_ip46_address, &as_addr, IP46_TYPE_ANY)) {
155 vec_add1(as_array, as_addr);
156 } else if (unformat(line_input, "del")) {
159 error = clib_error_return (0, "parse error: '%U'",
160 format_unformat_error, line_input);
165 if (!vec_len(as_array)) {
166 error = clib_error_return (0, "No AS address provided");
170 lb_garbage_collection();
171 clib_warning("vip index is %d", vip_index);
174 if ((ret = lb_vip_del_ass(vip_index, as_array, vec_len(as_array)))) {
175 error = clib_error_return (0, "lb_vip_del_ass error %d", ret);
179 if ((ret = lb_vip_add_ass(vip_index, as_array, vec_len(as_array)))) {
180 error = clib_error_return (0, "lb_vip_add_ass error %d", ret);
186 unformat_free (line_input);
192 VLIB_CLI_COMMAND (lb_as_command, static) =
195 .short_help = "lb as <vip-prefix> [<address> [<address> [...]]] [del]",
196 .function = lb_as_command_fn,
199 static clib_error_t *
200 lb_conf_command_fn (vlib_main_t * vm,
201 unformat_input_t * input, vlib_cli_command_t * cmd)
203 lb_main_t *lbm = &lb_main;
204 unformat_input_t _line_input, *line_input = &_line_input;
205 ip4_address_t ip4 = lbm->ip4_src_address;
206 ip6_address_t ip6 = lbm->ip6_src_address;
207 u32 per_cpu_sticky_buckets = lbm->per_cpu_sticky_buckets;
208 u32 per_cpu_sticky_buckets_log2 = 0;
209 u32 flow_timeout = lbm->flow_timeout;
211 clib_error_t *error = 0;
213 if (!unformat_user (input, unformat_line_input, line_input))
216 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
218 if (unformat(line_input, "ip4-src-address %U", unformat_ip4_address, &ip4))
220 else if (unformat(line_input, "ip6-src-address %U", unformat_ip6_address, &ip6))
222 else if (unformat(line_input, "buckets %d", &per_cpu_sticky_buckets))
224 else if (unformat(line_input, "buckets-log2 %d", &per_cpu_sticky_buckets_log2)) {
225 if (per_cpu_sticky_buckets_log2 >= 32)
226 return clib_error_return (0, "buckets-log2 value is too high");
227 per_cpu_sticky_buckets = 1 << per_cpu_sticky_buckets_log2;
228 } else if (unformat(line_input, "timeout %d", &flow_timeout))
231 error = clib_error_return (0, "parse error: '%U'",
232 format_unformat_error, line_input);
237 lb_garbage_collection();
239 if ((ret = lb_conf(&ip4, &ip6, per_cpu_sticky_buckets, flow_timeout))) {
240 error = clib_error_return (0, "lb_conf error %d", ret);
245 unformat_free (line_input);
250 VLIB_CLI_COMMAND (lb_conf_command, static) =
253 .short_help = "lb conf [ip4-src-address <addr>] [ip6-src-address <addr>] [buckets <n>] [timeout <s>]",
254 .function = lb_conf_command_fn,
257 static clib_error_t *
258 lb_show_command_fn (vlib_main_t * vm,
259 unformat_input_t * input, vlib_cli_command_t * cmd)
261 vlib_cli_output(vm, "%U", format_lb_main);
266 VLIB_CLI_COMMAND (lb_show_command, static) =
269 .short_help = "show lb",
270 .function = lb_show_command_fn,
273 static clib_error_t *
274 lb_show_vips_command_fn (vlib_main_t * vm,
275 unformat_input_t * input, vlib_cli_command_t * cmd)
277 unformat_input_t line_input;
278 lb_main_t *lbm = &lb_main;
282 if (!unformat_user (input, unformat_line_input, &line_input))
285 if (unformat(&line_input, "verbose"))
288 pool_foreach(vip, lbm->vips, {
289 vlib_cli_output(vm, "%U\n", verbose?format_lb_vip_detailed:format_lb_vip, vip);
292 unformat_free (&line_input);
296 VLIB_CLI_COMMAND (lb_show_vips_command, static) =
298 .path = "show lb vips",
299 .short_help = "show lb vips [verbose]",
300 .function = lb_show_vips_command_fn,
303 static clib_error_t *
304 lb_flowtable_flush_command_fn (vlib_main_t * vm,
305 unformat_input_t * input, vlib_cli_command_t * cmd)
308 vlib_thread_main_t *tm = vlib_get_thread_main();
309 lb_main_t *lbm = &lb_main;
311 for(thread_index = 0; thread_index < tm->n_vlib_mains; thread_index++ ) {
312 lb_hash_t *h = lbm->per_cpu[thread_index].sticky_ht;
317 lb_hash_foreach_entry(h, b, i) {
318 vlib_refcount_add(&lbm->as_refcount, thread_index, b->value[i], -1);
319 vlib_refcount_add(&lbm->as_refcount, thread_index, 0, 1);
323 lbm->per_cpu[thread_index].sticky_ht = 0;
331 * flush all lb flowtables
332 * This is indented for debug and unit-tests purposes only
334 VLIB_CLI_COMMAND (lb_flowtable_flush_command, static) =
336 .path = "test lb flowtable flush",
337 .short_help = "test lb flowtable flush",
338 .function = lb_flowtable_flush_command_fn,