FD.io VPP  v18.01-8-g0eacf49
Vector Packet Processing
cli.c
Go to the documentation of this file.
1 /*
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:
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
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.
14  */
15 
16 #include <lb/lb.h>
17 #include <lb/util.h>
18 
19 static clib_error_t *
21  unformat_input_t * input, vlib_cli_command_t * cmd)
22 {
23  unformat_input_t _line_input, *line_input = &_line_input;
24  ip46_address_t prefix;
25  u8 plen;
26  u32 new_len = 1024;
27  u8 del = 0;
28  int ret;
29  u32 gre4 = 0;
30  lb_vip_type_t type;
31  clib_error_t *error = 0;
32 
33  if (!unformat_user (input, unformat_line_input, line_input))
34  return 0;
35 
36  if (!unformat(line_input, "%U", unformat_ip46_prefix, &prefix, &plen, IP46_TYPE_ANY)) {
37  error = clib_error_return (0, "invalid vip prefix: '%U'",
38  format_unformat_error, line_input);
39  goto done;
40  }
41 
42  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
43  {
44  if (unformat(line_input, "new_len %d", &new_len))
45  ;
46  else if (unformat(line_input, "del"))
47  del = 1;
48  else if (unformat(line_input, "encap gre4"))
49  gre4 = 1;
50  else if (unformat(line_input, "encap gre6"))
51  gre4 = 0;
52  else {
53  error = clib_error_return (0, "parse error: '%U'",
54  format_unformat_error, line_input);
55  goto done;
56  }
57  }
58 
59 
60  if (ip46_prefix_is_ip4(&prefix, plen)) {
62  } else {
64  }
65 
67 
68  u32 index;
69  if (!del) {
70  if ((ret = lb_vip_add(&prefix, plen, type, new_len, &index))) {
71  error = clib_error_return (0, "lb_vip_add error %d", ret);
72  goto done;
73  } else {
74  vlib_cli_output(vm, "lb_vip_add ok %d", index);
75  }
76  } else {
77  if ((ret = lb_vip_find_index(&prefix, plen, &index))) {
78  error = clib_error_return (0, "lb_vip_find_index error %d", ret);
79  goto done;
80  } else if ((ret = lb_vip_del(index))) {
81  error = clib_error_return (0, "lb_vip_del error %d", ret);
82  goto done;
83  }
84  }
85 
86 done:
87  unformat_free (line_input);
88 
89  return error;
90 }
91 
92 VLIB_CLI_COMMAND (lb_vip_command, static) =
93 {
94  .path = "lb vip",
95  .short_help = "lb vip <prefix> [encap (gre6|gre4)] [new_len <n>] [del]",
96  .function = lb_vip_command_fn,
97 };
98 
99 static clib_error_t *
101  unformat_input_t * input, vlib_cli_command_t * cmd)
102 {
103  unformat_input_t _line_input, *line_input = &_line_input;
104  ip46_address_t vip_prefix, as_addr;
105  u8 vip_plen;
106  ip46_address_t *as_array = 0;
107  u32 vip_index;
108  u8 del = 0;
109  int ret;
110  clib_error_t *error = 0;
111 
112  if (!unformat_user (input, unformat_line_input, line_input))
113  return 0;
114 
115  if (!unformat(line_input, "%U", unformat_ip46_prefix, &vip_prefix, &vip_plen, IP46_TYPE_ANY)) {
116  error = clib_error_return (0, "invalid as address: '%U'",
117  format_unformat_error, line_input);
118  goto done;
119  }
120 
121  if ((ret = lb_vip_find_index(&vip_prefix, vip_plen, &vip_index))) {
122  error = clib_error_return (0, "lb_vip_find_index error %d", ret);
123  goto done;
124  }
125 
126  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
127  {
128  if (unformat(line_input, "%U", unformat_ip46_address, &as_addr, IP46_TYPE_ANY)) {
129  vec_add1(as_array, as_addr);
130  } else if (unformat(line_input, "del")) {
131  del = 1;
132  } else {
133  error = clib_error_return (0, "parse error: '%U'",
134  format_unformat_error, line_input);
135  goto done;
136  }
137  }
138 
139  if (!vec_len(as_array)) {
140  error = clib_error_return (0, "No AS address provided");
141  goto done;
142  }
143 
145  clib_warning("vip index is %d", vip_index);
146 
147  if (del) {
148  if ((ret = lb_vip_del_ass(vip_index, as_array, vec_len(as_array)))) {
149  error = clib_error_return (0, "lb_vip_del_ass error %d", ret);
150  goto done;
151  }
152  } else {
153  if ((ret = lb_vip_add_ass(vip_index, as_array, vec_len(as_array)))) {
154  error = clib_error_return (0, "lb_vip_add_ass error %d", ret);
155  goto done;
156  }
157  }
158 
159 done:
160  unformat_free (line_input);
161  vec_free(as_array);
162 
163  return error;
164 }
165 
166 VLIB_CLI_COMMAND (lb_as_command, static) =
167 {
168  .path = "lb as",
169  .short_help = "lb as <vip-prefix> [<address> [<address> [...]]] [del]",
170  .function = lb_as_command_fn,
171 };
172 
173 static clib_error_t *
175  unformat_input_t * input, vlib_cli_command_t * cmd)
176 {
177  lb_main_t *lbm = &lb_main;
178  unformat_input_t _line_input, *line_input = &_line_input;
179  ip4_address_t ip4 = lbm->ip4_src_address;
180  ip6_address_t ip6 = lbm->ip6_src_address;
181  u32 per_cpu_sticky_buckets = lbm->per_cpu_sticky_buckets;
182  u32 per_cpu_sticky_buckets_log2 = 0;
183  u32 flow_timeout = lbm->flow_timeout;
184  int ret;
185  clib_error_t *error = 0;
186 
187  if (!unformat_user (input, unformat_line_input, line_input))
188  return 0;
189 
190  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
191  {
192  if (unformat(line_input, "ip4-src-address %U", unformat_ip4_address, &ip4))
193  ;
194  else if (unformat(line_input, "ip6-src-address %U", unformat_ip6_address, &ip6))
195  ;
196  else if (unformat(line_input, "buckets %d", &per_cpu_sticky_buckets))
197  ;
198  else if (unformat(line_input, "buckets-log2 %d", &per_cpu_sticky_buckets_log2)) {
199  if (per_cpu_sticky_buckets_log2 >= 32)
200  return clib_error_return (0, "buckets-log2 value is too high");
201  per_cpu_sticky_buckets = 1 << per_cpu_sticky_buckets_log2;
202  } else if (unformat(line_input, "timeout %d", &flow_timeout))
203  ;
204  else {
205  error = clib_error_return (0, "parse error: '%U'",
206  format_unformat_error, line_input);
207  goto done;
208  }
209  }
210 
212 
213  if ((ret = lb_conf(&ip4, &ip6, per_cpu_sticky_buckets, flow_timeout))) {
214  error = clib_error_return (0, "lb_conf error %d", ret);
215  goto done;
216  }
217 
218 done:
219  unformat_free (line_input);
220 
221  return error;
222 }
223 
224 VLIB_CLI_COMMAND (lb_conf_command, static) =
225 {
226  .path = "lb conf",
227  .short_help = "lb conf [ip4-src-address <addr>] [ip6-src-address <addr>] [buckets <n>] [timeout <s>]",
228  .function = lb_conf_command_fn,
229 };
230 
231 static clib_error_t *
233  unformat_input_t * input, vlib_cli_command_t * cmd)
234 {
235  vlib_cli_output(vm, "%U", format_lb_main);
236  return NULL;
237 }
238 
239 
240 VLIB_CLI_COMMAND (lb_show_command, static) =
241 {
242  .path = "show lb",
243  .short_help = "show lb",
244  .function = lb_show_command_fn,
245 };
246 
247 static clib_error_t *
249  unformat_input_t * input, vlib_cli_command_t * cmd)
250 {
251  unformat_input_t line_input;
252  lb_main_t *lbm = &lb_main;
253  lb_vip_t *vip;
254  u8 verbose = 0;
255 
256  if (!unformat_user (input, unformat_line_input, &line_input))
257  return 0;
258 
259  if (unformat(&line_input, "verbose"))
260  verbose = 1;
261 
262  pool_foreach(vip, lbm->vips, {
263  vlib_cli_output(vm, "%U\n", verbose?format_lb_vip_detailed:format_lb_vip, vip);
264  });
265 
266  unformat_free (&line_input);
267  return NULL;
268 }
269 
270 VLIB_CLI_COMMAND (lb_show_vips_command, static) =
271 {
272  .path = "show lb vips",
273  .short_help = "show lb vips [verbose]",
274  .function = lb_show_vips_command_fn,
275 };
276 
277 static clib_error_t *
279  unformat_input_t * input, vlib_cli_command_t * cmd)
280 {
281  u32 thread_index;
283  lb_main_t *lbm = &lb_main;
284 
285  for(thread_index = 0; thread_index < tm->n_vlib_mains; thread_index++ ) {
286  lb_hash_t *h = lbm->per_cpu[thread_index].sticky_ht;
287  if (h != NULL) {
288  u32 i;
289  lb_hash_bucket_t *b;
290 
291  lb_hash_foreach_entry(h, b, i) {
292  vlib_refcount_add(&lbm->as_refcount, thread_index, b->value[i], -1);
293  vlib_refcount_add(&lbm->as_refcount, thread_index, 0, 1);
294  }
295 
296  lb_hash_free(h);
297  lbm->per_cpu[thread_index].sticky_ht = 0;
298  }
299  }
300 
301  return NULL;
302 }
303 
304 /*
305  * flush all lb flowtables
306  * This is indented for debug and unit-tests purposes only
307  */
308 VLIB_CLI_COMMAND (lb_flowtable_flush_command, static) =
309 {
310  .path = "test lb flowtable flush",
311  .short_help = "test lb flowtable flush",
312  .function = lb_flowtable_flush_command_fn,
313 };
static clib_error_t * lb_flowtable_flush_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: cli.c:278
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:337
static clib_error_t * lb_show_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: cli.c:232
u32 per_cpu_sticky_buckets
Number of buckets in the per-cpu sticky hash table.
Definition: lb.h:272
#define NULL
Definition: clib.h:55
int lb_conf(ip4_address_t *ip4_address, ip6_address_t *ip6_address, u32 per_cpu_sticky_buckets, u32 flow_timeout)
Fix global load-balancer parameters.
Definition: lb.c:364
int lb_vip_add_ass(u32 vip_index, ip46_address_t *addresses, u32 n)
Definition: lb.c:427
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:518
uword unformat_user(unformat_input_t *input, unformat_function_t *func,...)
Definition: unformat.c:983
static clib_error_t * lb_conf_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: cli.c:174
lb_hash_t * sticky_ht
Each CPU has its own sticky flow hash table.
Definition: lb.h:225
static clib_error_t * lb_show_vips_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: cli.c:248
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:438
unformat_function_t unformat_ip4_address
Definition: format.h:76
lb_main_t lb_main
Definition: lb.c:27
u32 flow_timeout
Flow timeout in seconds.
Definition: lb.h:277
Definition: lb.h:228
vlib_refcount_t as_refcount
Each AS has an associated reference counter.
Definition: lb.h:247
#define clib_error_return(e, args...)
Definition: error.h:99
lb_vip_t * vips
Pool of all Virtual IPs.
Definition: lb.h:232
ip4_address_t ip4_src_address
Source address used for IPv4 encapsulated traffic.
Definition: lb.h:267
unformat_function_t unformat_line_input
Definition: format.h:281
u32 value[LBHASH_ENTRY_PER_BUCKET]
Definition: lbhash.h:54
int lb_vip_del(u32 vip_index)
Definition: lb.c:697
struct _unformat_input_t unformat_input_t
format_function_t format_lb_main
Definition: lb.h:331
static_always_inline void vlib_refcount_add(vlib_refcount_t *r, u32 thread_index, u32 counter_index, i32 v)
Definition: refcount.h:68
#define lb_hash_foreach_entry(h, bucket, i)
Definition: lbhash.h:71
unformat_function_t unformat_ip6_address
Definition: format.h:94
#define UNFORMAT_END_OF_INPUT
Definition: format.h:143
int lb_vip_add(ip46_address_t *prefix, u8 plen, lb_vip_type_t type, u32 new_length, u32 *vip_index)
Definition: lb.c:639
vlib_main_t * vm
Definition: buffer.c:283
vec_header_t h
Definition: buffer.c:282
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:336
#define clib_warning(format, args...)
Definition: error.h:59
int lb_vip_del_ass(u32 vip_index, ip46_address_t *addresses, u32 n)
Definition: lb.c:584
static_always_inline void lb_hash_free(lb_hash_t *h)
Definition: lbhash.h:98
uword unformat_ip46_prefix(unformat_input_t *input, va_list *args)
Definition: kp.c:49
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:154
unsigned int u32
Definition: types.h:88
lb_vip_type_t
The load balancer supports IPv4 and IPv6 traffic and GRE4 and GRE6 encap.
Definition: lb.h:135
int lb_vip_find_index(ip46_address_t *prefix, u8 plen, u32 *vip_index)
Definition: lb.c:400
unformat_function_t unformat_ip46_address
Definition: format.h:71
lb_per_cpu_t * per_cpu
Some global data is per-cpu.
Definition: lb.h:252
ip6_address_t ip6_src_address
Source address used in IPv6 encapsulated traffic.
Definition: lb.h:262
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
unsigned char u8
Definition: types.h:56
static clib_error_t * lb_as_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: cli.c:100
static void unformat_free(unformat_input_t *i)
Definition: format.h:161
static clib_error_t * lb_vip_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: cli.c:20
void lb_garbage_collection()
Definition: lb.c:235
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
static vlib_thread_main_t * vlib_get_thread_main()
Definition: global_funcs.h:32
#define ip46_prefix_is_ip4(ip46, len)
Definition: kp.h:432
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:680
Load balancing service is provided per VIP.
Definition: lb.h:154
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:972
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:169