blob: 86b247eb2daf8703ef8b4ee04e13c019813f4da6 [file] [log] [blame]
Damjan Marion7cd468a2016-12-19 23:05:39 +01001/*
2 *------------------------------------------------------------------
3 * api_format.c
4 *
Dave Barachac0326f2020-07-14 18:30:05 -04005 * Copyright (c) 2014-2020 Cisco and/or its affiliates.
Damjan Marion7cd468a2016-12-19 23:05:39 +01006 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at:
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *------------------------------------------------------------------
18 */
19
20#include <vat/vat.h>
jialv01082ebeb2019-09-10 00:23:55 +080021#include <vlib/pci/pci.h>
Neale Ranns86327be2018-11-02 09:14:01 -070022#include <vpp/api/types.h>
Dave Barach59b25652017-09-10 15:04:27 -040023#include <vppinfra/socket.h>
Damjan Marion7cd468a2016-12-19 23:05:39 +010024#include <vlibapi/api.h>
25#include <vlibmemory/api.h>
Damjan Marion7cd468a2016-12-19 23:05:39 +010026#include <vnet/ip/ip.h>
Neale Rannscbe25aa2019-09-30 10:53:31 +000027#include <vnet/ip-neighbor/ip_neighbor.h>
Neale Ranns37029302018-08-10 05:30:06 -070028#include <vnet/ip/ip_types_api.h>
Damjan Marion7cd468a2016-12-19 23:05:39 +010029#include <vnet/l2/l2_input.h>
Florin Corasb040f982020-10-20 14:59:43 -070030#include <vnet/udp/udp_local.h>
Damjan Marion7cd468a2016-12-19 23:05:39 +010031
32#include <vpp/api/vpe_msg_enum.h>
33#include <vnet/l2/l2_classify.h>
34#include <vnet/l2/l2_vtr.h>
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +010035#include <vnet/classify/in_out_acl.h>
Damjan Marion7cd468a2016-12-19 23:05:39 +010036#include <vnet/classify/policer_classify.h>
37#include <vnet/classify/flow_classify.h>
38#include <vnet/mpls/mpls.h>
39#include <vnet/ipsec/ipsec.h>
Damjan Marion7cd468a2016-12-19 23:05:39 +010040#include <inttypes.h>
Damjan Marion7cd468a2016-12-19 23:05:39 +010041#include <vnet/ip/ip6_hop_by_hop.h>
42#include <vnet/ip/ip_source_and_port_range_check.h>
43#include <vnet/policer/xlate.h>
44#include <vnet/span/span.h>
45#include <vnet/policer/policer.h>
46#include <vnet/policer/police.h>
Neale Ranns32e1c012016-11-22 17:07:28 +000047#include <vnet/mfib/mfib_types.h>
Steven9cd2d7a2017-12-20 12:43:01 -080048#include <vnet/bonding/node.h>
Igor Mikhailov (imichail)582caa32018-04-26 21:33:02 -070049#include <vnet/qos/qos_types.h>
Neale Ranns37029302018-08-10 05:30:06 -070050#include <vnet/ethernet/ethernet_types_api.h>
51#include <vnet/ip/ip_types_api.h>
Damjan Marion7cd468a2016-12-19 23:05:39 +010052#include "vat/json_format.h"
Neale Ranns86327be2018-11-02 09:14:01 -070053#include <vnet/ip/ip_types_api.h>
54#include <vnet/ethernet/ethernet_types_api.h>
Damjan Marion7cd468a2016-12-19 23:05:39 +010055
56#include <inttypes.h>
57#include <sys/stat.h>
58
59#define vl_typedefs /* define message structures */
60#include <vpp/api/vpe_all_api_h.h>
61#undef vl_typedefs
62
63/* declare message handlers for each api */
64
65#define vl_endianfun /* define message structures */
66#include <vpp/api/vpe_all_api_h.h>
67#undef vl_endianfun
68
69/* instantiate all the print functions we know about */
Dave Barachf35a0722019-06-12 16:50:38 -040070#if VPP_API_TEST_BUILTIN == 0
Damjan Marion7cd468a2016-12-19 23:05:39 +010071#define vl_print(handle, ...)
Dave Barachf35a0722019-06-12 16:50:38 -040072#else
73#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
74#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +010075#define vl_printfun
76#include <vpp/api/vpe_all_api_h.h>
77#undef vl_printfun
78
Dave Barach2d6b2d62017-01-25 16:32:08 -050079#define __plugin_msg_base 0
Dave Barachfe6bdfd2017-01-20 19:50:09 -050080#include <vlibapi/vat_helper_macros.h>
81
Dave Barachb09f4d02019-07-15 16:00:03 -040082void vl_api_set_elog_main (elog_main_t * m);
83int vl_api_set_elog_trace_api_messages (int enable);
84
Dave Barach59b25652017-09-10 15:04:27 -040085#if VPP_API_TEST_BUILTIN == 0
86#include <netdb.h>
87
88u32
89vl (void *p)
90{
91 return vec_len (p);
92}
93
94int
95vat_socket_connect (vat_main_t * vam)
96{
Florin Coras66a10032018-12-21 16:23:09 -080097 int rv;
Dave Barach69eeadc2020-04-14 09:52:26 -040098 api_main_t *am = vlibapi_get_main ();
Florin Coras90a63982017-12-19 04:50:01 -080099 vam->socket_client_main = &socket_client_main;
Florin Coras66a10032018-12-21 16:23:09 -0800100 if ((rv = vl_socket_client_connect ((char *) vam->socket_name,
101 "vpp_api_test",
102 0 /* default socket rx, tx buffer */ )))
103 return rv;
Dave Barach69eeadc2020-04-14 09:52:26 -0400104
Florin Coras66a10032018-12-21 16:23:09 -0800105 /* vpp expects the client index in network order */
106 vam->my_client_index = htonl (socket_client_main.client_index);
Dave Barach69eeadc2020-04-14 09:52:26 -0400107 am->my_client_index = vam->my_client_index;
Florin Coras66a10032018-12-21 16:23:09 -0800108 return 0;
Dave Barach59b25652017-09-10 15:04:27 -0400109}
110#else /* vpp built-in case, we don't do sockets... */
111int
112vat_socket_connect (vat_main_t * vam)
113{
114 return 0;
115}
116
Florin Coras90a63982017-12-19 04:50:01 -0800117int
118vl_socket_client_read (int wait)
Dave Barach59b25652017-09-10 15:04:27 -0400119{
Florin Coras90a63982017-12-19 04:50:01 -0800120 return -1;
Dave Barach59b25652017-09-10 15:04:27 -0400121};
Florin Coras90a63982017-12-19 04:50:01 -0800122
123int
124vl_socket_client_write ()
125{
126 return -1;
127};
128
129void *
130vl_socket_client_msg_alloc (int nbytes)
131{
132 return 0;
133}
Dave Barach59b25652017-09-10 15:04:27 -0400134#endif
135
136
Dave Barachfe6bdfd2017-01-20 19:50:09 -0500137f64
138vat_time_now (vat_main_t * vam)
139{
140#if VPP_API_TEST_BUILTIN
141 return vlib_time_now (vam->vlib_main);
142#else
143 return clib_time_now (&vam->clib_time);
144#endif
145}
146
147void
148errmsg (char *fmt, ...)
149{
150 vat_main_t *vam = &vat_main;
151 va_list va;
152 u8 *s;
153
154 va_start (va, fmt);
155 s = va_format (0, fmt, &va);
156 va_end (va);
157
158 vec_add1 (s, 0);
159
160#if VPP_API_TEST_BUILTIN
161 vlib_cli_output (vam->vlib_main, (char *) s);
162#else
163 {
164 if (vam->ifp != stdin)
165 fformat (vam->ofp, "%s(%d): \n", vam->current_file,
166 vam->input_line_number);
Dave Barachb09f4d02019-07-15 16:00:03 -0400167 else
168 fformat (vam->ofp, "%s\n", (char *) s);
Dave Barachfe6bdfd2017-01-20 19:50:09 -0500169 fflush (vam->ofp);
170 }
171#endif
172
173 vec_free (s);
174}
175
Dave Barach4a3f69c2017-02-22 12:44:56 -0500176#if VPP_API_TEST_BUILTIN == 0
Damjan Marion7cd468a2016-12-19 23:05:39 +0100177static uword
178api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
179{
180 vat_main_t *vam = va_arg (*args, vat_main_t *);
181 u32 *result = va_arg (*args, u32 *);
182 u8 *if_name;
183 uword *p;
184
185 if (!unformat (input, "%s", &if_name))
186 return 0;
187
188 p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
189 if (p == 0)
190 return 0;
191 *result = p[0];
192 return 1;
193}
194
Damjan Marion7cd468a2016-12-19 23:05:39 +0100195/* Parse an IP4 address %d.%d.%d.%d. */
196uword
197unformat_ip4_address (unformat_input_t * input, va_list * args)
198{
199 u8 *result = va_arg (*args, u8 *);
200 unsigned a[4];
201
202 if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
203 return 0;
204
205 if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
206 return 0;
207
208 result[0] = a[0];
209 result[1] = a[1];
210 result[2] = a[2];
211 result[3] = a[3];
212
213 return 1;
214}
215
216uword
217unformat_ethernet_address (unformat_input_t * input, va_list * args)
218{
219 u8 *result = va_arg (*args, u8 *);
220 u32 i, a[6];
221
222 if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
223 &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
224 return 0;
225
226 /* Check range. */
227 for (i = 0; i < 6; i++)
228 if (a[i] >= (1 << 8))
229 return 0;
230
231 for (i = 0; i < 6; i++)
232 result[i] = a[i];
233
234 return 1;
235}
236
237/* Returns ethernet type as an int in host byte order. */
238uword
239unformat_ethernet_type_host_byte_order (unformat_input_t * input,
240 va_list * args)
241{
242 u16 *result = va_arg (*args, u16 *);
243 int type;
244
245 /* Numeric type. */
246 if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
247 {
248 if (type >= (1 << 16))
249 return 0;
250 *result = type;
251 return 1;
252 }
253 return 0;
254}
255
Jakub Grajciar23a386b2020-02-26 11:01:43 +0100256/* Parse an IP46 address. */
257uword
258unformat_ip46_address (unformat_input_t * input, va_list * args)
259{
260 ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
261 ip46_type_t type = va_arg (*args, ip46_type_t);
262 if ((type != IP46_TYPE_IP6) &&
263 unformat (input, "%U", unformat_ip4_address, &ip46->ip4))
264 {
265 ip46_address_mask_ip4 (ip46);
266 return 1;
267 }
268 else if ((type != IP46_TYPE_IP4) &&
269 unformat (input, "%U", unformat_ip6_address, &ip46->ip6))
270 {
271 return 1;
272 }
273 return 0;
274}
275
Damjan Marion7cd468a2016-12-19 23:05:39 +0100276/* Parse an IP6 address. */
277uword
278unformat_ip6_address (unformat_input_t * input, va_list * args)
279{
280 ip6_address_t *result = va_arg (*args, ip6_address_t *);
281 u16 hex_quads[8];
282 uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
283 uword c, n_colon, double_colon_index;
284
285 n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
286 double_colon_index = ARRAY_LEN (hex_quads);
287 while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
288 {
289 hex_digit = 16;
290 if (c >= '0' && c <= '9')
291 hex_digit = c - '0';
292 else if (c >= 'a' && c <= 'f')
293 hex_digit = c + 10 - 'a';
294 else if (c >= 'A' && c <= 'F')
295 hex_digit = c + 10 - 'A';
296 else if (c == ':' && n_colon < 2)
297 n_colon++;
298 else
299 {
300 unformat_put_input (input);
301 break;
302 }
303
304 /* Too many hex quads. */
305 if (n_hex_quads >= ARRAY_LEN (hex_quads))
306 return 0;
307
308 if (hex_digit < 16)
309 {
310 hex_quad = (hex_quad << 4) | hex_digit;
311
312 /* Hex quad must fit in 16 bits. */
313 if (n_hex_digits >= 4)
314 return 0;
315
316 n_colon = 0;
317 n_hex_digits++;
318 }
319
320 /* Save position of :: */
321 if (n_colon == 2)
322 {
323 /* More than one :: ? */
324 if (double_colon_index < ARRAY_LEN (hex_quads))
325 return 0;
326 double_colon_index = n_hex_quads;
327 }
328
329 if (n_colon > 0 && n_hex_digits > 0)
330 {
331 hex_quads[n_hex_quads++] = hex_quad;
332 hex_quad = 0;
333 n_hex_digits = 0;
334 }
335 }
336
337 if (n_hex_digits > 0)
338 hex_quads[n_hex_quads++] = hex_quad;
339
340 {
341 word i;
342
343 /* Expand :: to appropriate number of zero hex quads. */
344 if (double_colon_index < ARRAY_LEN (hex_quads))
345 {
346 word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
347
348 for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
349 hex_quads[n_zero + i] = hex_quads[i];
350
351 for (i = 0; i < n_zero; i++)
352 hex_quads[double_colon_index + i] = 0;
353
354 n_hex_quads = ARRAY_LEN (hex_quads);
355 }
356
357 /* Too few hex quads given. */
358 if (n_hex_quads < ARRAY_LEN (hex_quads))
359 return 0;
360
361 for (i = 0; i < ARRAY_LEN (hex_quads); i++)
362 result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
363
364 return 1;
365 }
366}
367
368uword
369unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
370{
371 u32 *r = va_arg (*args, u32 *);
372
373 if (0);
374#define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
375 foreach_ipsec_policy_action
376#undef _
377 else
378 return 0;
379 return 1;
380}
381
Damjan Marion7cd468a2016-12-19 23:05:39 +0100382u8 *
383format_ipsec_crypto_alg (u8 * s, va_list * args)
384{
385 u32 i = va_arg (*args, u32);
386 u8 *t = 0;
387
388 switch (i)
389 {
390#define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
391 foreach_ipsec_crypto_alg
392#undef _
393 default:
394 return format (s, "unknown");
395 }
396 return format (s, "%s", t);
397}
398
Damjan Marion7cd468a2016-12-19 23:05:39 +0100399u8 *
400format_ipsec_integ_alg (u8 * s, va_list * args)
401{
402 u32 i = va_arg (*args, u32);
403 u8 *t = 0;
404
405 switch (i)
406 {
407#define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
408 foreach_ipsec_integ_alg
409#undef _
410 default:
411 return format (s, "unknown");
412 }
413 return format (s, "%s", t);
414}
415
Dave Barach4a3f69c2017-02-22 12:44:56 -0500416#else /* VPP_API_TEST_BUILTIN == 1 */
417static uword
418api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
419{
Benoît Ganne49ee6842019-04-30 11:50:46 +0200420 vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
Dave Barach4a3f69c2017-02-22 12:44:56 -0500421 vnet_main_t *vnm = vnet_get_main ();
422 u32 *result = va_arg (*args, u32 *);
Dave Barach4a3f69c2017-02-22 12:44:56 -0500423
eyal bariaf86a482018-04-17 11:20:27 +0300424 return unformat (input, "%U", unformat_vnet_sw_interface, vnm, result);
Dave Barach4a3f69c2017-02-22 12:44:56 -0500425}
eyal bariaf86a482018-04-17 11:20:27 +0300426
Damjan Marion7cd468a2016-12-19 23:05:39 +0100427#endif /* VPP_API_TEST_BUILTIN */
428
Benoît Ganne49ee6842019-04-30 11:50:46 +0200429#if (VPP_API_TEST_BUILTIN==0)
430
Neale Ranns32e1c012016-11-22 17:07:28 +0000431static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
432static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
433static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
434static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
435
436uword
437unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
438{
439 mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
440 mfib_itf_attribute_t attr;
441
442 old = *iflags;
443 FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
444 {
445 if (unformat (input, mfib_itf_flag_long_names[attr]))
446 *iflags |= (1 << attr);
447 }
448 FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
449 {
450 if (unformat (input, mfib_itf_flag_names[attr]))
451 *iflags |= (1 << attr);
452 }
453
454 return (old == *iflags ? 0 : 1);
455}
456
457uword
458unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
459{
460 mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
461 mfib_entry_attribute_t attr;
462
463 old = *eflags;
464 FOR_EACH_MFIB_ATTRIBUTE (attr)
465 {
466 if (unformat (input, mfib_flag_long_names[attr]))
467 *eflags |= (1 << attr);
468 }
469 FOR_EACH_MFIB_ATTRIBUTE (attr)
470 {
471 if (unformat (input, mfib_flag_names[attr]))
472 *eflags |= (1 << attr);
473 }
474
475 return (old == *eflags ? 0 : 1);
476}
477
Damjan Marion7cd468a2016-12-19 23:05:39 +0100478u8 *
479format_ip4_address (u8 * s, va_list * args)
480{
481 u8 *a = va_arg (*args, u8 *);
482 return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
483}
484
485u8 *
486format_ip6_address (u8 * s, va_list * args)
487{
488 ip6_address_t *a = va_arg (*args, ip6_address_t *);
489 u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
490
491 i_max_n_zero = ARRAY_LEN (a->as_u16);
492 max_n_zeros = 0;
493 i_first_zero = i_max_n_zero;
494 n_zeros = 0;
495 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
496 {
497 u32 is_zero = a->as_u16[i] == 0;
498 if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
499 {
500 i_first_zero = i;
501 n_zeros = 0;
502 }
503 n_zeros += is_zero;
504 if ((!is_zero && n_zeros > max_n_zeros)
505 || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
506 {
507 i_max_n_zero = i_first_zero;
508 max_n_zeros = n_zeros;
509 i_first_zero = ARRAY_LEN (a->as_u16);
510 n_zeros = 0;
511 }
512 }
513
514 last_double_colon = 0;
515 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
516 {
517 if (i == i_max_n_zero && max_n_zeros > 1)
518 {
519 s = format (s, "::");
520 i += max_n_zeros - 1;
521 last_double_colon = 1;
522 }
523 else
524 {
525 s = format (s, "%s%x",
526 (last_double_colon || i == 0) ? "" : ":",
527 clib_net_to_host_u16 (a->as_u16[i]));
528 last_double_colon = 0;
529 }
530 }
531
532 return s;
533}
534
535/* Format an IP46 address. */
536u8 *
537format_ip46_address (u8 * s, va_list * args)
538{
539 ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
540 ip46_type_t type = va_arg (*args, ip46_type_t);
541 int is_ip4 = 1;
542
543 switch (type)
544 {
545 case IP46_TYPE_ANY:
546 is_ip4 = ip46_address_is_ip4 (ip46);
547 break;
548 case IP46_TYPE_IP4:
549 is_ip4 = 1;
550 break;
551 case IP46_TYPE_IP6:
552 is_ip4 = 0;
553 break;
554 }
555
556 return is_ip4 ?
557 format (s, "%U", format_ip4_address, &ip46->ip4) :
558 format (s, "%U", format_ip6_address, &ip46->ip6);
559}
560
561u8 *
562format_ethernet_address (u8 * s, va_list * args)
563{
564 u8 *a = va_arg (*args, u8 *);
565
566 return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
567 a[0], a[1], a[2], a[3], a[4], a[5]);
568}
569#endif
570
571static void
Neale Ranns097fa662018-05-01 05:17:55 -0700572increment_v4_address (vl_api_ip4_address_t * i)
Damjan Marion7cd468a2016-12-19 23:05:39 +0100573{
Neale Ranns097fa662018-05-01 05:17:55 -0700574 ip4_address_t *a = (ip4_address_t *) i;
Damjan Marion7cd468a2016-12-19 23:05:39 +0100575 u32 v;
576
577 v = ntohl (a->as_u32) + 1;
578 a->as_u32 = ntohl (v);
579}
580
581static void
Neale Ranns097fa662018-05-01 05:17:55 -0700582increment_v6_address (vl_api_ip6_address_t * i)
Neale Ranns2b5ba952019-04-02 10:15:40 +0000583{
Neale Ranns097fa662018-05-01 05:17:55 -0700584 ip6_address_t *a = (ip6_address_t *) i;
Damjan Marion7cd468a2016-12-19 23:05:39 +0100585 u64 v0, v1;
586
587 v0 = clib_net_to_host_u64 (a->as_u64[0]);
588 v1 = clib_net_to_host_u64 (a->as_u64[1]);
589
590 v1 += 1;
591 if (v1 == 0)
592 v0 += 1;
593 a->as_u64[0] = clib_net_to_host_u64 (v0);
594 a->as_u64[1] = clib_net_to_host_u64 (v1);
595}
596
597static void
Neale Ranns097fa662018-05-01 05:17:55 -0700598increment_address (vl_api_address_t * a)
599{
Dave Barach54582662020-04-21 08:01:16 -0400600 if (a->af == ADDRESS_IP4)
Neale Ranns097fa662018-05-01 05:17:55 -0700601 increment_v4_address (&a->un.ip4);
Dave Barach54582662020-04-21 08:01:16 -0400602 else if (a->af == ADDRESS_IP6)
Neale Ranns097fa662018-05-01 05:17:55 -0700603 increment_v6_address (&a->un.ip6);
604}
605
606static void
607set_ip4_address (vl_api_address_t * a, u32 v)
608{
609 if (a->af == ADDRESS_IP4)
610 {
611 ip4_address_t *i = (ip4_address_t *) & a->un.ip4;
612 i->as_u32 = v;
613 }
614}
615
Jakub Grajciar23a386b2020-02-26 11:01:43 +0100616void
617ip_set (ip46_address_t * dst, void *src, u8 is_ip4)
618{
619 if (is_ip4)
620 dst->ip4.as_u32 = ((ip4_address_t *) src)->as_u32;
621 else
622 clib_memcpy_fast (&dst->ip6, (ip6_address_t *) src,
623 sizeof (ip6_address_t));
624}
625
Neale Ranns097fa662018-05-01 05:17:55 -0700626static void
Mohsin Kazmi57938f62017-10-27 21:28:07 +0200627increment_mac_address (u8 * mac)
Damjan Marion7cd468a2016-12-19 23:05:39 +0100628{
Mohsin Kazmi57938f62017-10-27 21:28:07 +0200629 u64 tmp = *((u64 *) mac);
Damjan Marion7cd468a2016-12-19 23:05:39 +0100630 tmp = clib_net_to_host_u64 (tmp);
631 tmp += 1 << 16; /* skip unused (least significant) octets */
632 tmp = clib_host_to_net_u64 (tmp);
Mohsin Kazmi57938f62017-10-27 21:28:07 +0200633
634 clib_memcpy (mac, &tmp, 6);
Damjan Marion7cd468a2016-12-19 23:05:39 +0100635}
636
Neale Ranns097fa662018-05-01 05:17:55 -0700637static void
638vat_json_object_add_address (vat_json_node_t * node,
639 const char *str, const vl_api_address_t * addr)
640{
641 if (ADDRESS_IP6 == addr->af)
642 {
643 struct in6_addr ip6;
644
645 clib_memcpy (&ip6, &addr->un.ip6, sizeof (ip6));
646 vat_json_object_add_ip6 (node, str, ip6);
647 }
648 else
649 {
650 struct in_addr ip4;
651
652 clib_memcpy (&ip4, &addr->un.ip4, sizeof (ip4));
653 vat_json_object_add_ip4 (node, str, ip4);
654 }
655}
656
657static void
658vat_json_object_add_prefix (vat_json_node_t * node,
659 const vl_api_prefix_t * prefix)
660{
Paul Vinciguerraab055082019-06-06 14:07:55 -0400661 vat_json_object_add_uint (node, "len", prefix->len);
662 vat_json_object_add_address (node, "address", &prefix->address);
Neale Ranns097fa662018-05-01 05:17:55 -0700663}
664
Damjan Marion7cd468a2016-12-19 23:05:39 +0100665static void vl_api_create_loopback_reply_t_handler
666 (vl_api_create_loopback_reply_t * mp)
667{
668 vat_main_t *vam = &vat_main;
669 i32 retval = ntohl (mp->retval);
670
671 vam->retval = retval;
672 vam->regenerate_interface_table = 1;
673 vam->sw_if_index = ntohl (mp->sw_if_index);
674 vam->result_ready = 1;
675}
676
677static void vl_api_create_loopback_reply_t_handler_json
678 (vl_api_create_loopback_reply_t * mp)
679{
680 vat_main_t *vam = &vat_main;
681 vat_json_node_t node;
682
683 vat_json_init_object (&node);
684 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
685 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
686
687 vat_json_print (vam->ofp, &node);
688 vat_json_free (&node);
689 vam->retval = ntohl (mp->retval);
690 vam->result_ready = 1;
691}
692
Jon Loeligerc83c3b72017-02-23 13:57:35 -0600693static void vl_api_create_loopback_instance_reply_t_handler
694 (vl_api_create_loopback_instance_reply_t * mp)
695{
696 vat_main_t *vam = &vat_main;
697 i32 retval = ntohl (mp->retval);
698
699 vam->retval = retval;
700 vam->regenerate_interface_table = 1;
701 vam->sw_if_index = ntohl (mp->sw_if_index);
702 vam->result_ready = 1;
703}
704
705static void vl_api_create_loopback_instance_reply_t_handler_json
706 (vl_api_create_loopback_instance_reply_t * mp)
707{
708 vat_main_t *vam = &vat_main;
709 vat_json_node_t node;
710
711 vat_json_init_object (&node);
712 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
713 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
714
715 vat_json_print (vam->ofp, &node);
716 vat_json_free (&node);
717 vam->retval = ntohl (mp->retval);
718 vam->result_ready = 1;
719}
720
Damjan Marion7cd468a2016-12-19 23:05:39 +0100721static void vl_api_create_vlan_subif_reply_t_handler
722 (vl_api_create_vlan_subif_reply_t * mp)
723{
724 vat_main_t *vam = &vat_main;
725 i32 retval = ntohl (mp->retval);
726
727 vam->retval = retval;
728 vam->regenerate_interface_table = 1;
729 vam->sw_if_index = ntohl (mp->sw_if_index);
730 vam->result_ready = 1;
731}
732
733static void vl_api_create_vlan_subif_reply_t_handler_json
734 (vl_api_create_vlan_subif_reply_t * mp)
735{
736 vat_main_t *vam = &vat_main;
737 vat_json_node_t node;
738
739 vat_json_init_object (&node);
740 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
741 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
742
743 vat_json_print (vam->ofp, &node);
744 vat_json_free (&node);
745
746 vam->retval = ntohl (mp->retval);
747 vam->result_ready = 1;
748}
749
750static void vl_api_create_subif_reply_t_handler
751 (vl_api_create_subif_reply_t * mp)
752{
753 vat_main_t *vam = &vat_main;
754 i32 retval = ntohl (mp->retval);
755
756 vam->retval = retval;
757 vam->regenerate_interface_table = 1;
758 vam->sw_if_index = ntohl (mp->sw_if_index);
759 vam->result_ready = 1;
760}
761
762static void vl_api_create_subif_reply_t_handler_json
763 (vl_api_create_subif_reply_t * mp)
764{
765 vat_main_t *vam = &vat_main;
766 vat_json_node_t node;
767
768 vat_json_init_object (&node);
769 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
770 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
771
772 vat_json_print (vam->ofp, &node);
773 vat_json_free (&node);
774
775 vam->retval = ntohl (mp->retval);
776 vam->result_ready = 1;
777}
778
779static void vl_api_interface_name_renumber_reply_t_handler
780 (vl_api_interface_name_renumber_reply_t * mp)
781{
782 vat_main_t *vam = &vat_main;
783 i32 retval = ntohl (mp->retval);
784
785 vam->retval = retval;
786 vam->regenerate_interface_table = 1;
787 vam->result_ready = 1;
788}
789
790static void vl_api_interface_name_renumber_reply_t_handler_json
791 (vl_api_interface_name_renumber_reply_t * mp)
792{
793 vat_main_t *vam = &vat_main;
794 vat_json_node_t node;
795
796 vat_json_init_object (&node);
797 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
798
799 vat_json_print (vam->ofp, &node);
800 vat_json_free (&node);
801
802 vam->retval = ntohl (mp->retval);
803 vam->result_ready = 1;
804}
805
806/*
807 * Special-case: build the interface table, maintain
808 * the next loopback sw_if_index vbl.
809 */
810static void vl_api_sw_interface_details_t_handler
811 (vl_api_sw_interface_details_t * mp)
812{
813 vat_main_t *vam = &vat_main;
Ole Troane5ff5a32019-08-23 22:55:18 +0200814 u8 *s = format (0, "%s%c", mp->interface_name, 0);
Damjan Marion7cd468a2016-12-19 23:05:39 +0100815
816 hash_set_mem (vam->sw_if_index_by_interface_name, s,
817 ntohl (mp->sw_if_index));
818
819 /* In sub interface case, fill the sub interface table entry */
820 if (mp->sw_if_index != mp->sup_sw_if_index)
821 {
822 sw_interface_subif_t *sub = NULL;
823
824 vec_add2 (vam->sw_if_subif_table, sub, 1);
825
826 vec_validate (sub->interface_name, strlen ((char *) s) + 1);
827 strncpy ((char *) sub->interface_name, (char *) s,
828 vec_len (sub->interface_name));
829 sub->sw_if_index = ntohl (mp->sw_if_index);
830 sub->sub_id = ntohl (mp->sub_id);
831
Jakub Grajciar053204a2019-03-18 13:17:53 +0100832 sub->raw_flags = ntohl (mp->sub_if_flags & SUB_IF_API_FLAG_MASK_VNET);
833
Damjan Marion7cd468a2016-12-19 23:05:39 +0100834 sub->sub_number_of_tags = mp->sub_number_of_tags;
835 sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
836 sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
Damjan Marion7cd468a2016-12-19 23:05:39 +0100837
838 /* vlan tag rewrite */
839 sub->vtr_op = ntohl (mp->vtr_op);
840 sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
841 sub->vtr_tag1 = ntohl (mp->vtr_tag1);
842 sub->vtr_tag2 = ntohl (mp->vtr_tag2);
843 }
844}
845
846static void vl_api_sw_interface_details_t_handler_json
847 (vl_api_sw_interface_details_t * mp)
848{
849 vat_main_t *vam = &vat_main;
850 vat_json_node_t *node = NULL;
851
852 if (VAT_JSON_ARRAY != vam->json_tree.type)
853 {
854 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
855 vat_json_init_array (&vam->json_tree);
856 }
857 node = vat_json_array_add (&vam->json_tree);
858
859 vat_json_init_object (node);
860 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
861 vat_json_object_add_uint (node, "sup_sw_if_index",
862 ntohl (mp->sup_sw_if_index));
Damjan Marion7cd468a2016-12-19 23:05:39 +0100863 vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
864 sizeof (mp->l2_address));
865 vat_json_object_add_string_copy (node, "interface_name",
Ole Troane5ff5a32019-08-23 22:55:18 +0200866 mp->interface_name);
Mohsin Kazmide312c22019-09-27 13:44:28 +0200867 vat_json_object_add_string_copy (node, "interface_dev_type",
868 mp->interface_dev_type);
Jakub Grajciar053204a2019-03-18 13:17:53 +0100869 vat_json_object_add_uint (node, "flags", mp->flags);
Damjan Marion7cd468a2016-12-19 23:05:39 +0100870 vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
871 vat_json_object_add_uint (node, "link_speed", mp->link_speed);
Damjan Marionfe7d4a22018-04-13 19:43:39 +0200872 vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
Damjan Marion7cd468a2016-12-19 23:05:39 +0100873 vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
Damjan Marion7cd468a2016-12-19 23:05:39 +0100874 vat_json_object_add_uint (node, "sub_number_of_tags",
875 mp->sub_number_of_tags);
876 vat_json_object_add_uint (node, "sub_outer_vlan_id",
877 ntohs (mp->sub_outer_vlan_id));
878 vat_json_object_add_uint (node, "sub_inner_vlan_id",
879 ntohs (mp->sub_inner_vlan_id));
Jakub Grajciar053204a2019-03-18 13:17:53 +0100880 vat_json_object_add_uint (node, "sub_if_flags", ntohl (mp->sub_if_flags));
Damjan Marion7cd468a2016-12-19 23:05:39 +0100881 vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
882 vat_json_object_add_uint (node, "vtr_push_dot1q",
883 ntohl (mp->vtr_push_dot1q));
884 vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
885 vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
Jakub Grajciar053204a2019-03-18 13:17:53 +0100886 if (ntohl (mp->sub_if_flags) & SUB_IF_API_FLAG_DOT1AH)
Pavel Kotucek65e84572017-01-16 17:01:56 +0100887 {
888 vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
889 format (0, "%U",
890 format_ethernet_address,
891 &mp->b_dmac));
892 vat_json_object_add_string_copy (node, "pbb_vtr_smac",
893 format (0, "%U",
894 format_ethernet_address,
895 &mp->b_smac));
896 vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
897 vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
898 }
Damjan Marion7cd468a2016-12-19 23:05:39 +0100899}
900
Dave Baracha1a093d2017-03-02 13:13:23 -0500901#if VPP_API_TEST_BUILTIN == 0
Neale Rannsa07bd702017-08-07 07:53:49 -0700902static void vl_api_sw_interface_event_t_handler
903 (vl_api_sw_interface_event_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +0100904{
905 vat_main_t *vam = &vat_main;
906 if (vam->interface_event_display)
907 errmsg ("interface flags: sw_if_index %d %s %s",
908 ntohl (mp->sw_if_index),
Jakub Grajciar053204a2019-03-18 13:17:53 +0100909 ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_ADMIN_UP) ?
910 "admin-up" : "admin-down",
911 ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_LINK_UP) ?
912 "link-up" : "link-down");
Damjan Marion7cd468a2016-12-19 23:05:39 +0100913}
Dave Baracha1a093d2017-03-02 13:13:23 -0500914#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +0100915
Benoît Ganne49ee6842019-04-30 11:50:46 +0200916__clib_unused static void
917vl_api_sw_interface_event_t_handler_json (vl_api_sw_interface_event_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +0100918{
919 /* JSON output not supported */
920}
921
922static void
923vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
924{
925 vat_main_t *vam = &vat_main;
926 i32 retval = ntohl (mp->retval);
927
928 vam->retval = retval;
Damjan Marion7bee80c2017-04-26 15:32:12 +0200929 vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
Damjan Marion7cd468a2016-12-19 23:05:39 +0100930 vam->result_ready = 1;
931}
932
933static void
934vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
935{
936 vat_main_t *vam = &vat_main;
937 vat_json_node_t node;
Damjan Marion7cd468a2016-12-19 23:05:39 +0100938 void *oldheap;
939 u8 *reply;
940
941 vat_json_init_object (&node);
942 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
943 vat_json_object_add_uint (&node, "reply_in_shmem",
944 ntohl (mp->reply_in_shmem));
945 /* Toss the shared-memory original... */
Nathan Skrzypczak0aa40132019-11-25 16:29:38 +0100946 oldheap = vl_msg_push_heap ();
Damjan Marion7cd468a2016-12-19 23:05:39 +0100947
Damjan Marion7bee80c2017-04-26 15:32:12 +0200948 reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
Damjan Marion7cd468a2016-12-19 23:05:39 +0100949 vec_free (reply);
950
Nathan Skrzypczak0aa40132019-11-25 16:29:38 +0100951 vl_msg_pop_heap (oldheap);
Damjan Marion7cd468a2016-12-19 23:05:39 +0100952
953 vat_json_print (vam->ofp, &node);
954 vat_json_free (&node);
955
956 vam->retval = ntohl (mp->retval);
957 vam->result_ready = 1;
958}
959
960static void
961vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
962{
963 vat_main_t *vam = &vat_main;
964 i32 retval = ntohl (mp->retval);
Dave Barach59b25652017-09-10 15:04:27 -0400965
966 vec_reset_length (vam->cmd_reply);
Damjan Marion7cd468a2016-12-19 23:05:39 +0100967
968 vam->retval = retval;
Dave Barach59b25652017-09-10 15:04:27 -0400969 if (retval == 0)
Dave Barach77841402020-04-29 17:04:10 -0400970 vam->cmd_reply = vl_api_from_api_to_new_vec (mp, &mp->reply);
Damjan Marion7cd468a2016-12-19 23:05:39 +0100971 vam->result_ready = 1;
972}
973
974static void
975vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
976{
977 vat_main_t *vam = &vat_main;
978 vat_json_node_t node;
Jakub Grajciar2dbee932020-02-07 11:30:26 +0100979 u8 *reply = 0; /* reply vector */
Damjan Marion7cd468a2016-12-19 23:05:39 +0100980
Dave Barach77841402020-04-29 17:04:10 -0400981 reply = vl_api_from_api_to_new_vec (mp, &mp->reply);
Dave Barach59b25652017-09-10 15:04:27 -0400982 vec_reset_length (vam->cmd_reply);
983
Damjan Marion7cd468a2016-12-19 23:05:39 +0100984 vat_json_init_object (&node);
985 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
Jakub Grajciar2dbee932020-02-07 11:30:26 +0100986 vat_json_object_add_string_copy (&node, "reply", reply);
Damjan Marion7cd468a2016-12-19 23:05:39 +0100987
988 vat_json_print (vam->ofp, &node);
989 vat_json_free (&node);
Jakub Grajciar2dbee932020-02-07 11:30:26 +0100990 vec_free (reply);
Damjan Marion7cd468a2016-12-19 23:05:39 +0100991
992 vam->retval = ntohl (mp->retval);
993 vam->result_ready = 1;
994}
995
Damjan Marion7cd468a2016-12-19 23:05:39 +0100996static void vl_api_get_node_index_reply_t_handler
997 (vl_api_get_node_index_reply_t * mp)
998{
999 vat_main_t *vam = &vat_main;
1000 i32 retval = ntohl (mp->retval);
1001 if (vam->async_mode)
1002 {
1003 vam->async_errors += (retval < 0);
1004 }
1005 else
1006 {
1007 vam->retval = retval;
1008 if (retval == 0)
1009 errmsg ("node index %d", ntohl (mp->node_index));
1010 vam->result_ready = 1;
1011 }
1012}
1013
1014static void vl_api_get_node_index_reply_t_handler_json
1015 (vl_api_get_node_index_reply_t * mp)
1016{
1017 vat_main_t *vam = &vat_main;
1018 vat_json_node_t node;
1019
1020 vat_json_init_object (&node);
1021 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1022 vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1023
1024 vat_json_print (vam->ofp, &node);
1025 vat_json_free (&node);
1026
1027 vam->retval = ntohl (mp->retval);
1028 vam->result_ready = 1;
1029}
1030
1031static void vl_api_get_next_index_reply_t_handler
1032 (vl_api_get_next_index_reply_t * mp)
1033{
1034 vat_main_t *vam = &vat_main;
1035 i32 retval = ntohl (mp->retval);
1036 if (vam->async_mode)
1037 {
1038 vam->async_errors += (retval < 0);
1039 }
1040 else
1041 {
1042 vam->retval = retval;
1043 if (retval == 0)
1044 errmsg ("next node index %d", ntohl (mp->next_index));
1045 vam->result_ready = 1;
1046 }
1047}
1048
1049static void vl_api_get_next_index_reply_t_handler_json
1050 (vl_api_get_next_index_reply_t * mp)
1051{
1052 vat_main_t *vam = &vat_main;
1053 vat_json_node_t node;
1054
1055 vat_json_init_object (&node);
1056 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1057 vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1058
1059 vat_json_print (vam->ofp, &node);
1060 vat_json_free (&node);
1061
1062 vam->retval = ntohl (mp->retval);
1063 vam->result_ready = 1;
1064}
1065
1066static void vl_api_add_node_next_reply_t_handler
1067 (vl_api_add_node_next_reply_t * mp)
1068{
1069 vat_main_t *vam = &vat_main;
1070 i32 retval = ntohl (mp->retval);
1071 if (vam->async_mode)
1072 {
1073 vam->async_errors += (retval < 0);
1074 }
1075 else
1076 {
1077 vam->retval = retval;
1078 if (retval == 0)
1079 errmsg ("next index %d", ntohl (mp->next_index));
1080 vam->result_ready = 1;
1081 }
1082}
1083
1084static void vl_api_add_node_next_reply_t_handler_json
1085 (vl_api_add_node_next_reply_t * mp)
1086{
1087 vat_main_t *vam = &vat_main;
1088 vat_json_node_t node;
1089
1090 vat_json_init_object (&node);
1091 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1092 vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1093
1094 vat_json_print (vam->ofp, &node);
1095 vat_json_free (&node);
1096
1097 vam->retval = ntohl (mp->retval);
1098 vam->result_ready = 1;
1099}
1100
1101static void vl_api_show_version_reply_t_handler
1102 (vl_api_show_version_reply_t * mp)
1103{
1104 vat_main_t *vam = &vat_main;
1105 i32 retval = ntohl (mp->retval);
1106
1107 if (retval >= 0)
1108 {
Ole Troane5ff5a32019-08-23 22:55:18 +02001109 errmsg (" program: %s", mp->program);
1110 errmsg (" version: %s", mp->version);
1111 errmsg (" build date: %s", mp->build_date);
1112 errmsg ("build directory: %s", mp->build_directory);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001113 }
1114 vam->retval = retval;
1115 vam->result_ready = 1;
1116}
1117
1118static void vl_api_show_version_reply_t_handler_json
1119 (vl_api_show_version_reply_t * mp)
1120{
1121 vat_main_t *vam = &vat_main;
1122 vat_json_node_t node;
1123
1124 vat_json_init_object (&node);
1125 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
Ole Troane5ff5a32019-08-23 22:55:18 +02001126 vat_json_object_add_string_copy (&node, "program", mp->program);
1127 vat_json_object_add_string_copy (&node, "version", mp->version);
1128 vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001129 vat_json_object_add_string_copy (&node, "build_directory",
Ole Troane5ff5a32019-08-23 22:55:18 +02001130 mp->build_directory);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001131
1132 vat_json_print (vam->ofp, &node);
1133 vat_json_free (&node);
1134
1135 vam->retval = ntohl (mp->retval);
1136 vam->result_ready = 1;
1137}
1138
Mohsin Kazmi5d64c782018-09-11 20:27:09 +02001139static void vl_api_show_threads_reply_t_handler
1140 (vl_api_show_threads_reply_t * mp)
1141{
1142 vat_main_t *vam = &vat_main;
1143 i32 retval = ntohl (mp->retval);
1144 int i, count = 0;
1145
1146 if (retval >= 0)
1147 count = ntohl (mp->count);
1148
1149 for (i = 0; i < count; i++)
1150 print (vam->ofp,
1151 "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1152 ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1153 mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1154 ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1155 ntohl (mp->thread_data[i].cpu_socket));
1156
1157 vam->retval = retval;
1158 vam->result_ready = 1;
1159}
1160
1161static void vl_api_show_threads_reply_t_handler_json
1162 (vl_api_show_threads_reply_t * mp)
1163{
1164 vat_main_t *vam = &vat_main;
1165 vat_json_node_t node;
1166 vl_api_thread_data_t *td;
Mohsin Kazmi5df628b2018-10-01 17:41:08 +02001167 i32 retval = ntohl (mp->retval);
1168 int i, count = 0;
1169
1170 if (retval >= 0)
1171 count = ntohl (mp->count);
Mohsin Kazmi5d64c782018-09-11 20:27:09 +02001172
1173 vat_json_init_object (&node);
Mohsin Kazmi5df628b2018-10-01 17:41:08 +02001174 vat_json_object_add_int (&node, "retval", retval);
Mohsin Kazmi5d64c782018-09-11 20:27:09 +02001175 vat_json_object_add_uint (&node, "count", count);
1176
1177 for (i = 0; i < count; i++)
1178 {
1179 td = &mp->thread_data[i];
1180 vat_json_object_add_uint (&node, "id", ntohl (td->id));
1181 vat_json_object_add_string_copy (&node, "name", td->name);
1182 vat_json_object_add_string_copy (&node, "type", td->type);
1183 vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1184 vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1185 vat_json_object_add_int (&node, "core", ntohl (td->id));
1186 vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1187 }
1188
1189 vat_json_print (vam->ofp, &node);
1190 vat_json_free (&node);
1191
Mohsin Kazmi5df628b2018-10-01 17:41:08 +02001192 vam->retval = retval;
Mohsin Kazmi5d64c782018-09-11 20:27:09 +02001193 vam->result_ready = 1;
1194}
1195
1196static int
1197api_show_threads (vat_main_t * vam)
1198{
1199 vl_api_show_threads_t *mp;
1200 int ret;
1201
1202 print (vam->ofp,
1203 "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1204 "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1205
1206 M (SHOW_THREADS, mp);
1207
1208 S (mp);
1209 W (ret);
1210 return ret;
1211}
1212
Damjan Marion7cd468a2016-12-19 23:05:39 +01001213static void
John Lo8d00fff2017-08-03 00:35:36 -04001214vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1215{
1216 u32 n_macs = ntohl (mp->n_macs);
Paul Vinciguerraec11b132018-09-24 05:25:00 -07001217 errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
John Lo8d00fff2017-08-03 00:35:36 -04001218 ntohl (mp->pid), mp->client_index, n_macs);
1219 int i;
1220 for (i = 0; i < n_macs; i++)
1221 {
1222 vl_api_mac_entry_t *mac = &mp->mac[i];
John Loe23c99e2018-03-13 21:53:18 -04001223 errmsg (" [%d] sw_if_index %d mac_addr %U action %d \n",
John Lo8d00fff2017-08-03 00:35:36 -04001224 i + 1, ntohl (mac->sw_if_index),
John Loe23c99e2018-03-13 21:53:18 -04001225 format_ethernet_address, mac->mac_addr, mac->action);
John Lo8d00fff2017-08-03 00:35:36 -04001226 if (i == 1000)
1227 break;
1228 }
1229}
1230
1231static void
1232vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1233{
1234 /* JSON output not supported */
1235}
1236
Ole Troan01384fe2017-05-12 11:55:35 +02001237#define vl_api_bridge_domain_details_t_endian vl_noop_handler
1238#define vl_api_bridge_domain_details_t_print vl_noop_handler
1239
Damjan Marion7cd468a2016-12-19 23:05:39 +01001240/*
1241 * Special-case: build the bridge domain table, maintain
1242 * the next bd id vbl.
1243 */
1244static void vl_api_bridge_domain_details_t_handler
1245 (vl_api_bridge_domain_details_t * mp)
1246{
1247 vat_main_t *vam = &vat_main;
1248 u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
Ole Troan01384fe2017-05-12 11:55:35 +02001249 int i;
Damjan Marion7cd468a2016-12-19 23:05:39 +01001250
Mohsin Kazmi762d83c2018-09-27 15:00:32 +02001251 print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1252 " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
Damjan Marion7cd468a2016-12-19 23:05:39 +01001253
Mohsin Kazmi762d83c2018-09-27 15:00:32 +02001254 print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
Damjan Marion7cd468a2016-12-19 23:05:39 +01001255 ntohl (mp->bd_id), mp->learn, mp->forward,
Mohsin Kazmi762d83c2018-09-27 15:00:32 +02001256 mp->flood, ntohl (mp->bvi_sw_if_index),
1257 ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001258
1259 if (n_sw_ifs)
Ole Troan01384fe2017-05-12 11:55:35 +02001260 {
1261 vl_api_bridge_domain_sw_if_t *sw_ifs;
1262 print (vam->ofp, "\n\n%s %s %s", "sw_if_index", "SHG",
1263 "Interface Name");
1264
1265 sw_ifs = mp->sw_if_details;
1266 for (i = 0; i < n_sw_ifs; i++)
1267 {
1268 u8 *sw_if_name = 0;
1269 u32 sw_if_index;
1270 hash_pair_t *p;
1271
1272 sw_if_index = ntohl (sw_ifs->sw_if_index);
1273
1274 /* *INDENT-OFF* */
1275 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1276 ({
1277 if ((u32) p->value[0] == sw_if_index)
1278 {
1279 sw_if_name = (u8 *)(p->key);
1280 break;
1281 }
1282 }));
1283 /* *INDENT-ON* */
1284 print (vam->ofp, "%7d %3d %s", sw_if_index,
1285 sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1286 "sw_if_index not found!");
1287
1288 sw_ifs++;
1289 }
1290 }
Damjan Marion7cd468a2016-12-19 23:05:39 +01001291}
1292
1293static void vl_api_bridge_domain_details_t_handler_json
1294 (vl_api_bridge_domain_details_t * mp)
1295{
1296 vat_main_t *vam = &vat_main;
1297 vat_json_node_t *node, *array = NULL;
Ole Troan01384fe2017-05-12 11:55:35 +02001298 u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001299
1300 if (VAT_JSON_ARRAY != vam->json_tree.type)
1301 {
1302 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1303 vat_json_init_array (&vam->json_tree);
1304 }
1305 node = vat_json_array_add (&vam->json_tree);
1306
1307 vat_json_init_object (node);
1308 vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1309 vat_json_object_add_uint (node, "flood", mp->flood);
1310 vat_json_object_add_uint (node, "forward", mp->forward);
1311 vat_json_object_add_uint (node, "learn", mp->learn);
1312 vat_json_object_add_uint (node, "bvi_sw_if_index",
1313 ntohl (mp->bvi_sw_if_index));
Ole Troan01384fe2017-05-12 11:55:35 +02001314 vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001315 array = vat_json_object_add (node, "sw_if");
1316 vat_json_init_array (array);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001317
Damjan Marion7cd468a2016-12-19 23:05:39 +01001318
Damjan Marion7cd468a2016-12-19 23:05:39 +01001319
Ole Troan01384fe2017-05-12 11:55:35 +02001320 if (n_sw_ifs)
1321 {
1322 vl_api_bridge_domain_sw_if_t *sw_ifs;
1323 int i;
Damjan Marion7cd468a2016-12-19 23:05:39 +01001324
Ole Troan01384fe2017-05-12 11:55:35 +02001325 sw_ifs = mp->sw_if_details;
1326 for (i = 0; i < n_sw_ifs; i++)
1327 {
1328 node = vat_json_array_add (array);
1329 vat_json_init_object (node);
1330 vat_json_object_add_uint (node, "sw_if_index",
1331 ntohl (sw_ifs->sw_if_index));
1332 vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1333 sw_ifs++;
1334 }
1335 }
Damjan Marion7cd468a2016-12-19 23:05:39 +01001336}
1337
1338static void vl_api_control_ping_reply_t_handler
1339 (vl_api_control_ping_reply_t * mp)
1340{
1341 vat_main_t *vam = &vat_main;
1342 i32 retval = ntohl (mp->retval);
1343 if (vam->async_mode)
1344 {
1345 vam->async_errors += (retval < 0);
1346 }
1347 else
1348 {
1349 vam->retval = retval;
1350 vam->result_ready = 1;
1351 }
Florin Coras90a63982017-12-19 04:50:01 -08001352 if (vam->socket_client_main)
1353 vam->socket_client_main->control_pings_outstanding--;
Damjan Marion7cd468a2016-12-19 23:05:39 +01001354}
1355
1356static void vl_api_control_ping_reply_t_handler_json
1357 (vl_api_control_ping_reply_t * mp)
1358{
1359 vat_main_t *vam = &vat_main;
1360 i32 retval = ntohl (mp->retval);
1361
1362 if (VAT_JSON_NONE != vam->json_tree.type)
1363 {
1364 vat_json_print (vam->ofp, &vam->json_tree);
1365 vat_json_free (&vam->json_tree);
1366 vam->json_tree.type = VAT_JSON_NONE;
1367 }
1368 else
1369 {
1370 /* just print [] */
1371 vat_json_init_array (&vam->json_tree);
1372 vat_json_print (vam->ofp, &vam->json_tree);
1373 vam->json_tree.type = VAT_JSON_NONE;
1374 }
1375
1376 vam->retval = retval;
1377 vam->result_ready = 1;
1378}
1379
1380static void
Eyal Barifead6702017-04-04 04:46:32 +03001381 vl_api_bridge_domain_set_mac_age_reply_t_handler
1382 (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1383{
1384 vat_main_t *vam = &vat_main;
1385 i32 retval = ntohl (mp->retval);
1386 if (vam->async_mode)
1387 {
1388 vam->async_errors += (retval < 0);
1389 }
1390 else
1391 {
1392 vam->retval = retval;
1393 vam->result_ready = 1;
1394 }
1395}
1396
1397static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1398 (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1399{
1400 vat_main_t *vam = &vat_main;
1401 vat_json_node_t node;
1402
1403 vat_json_init_object (&node);
1404 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1405
1406 vat_json_print (vam->ofp, &node);
1407 vat_json_free (&node);
1408
1409 vam->retval = ntohl (mp->retval);
1410 vam->result_ready = 1;
1411}
1412
1413static void
Damjan Marion7cd468a2016-12-19 23:05:39 +01001414vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1415{
1416 vat_main_t *vam = &vat_main;
1417 i32 retval = ntohl (mp->retval);
1418 if (vam->async_mode)
1419 {
1420 vam->async_errors += (retval < 0);
1421 }
1422 else
1423 {
1424 vam->retval = retval;
1425 vam->result_ready = 1;
1426 }
1427}
1428
1429static void vl_api_l2_flags_reply_t_handler_json
1430 (vl_api_l2_flags_reply_t * mp)
1431{
1432 vat_main_t *vam = &vat_main;
1433 vat_json_node_t node;
1434
1435 vat_json_init_object (&node);
1436 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1437 vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1438 ntohl (mp->resulting_feature_bitmap));
1439
1440 vat_json_print (vam->ofp, &node);
1441 vat_json_free (&node);
1442
1443 vam->retval = ntohl (mp->retval);
1444 vam->result_ready = 1;
1445}
1446
1447static void vl_api_bridge_flags_reply_t_handler
1448 (vl_api_bridge_flags_reply_t * mp)
1449{
1450 vat_main_t *vam = &vat_main;
1451 i32 retval = ntohl (mp->retval);
1452 if (vam->async_mode)
1453 {
1454 vam->async_errors += (retval < 0);
1455 }
1456 else
1457 {
1458 vam->retval = retval;
1459 vam->result_ready = 1;
1460 }
1461}
1462
1463static void vl_api_bridge_flags_reply_t_handler_json
1464 (vl_api_bridge_flags_reply_t * mp)
1465{
1466 vat_main_t *vam = &vat_main;
1467 vat_json_node_t node;
1468
1469 vat_json_init_object (&node);
1470 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1471 vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1472 ntohl (mp->resulting_feature_bitmap));
1473
1474 vat_json_print (vam->ofp, &node);
1475 vat_json_free (&node);
1476
1477 vam->retval = ntohl (mp->retval);
1478 vam->result_ready = 1;
1479}
1480
Damjan Marion8389fb92017-10-13 18:29:53 +02001481static void
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01001482vl_api_virtio_pci_create_reply_t_handler (vl_api_virtio_pci_create_reply_t *
1483 mp)
1484{
1485 vat_main_t *vam = &vat_main;
1486 i32 retval = ntohl (mp->retval);
1487 if (vam->async_mode)
1488 {
1489 vam->async_errors += (retval < 0);
1490 }
1491 else
1492 {
1493 vam->retval = retval;
1494 vam->sw_if_index = ntohl (mp->sw_if_index);
1495 vam->result_ready = 1;
1496 }
1497}
1498
1499static void vl_api_virtio_pci_create_reply_t_handler_json
1500 (vl_api_virtio_pci_create_reply_t * mp)
1501{
1502 vat_main_t *vam = &vat_main;
1503 vat_json_node_t node;
1504
1505 vat_json_init_object (&node);
1506 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1507 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1508
1509 vat_json_print (vam->ofp, &node);
1510 vat_json_free (&node);
1511
1512 vam->retval = ntohl (mp->retval);
1513 vam->result_ready = 1;
1514
1515}
1516
1517static void
Mohsin Kazmi518251b2020-09-01 17:17:44 +00001518 vl_api_virtio_pci_create_v2_reply_t_handler
1519 (vl_api_virtio_pci_create_v2_reply_t * mp)
1520{
1521 vat_main_t *vam = &vat_main;
1522 i32 retval = ntohl (mp->retval);
1523 if (vam->async_mode)
1524 {
1525 vam->async_errors += (retval < 0);
1526 }
1527 else
1528 {
1529 vam->retval = retval;
1530 vam->sw_if_index = ntohl (mp->sw_if_index);
1531 vam->result_ready = 1;
1532 }
1533}
1534
1535static void vl_api_virtio_pci_create_v2_reply_t_handler_json
1536 (vl_api_virtio_pci_create_v2_reply_t * mp)
1537{
1538 vat_main_t *vam = &vat_main;
1539 vat_json_node_t node;
1540
1541 vat_json_init_object (&node);
1542 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1543 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1544
1545 vat_json_print (vam->ofp, &node);
1546 vat_json_free (&node);
1547
1548 vam->retval = ntohl (mp->retval);
1549 vam->result_ready = 1;
1550}
1551
1552static void
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01001553vl_api_virtio_pci_delete_reply_t_handler (vl_api_virtio_pci_delete_reply_t *
1554 mp)
1555{
1556 vat_main_t *vam = &vat_main;
1557 i32 retval = ntohl (mp->retval);
1558 if (vam->async_mode)
1559 {
1560 vam->async_errors += (retval < 0);
1561 }
1562 else
1563 {
1564 vam->retval = retval;
1565 vam->result_ready = 1;
1566 }
1567}
1568
1569static void vl_api_virtio_pci_delete_reply_t_handler_json
1570 (vl_api_virtio_pci_delete_reply_t * mp)
1571{
1572 vat_main_t *vam = &vat_main;
1573 vat_json_node_t node;
1574
1575 vat_json_init_object (&node);
1576 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1577
1578 vat_json_print (vam->ofp, &node);
1579 vat_json_free (&node);
1580
1581 vam->retval = ntohl (mp->retval);
1582 vam->result_ready = 1;
1583}
1584
Damjan Marion7cd468a2016-12-19 23:05:39 +01001585static void vl_api_mpls_tunnel_add_del_reply_t_handler
1586 (vl_api_mpls_tunnel_add_del_reply_t * mp)
1587{
1588 vat_main_t *vam = &vat_main;
1589 i32 retval = ntohl (mp->retval);
1590 if (vam->async_mode)
1591 {
1592 vam->async_errors += (retval < 0);
1593 }
1594 else
1595 {
1596 vam->retval = retval;
John Lo06fda9c2018-10-03 16:32:44 -04001597 vam->sw_if_index = ntohl (mp->sw_if_index);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001598 vam->result_ready = 1;
1599 }
John Lo06fda9c2018-10-03 16:32:44 -04001600 vam->regenerate_interface_table = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01001601}
1602
1603static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1604 (vl_api_mpls_tunnel_add_del_reply_t * mp)
1605{
1606 vat_main_t *vam = &vat_main;
1607 vat_json_node_t node;
1608
1609 vat_json_init_object (&node);
1610 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1611 vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1612 ntohl (mp->sw_if_index));
1613
1614 vat_json_print (vam->ofp, &node);
1615 vat_json_free (&node);
1616
1617 vam->retval = ntohl (mp->retval);
1618 vam->result_ready = 1;
1619}
1620
Damjan Marion7cd468a2016-12-19 23:05:39 +01001621static void vl_api_ip_address_details_t_handler
1622 (vl_api_ip_address_details_t * mp)
1623{
1624 vat_main_t *vam = &vat_main;
1625 static ip_address_details_t empty_ip_address_details = { {0} };
1626 ip_address_details_t *address = NULL;
1627 ip_details_t *current_ip_details = NULL;
1628 ip_details_t *details = NULL;
1629
1630 details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1631
1632 if (!details || vam->current_sw_if_index >= vec_len (details)
1633 || !details[vam->current_sw_if_index].present)
1634 {
1635 errmsg ("ip address details arrived but not stored");
1636 errmsg ("ip_dump should be called first");
1637 return;
1638 }
1639
1640 current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1641
1642#define addresses (current_ip_details->addr)
1643
1644 vec_validate_init_empty (addresses, vec_len (addresses),
1645 empty_ip_address_details);
1646
1647 address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1648
Neale Ranns097fa662018-05-01 05:17:55 -07001649 clib_memcpy (&address->ip, &mp->prefix.address.un, sizeof (address->ip));
Paul Vinciguerraab055082019-06-06 14:07:55 -04001650 address->prefix_length = mp->prefix.len;
Damjan Marion7cd468a2016-12-19 23:05:39 +01001651#undef addresses
1652}
1653
1654static void vl_api_ip_address_details_t_handler_json
1655 (vl_api_ip_address_details_t * mp)
1656{
1657 vat_main_t *vam = &vat_main;
1658 vat_json_node_t *node = NULL;
Damjan Marion7cd468a2016-12-19 23:05:39 +01001659
1660 if (VAT_JSON_ARRAY != vam->json_tree.type)
1661 {
1662 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1663 vat_json_init_array (&vam->json_tree);
1664 }
1665 node = vat_json_array_add (&vam->json_tree);
1666
1667 vat_json_init_object (node);
Neale Ranns097fa662018-05-01 05:17:55 -07001668 vat_json_object_add_prefix (node, &mp->prefix);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001669}
1670
1671static void
1672vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1673{
1674 vat_main_t *vam = &vat_main;
1675 static ip_details_t empty_ip_details = { 0 };
1676 ip_details_t *ip = NULL;
1677 u32 sw_if_index = ~0;
1678
1679 sw_if_index = ntohl (mp->sw_if_index);
1680
1681 vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1682 sw_if_index, empty_ip_details);
1683
1684 ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1685 sw_if_index);
1686
1687 ip->present = 1;
1688}
1689
1690static void
1691vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1692{
1693 vat_main_t *vam = &vat_main;
1694
1695 if (VAT_JSON_ARRAY != vam->json_tree.type)
1696 {
1697 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1698 vat_json_init_array (&vam->json_tree);
1699 }
1700 vat_json_array_add_uint (&vam->json_tree,
1701 clib_net_to_host_u32 (mp->sw_if_index));
1702}
1703
Damjan Marion7cd468a2016-12-19 23:05:39 +01001704static void vl_api_get_first_msg_id_reply_t_handler
1705 (vl_api_get_first_msg_id_reply_t * mp)
1706{
1707 vat_main_t *vam = &vat_main;
1708 i32 retval = ntohl (mp->retval);
1709
1710 if (vam->async_mode)
1711 {
1712 vam->async_errors += (retval < 0);
1713 }
1714 else
1715 {
1716 vam->retval = retval;
1717 vam->result_ready = 1;
1718 }
1719 if (retval >= 0)
1720 {
1721 errmsg ("first message id %d", ntohs (mp->first_msg_id));
1722 }
1723}
1724
1725static void vl_api_get_first_msg_id_reply_t_handler_json
1726 (vl_api_get_first_msg_id_reply_t * mp)
1727{
1728 vat_main_t *vam = &vat_main;
1729 vat_json_node_t node;
1730
1731 vat_json_init_object (&node);
1732 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1733 vat_json_object_add_uint (&node, "first_msg_id",
1734 (uint) ntohs (mp->first_msg_id));
1735
1736 vat_json_print (vam->ofp, &node);
1737 vat_json_free (&node);
1738
1739 vam->retval = ntohl (mp->retval);
1740 vam->result_ready = 1;
1741}
1742
1743static void vl_api_get_node_graph_reply_t_handler
1744 (vl_api_get_node_graph_reply_t * mp)
1745{
1746 vat_main_t *vam = &vat_main;
Damjan Marion7cd468a2016-12-19 23:05:39 +01001747 i32 retval = ntohl (mp->retval);
1748 u8 *pvt_copy, *reply;
1749 void *oldheap;
1750 vlib_node_t *node;
1751 int i;
1752
1753 if (vam->async_mode)
1754 {
1755 vam->async_errors += (retval < 0);
1756 }
1757 else
1758 {
1759 vam->retval = retval;
1760 vam->result_ready = 1;
1761 }
1762
1763 /* "Should never happen..." */
1764 if (retval != 0)
1765 return;
1766
Damjan Marion7bee80c2017-04-26 15:32:12 +02001767 reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001768 pvt_copy = vec_dup (reply);
1769
1770 /* Toss the shared-memory original... */
Nathan Skrzypczak0aa40132019-11-25 16:29:38 +01001771 oldheap = vl_msg_push_heap ();
Damjan Marion7cd468a2016-12-19 23:05:39 +01001772
1773 vec_free (reply);
1774
Nathan Skrzypczak0aa40132019-11-25 16:29:38 +01001775 vl_msg_pop_heap (oldheap);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001776
1777 if (vam->graph_nodes)
1778 {
1779 hash_free (vam->graph_node_index_by_name);
1780
Dave Barach1ddbc012018-06-13 09:26:05 -04001781 for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
Damjan Marion7cd468a2016-12-19 23:05:39 +01001782 {
Dave Barach1ddbc012018-06-13 09:26:05 -04001783 node = vam->graph_nodes[0][i];
Damjan Marion7cd468a2016-12-19 23:05:39 +01001784 vec_free (node->name);
1785 vec_free (node->next_nodes);
1786 vec_free (node);
1787 }
Dave Barach1ddbc012018-06-13 09:26:05 -04001788 vec_free (vam->graph_nodes[0]);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001789 vec_free (vam->graph_nodes);
1790 }
1791
1792 vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
1793 vam->graph_nodes = vlib_node_unserialize (pvt_copy);
1794 vec_free (pvt_copy);
1795
Dave Barach1ddbc012018-06-13 09:26:05 -04001796 for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
Damjan Marion7cd468a2016-12-19 23:05:39 +01001797 {
Dave Barach1ddbc012018-06-13 09:26:05 -04001798 node = vam->graph_nodes[0][i];
Damjan Marion7cd468a2016-12-19 23:05:39 +01001799 hash_set_mem (vam->graph_node_index_by_name, node->name, i);
1800 }
1801}
1802
1803static void vl_api_get_node_graph_reply_t_handler_json
1804 (vl_api_get_node_graph_reply_t * mp)
1805{
1806 vat_main_t *vam = &vat_main;
Damjan Marion7cd468a2016-12-19 23:05:39 +01001807 void *oldheap;
1808 vat_json_node_t node;
1809 u8 *reply;
1810
1811 /* $$$$ make this real? */
1812 vat_json_init_object (&node);
1813 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1814 vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
1815
Damjan Marion7bee80c2017-04-26 15:32:12 +02001816 reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001817
1818 /* Toss the shared-memory original... */
Nathan Skrzypczak0aa40132019-11-25 16:29:38 +01001819 oldheap = vl_msg_push_heap ();
Damjan Marion7cd468a2016-12-19 23:05:39 +01001820
1821 vec_free (reply);
1822
Nathan Skrzypczak0aa40132019-11-25 16:29:38 +01001823 vl_msg_pop_heap (oldheap);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001824
1825 vat_json_print (vam->ofp, &node);
1826 vat_json_free (&node);
1827
1828 vam->retval = ntohl (mp->retval);
1829 vam->result_ready = 1;
1830}
1831
Damjan Marion7cd468a2016-12-19 23:05:39 +01001832/* Format hex dump. */
1833u8 *
1834format_hex_bytes (u8 * s, va_list * va)
1835{
1836 u8 *bytes = va_arg (*va, u8 *);
1837 int n_bytes = va_arg (*va, int);
1838 uword i;
1839
1840 /* Print short or long form depending on byte count. */
1841 uword short_form = n_bytes <= 32;
Christophe Fontained3c008d2017-10-02 18:10:54 +02001842 u32 indent = format_get_indent (s);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001843
1844 if (n_bytes == 0)
1845 return s;
1846
1847 for (i = 0; i < n_bytes; i++)
1848 {
1849 if (!short_form && (i % 32) == 0)
1850 s = format (s, "%08x: ", i);
1851 s = format (s, "%02x", bytes[i]);
1852 if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
1853 s = format (s, "\n%U", format_white_space, indent);
1854 }
1855
1856 return s;
1857}
1858
Damjan Marion7cd468a2016-12-19 23:05:39 +01001859/*
1860 * Generate boilerplate reply handlers, which
1861 * dig the return value out of the xxx_reply_t API message,
1862 * stick it into vam->retval, and set vam->result_ready
1863 *
1864 * Could also do this by pointing N message decode slots at
1865 * a single function, but that could break in subtle ways.
1866 */
1867
1868#define foreach_standard_reply_retval_handler \
1869_(sw_interface_set_flags_reply) \
1870_(sw_interface_add_del_address_reply) \
Stevenad8015b2017-10-29 22:10:46 -07001871_(sw_interface_set_rx_mode_reply) \
Mohsin Kazmi54f7c512018-08-23 18:28:11 +02001872_(sw_interface_set_rx_placement_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01001873_(sw_interface_set_table_reply) \
1874_(sw_interface_set_mpls_enable_reply) \
1875_(sw_interface_set_vpath_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01001876_(sw_interface_set_l2_bridge_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01001877_(bridge_domain_add_del_reply) \
1878_(sw_interface_set_l2_xconnect_reply) \
1879_(l2fib_add_del_reply) \
Eyal Barif24991c2017-04-05 05:33:21 +03001880_(l2fib_flush_int_reply) \
1881_(l2fib_flush_bd_reply) \
Neale Ranns097fa662018-05-01 05:17:55 -07001882_(ip_route_add_del_reply) \
Neale Ranns28ab9cc2017-08-14 07:18:42 -07001883_(ip_table_add_del_reply) \
Neale Ranns9db6ada2019-11-08 12:42:31 +00001884_(ip_table_replace_begin_reply) \
1885_(ip_table_flush_reply) \
1886_(ip_table_replace_end_reply) \
Neale Ranns32e1c012016-11-22 17:07:28 +00001887_(ip_mroute_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01001888_(mpls_route_add_del_reply) \
Neale Ranns28ab9cc2017-08-14 07:18:42 -07001889_(mpls_table_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01001890_(mpls_ip_bind_unbind_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01001891_(sw_interface_set_unnumbered_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01001892_(set_ip_flow_hash_reply) \
1893_(sw_interface_ip6_enable_disable_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01001894_(l2_patch_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01001895_(l2_fib_clear_table_reply) \
1896_(l2_interface_efp_filter_reply) \
1897_(l2_interface_vlan_tag_rewrite_reply) \
John Lo8d00fff2017-08-03 00:35:36 -04001898_(want_l2_macs_events_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01001899_(delete_loopback_reply) \
1900_(bd_ip_mac_add_del_reply) \
John Loe26c81f2019-01-07 15:16:33 -05001901_(bd_ip_mac_flush_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01001902_(want_interface_events_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01001903_(sw_interface_clear_stats_reply) \
Dave Barach65457162017-10-10 17:53:14 -04001904_(ioam_enable_reply) \
1905_(ioam_disable_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01001906_(sw_interface_span_enable_disable_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01001907_(ip_source_and_port_range_check_add_del_reply) \
1908_(ip_source_and_port_range_check_interface_add_del_reply)\
1909_(delete_subif_reply) \
1910_(l2_interface_pbb_tag_rewrite_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01001911_(sw_interface_tag_add_del_reply) \
Matthew Smithe0792fd2019-07-12 11:48:24 -05001912_(sw_interface_add_del_mac_address_reply) \
Ole Troand7231612018-06-07 10:17:57 +02001913_(hw_interface_set_mtu_reply) \
Florin Corascea194d2017-10-02 00:18:51 -07001914_(tcp_configure_src_addresses_reply) \
Florin Coras595992c2017-11-06 17:17:08 -08001915_(session_rule_add_del_reply) \
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +01001916_(ip_container_proxy_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01001917
1918#define _(n) \
1919 static void vl_api_##n##_t_handler \
1920 (vl_api_##n##_t * mp) \
1921 { \
1922 vat_main_t * vam = &vat_main; \
1923 i32 retval = ntohl(mp->retval); \
1924 if (vam->async_mode) { \
1925 vam->async_errors += (retval < 0); \
1926 } else { \
1927 vam->retval = retval; \
1928 vam->result_ready = 1; \
1929 } \
1930 }
1931foreach_standard_reply_retval_handler;
1932#undef _
1933
1934#define _(n) \
1935 static void vl_api_##n##_t_handler_json \
1936 (vl_api_##n##_t * mp) \
1937 { \
1938 vat_main_t * vam = &vat_main; \
1939 vat_json_node_t node; \
1940 vat_json_init_object(&node); \
1941 vat_json_object_add_int(&node, "retval", ntohl(mp->retval)); \
1942 vat_json_print(vam->ofp, &node); \
1943 vam->retval = ntohl(mp->retval); \
1944 vam->result_ready = 1; \
1945 }
1946foreach_standard_reply_retval_handler;
1947#undef _
1948
1949/*
1950 * Table of message reply handlers, must include boilerplate handlers
1951 * we just generated
1952 */
1953
1954#define foreach_vpe_api_reply_msg \
1955_(CREATE_LOOPBACK_REPLY, create_loopback_reply) \
Jon Loeligerc83c3b72017-02-23 13:57:35 -06001956_(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01001957_(SW_INTERFACE_DETAILS, sw_interface_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01001958_(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply) \
1959_(CONTROL_PING_REPLY, control_ping_reply) \
1960_(CLI_REPLY, cli_reply) \
1961_(CLI_INBAND_REPLY, cli_inband_reply) \
1962_(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY, \
1963 sw_interface_add_del_address_reply) \
Stevenad8015b2017-10-29 22:10:46 -07001964_(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply) \
Mohsin Kazmi54f7c512018-08-23 18:28:11 +02001965_(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply) \
Mohsin Kazmif0b42f42018-09-10 18:11:00 +02001966_(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01001967_(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply) \
1968_(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
1969_(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01001970_(SW_INTERFACE_SET_L2_XCONNECT_REPLY, \
1971 sw_interface_set_l2_xconnect_reply) \
1972_(SW_INTERFACE_SET_L2_BRIDGE_REPLY, \
1973 sw_interface_set_l2_bridge_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01001974_(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply) \
1975_(BRIDGE_DOMAIN_DETAILS, bridge_domain_details) \
Eyal Barifead6702017-04-04 04:46:32 +03001976_(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01001977_(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply) \
Eyal Barif24991c2017-04-05 05:33:21 +03001978_(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply) \
1979_(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01001980_(L2_FLAGS_REPLY, l2_flags_reply) \
1981_(BRIDGE_FLAGS_REPLY, bridge_flags_reply) \
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01001982_(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply) \
Mohsin Kazmi518251b2020-09-01 17:17:44 +00001983_(VIRTIO_PCI_CREATE_V2_REPLY, virtio_pci_create_v2_reply) \
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01001984_(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply) \
1985_(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details) \
Neale Ranns097fa662018-05-01 05:17:55 -07001986_(IP_ROUTE_ADD_DEL_REPLY, ip_route_add_del_reply) \
Neale Ranns28ab9cc2017-08-14 07:18:42 -07001987_(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply) \
Neale Ranns9db6ada2019-11-08 12:42:31 +00001988_(IP_TABLE_REPLACE_BEGIN_REPLY, ip_table_replace_begin_reply) \
1989_(IP_TABLE_FLUSH_REPLY, ip_table_flush_reply) \
1990_(IP_TABLE_REPLACE_END_REPLY, ip_table_replace_end_reply) \
Neale Ranns32e1c012016-11-22 17:07:28 +00001991_(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply) \
Neale Ranns28ab9cc2017-08-14 07:18:42 -07001992_(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01001993_(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply) \
1994_(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01001995_(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply) \
1996_(SW_INTERFACE_SET_UNNUMBERED_REPLY, \
1997 sw_interface_set_unnumbered_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01001998_(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply) \
1999_(CREATE_SUBIF_REPLY, create_subif_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01002000_(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply) \
2001_(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY, \
2002 sw_interface_ip6_enable_disable_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01002003_(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01002004_(GET_NODE_INDEX_REPLY, get_node_index_reply) \
2005_(ADD_NODE_NEXT_REPLY, add_node_next_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01002006_(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply) \
2007_(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply) \
2008_(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01002009_(SHOW_VERSION_REPLY, show_version_reply) \
Mohsin Kazmi5d64c782018-09-11 20:27:09 +02002010_(SHOW_THREADS_REPLY, show_threads_reply) \
Ole Troan01384fe2017-05-12 11:55:35 +02002011_(L2_FIB_TABLE_DETAILS, l2_fib_table_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01002012_(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply) \
John Lo8d00fff2017-08-03 00:35:36 -04002013_(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply) \
2014_(L2_MACS_EVENT, l2_macs_event) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01002015_(IP_ADDRESS_DETAILS, ip_address_details) \
2016_(IP_DETAILS, ip_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01002017_(DELETE_LOOPBACK_REPLY, delete_loopback_reply) \
2018_(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply) \
John Loe26c81f2019-01-07 15:16:33 -05002019_(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply) \
Mohsin Kazmi5d82d2f2018-08-13 19:17:54 +02002020_(BD_IP_MAC_DETAILS, bd_ip_mac_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01002021_(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01002022_(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01002023_(GET_NODE_GRAPH_REPLY, get_node_graph_reply) \
2024_(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply) \
2025_(IOAM_ENABLE_REPLY, ioam_enable_reply) \
2026_(IOAM_DISABLE_REPLY, ioam_disable_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01002027_(MPLS_TUNNEL_DETAILS, mpls_tunnel_details) \
Neale Ranns097fa662018-05-01 05:17:55 -07002028_(MPLS_TABLE_DETAILS, mpls_table_details) \
2029_(MPLS_ROUTE_DETAILS, mpls_route_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01002030_(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
2031_(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details) \
2032_(GET_NEXT_INDEX_REPLY, get_next_index_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01002033_(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY, \
2034 ip_source_and_port_range_check_add_del_reply) \
2035_(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY, \
2036 ip_source_and_port_range_check_interface_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01002037_(DELETE_SUBIF_REPLY, delete_subif_reply) \
2038_(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
Neale Ranns097fa662018-05-01 05:17:55 -07002039_(IP_TABLE_DETAILS, ip_table_details) \
2040_(IP_ROUTE_DETAILS, ip_route_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01002041_(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply) \
Matthew Smithe0792fd2019-07-12 11:48:24 -05002042_(SW_INTERFACE_ADD_DEL_MAC_ADDRESS_REPLY, sw_interface_add_del_mac_address_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01002043_(L2_XCONNECT_DETAILS, l2_xconnect_details) \
Ole Troand7231612018-06-07 10:17:57 +02002044_(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply) \
Pavel Kotucek6899a302017-06-08 08:46:10 +02002045_(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply) \
Florin Corascea194d2017-10-02 00:18:51 -07002046_(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
Dave Barach65457162017-10-10 17:53:14 -04002047_(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply) \
Florin Coras6c36f532017-11-03 18:32:34 -07002048_(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply) \
Florin Coras595992c2017-11-06 17:17:08 -08002049_(SESSION_RULES_DETAILS, session_rules_details) \
2050_(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01002051
Dave Baracha1a093d2017-03-02 13:13:23 -05002052#define foreach_standalone_reply_msg \
Ole Troanf49ba0e2018-11-13 14:04:50 +01002053_(SW_INTERFACE_EVENT, sw_interface_event)
Dave Baracha1a093d2017-03-02 13:13:23 -05002054
Damjan Marion7cd468a2016-12-19 23:05:39 +01002055typedef struct
2056{
2057 u8 *name;
2058 u32 value;
2059} name_sort_t;
2060
Damjan Marion7cd468a2016-12-19 23:05:39 +01002061#define STR_VTR_OP_CASE(op) \
2062 case L2_VTR_ ## op: \
2063 return "" # op;
2064
2065static const char *
2066str_vtr_op (u32 vtr_op)
2067{
2068 switch (vtr_op)
2069 {
2070 STR_VTR_OP_CASE (DISABLED);
2071 STR_VTR_OP_CASE (PUSH_1);
2072 STR_VTR_OP_CASE (PUSH_2);
2073 STR_VTR_OP_CASE (POP_1);
2074 STR_VTR_OP_CASE (POP_2);
2075 STR_VTR_OP_CASE (TRANSLATE_1_1);
2076 STR_VTR_OP_CASE (TRANSLATE_1_2);
2077 STR_VTR_OP_CASE (TRANSLATE_2_1);
2078 STR_VTR_OP_CASE (TRANSLATE_2_2);
2079 }
2080
2081 return "UNKNOWN";
2082}
2083
2084static int
2085dump_sub_interface_table (vat_main_t * vam)
2086{
2087 const sw_interface_subif_t *sub = NULL;
2088
2089 if (vam->json_output)
2090 {
2091 clib_warning
2092 ("JSON output supported only for VPE API calls and dump_stats_table");
2093 return -99;
2094 }
2095
2096 print (vam->ofp,
2097 "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
2098 "Interface", "sw_if_index",
2099 "sub id", "dot1ad", "tags", "outer id",
2100 "inner id", "exact", "default", "outer any", "inner any");
2101
2102 vec_foreach (sub, vam->sw_if_subif_table)
2103 {
2104 print (vam->ofp,
2105 "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
2106 sub->interface_name,
2107 sub->sw_if_index,
2108 sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
2109 sub->sub_number_of_tags, sub->sub_outer_vlan_id,
2110 sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
2111 sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
2112 if (sub->vtr_op != L2_VTR_DISABLED)
2113 {
2114 print (vam->ofp,
2115 " vlan-tag-rewrite - op: %-14s [ dot1q: %d "
2116 "tag1: %d tag2: %d ]",
2117 str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
2118 sub->vtr_tag1, sub->vtr_tag2);
2119 }
2120 }
2121
2122 return 0;
2123}
2124
2125static int
2126name_sort_cmp (void *a1, void *a2)
2127{
2128 name_sort_t *n1 = a1;
2129 name_sort_t *n2 = a2;
2130
2131 return strcmp ((char *) n1->name, (char *) n2->name);
2132}
2133
2134static int
2135dump_interface_table (vat_main_t * vam)
2136{
2137 hash_pair_t *p;
2138 name_sort_t *nses = 0, *ns;
2139
2140 if (vam->json_output)
2141 {
2142 clib_warning
2143 ("JSON output supported only for VPE API calls and dump_stats_table");
2144 return -99;
2145 }
2146
2147 /* *INDENT-OFF* */
2148 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
2149 ({
2150 vec_add2 (nses, ns, 1);
2151 ns->name = (u8 *)(p->key);
2152 ns->value = (u32) p->value[0];
2153 }));
2154 /* *INDENT-ON* */
2155
2156 vec_sort_with_function (nses, name_sort_cmp);
2157
2158 print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
2159 vec_foreach (ns, nses)
2160 {
2161 print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
2162 }
2163 vec_free (nses);
2164 return 0;
2165}
2166
2167static int
2168dump_ip_table (vat_main_t * vam, int is_ipv6)
2169{
2170 const ip_details_t *det = NULL;
2171 const ip_address_details_t *address = NULL;
2172 u32 i = ~0;
2173
2174 print (vam->ofp, "%-12s", "sw_if_index");
2175
2176 vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
2177 {
2178 i++;
2179 if (!det->present)
2180 {
2181 continue;
2182 }
2183 print (vam->ofp, "%-12d", i);
2184 print (vam->ofp, " %-30s%-13s", "Address", "Prefix length");
2185 if (!det->addr)
2186 {
2187 continue;
2188 }
2189 vec_foreach (address, det->addr)
2190 {
2191 print (vam->ofp,
2192 " %-30U%-13d",
2193 is_ipv6 ? format_ip6_address : format_ip4_address,
2194 address->ip, address->prefix_length);
2195 }
2196 }
2197
2198 return 0;
2199}
2200
2201static int
2202dump_ipv4_table (vat_main_t * vam)
2203{
2204 if (vam->json_output)
2205 {
2206 clib_warning
2207 ("JSON output supported only for VPE API calls and dump_stats_table");
2208 return -99;
2209 }
2210
2211 return dump_ip_table (vam, 0);
2212}
2213
2214static int
2215dump_ipv6_table (vat_main_t * vam)
2216{
2217 if (vam->json_output)
2218 {
2219 clib_warning
2220 ("JSON output supported only for VPE API calls and dump_stats_table");
2221 return -99;
2222 }
2223
2224 return dump_ip_table (vam, 1);
2225}
2226
Damjan Marion7cd468a2016-12-19 23:05:39 +01002227/*
Dave Barach59b25652017-09-10 15:04:27 -04002228 * Pass CLI buffers directly in the CLI_INBAND API message,
2229 * instead of an additional shared memory area.
Damjan Marion7cd468a2016-12-19 23:05:39 +01002230 */
2231static int
2232exec_inband (vat_main_t * vam)
2233{
2234 vl_api_cli_inband_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002235 unformat_input_t *i = vam->input;
Jon Loeliger56c7b012017-02-01 12:31:41 -06002236 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002237
2238 if (vec_len (i->buffer) == 0)
2239 return -1;
2240
2241 if (vam->exec_mode == 0 && unformat (i, "mode"))
2242 {
2243 vam->exec_mode = 1;
2244 return 0;
2245 }
2246 if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
2247 {
2248 vam->exec_mode = 0;
2249 return 0;
2250 }
2251
2252 /*
2253 * In order for the CLI command to work, it
2254 * must be a vector ending in \n, not a C-string ending
2255 * in \n\0.
2256 */
Jakub Grajciar2dbee932020-02-07 11:30:26 +01002257 M2 (CLI_INBAND, mp, vec_len (vam->input->buffer));
2258 vl_api_vec_to_api_string (vam->input->buffer, &mp->cmd);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002259
Jon Loeliger7bc770c2017-01-31 14:03:33 -06002260 S (mp);
Dave Barach59b25652017-09-10 15:04:27 -04002261 W (ret);
2262 /* json responses may or may not include a useful reply... */
2263 if (vec_len (vam->cmd_reply))
Dave Barachcf5e8482017-10-17 11:48:29 -04002264 print (vam->ofp, "%v", (char *) (vam->cmd_reply));
Jon Loeliger56c7b012017-02-01 12:31:41 -06002265 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002266}
2267
Dave Barach59b25652017-09-10 15:04:27 -04002268int
2269exec (vat_main_t * vam)
2270{
2271 return exec_inband (vam);
2272}
2273
Damjan Marion7cd468a2016-12-19 23:05:39 +01002274static int
2275api_create_loopback (vat_main_t * vam)
2276{
2277 unformat_input_t *i = vam->input;
2278 vl_api_create_loopback_t *mp;
Jon Loeligerc83c3b72017-02-23 13:57:35 -06002279 vl_api_create_loopback_instance_t *mp_lbi;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002280 u8 mac_address[6];
2281 u8 mac_set = 0;
Jon Loeligerc83c3b72017-02-23 13:57:35 -06002282 u8 is_specified = 0;
2283 u32 user_instance = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06002284 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002285
Dave Barachb7b92992018-10-17 10:38:51 -04002286 clib_memset (mac_address, 0, sizeof (mac_address));
Damjan Marion7cd468a2016-12-19 23:05:39 +01002287
2288 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2289 {
2290 if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
2291 mac_set = 1;
Jon Loeligerc83c3b72017-02-23 13:57:35 -06002292 if (unformat (i, "instance %d", &user_instance))
2293 is_specified = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002294 else
2295 break;
2296 }
2297
Jon Loeligerc83c3b72017-02-23 13:57:35 -06002298 if (is_specified)
2299 {
2300 M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
2301 mp_lbi->is_specified = is_specified;
2302 if (is_specified)
2303 mp_lbi->user_instance = htonl (user_instance);
2304 if (mac_set)
2305 clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
2306 S (mp_lbi);
2307 }
2308 else
2309 {
2310 /* Construct the API message */
2311 M (CREATE_LOOPBACK, mp);
2312 if (mac_set)
2313 clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
2314 S (mp);
2315 }
Damjan Marion7cd468a2016-12-19 23:05:39 +01002316
Jon Loeliger56c7b012017-02-01 12:31:41 -06002317 W (ret);
2318 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002319}
2320
2321static int
2322api_delete_loopback (vat_main_t * vam)
2323{
2324 unformat_input_t *i = vam->input;
2325 vl_api_delete_loopback_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002326 u32 sw_if_index = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06002327 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002328
2329 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2330 {
2331 if (unformat (i, "sw_if_index %d", &sw_if_index))
2332 ;
2333 else
2334 break;
2335 }
2336
2337 if (sw_if_index == ~0)
2338 {
2339 errmsg ("missing sw_if_index");
2340 return -99;
2341 }
2342
2343 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06002344 M (DELETE_LOOPBACK, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002345 mp->sw_if_index = ntohl (sw_if_index);
2346
Jon Loeliger7bc770c2017-01-31 14:03:33 -06002347 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06002348 W (ret);
2349 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002350}
2351
2352static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01002353api_want_interface_events (vat_main_t * vam)
2354{
2355 unformat_input_t *i = vam->input;
2356 vl_api_want_interface_events_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002357 int enable = -1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06002358 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002359
2360 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2361 {
2362 if (unformat (i, "enable"))
2363 enable = 1;
2364 else if (unformat (i, "disable"))
2365 enable = 0;
2366 else
2367 break;
2368 }
2369
2370 if (enable == -1)
2371 {
2372 errmsg ("missing enable|disable");
2373 return -99;
2374 }
2375
Jon Loeliger8a2aea32017-01-31 13:19:40 -06002376 M (WANT_INTERFACE_EVENTS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002377 mp->enable_disable = enable;
2378
2379 vam->interface_event_display = enable;
2380
Jon Loeliger7bc770c2017-01-31 14:03:33 -06002381 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06002382 W (ret);
2383 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002384}
2385
2386
2387/* Note: non-static, called once to set up the initial intfc table */
2388int
2389api_sw_interface_dump (vat_main_t * vam)
2390{
2391 vl_api_sw_interface_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -06002392 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002393 hash_pair_t *p;
2394 name_sort_t *nses = 0, *ns;
2395 sw_interface_subif_t *sub = NULL;
Jon Loeliger56c7b012017-02-01 12:31:41 -06002396 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002397
2398 /* Toss the old name table */
2399 /* *INDENT-OFF* */
2400 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
2401 ({
2402 vec_add2 (nses, ns, 1);
2403 ns->name = (u8 *)(p->key);
2404 ns->value = (u32) p->value[0];
2405 }));
2406 /* *INDENT-ON* */
2407
2408 hash_free (vam->sw_if_index_by_interface_name);
2409
2410 vec_foreach (ns, nses) vec_free (ns->name);
2411
2412 vec_free (nses);
2413
2414 vec_foreach (sub, vam->sw_if_subif_table)
2415 {
2416 vec_free (sub->interface_name);
2417 }
2418 vec_free (vam->sw_if_subif_table);
2419
2420 /* recreate the interface name hash table */
2421 vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
2422
Dave Barachf72212e2018-01-11 10:25:07 -05002423 /*
2424 * Ask for all interface names. Otherwise, the epic catalog of
2425 * name filters becomes ridiculously long, and vat ends up needing
2426 * to be taught about new interface types.
2427 */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06002428 M (SW_INTERFACE_DUMP, mp);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06002429 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002430
2431 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -04002432 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06002433 S (mp_ping);
2434
Jon Loeliger56c7b012017-02-01 12:31:41 -06002435 W (ret);
2436 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002437}
2438
2439static int
2440api_sw_interface_set_flags (vat_main_t * vam)
2441{
2442 unformat_input_t *i = vam->input;
2443 vl_api_sw_interface_set_flags_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002444 u32 sw_if_index;
2445 u8 sw_if_index_set = 0;
Neale Rannsa07bd702017-08-07 07:53:49 -07002446 u8 admin_up = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06002447 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002448
2449 /* Parse args required to build the message */
2450 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2451 {
2452 if (unformat (i, "admin-up"))
2453 admin_up = 1;
2454 else if (unformat (i, "admin-down"))
2455 admin_up = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002456 else
2457 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2458 sw_if_index_set = 1;
2459 else if (unformat (i, "sw_if_index %d", &sw_if_index))
2460 sw_if_index_set = 1;
2461 else
2462 break;
2463 }
2464
2465 if (sw_if_index_set == 0)
2466 {
2467 errmsg ("missing interface name or sw_if_index");
2468 return -99;
2469 }
2470
2471 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06002472 M (SW_INTERFACE_SET_FLAGS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002473 mp->sw_if_index = ntohl (sw_if_index);
Jakub Grajciar053204a2019-03-18 13:17:53 +01002474 mp->flags = ntohl ((admin_up) ? IF_STATUS_API_FLAG_ADMIN_UP : 0);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002475
2476 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06002477 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002478
2479 /* Wait for a reply, return the good/bad news... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06002480 W (ret);
2481 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002482}
2483
2484static int
Stevenad8015b2017-10-29 22:10:46 -07002485api_sw_interface_set_rx_mode (vat_main_t * vam)
2486{
2487 unformat_input_t *i = vam->input;
2488 vl_api_sw_interface_set_rx_mode_t *mp;
2489 u32 sw_if_index;
2490 u8 sw_if_index_set = 0;
2491 int ret;
2492 u8 queue_id_valid = 0;
2493 u32 queue_id;
Damjan Marioneabd4242020-10-07 20:59:07 +02002494 vnet_hw_if_rx_mode mode = VNET_HW_IF_RX_MODE_UNKNOWN;
Stevenad8015b2017-10-29 22:10:46 -07002495
2496 /* Parse args required to build the message */
2497 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2498 {
2499 if (unformat (i, "queue %d", &queue_id))
2500 queue_id_valid = 1;
2501 else if (unformat (i, "polling"))
Damjan Marioneabd4242020-10-07 20:59:07 +02002502 mode = VNET_HW_IF_RX_MODE_POLLING;
Stevenad8015b2017-10-29 22:10:46 -07002503 else if (unformat (i, "interrupt"))
Damjan Marioneabd4242020-10-07 20:59:07 +02002504 mode = VNET_HW_IF_RX_MODE_INTERRUPT;
Stevenad8015b2017-10-29 22:10:46 -07002505 else if (unformat (i, "adaptive"))
Damjan Marioneabd4242020-10-07 20:59:07 +02002506 mode = VNET_HW_IF_RX_MODE_ADAPTIVE;
Stevenad8015b2017-10-29 22:10:46 -07002507 else
2508 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2509 sw_if_index_set = 1;
2510 else if (unformat (i, "sw_if_index %d", &sw_if_index))
2511 sw_if_index_set = 1;
2512 else
2513 break;
2514 }
2515
2516 if (sw_if_index_set == 0)
2517 {
2518 errmsg ("missing interface name or sw_if_index");
2519 return -99;
2520 }
Damjan Marioneabd4242020-10-07 20:59:07 +02002521 if (mode == VNET_HW_IF_RX_MODE_UNKNOWN)
Stevenad8015b2017-10-29 22:10:46 -07002522 {
2523 errmsg ("missing rx-mode");
2524 return -99;
2525 }
2526
2527 /* Construct the API message */
2528 M (SW_INTERFACE_SET_RX_MODE, mp);
2529 mp->sw_if_index = ntohl (sw_if_index);
Jakub Grajciar053204a2019-03-18 13:17:53 +01002530 mp->mode = (vl_api_rx_mode_t) mode;
Stevenad8015b2017-10-29 22:10:46 -07002531 mp->queue_id_valid = queue_id_valid;
2532 mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
2533
2534 /* send it... */
2535 S (mp);
2536
2537 /* Wait for a reply, return the good/bad news... */
2538 W (ret);
2539 return ret;
2540}
2541
2542static int
Mohsin Kazmi54f7c512018-08-23 18:28:11 +02002543api_sw_interface_set_rx_placement (vat_main_t * vam)
2544{
2545 unformat_input_t *i = vam->input;
2546 vl_api_sw_interface_set_rx_placement_t *mp;
2547 u32 sw_if_index;
2548 u8 sw_if_index_set = 0;
2549 int ret;
2550 u8 is_main = 0;
2551 u32 queue_id, thread_index;
2552
2553 /* Parse args required to build the message */
2554 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2555 {
2556 if (unformat (i, "queue %d", &queue_id))
2557 ;
2558 else if (unformat (i, "main"))
2559 is_main = 1;
2560 else if (unformat (i, "worker %d", &thread_index))
2561 ;
2562 else
2563 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2564 sw_if_index_set = 1;
2565 else if (unformat (i, "sw_if_index %d", &sw_if_index))
2566 sw_if_index_set = 1;
2567 else
2568 break;
2569 }
2570
2571 if (sw_if_index_set == 0)
2572 {
2573 errmsg ("missing interface name or sw_if_index");
2574 return -99;
2575 }
2576
2577 if (is_main)
2578 thread_index = 0;
2579 /* Construct the API message */
2580 M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
2581 mp->sw_if_index = ntohl (sw_if_index);
2582 mp->worker_id = ntohl (thread_index);
2583 mp->queue_id = ntohl (queue_id);
2584 mp->is_main = is_main;
2585
2586 /* send it... */
2587 S (mp);
2588 /* Wait for a reply, return the good/bad news... */
2589 W (ret);
2590 return ret;
2591}
2592
Mohsin Kazmif0b42f42018-09-10 18:11:00 +02002593static void vl_api_sw_interface_rx_placement_details_t_handler
2594 (vl_api_sw_interface_rx_placement_details_t * mp)
2595{
2596 vat_main_t *vam = &vat_main;
2597 u32 worker_id = ntohl (mp->worker_id);
2598
2599 print (vam->ofp,
2600 "\n%-11d %-11s %-6d %-5d %-9s",
2601 ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
2602 worker_id, ntohl (mp->queue_id),
2603 (mp->mode ==
2604 1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
2605}
2606
2607static void vl_api_sw_interface_rx_placement_details_t_handler_json
2608 (vl_api_sw_interface_rx_placement_details_t * mp)
2609{
2610 vat_main_t *vam = &vat_main;
2611 vat_json_node_t *node = NULL;
2612
2613 if (VAT_JSON_ARRAY != vam->json_tree.type)
2614 {
2615 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2616 vat_json_init_array (&vam->json_tree);
2617 }
2618 node = vat_json_array_add (&vam->json_tree);
2619
2620 vat_json_init_object (node);
2621 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2622 vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
2623 vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
2624 vat_json_object_add_uint (node, "mode", mp->mode);
2625}
2626
2627static int
2628api_sw_interface_rx_placement_dump (vat_main_t * vam)
2629{
2630 unformat_input_t *i = vam->input;
2631 vl_api_sw_interface_rx_placement_dump_t *mp;
2632 vl_api_control_ping_t *mp_ping;
2633 int ret;
2634 u32 sw_if_index;
2635 u8 sw_if_index_set = 0;
2636
2637 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2638 {
2639 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2640 sw_if_index_set++;
2641 else if (unformat (i, "sw_if_index %d", &sw_if_index))
2642 sw_if_index_set++;
2643 else
2644 break;
2645 }
2646
2647 print (vam->ofp,
2648 "\n%-11s %-11s %-6s %-5s %-4s",
2649 "sw_if_index", "main/worker", "thread", "queue", "mode");
2650
2651 /* Dump Interface rx placement */
2652 M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
2653
2654 if (sw_if_index_set)
2655 mp->sw_if_index = htonl (sw_if_index);
2656 else
2657 mp->sw_if_index = ~0;
2658
2659 S (mp);
2660
2661 /* Use a control ping for synchronization */
2662 MPING (CONTROL_PING, mp_ping);
2663 S (mp_ping);
2664
2665 W (ret);
2666 return ret;
2667}
2668
Mohsin Kazmi54f7c512018-08-23 18:28:11 +02002669static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01002670api_sw_interface_clear_stats (vat_main_t * vam)
2671{
2672 unformat_input_t *i = vam->input;
2673 vl_api_sw_interface_clear_stats_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002674 u32 sw_if_index;
2675 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06002676 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002677
2678 /* Parse args required to build the message */
2679 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2680 {
2681 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2682 sw_if_index_set = 1;
2683 else if (unformat (i, "sw_if_index %d", &sw_if_index))
2684 sw_if_index_set = 1;
2685 else
2686 break;
2687 }
2688
2689 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06002690 M (SW_INTERFACE_CLEAR_STATS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002691
2692 if (sw_if_index_set == 1)
2693 mp->sw_if_index = ntohl (sw_if_index);
2694 else
2695 mp->sw_if_index = ~0;
2696
2697 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06002698 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002699
2700 /* Wait for a reply, return the good/bad news... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06002701 W (ret);
2702 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002703}
2704
Damjan Marion7cd468a2016-12-19 23:05:39 +01002705static int
2706api_sw_interface_add_del_address (vat_main_t * vam)
2707{
2708 unformat_input_t *i = vam->input;
2709 vl_api_sw_interface_add_del_address_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002710 u32 sw_if_index;
2711 u8 sw_if_index_set = 0;
2712 u8 is_add = 1, del_all = 0;
2713 u32 address_length = 0;
2714 u8 v4_address_set = 0;
2715 u8 v6_address_set = 0;
2716 ip4_address_t v4address;
2717 ip6_address_t v6address;
Jon Loeliger56c7b012017-02-01 12:31:41 -06002718 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002719
2720 /* Parse args required to build the message */
2721 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2722 {
2723 if (unformat (i, "del-all"))
2724 del_all = 1;
2725 else if (unformat (i, "del"))
2726 is_add = 0;
2727 else
2728 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2729 sw_if_index_set = 1;
2730 else if (unformat (i, "sw_if_index %d", &sw_if_index))
2731 sw_if_index_set = 1;
2732 else if (unformat (i, "%U/%d",
2733 unformat_ip4_address, &v4address, &address_length))
2734 v4_address_set = 1;
2735 else if (unformat (i, "%U/%d",
2736 unformat_ip6_address, &v6address, &address_length))
2737 v6_address_set = 1;
2738 else
2739 break;
2740 }
2741
2742 if (sw_if_index_set == 0)
2743 {
2744 errmsg ("missing interface name or sw_if_index");
2745 return -99;
2746 }
2747 if (v4_address_set && v6_address_set)
2748 {
2749 errmsg ("both v4 and v6 addresses set");
2750 return -99;
2751 }
2752 if (!v4_address_set && !v6_address_set && !del_all)
2753 {
2754 errmsg ("no addresses set");
2755 return -99;
2756 }
2757
2758 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06002759 M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002760
2761 mp->sw_if_index = ntohl (sw_if_index);
2762 mp->is_add = is_add;
2763 mp->del_all = del_all;
2764 if (v6_address_set)
2765 {
Jakub Grajciar053204a2019-03-18 13:17:53 +01002766 mp->prefix.address.af = ADDRESS_IP6;
2767 clib_memcpy (mp->prefix.address.un.ip6, &v6address, sizeof (v6address));
Damjan Marion7cd468a2016-12-19 23:05:39 +01002768 }
2769 else
2770 {
Jakub Grajciar053204a2019-03-18 13:17:53 +01002771 mp->prefix.address.af = ADDRESS_IP4;
2772 clib_memcpy (mp->prefix.address.un.ip4, &v4address, sizeof (v4address));
Damjan Marion7cd468a2016-12-19 23:05:39 +01002773 }
Jakub Grajciar053204a2019-03-18 13:17:53 +01002774 mp->prefix.len = address_length;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002775
2776 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06002777 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002778
2779 /* Wait for a reply, return good/bad news */
Jon Loeliger56c7b012017-02-01 12:31:41 -06002780 W (ret);
2781 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002782}
2783
2784static int
2785api_sw_interface_set_mpls_enable (vat_main_t * vam)
2786{
2787 unformat_input_t *i = vam->input;
2788 vl_api_sw_interface_set_mpls_enable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002789 u32 sw_if_index;
2790 u8 sw_if_index_set = 0;
2791 u8 enable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06002792 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002793
2794 /* Parse args required to build the message */
2795 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2796 {
2797 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2798 sw_if_index_set = 1;
2799 else if (unformat (i, "sw_if_index %d", &sw_if_index))
2800 sw_if_index_set = 1;
2801 else if (unformat (i, "disable"))
2802 enable = 0;
2803 else if (unformat (i, "dis"))
2804 enable = 0;
2805 else
2806 break;
2807 }
2808
2809 if (sw_if_index_set == 0)
2810 {
2811 errmsg ("missing interface name or sw_if_index");
2812 return -99;
2813 }
2814
2815 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06002816 M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002817
2818 mp->sw_if_index = ntohl (sw_if_index);
2819 mp->enable = enable;
2820
2821 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06002822 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002823
2824 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06002825 W (ret);
2826 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002827}
2828
2829static int
2830api_sw_interface_set_table (vat_main_t * vam)
2831{
2832 unformat_input_t *i = vam->input;
2833 vl_api_sw_interface_set_table_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002834 u32 sw_if_index, vrf_id = 0;
2835 u8 sw_if_index_set = 0;
2836 u8 is_ipv6 = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06002837 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002838
2839 /* Parse args required to build the message */
2840 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2841 {
2842 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2843 sw_if_index_set = 1;
2844 else if (unformat (i, "sw_if_index %d", &sw_if_index))
2845 sw_if_index_set = 1;
2846 else if (unformat (i, "vrf %d", &vrf_id))
2847 ;
2848 else if (unformat (i, "ipv6"))
2849 is_ipv6 = 1;
2850 else
2851 break;
2852 }
2853
2854 if (sw_if_index_set == 0)
2855 {
2856 errmsg ("missing interface name or sw_if_index");
2857 return -99;
2858 }
2859
2860 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06002861 M (SW_INTERFACE_SET_TABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002862
2863 mp->sw_if_index = ntohl (sw_if_index);
2864 mp->is_ipv6 = is_ipv6;
2865 mp->vrf_id = ntohl (vrf_id);
2866
2867 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06002868 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002869
2870 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06002871 W (ret);
2872 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002873}
2874
2875static void vl_api_sw_interface_get_table_reply_t_handler
2876 (vl_api_sw_interface_get_table_reply_t * mp)
2877{
2878 vat_main_t *vam = &vat_main;
2879
2880 print (vam->ofp, "%d", ntohl (mp->vrf_id));
2881
2882 vam->retval = ntohl (mp->retval);
2883 vam->result_ready = 1;
2884
2885}
2886
2887static void vl_api_sw_interface_get_table_reply_t_handler_json
2888 (vl_api_sw_interface_get_table_reply_t * mp)
2889{
2890 vat_main_t *vam = &vat_main;
2891 vat_json_node_t node;
2892
2893 vat_json_init_object (&node);
2894 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2895 vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
2896
2897 vat_json_print (vam->ofp, &node);
2898 vat_json_free (&node);
2899
2900 vam->retval = ntohl (mp->retval);
2901 vam->result_ready = 1;
2902}
2903
2904static int
2905api_sw_interface_get_table (vat_main_t * vam)
2906{
2907 unformat_input_t *i = vam->input;
2908 vl_api_sw_interface_get_table_t *mp;
2909 u32 sw_if_index;
2910 u8 sw_if_index_set = 0;
2911 u8 is_ipv6 = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06002912 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002913
2914 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2915 {
2916 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2917 sw_if_index_set = 1;
2918 else if (unformat (i, "sw_if_index %d", &sw_if_index))
2919 sw_if_index_set = 1;
2920 else if (unformat (i, "ipv6"))
2921 is_ipv6 = 1;
2922 else
2923 break;
2924 }
2925
2926 if (sw_if_index_set == 0)
2927 {
2928 errmsg ("missing interface name or sw_if_index");
2929 return -99;
2930 }
2931
Jon Loeliger8a2aea32017-01-31 13:19:40 -06002932 M (SW_INTERFACE_GET_TABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002933 mp->sw_if_index = htonl (sw_if_index);
2934 mp->is_ipv6 = is_ipv6;
2935
Jon Loeliger7bc770c2017-01-31 14:03:33 -06002936 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06002937 W (ret);
2938 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002939}
2940
2941static int
2942api_sw_interface_set_vpath (vat_main_t * vam)
2943{
2944 unformat_input_t *i = vam->input;
2945 vl_api_sw_interface_set_vpath_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002946 u32 sw_if_index = 0;
2947 u8 sw_if_index_set = 0;
2948 u8 is_enable = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06002949 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002950
2951 /* Parse args required to build the message */
2952 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2953 {
2954 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2955 sw_if_index_set = 1;
2956 else if (unformat (i, "sw_if_index %d", &sw_if_index))
2957 sw_if_index_set = 1;
2958 else if (unformat (i, "enable"))
2959 is_enable = 1;
2960 else if (unformat (i, "disable"))
2961 is_enable = 0;
2962 else
2963 break;
2964 }
2965
2966 if (sw_if_index_set == 0)
2967 {
2968 errmsg ("missing interface name or sw_if_index");
2969 return -99;
2970 }
2971
2972 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06002973 M (SW_INTERFACE_SET_VPATH, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002974
2975 mp->sw_if_index = ntohl (sw_if_index);
2976 mp->enable = is_enable;
2977
2978 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06002979 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002980
2981 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06002982 W (ret);
2983 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002984}
2985
2986static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01002987api_sw_interface_set_l2_xconnect (vat_main_t * vam)
2988{
2989 unformat_input_t *i = vam->input;
2990 vl_api_sw_interface_set_l2_xconnect_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002991 u32 rx_sw_if_index;
2992 u8 rx_sw_if_index_set = 0;
2993 u32 tx_sw_if_index;
2994 u8 tx_sw_if_index_set = 0;
2995 u8 enable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06002996 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002997
2998 /* Parse args required to build the message */
2999 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3000 {
3001 if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
3002 rx_sw_if_index_set = 1;
3003 else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
3004 tx_sw_if_index_set = 1;
3005 else if (unformat (i, "rx"))
3006 {
3007 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3008 {
3009 if (unformat (i, "%U", api_unformat_sw_if_index, vam,
3010 &rx_sw_if_index))
3011 rx_sw_if_index_set = 1;
3012 }
3013 else
3014 break;
3015 }
3016 else if (unformat (i, "tx"))
3017 {
3018 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3019 {
3020 if (unformat (i, "%U", api_unformat_sw_if_index, vam,
3021 &tx_sw_if_index))
3022 tx_sw_if_index_set = 1;
3023 }
3024 else
3025 break;
3026 }
3027 else if (unformat (i, "enable"))
3028 enable = 1;
3029 else if (unformat (i, "disable"))
3030 enable = 0;
3031 else
3032 break;
3033 }
3034
3035 if (rx_sw_if_index_set == 0)
3036 {
3037 errmsg ("missing rx interface name or rx_sw_if_index");
3038 return -99;
3039 }
3040
3041 if (enable && (tx_sw_if_index_set == 0))
3042 {
3043 errmsg ("missing tx interface name or tx_sw_if_index");
3044 return -99;
3045 }
3046
Jon Loeliger8a2aea32017-01-31 13:19:40 -06003047 M (SW_INTERFACE_SET_L2_XCONNECT, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003048
3049 mp->rx_sw_if_index = ntohl (rx_sw_if_index);
3050 mp->tx_sw_if_index = ntohl (tx_sw_if_index);
3051 mp->enable = enable;
3052
Jon Loeliger7bc770c2017-01-31 14:03:33 -06003053 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06003054 W (ret);
3055 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003056}
3057
3058static int
3059api_sw_interface_set_l2_bridge (vat_main_t * vam)
3060{
3061 unformat_input_t *i = vam->input;
3062 vl_api_sw_interface_set_l2_bridge_t *mp;
Neale Rannsb4743802018-09-05 09:13:57 -07003063 vl_api_l2_port_type_t port_type;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003064 u32 rx_sw_if_index;
3065 u8 rx_sw_if_index_set = 0;
3066 u32 bd_id;
3067 u8 bd_id_set = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003068 u32 shg = 0;
3069 u8 enable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06003070 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003071
Neale Rannsb4743802018-09-05 09:13:57 -07003072 port_type = L2_API_PORT_TYPE_NORMAL;
3073
Damjan Marion7cd468a2016-12-19 23:05:39 +01003074 /* Parse args required to build the message */
3075 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3076 {
3077 if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
3078 rx_sw_if_index_set = 1;
3079 else if (unformat (i, "bd_id %d", &bd_id))
3080 bd_id_set = 1;
3081 else
3082 if (unformat
3083 (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
3084 rx_sw_if_index_set = 1;
3085 else if (unformat (i, "shg %d", &shg))
3086 ;
3087 else if (unformat (i, "bvi"))
Neale Rannsb4743802018-09-05 09:13:57 -07003088 port_type = L2_API_PORT_TYPE_BVI;
3089 else if (unformat (i, "uu-fwd"))
3090 port_type = L2_API_PORT_TYPE_UU_FWD;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003091 else if (unformat (i, "enable"))
3092 enable = 1;
3093 else if (unformat (i, "disable"))
3094 enable = 0;
3095 else
3096 break;
3097 }
3098
3099 if (rx_sw_if_index_set == 0)
3100 {
3101 errmsg ("missing rx interface name or sw_if_index");
3102 return -99;
3103 }
3104
3105 if (enable && (bd_id_set == 0))
3106 {
3107 errmsg ("missing bridge domain");
3108 return -99;
3109 }
3110
Jon Loeliger8a2aea32017-01-31 13:19:40 -06003111 M (SW_INTERFACE_SET_L2_BRIDGE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003112
3113 mp->rx_sw_if_index = ntohl (rx_sw_if_index);
3114 mp->bd_id = ntohl (bd_id);
3115 mp->shg = (u8) shg;
Neale Rannsb4743802018-09-05 09:13:57 -07003116 mp->port_type = ntohl (port_type);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003117 mp->enable = enable;
3118
Jon Loeliger7bc770c2017-01-31 14:03:33 -06003119 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06003120 W (ret);
3121 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003122}
3123
3124static int
3125api_bridge_domain_dump (vat_main_t * vam)
3126{
3127 unformat_input_t *i = vam->input;
3128 vl_api_bridge_domain_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -06003129 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003130 u32 bd_id = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06003131 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003132
3133 /* Parse args required to build the message */
3134 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3135 {
3136 if (unformat (i, "bd_id %d", &bd_id))
3137 ;
3138 else
3139 break;
3140 }
3141
Jon Loeliger8a2aea32017-01-31 13:19:40 -06003142 M (BRIDGE_DOMAIN_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003143 mp->bd_id = ntohl (bd_id);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06003144 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003145
3146 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -04003147 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06003148 S (mp_ping);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003149
Jon Loeliger56c7b012017-02-01 12:31:41 -06003150 W (ret);
3151 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003152}
3153
3154static int
3155api_bridge_domain_add_del (vat_main_t * vam)
3156{
3157 unformat_input_t *i = vam->input;
3158 vl_api_bridge_domain_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003159 u32 bd_id = ~0;
3160 u8 is_add = 1;
3161 u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
Jerome Tollet50570ec2017-09-14 12:53:56 +01003162 u8 *bd_tag = NULL;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003163 u32 mac_age = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06003164 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003165
3166 /* Parse args required to build the message */
3167 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3168 {
3169 if (unformat (i, "bd_id %d", &bd_id))
3170 ;
3171 else if (unformat (i, "flood %d", &flood))
3172 ;
3173 else if (unformat (i, "uu-flood %d", &uu_flood))
3174 ;
3175 else if (unformat (i, "forward %d", &forward))
3176 ;
3177 else if (unformat (i, "learn %d", &learn))
3178 ;
3179 else if (unformat (i, "arp-term %d", &arp_term))
3180 ;
3181 else if (unformat (i, "mac-age %d", &mac_age))
3182 ;
Jerome Tollet50570ec2017-09-14 12:53:56 +01003183 else if (unformat (i, "bd-tag %s", &bd_tag))
3184 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003185 else if (unformat (i, "del"))
3186 {
3187 is_add = 0;
3188 flood = uu_flood = forward = learn = 0;
3189 }
3190 else
3191 break;
3192 }
3193
3194 if (bd_id == ~0)
3195 {
3196 errmsg ("missing bridge domain");
Jerome Tollet50570ec2017-09-14 12:53:56 +01003197 ret = -99;
3198 goto done;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003199 }
3200
3201 if (mac_age > 255)
3202 {
3203 errmsg ("mac age must be less than 256 ");
Jerome Tollet50570ec2017-09-14 12:53:56 +01003204 ret = -99;
3205 goto done;
3206 }
3207
John Lo70bfcaf2017-11-14 13:19:26 -05003208 if ((bd_tag) && (vec_len (bd_tag) > 63))
Jerome Tollet50570ec2017-09-14 12:53:56 +01003209 {
3210 errmsg ("bd-tag cannot be longer than 63");
3211 ret = -99;
3212 goto done;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003213 }
3214
Jon Loeliger8a2aea32017-01-31 13:19:40 -06003215 M (BRIDGE_DOMAIN_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003216
3217 mp->bd_id = ntohl (bd_id);
3218 mp->flood = flood;
3219 mp->uu_flood = uu_flood;
3220 mp->forward = forward;
3221 mp->learn = learn;
3222 mp->arp_term = arp_term;
3223 mp->is_add = is_add;
3224 mp->mac_age = (u8) mac_age;
Jerome Tollet50570ec2017-09-14 12:53:56 +01003225 if (bd_tag)
John Lo70bfcaf2017-11-14 13:19:26 -05003226 {
3227 clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
3228 mp->bd_tag[vec_len (bd_tag)] = 0;
3229 }
Jon Loeliger7bc770c2017-01-31 14:03:33 -06003230 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06003231 W (ret);
Jerome Tollet50570ec2017-09-14 12:53:56 +01003232
3233done:
3234 vec_free (bd_tag);
Jon Loeliger56c7b012017-02-01 12:31:41 -06003235 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003236}
3237
3238static int
Eyal Barif24991c2017-04-05 05:33:21 +03003239api_l2fib_flush_bd (vat_main_t * vam)
3240{
3241 unformat_input_t *i = vam->input;
3242 vl_api_l2fib_flush_bd_t *mp;
3243 u32 bd_id = ~0;
3244 int ret;
3245
3246 /* Parse args required to build the message */
3247 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3248 {
3249 if (unformat (i, "bd_id %d", &bd_id));
3250 else
3251 break;
3252 }
3253
3254 if (bd_id == ~0)
3255 {
3256 errmsg ("missing bridge domain");
3257 return -99;
3258 }
3259
3260 M (L2FIB_FLUSH_BD, mp);
3261
3262 mp->bd_id = htonl (bd_id);
3263
3264 S (mp);
3265 W (ret);
3266 return ret;
3267}
3268
3269static int
3270api_l2fib_flush_int (vat_main_t * vam)
3271{
3272 unformat_input_t *i = vam->input;
3273 vl_api_l2fib_flush_int_t *mp;
3274 u32 sw_if_index = ~0;
3275 int ret;
3276
3277 /* Parse args required to build the message */
3278 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3279 {
3280 if (unformat (i, "sw_if_index %d", &sw_if_index));
3281 else
3282 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
3283 else
3284 break;
3285 }
3286
3287 if (sw_if_index == ~0)
3288 {
3289 errmsg ("missing interface name or sw_if_index");
3290 return -99;
3291 }
3292
3293 M (L2FIB_FLUSH_INT, mp);
3294
3295 mp->sw_if_index = ntohl (sw_if_index);
3296
3297 S (mp);
3298 W (ret);
3299 return ret;
3300}
3301
3302static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01003303api_l2fib_add_del (vat_main_t * vam)
3304{
3305 unformat_input_t *i = vam->input;
3306 vl_api_l2fib_add_del_t *mp;
3307 f64 timeout;
Mohsin Kazmi57938f62017-10-27 21:28:07 +02003308 u8 mac[6] = { 0 };
Damjan Marion7cd468a2016-12-19 23:05:39 +01003309 u8 mac_set = 0;
3310 u32 bd_id;
3311 u8 bd_id_set = 0;
John Lo7dbd7262018-05-31 10:25:18 -04003312 u32 sw_if_index = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003313 u8 sw_if_index_set = 0;
3314 u8 is_add = 1;
3315 u8 static_mac = 0;
3316 u8 filter_mac = 0;
3317 u8 bvi_mac = 0;
3318 int count = 1;
3319 f64 before = 0;
3320 int j;
3321
3322 /* Parse args required to build the message */
3323 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3324 {
Mohsin Kazmi57938f62017-10-27 21:28:07 +02003325 if (unformat (i, "mac %U", unformat_ethernet_address, mac))
Damjan Marion7cd468a2016-12-19 23:05:39 +01003326 mac_set = 1;
3327 else if (unformat (i, "bd_id %d", &bd_id))
3328 bd_id_set = 1;
3329 else if (unformat (i, "sw_if_index %d", &sw_if_index))
3330 sw_if_index_set = 1;
3331 else if (unformat (i, "sw_if"))
3332 {
3333 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3334 {
3335 if (unformat
3336 (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
3337 sw_if_index_set = 1;
3338 }
3339 else
3340 break;
3341 }
3342 else if (unformat (i, "static"))
3343 static_mac = 1;
3344 else if (unformat (i, "filter"))
3345 {
3346 filter_mac = 1;
3347 static_mac = 1;
3348 }
3349 else if (unformat (i, "bvi"))
3350 {
3351 bvi_mac = 1;
3352 static_mac = 1;
3353 }
3354 else if (unformat (i, "del"))
3355 is_add = 0;
3356 else if (unformat (i, "count %d", &count))
3357 ;
3358 else
3359 break;
3360 }
3361
3362 if (mac_set == 0)
3363 {
3364 errmsg ("missing mac address");
3365 return -99;
3366 }
3367
3368 if (bd_id_set == 0)
3369 {
3370 errmsg ("missing bridge domain");
3371 return -99;
3372 }
3373
3374 if (is_add && sw_if_index_set == 0 && filter_mac == 0)
3375 {
3376 errmsg ("missing interface name or sw_if_index");
3377 return -99;
3378 }
3379
3380 if (count > 1)
3381 {
3382 /* Turn on async mode */
3383 vam->async_mode = 1;
3384 vam->async_errors = 0;
3385 before = vat_time_now (vam);
3386 }
3387
3388 for (j = 0; j < count; j++)
3389 {
Jon Loeliger8a2aea32017-01-31 13:19:40 -06003390 M (L2FIB_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003391
Mohsin Kazmi57938f62017-10-27 21:28:07 +02003392 clib_memcpy (mp->mac, mac, 6);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003393 mp->bd_id = ntohl (bd_id);
3394 mp->is_add = is_add;
John Lo7dbd7262018-05-31 10:25:18 -04003395 mp->sw_if_index = ntohl (sw_if_index);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003396
3397 if (is_add)
3398 {
Damjan Marion7cd468a2016-12-19 23:05:39 +01003399 mp->static_mac = static_mac;
3400 mp->filter_mac = filter_mac;
3401 mp->bvi_mac = bvi_mac;
3402 }
Mohsin Kazmi57938f62017-10-27 21:28:07 +02003403 increment_mac_address (mac);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003404 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06003405 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003406 }
3407
3408 if (count > 1)
3409 {
Jon Loeliger2d23eca2017-02-01 13:09:58 -06003410 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003411 f64 after;
3412
3413 /* Shut off async mode */
3414 vam->async_mode = 0;
3415
Dave Barach59b25652017-09-10 15:04:27 -04003416 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06003417 S (mp_ping);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003418
3419 timeout = vat_time_now (vam) + 1.0;
3420 while (vat_time_now (vam) < timeout)
3421 if (vam->result_ready == 1)
3422 goto out;
3423 vam->retval = -99;
3424
3425 out:
3426 if (vam->retval == -99)
3427 errmsg ("timeout");
3428
3429 if (vam->async_errors > 0)
3430 {
3431 errmsg ("%d asynchronous errors", vam->async_errors);
3432 vam->retval = -98;
3433 }
3434 vam->async_errors = 0;
3435 after = vat_time_now (vam);
3436
3437 print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
3438 count, after - before, count / (after - before));
3439 }
3440 else
3441 {
Jon Loeliger56c7b012017-02-01 12:31:41 -06003442 int ret;
3443
Damjan Marion7cd468a2016-12-19 23:05:39 +01003444 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06003445 W (ret);
3446 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003447 }
3448 /* Return the good/bad news */
3449 return (vam->retval);
3450}
3451
3452static int
Eyal Barifead6702017-04-04 04:46:32 +03003453api_bridge_domain_set_mac_age (vat_main_t * vam)
3454{
3455 unformat_input_t *i = vam->input;
3456 vl_api_bridge_domain_set_mac_age_t *mp;
3457 u32 bd_id = ~0;
3458 u32 mac_age = 0;
3459 int ret;
3460
3461 /* Parse args required to build the message */
3462 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3463 {
3464 if (unformat (i, "bd_id %d", &bd_id));
3465 else if (unformat (i, "mac-age %d", &mac_age));
3466 else
3467 break;
3468 }
3469
3470 if (bd_id == ~0)
3471 {
3472 errmsg ("missing bridge domain");
3473 return -99;
3474 }
3475
3476 if (mac_age > 255)
3477 {
3478 errmsg ("mac age must be less than 256 ");
3479 return -99;
3480 }
3481
3482 M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
3483
3484 mp->bd_id = htonl (bd_id);
3485 mp->mac_age = (u8) mac_age;
3486
3487 S (mp);
3488 W (ret);
3489 return ret;
3490}
3491
3492static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01003493api_l2_flags (vat_main_t * vam)
3494{
3495 unformat_input_t *i = vam->input;
3496 vl_api_l2_flags_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003497 u32 sw_if_index;
John Lo8d00fff2017-08-03 00:35:36 -04003498 u32 flags = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003499 u8 sw_if_index_set = 0;
John Lo8d00fff2017-08-03 00:35:36 -04003500 u8 is_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06003501 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003502
3503 /* Parse args required to build the message */
3504 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3505 {
3506 if (unformat (i, "sw_if_index %d", &sw_if_index))
3507 sw_if_index_set = 1;
3508 else if (unformat (i, "sw_if"))
3509 {
3510 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3511 {
3512 if (unformat
3513 (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
3514 sw_if_index_set = 1;
3515 }
3516 else
3517 break;
3518 }
3519 else if (unformat (i, "learn"))
John Lo8d00fff2017-08-03 00:35:36 -04003520 flags |= L2_LEARN;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003521 else if (unformat (i, "forward"))
John Lo8d00fff2017-08-03 00:35:36 -04003522 flags |= L2_FWD;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003523 else if (unformat (i, "flood"))
John Lo8d00fff2017-08-03 00:35:36 -04003524 flags |= L2_FLOOD;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003525 else if (unformat (i, "uu-flood"))
John Lo8d00fff2017-08-03 00:35:36 -04003526 flags |= L2_UU_FLOOD;
3527 else if (unformat (i, "arp-term"))
3528 flags |= L2_ARP_TERM;
3529 else if (unformat (i, "off"))
3530 is_set = 0;
3531 else if (unformat (i, "disable"))
3532 is_set = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003533 else
3534 break;
3535 }
3536
3537 if (sw_if_index_set == 0)
3538 {
3539 errmsg ("missing interface name or sw_if_index");
3540 return -99;
3541 }
3542
Jon Loeliger8a2aea32017-01-31 13:19:40 -06003543 M (L2_FLAGS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003544
3545 mp->sw_if_index = ntohl (sw_if_index);
John Lo8d00fff2017-08-03 00:35:36 -04003546 mp->feature_bitmap = ntohl (flags);
3547 mp->is_set = is_set;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003548
Jon Loeliger7bc770c2017-01-31 14:03:33 -06003549 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06003550 W (ret);
3551 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003552}
3553
3554static int
3555api_bridge_flags (vat_main_t * vam)
3556{
3557 unformat_input_t *i = vam->input;
3558 vl_api_bridge_flags_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003559 u32 bd_id;
3560 u8 bd_id_set = 0;
3561 u8 is_set = 1;
Neale Rannsb4743802018-09-05 09:13:57 -07003562 bd_flags_t flags = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06003563 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003564
3565 /* Parse args required to build the message */
3566 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3567 {
3568 if (unformat (i, "bd_id %d", &bd_id))
3569 bd_id_set = 1;
3570 else if (unformat (i, "learn"))
Neale Rannsb4743802018-09-05 09:13:57 -07003571 flags |= BRIDGE_API_FLAG_LEARN;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003572 else if (unformat (i, "forward"))
Neale Rannsb4743802018-09-05 09:13:57 -07003573 flags |= BRIDGE_API_FLAG_FWD;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003574 else if (unformat (i, "flood"))
Neale Rannsb4743802018-09-05 09:13:57 -07003575 flags |= BRIDGE_API_FLAG_FLOOD;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003576 else if (unformat (i, "uu-flood"))
Neale Rannsb4743802018-09-05 09:13:57 -07003577 flags |= BRIDGE_API_FLAG_UU_FLOOD;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003578 else if (unformat (i, "arp-term"))
Neale Rannsb4743802018-09-05 09:13:57 -07003579 flags |= BRIDGE_API_FLAG_ARP_TERM;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003580 else if (unformat (i, "off"))
3581 is_set = 0;
3582 else if (unformat (i, "disable"))
3583 is_set = 0;
3584 else
3585 break;
3586 }
3587
3588 if (bd_id_set == 0)
3589 {
3590 errmsg ("missing bridge domain");
3591 return -99;
3592 }
3593
Jon Loeliger8a2aea32017-01-31 13:19:40 -06003594 M (BRIDGE_FLAGS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003595
3596 mp->bd_id = ntohl (bd_id);
Neale Rannsb4743802018-09-05 09:13:57 -07003597 mp->flags = ntohl (flags);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003598 mp->is_set = is_set;
3599
Jon Loeliger7bc770c2017-01-31 14:03:33 -06003600 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06003601 W (ret);
3602 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003603}
3604
3605static int
3606api_bd_ip_mac_add_del (vat_main_t * vam)
3607{
Neale Ranns4d5b9172018-10-24 02:57:49 -07003608 vl_api_address_t ip = VL_API_ZERO_ADDRESS;
Ole Troan8006c6a2018-12-17 12:02:26 +01003609 vl_api_mac_address_t mac = { 0 };
Damjan Marion7cd468a2016-12-19 23:05:39 +01003610 unformat_input_t *i = vam->input;
3611 vl_api_bd_ip_mac_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003612 u32 bd_id;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003613 u8 is_add = 1;
3614 u8 bd_id_set = 0;
3615 u8 ip_set = 0;
3616 u8 mac_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06003617 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003618
3619
3620 /* Parse args required to build the message */
3621 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3622 {
3623 if (unformat (i, "bd_id %d", &bd_id))
3624 {
3625 bd_id_set++;
3626 }
Neale Ranns4d5b9172018-10-24 02:57:49 -07003627 else if (unformat (i, "%U", unformat_vl_api_address, &ip))
Damjan Marion7cd468a2016-12-19 23:05:39 +01003628 {
3629 ip_set++;
3630 }
Neale Ranns4d5b9172018-10-24 02:57:49 -07003631 else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
Damjan Marion7cd468a2016-12-19 23:05:39 +01003632 {
3633 mac_set++;
3634 }
3635 else if (unformat (i, "del"))
3636 is_add = 0;
3637 else
3638 break;
3639 }
3640
3641 if (bd_id_set == 0)
3642 {
3643 errmsg ("missing bridge domain");
3644 return -99;
3645 }
3646 else if (ip_set == 0)
3647 {
3648 errmsg ("missing IP address");
3649 return -99;
3650 }
3651 else if (mac_set == 0)
3652 {
3653 errmsg ("missing MAC address");
3654 return -99;
3655 }
3656
Jon Loeliger8a2aea32017-01-31 13:19:40 -06003657 M (BD_IP_MAC_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003658
Neale Rannsbc764c82019-06-19 07:07:13 -07003659 mp->entry.bd_id = ntohl (bd_id);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003660 mp->is_add = is_add;
Neale Ranns4d5b9172018-10-24 02:57:49 -07003661
Neale Rannsbc764c82019-06-19 07:07:13 -07003662 clib_memcpy (&mp->entry.ip, &ip, sizeof (ip));
3663 clib_memcpy (&mp->entry.mac, &mac, sizeof (mac));
Neale Ranns4d5b9172018-10-24 02:57:49 -07003664
Jon Loeliger7bc770c2017-01-31 14:03:33 -06003665 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06003666 W (ret);
3667 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003668}
3669
John Loe26c81f2019-01-07 15:16:33 -05003670static int
3671api_bd_ip_mac_flush (vat_main_t * vam)
3672{
3673 unformat_input_t *i = vam->input;
3674 vl_api_bd_ip_mac_flush_t *mp;
3675 u32 bd_id;
3676 u8 bd_id_set = 0;
3677 int ret;
3678
3679 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3680 {
3681 if (unformat (i, "bd_id %d", &bd_id))
3682 {
3683 bd_id_set++;
3684 }
3685 else
3686 break;
3687 }
3688
3689 if (bd_id_set == 0)
3690 {
3691 errmsg ("missing bridge domain");
3692 return -99;
3693 }
3694
3695 M (BD_IP_MAC_FLUSH, mp);
3696
3697 mp->bd_id = ntohl (bd_id);
3698
3699 S (mp);
3700 W (ret);
3701 return ret;
3702}
3703
Mohsin Kazmi5d82d2f2018-08-13 19:17:54 +02003704static void vl_api_bd_ip_mac_details_t_handler
3705 (vl_api_bd_ip_mac_details_t * mp)
3706{
3707 vat_main_t *vam = &vat_main;
Mohsin Kazmi5d82d2f2018-08-13 19:17:54 +02003708
3709 print (vam->ofp,
Neale Rannsbc764c82019-06-19 07:07:13 -07003710 "\n%-5d %U %U",
3711 ntohl (mp->entry.bd_id),
3712 format_vl_api_mac_address, mp->entry.mac,
3713 format_vl_api_address, &mp->entry.ip);
Mohsin Kazmi5d82d2f2018-08-13 19:17:54 +02003714}
3715
3716static void vl_api_bd_ip_mac_details_t_handler_json
3717 (vl_api_bd_ip_mac_details_t * mp)
3718{
3719 vat_main_t *vam = &vat_main;
3720 vat_json_node_t *node = NULL;
3721
3722 if (VAT_JSON_ARRAY != vam->json_tree.type)
3723 {
3724 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3725 vat_json_init_array (&vam->json_tree);
3726 }
3727 node = vat_json_array_add (&vam->json_tree);
3728
3729 vat_json_init_object (node);
Neale Rannsbc764c82019-06-19 07:07:13 -07003730 vat_json_object_add_uint (node, "bd_id", ntohl (mp->entry.bd_id));
Mohsin Kazmi5d82d2f2018-08-13 19:17:54 +02003731 vat_json_object_add_string_copy (node, "mac_address",
Neale Rannsbc764c82019-06-19 07:07:13 -07003732 format (0, "%U", format_vl_api_mac_address,
3733 &mp->entry.mac));
Mohsin Kazmi5d82d2f2018-08-13 19:17:54 +02003734 u8 *ip = 0;
3735
Neale Rannsbc764c82019-06-19 07:07:13 -07003736 ip = format (0, "%U", format_vl_api_address, &mp->entry.ip);
Mohsin Kazmi5d82d2f2018-08-13 19:17:54 +02003737 vat_json_object_add_string_copy (node, "ip_address", ip);
3738 vec_free (ip);
3739}
3740
3741static int
3742api_bd_ip_mac_dump (vat_main_t * vam)
3743{
3744 unformat_input_t *i = vam->input;
3745 vl_api_bd_ip_mac_dump_t *mp;
3746 vl_api_control_ping_t *mp_ping;
3747 int ret;
3748 u32 bd_id;
3749 u8 bd_id_set = 0;
3750
3751 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3752 {
3753 if (unformat (i, "bd_id %d", &bd_id))
3754 {
3755 bd_id_set++;
3756 }
3757 else
3758 break;
3759 }
3760
3761 print (vam->ofp,
3762 "\n%-5s %-7s %-20s %-30s",
3763 "bd_id", "is_ipv6", "mac_address", "ip_address");
3764
3765 /* Dump Bridge Domain Ip to Mac entries */
3766 M (BD_IP_MAC_DUMP, mp);
3767
3768 if (bd_id_set)
3769 mp->bd_id = htonl (bd_id);
3770 else
3771 mp->bd_id = ~0;
3772
3773 S (mp);
3774
3775 /* Use a control ping for synchronization */
3776 MPING (CONTROL_PING, mp_ping);
3777 S (mp_ping);
3778
3779 W (ret);
3780 return ret;
3781}
3782
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01003783uword
jialv01082ebeb2019-09-10 00:23:55 +08003784unformat_vlib_pci_addr (unformat_input_t * input, va_list * args)
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01003785{
jialv01082ebeb2019-09-10 00:23:55 +08003786 vlib_pci_addr_t *addr = va_arg (*args, vlib_pci_addr_t *);
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01003787 u32 x[4];
3788
3789 if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
3790 return 0;
3791
3792 addr->domain = x[0];
3793 addr->bus = x[1];
3794 addr->slot = x[2];
3795 addr->function = x[3];
3796
3797 return 1;
3798}
3799
3800static int
Mohsin Kazmi518251b2020-09-01 17:17:44 +00003801api_virtio_pci_create_v2 (vat_main_t * vam)
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01003802{
3803 unformat_input_t *i = vam->input;
Mohsin Kazmi518251b2020-09-01 17:17:44 +00003804 vl_api_virtio_pci_create_v2_t *mp;
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01003805 u8 mac_address[6];
3806 u8 random_mac = 1;
3807 u32 pci_addr = 0;
3808 u64 features = (u64) ~ (0ULL);
Mohsin Kazmi518251b2020-09-01 17:17:44 +00003809 u32 virtio_flags = 0;
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01003810 int ret;
3811
3812 clib_memset (mac_address, 0, sizeof (mac_address));
3813
3814 /* Parse args required to build the message */
3815 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3816 {
3817 if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
3818 {
3819 random_mac = 0;
3820 }
jialv01082ebeb2019-09-10 00:23:55 +08003821 else if (unformat (i, "pci-addr %U", unformat_vlib_pci_addr, &pci_addr))
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01003822 ;
3823 else if (unformat (i, "features 0x%llx", &features))
3824 ;
Mohsin Kazmibbd6b742019-05-02 13:54:59 +02003825 else if (unformat (i, "gso-enabled"))
Mohsin Kazmi518251b2020-09-01 17:17:44 +00003826 virtio_flags |= VIRTIO_API_FLAG_GSO;
Mohsin Kazmi6d4af892020-01-03 15:11:53 +00003827 else if (unformat (i, "csum-offload-enabled"))
Mohsin Kazmi518251b2020-09-01 17:17:44 +00003828 virtio_flags |= VIRTIO_API_FLAG_CSUM_OFFLOAD;
3829 else if (unformat (i, "gro-coalesce"))
3830 virtio_flags |= VIRTIO_API_FLAG_GRO_COALESCE;
3831 else if (unformat (i, "packed"))
3832 virtio_flags |= VIRTIO_API_FLAG_PACKED;
3833 else if (unformat (i, "in-order"))
3834 virtio_flags |= VIRTIO_API_FLAG_IN_ORDER;
Mohsin Kazmie347acb2020-09-28 10:26:33 +00003835 else if (unformat (i, "buffering"))
3836 virtio_flags |= VIRTIO_API_FLAG_BUFFERING;
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01003837 else
3838 break;
3839 }
3840
3841 if (pci_addr == 0)
3842 {
3843 errmsg ("pci address must be non zero. ");
3844 return -99;
3845 }
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01003846
3847 /* Construct the API message */
Mohsin Kazmi518251b2020-09-01 17:17:44 +00003848 M (VIRTIO_PCI_CREATE_V2, mp);
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01003849
3850 mp->use_random_mac = random_mac;
3851
Jakub Grajciar2c504f82019-09-26 10:34:41 +02003852 mp->pci_addr.domain = htons (((vlib_pci_addr_t) pci_addr).domain);
3853 mp->pci_addr.bus = ((vlib_pci_addr_t) pci_addr).bus;
3854 mp->pci_addr.slot = ((vlib_pci_addr_t) pci_addr).slot;
3855 mp->pci_addr.function = ((vlib_pci_addr_t) pci_addr).function;
3856
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01003857 mp->features = clib_host_to_net_u64 (features);
Mohsin Kazmi518251b2020-09-01 17:17:44 +00003858 mp->virtio_flags = clib_host_to_net_u32 (virtio_flags);
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01003859
3860 if (random_mac == 0)
3861 clib_memcpy (mp->mac_address, mac_address, 6);
3862
3863 /* send it... */
3864 S (mp);
3865
3866 /* Wait for a reply... */
3867 W (ret);
3868 return ret;
3869}
3870
3871static int
3872api_virtio_pci_delete (vat_main_t * vam)
3873{
3874 unformat_input_t *i = vam->input;
3875 vl_api_virtio_pci_delete_t *mp;
3876 u32 sw_if_index = ~0;
3877 u8 sw_if_index_set = 0;
3878 int ret;
3879
3880 /* Parse args required to build the message */
3881 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3882 {
3883 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
3884 sw_if_index_set = 1;
3885 else if (unformat (i, "sw_if_index %d", &sw_if_index))
3886 sw_if_index_set = 1;
3887 else
3888 break;
3889 }
3890
3891 if (sw_if_index_set == 0)
3892 {
3893 errmsg ("missing vpp interface name. ");
3894 return -99;
3895 }
3896
3897 /* Construct the API message */
3898 M (VIRTIO_PCI_DELETE, mp);
3899
3900 mp->sw_if_index = htonl (sw_if_index);
3901
3902 /* send it... */
3903 S (mp);
3904
3905 /* Wait for a reply... */
3906 W (ret);
3907 return ret;
3908}
3909
Damjan Marion8389fb92017-10-13 18:29:53 +02003910static int
Neale Ranns28ab9cc2017-08-14 07:18:42 -07003911api_ip_table_add_del (vat_main_t * vam)
3912{
3913 unformat_input_t *i = vam->input;
3914 vl_api_ip_table_add_del_t *mp;
3915 u32 table_id = ~0;
3916 u8 is_ipv6 = 0;
3917 u8 is_add = 1;
3918 int ret = 0;
3919
3920 /* Parse args required to build the message */
3921 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3922 {
3923 if (unformat (i, "ipv6"))
3924 is_ipv6 = 1;
3925 else if (unformat (i, "del"))
3926 is_add = 0;
3927 else if (unformat (i, "add"))
3928 is_add = 1;
3929 else if (unformat (i, "table %d", &table_id))
3930 ;
3931 else
3932 {
3933 clib_warning ("parse error '%U'", format_unformat_error, i);
3934 return -99;
3935 }
3936 }
3937
3938 if (~0 == table_id)
3939 {
3940 errmsg ("missing table-ID");
3941 return -99;
3942 }
3943
3944 /* Construct the API message */
3945 M (IP_TABLE_ADD_DEL, mp);
3946
Neale Ranns097fa662018-05-01 05:17:55 -07003947 mp->table.table_id = ntohl (table_id);
3948 mp->table.is_ip6 = is_ipv6;
Neale Ranns28ab9cc2017-08-14 07:18:42 -07003949 mp->is_add = is_add;
3950
3951 /* send it... */
3952 S (mp);
3953
3954 /* Wait for a reply... */
3955 W (ret);
3956
3957 return ret;
3958}
3959
Neale Ranns097fa662018-05-01 05:17:55 -07003960uword
3961unformat_fib_path (unformat_input_t * input, va_list * args)
3962{
3963 vat_main_t *vam = va_arg (*args, vat_main_t *);
3964 vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
3965 u32 weight, preference;
3966 mpls_label_t out_label;
3967
3968 clib_memset (path, 0, sizeof (*path));
3969 path->weight = 1;
3970 path->sw_if_index = ~0;
3971 path->rpf_id = ~0;
3972 path->n_labels = 0;
3973
3974 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
3975 {
3976 if (unformat (input, "%U %U",
3977 unformat_vl_api_ip4_address,
3978 &path->nh.address.ip4,
3979 api_unformat_sw_if_index, vam, &path->sw_if_index))
3980 {
3981 path->proto = FIB_API_PATH_NH_PROTO_IP4;
3982 }
3983 else if (unformat (input, "%U %U",
3984 unformat_vl_api_ip6_address,
3985 &path->nh.address.ip6,
3986 api_unformat_sw_if_index, vam, &path->sw_if_index))
3987 {
3988 path->proto = FIB_API_PATH_NH_PROTO_IP6;
3989 }
3990 else if (unformat (input, "weight %u", &weight))
3991 {
3992 path->weight = weight;
3993 }
3994 else if (unformat (input, "preference %u", &preference))
3995 {
3996 path->preference = preference;
3997 }
3998 else if (unformat (input, "%U next-hop-table %d",
3999 unformat_vl_api_ip4_address,
4000 &path->nh.address.ip4, &path->table_id))
4001 {
4002 path->proto = FIB_API_PATH_NH_PROTO_IP4;
4003 }
4004 else if (unformat (input, "%U next-hop-table %d",
4005 unformat_vl_api_ip6_address,
4006 &path->nh.address.ip6, &path->table_id))
4007 {
4008 path->proto = FIB_API_PATH_NH_PROTO_IP6;
4009 }
4010 else if (unformat (input, "%U",
4011 unformat_vl_api_ip4_address, &path->nh.address.ip4))
4012 {
4013 /*
4014 * the recursive next-hops are by default in the default table
4015 */
4016 path->table_id = 0;
4017 path->sw_if_index = ~0;
4018 path->proto = FIB_API_PATH_NH_PROTO_IP4;
4019 }
4020 else if (unformat (input, "%U",
4021 unformat_vl_api_ip6_address, &path->nh.address.ip6))
4022 {
4023 /*
4024 * the recursive next-hops are by default in the default table
4025 */
4026 path->table_id = 0;
4027 path->sw_if_index = ~0;
4028 path->proto = FIB_API_PATH_NH_PROTO_IP6;
4029 }
4030 else if (unformat (input, "resolve-via-host"))
4031 {
4032 path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
4033 }
4034 else if (unformat (input, "resolve-via-attached"))
4035 {
4036 path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
4037 }
4038 else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
4039 {
4040 path->type = FIB_API_PATH_TYPE_LOCAL;
4041 path->sw_if_index = ~0;
4042 path->proto = FIB_API_PATH_NH_PROTO_IP4;
4043 }
4044 else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
4045 {
4046 path->type = FIB_API_PATH_TYPE_LOCAL;
4047 path->sw_if_index = ~0;
4048 path->proto = FIB_API_PATH_NH_PROTO_IP6;
4049 }
4050 else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
4051 ;
4052 else if (unformat (input, "via-label %d", &path->nh.via_label))
4053 {
4054 path->proto = FIB_API_PATH_NH_PROTO_MPLS;
4055 path->sw_if_index = ~0;
4056 }
4057 else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
4058 {
4059 path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
4060 path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
4061 }
4062 else if (unformat (input, "local"))
4063 {
4064 path->type = FIB_API_PATH_TYPE_LOCAL;
4065 }
4066 else if (unformat (input, "out-labels"))
4067 {
4068 while (unformat (input, "%d", &out_label))
4069 {
4070 path->label_stack[path->n_labels].label = out_label;
4071 path->label_stack[path->n_labels].is_uniform = 0;
4072 path->label_stack[path->n_labels].ttl = 64;
4073 path->n_labels++;
4074 }
4075 }
4076 else if (unformat (input, "via"))
4077 {
4078 /* new path, back up and return */
4079 unformat_put_input (input);
4080 unformat_put_input (input);
4081 unformat_put_input (input);
4082 unformat_put_input (input);
4083 break;
4084 }
4085 else
4086 {
4087 return (0);
4088 }
4089 }
4090
4091 path->proto = ntohl (path->proto);
4092 path->type = ntohl (path->type);
4093 path->flags = ntohl (path->flags);
4094 path->table_id = ntohl (path->table_id);
4095 path->sw_if_index = ntohl (path->sw_if_index);
4096
4097 return (1);
4098}
4099
Neale Ranns28ab9cc2017-08-14 07:18:42 -07004100static int
Neale Ranns097fa662018-05-01 05:17:55 -07004101api_ip_route_add_del (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +01004102{
4103 unformat_input_t *i = vam->input;
Neale Ranns097fa662018-05-01 05:17:55 -07004104 vl_api_ip_route_add_del_t *mp;
4105 u32 vrf_id = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004106 u8 is_add = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004107 u8 is_multipath = 0;
Neale Ranns097fa662018-05-01 05:17:55 -07004108 u8 prefix_set = 0;
4109 u8 path_count = 0;
4110 vl_api_prefix_t pfx = { };
4111 vl_api_fib_path_t paths[8];
Damjan Marion7cd468a2016-12-19 23:05:39 +01004112 int count = 1;
4113 int j;
4114 f64 before = 0;
4115 u32 random_add_del = 0;
4116 u32 *random_vector = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004117 u32 random_seed = 0xdeaddabe;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004118
4119 /* Parse args required to build the message */
4120 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4121 {
Neale Ranns097fa662018-05-01 05:17:55 -07004122 if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
4123 prefix_set = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004124 else if (unformat (i, "del"))
4125 is_add = 0;
4126 else if (unformat (i, "add"))
4127 is_add = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004128 else if (unformat (i, "vrf %d", &vrf_id))
4129 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004130 else if (unformat (i, "count %d", &count))
4131 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004132 else if (unformat (i, "random"))
4133 random_add_del = 1;
Neale Ranns097fa662018-05-01 05:17:55 -07004134 else if (unformat (i, "multipath"))
4135 is_multipath = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004136 else if (unformat (i, "seed %d", &random_seed))
4137 ;
4138 else
Neale Ranns097fa662018-05-01 05:17:55 -07004139 if (unformat
4140 (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
4141 {
4142 path_count++;
4143 if (8 == path_count)
4144 {
4145 errmsg ("max 8 paths");
4146 return -99;
4147 }
4148 }
4149 else
Damjan Marion7cd468a2016-12-19 23:05:39 +01004150 {
4151 clib_warning ("parse error '%U'", format_unformat_error, i);
4152 return -99;
4153 }
4154 }
4155
Neale Ranns097fa662018-05-01 05:17:55 -07004156 if (!path_count)
Damjan Marion7cd468a2016-12-19 23:05:39 +01004157 {
Neale Ranns097fa662018-05-01 05:17:55 -07004158 errmsg ("specify a path; via ...");
Damjan Marion7cd468a2016-12-19 23:05:39 +01004159 return -99;
4160 }
Neale Ranns097fa662018-05-01 05:17:55 -07004161 if (prefix_set == 0)
Damjan Marion7cd468a2016-12-19 23:05:39 +01004162 {
Neale Ranns097fa662018-05-01 05:17:55 -07004163 errmsg ("missing prefix");
Damjan Marion7cd468a2016-12-19 23:05:39 +01004164 return -99;
4165 }
4166
4167 /* Generate a pile of unique, random routes */
4168 if (random_add_del)
4169 {
Neale Ranns097fa662018-05-01 05:17:55 -07004170 ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004171 u32 this_random_address;
Neale Ranns097fa662018-05-01 05:17:55 -07004172 uword *random_hash;
4173
Damjan Marion7cd468a2016-12-19 23:05:39 +01004174 random_hash = hash_create (count, sizeof (uword));
4175
Neale Ranns097fa662018-05-01 05:17:55 -07004176 hash_set (random_hash, i->as_u32, 1);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004177 for (j = 0; j <= count; j++)
4178 {
4179 do
4180 {
4181 this_random_address = random_u32 (&random_seed);
4182 this_random_address =
4183 clib_host_to_net_u32 (this_random_address);
4184 }
4185 while (hash_get (random_hash, this_random_address));
4186 vec_add1 (random_vector, this_random_address);
4187 hash_set (random_hash, this_random_address, 1);
4188 }
4189 hash_free (random_hash);
Neale Ranns097fa662018-05-01 05:17:55 -07004190 set_ip4_address (&pfx.address, random_vector[0]);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004191 }
4192
4193 if (count > 1)
4194 {
4195 /* Turn on async mode */
4196 vam->async_mode = 1;
4197 vam->async_errors = 0;
4198 before = vat_time_now (vam);
4199 }
4200
4201 for (j = 0; j < count; j++)
4202 {
4203 /* Construct the API message */
Neale Ranns097fa662018-05-01 05:17:55 -07004204 M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004205
4206 mp->is_add = is_add;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004207 mp->is_multipath = is_multipath;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004208
Neale Ranns097fa662018-05-01 05:17:55 -07004209 clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
4210 mp->route.table_id = ntohl (vrf_id);
4211 mp->route.n_paths = path_count;
4212
4213 clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
4214
4215 if (random_add_del)
4216 set_ip4_address (&pfx.address, random_vector[j + 1]);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004217 else
Neale Ranns097fa662018-05-01 05:17:55 -07004218 increment_address (&pfx.address);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004219 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004220 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004221 /* If we receive SIGTERM, stop now... */
4222 if (vam->do_exit)
4223 break;
4224 }
4225
4226 /* When testing multiple add/del ops, use a control-ping to sync */
4227 if (count > 1)
4228 {
Jon Loeliger2d23eca2017-02-01 13:09:58 -06004229 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004230 f64 after;
Jon Loeliger1f9191f2017-01-31 15:27:19 -06004231 f64 timeout;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004232
4233 /* Shut off async mode */
4234 vam->async_mode = 0;
4235
Dave Barach59b25652017-09-10 15:04:27 -04004236 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06004237 S (mp_ping);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004238
4239 timeout = vat_time_now (vam) + 1.0;
4240 while (vat_time_now (vam) < timeout)
4241 if (vam->result_ready == 1)
4242 goto out;
4243 vam->retval = -99;
4244
4245 out:
4246 if (vam->retval == -99)
4247 errmsg ("timeout");
4248
4249 if (vam->async_errors > 0)
4250 {
4251 errmsg ("%d asynchronous errors", vam->async_errors);
4252 vam->retval = -98;
4253 }
4254 vam->async_errors = 0;
4255 after = vat_time_now (vam);
4256
4257 /* slim chance, but we might have eaten SIGTERM on the first iteration */
4258 if (j > 0)
4259 count = j;
4260
4261 print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
4262 count, after - before, count / (after - before));
4263 }
4264 else
4265 {
Jon Loeliger56c7b012017-02-01 12:31:41 -06004266 int ret;
4267
Damjan Marion7cd468a2016-12-19 23:05:39 +01004268 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06004269 W (ret);
4270 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004271 }
4272
4273 /* Return the good/bad news */
4274 return (vam->retval);
4275}
4276
4277static int
Neale Ranns32e1c012016-11-22 17:07:28 +00004278api_ip_mroute_add_del (vat_main_t * vam)
4279{
4280 unformat_input_t *i = vam->input;
Neale Ranns097fa662018-05-01 05:17:55 -07004281 u8 path_set = 0, prefix_set = 0, is_add = 1;
Neale Ranns32e1c012016-11-22 17:07:28 +00004282 vl_api_ip_mroute_add_del_t *mp;
Neale Ranns32e1c012016-11-22 17:07:28 +00004283 mfib_entry_flags_t eflags = 0;
Neale Ranns097fa662018-05-01 05:17:55 -07004284 vl_api_mfib_path_t path;
4285 vl_api_mprefix_t pfx = { };
4286 u32 vrf_id = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004287 int ret;
Neale Ranns32e1c012016-11-22 17:07:28 +00004288
4289 /* Parse args required to build the message */
4290 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4291 {
Neale Ranns097fa662018-05-01 05:17:55 -07004292 if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
Neale Ranns32e1c012016-11-22 17:07:28 +00004293 {
Neale Ranns097fa662018-05-01 05:17:55 -07004294 prefix_set = 1;
4295 pfx.grp_address_length = htons (pfx.grp_address_length);
Neale Ranns32e1c012016-11-22 17:07:28 +00004296 }
4297 else if (unformat (i, "del"))
4298 is_add = 0;
4299 else if (unformat (i, "add"))
4300 is_add = 1;
4301 else if (unformat (i, "vrf %d", &vrf_id))
4302 ;
Neale Ranns097fa662018-05-01 05:17:55 -07004303 else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
4304 path.itf_flags = htonl (path.itf_flags);
Neale Ranns32e1c012016-11-22 17:07:28 +00004305 else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
4306 ;
Neale Ranns097fa662018-05-01 05:17:55 -07004307 else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
4308 path_set = 1;
Neale Ranns32e1c012016-11-22 17:07:28 +00004309 else
4310 {
4311 clib_warning ("parse error '%U'", format_unformat_error, i);
4312 return -99;
4313 }
4314 }
4315
Neale Ranns097fa662018-05-01 05:17:55 -07004316 if (prefix_set == 0)
Neale Ranns32e1c012016-11-22 17:07:28 +00004317 {
4318 errmsg ("missing addresses\n");
4319 return -99;
4320 }
Neale Ranns097fa662018-05-01 05:17:55 -07004321 if (path_set == 0)
4322 {
4323 errmsg ("missing path\n");
4324 return -99;
4325 }
Neale Ranns32e1c012016-11-22 17:07:28 +00004326
4327 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004328 M (IP_MROUTE_ADD_DEL, mp);
Neale Ranns32e1c012016-11-22 17:07:28 +00004329
Neale Ranns32e1c012016-11-22 17:07:28 +00004330 mp->is_add = is_add;
Neale Ranns097fa662018-05-01 05:17:55 -07004331 mp->is_multipath = 1;
Neale Ranns32e1c012016-11-22 17:07:28 +00004332
Neale Ranns097fa662018-05-01 05:17:55 -07004333 clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
4334 mp->route.table_id = htonl (vrf_id);
4335 mp->route.n_paths = 1;
4336 mp->route.entry_flags = htonl (eflags);
Neale Ranns32e1c012016-11-22 17:07:28 +00004337
Neale Ranns097fa662018-05-01 05:17:55 -07004338 clib_memcpy (&mp->route.paths, &path, sizeof (path));
Neale Ranns32e1c012016-11-22 17:07:28 +00004339
4340 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004341 S (mp);
Neale Ranns32e1c012016-11-22 17:07:28 +00004342 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06004343 W (ret);
4344 return ret;
Neale Ranns32e1c012016-11-22 17:07:28 +00004345}
4346
4347static int
Neale Ranns28ab9cc2017-08-14 07:18:42 -07004348api_mpls_table_add_del (vat_main_t * vam)
4349{
4350 unformat_input_t *i = vam->input;
4351 vl_api_mpls_table_add_del_t *mp;
4352 u32 table_id = ~0;
4353 u8 is_add = 1;
4354 int ret = 0;
4355
4356 /* Parse args required to build the message */
4357 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4358 {
Florin Corasd0a59722017-10-15 17:41:21 +00004359 if (unformat (i, "table %d", &table_id))
4360 ;
4361 else if (unformat (i, "del"))
Neale Ranns28ab9cc2017-08-14 07:18:42 -07004362 is_add = 0;
4363 else if (unformat (i, "add"))
4364 is_add = 1;
4365 else
4366 {
4367 clib_warning ("parse error '%U'", format_unformat_error, i);
4368 return -99;
4369 }
4370 }
4371
4372 if (~0 == table_id)
4373 {
4374 errmsg ("missing table-ID");
4375 return -99;
4376 }
4377
4378 /* Construct the API message */
4379 M (MPLS_TABLE_ADD_DEL, mp);
4380
Neale Ranns097fa662018-05-01 05:17:55 -07004381 mp->mt_table.mt_table_id = ntohl (table_id);
Neale Ranns28ab9cc2017-08-14 07:18:42 -07004382 mp->mt_is_add = is_add;
4383
4384 /* send it... */
4385 S (mp);
4386
4387 /* Wait for a reply... */
4388 W (ret);
4389
4390 return ret;
4391}
4392
4393static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01004394api_mpls_route_add_del (vat_main_t * vam)
4395{
Neale Ranns097fa662018-05-01 05:17:55 -07004396 u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
4397 mpls_label_t local_label = MPLS_LABEL_INVALID;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004398 unformat_input_t *i = vam->input;
4399 vl_api_mpls_route_add_del_t *mp;
Neale Ranns097fa662018-05-01 05:17:55 -07004400 vl_api_fib_path_t paths[8];
4401 int count = 1, j;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004402 f64 before = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004403
4404 /* Parse args required to build the message */
4405 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4406 {
Neale Ranns097fa662018-05-01 05:17:55 -07004407 if (unformat (i, "%d", &local_label))
Damjan Marion7cd468a2016-12-19 23:05:39 +01004408 ;
4409 else if (unformat (i, "eos"))
4410 is_eos = 1;
4411 else if (unformat (i, "non-eos"))
4412 is_eos = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004413 else if (unformat (i, "del"))
4414 is_add = 0;
4415 else if (unformat (i, "add"))
4416 is_add = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004417 else if (unformat (i, "multipath"))
4418 is_multipath = 1;
4419 else if (unformat (i, "count %d", &count))
4420 ;
John Loe166fd92018-09-13 14:08:59 -04004421 else
4422 if (unformat
Neale Ranns097fa662018-05-01 05:17:55 -07004423 (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
John Loe166fd92018-09-13 14:08:59 -04004424 {
Neale Ranns097fa662018-05-01 05:17:55 -07004425 path_count++;
4426 if (8 == path_count)
4427 {
4428 errmsg ("max 8 paths");
4429 return -99;
4430 }
John Loe166fd92018-09-13 14:08:59 -04004431 }
Damjan Marion7cd468a2016-12-19 23:05:39 +01004432 else
4433 {
4434 clib_warning ("parse error '%U'", format_unformat_error, i);
4435 return -99;
4436 }
4437 }
4438
Neale Ranns097fa662018-05-01 05:17:55 -07004439 if (!path_count)
Damjan Marion7cd468a2016-12-19 23:05:39 +01004440 {
Neale Ranns097fa662018-05-01 05:17:55 -07004441 errmsg ("specify a path; via ...");
Damjan Marion7cd468a2016-12-19 23:05:39 +01004442 return -99;
4443 }
4444
4445 if (MPLS_LABEL_INVALID == local_label)
4446 {
4447 errmsg ("missing label");
4448 return -99;
4449 }
4450
4451 if (count > 1)
4452 {
4453 /* Turn on async mode */
4454 vam->async_mode = 1;
4455 vam->async_errors = 0;
4456 before = vat_time_now (vam);
4457 }
4458
4459 for (j = 0; j < count; j++)
4460 {
4461 /* Construct the API message */
Neale Ranns097fa662018-05-01 05:17:55 -07004462 M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004463
4464 mp->mr_is_add = is_add;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004465 mp->mr_is_multipath = is_multipath;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004466
Neale Ranns097fa662018-05-01 05:17:55 -07004467 mp->mr_route.mr_label = local_label;
4468 mp->mr_route.mr_eos = is_eos;
4469 mp->mr_route.mr_table_id = 0;
4470 mp->mr_route.mr_n_paths = path_count;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004471
Neale Ranns097fa662018-05-01 05:17:55 -07004472 clib_memcpy (&mp->mr_route.mr_paths, paths,
4473 sizeof (paths[0]) * path_count);
Neale Rannsda78f952017-05-24 09:15:43 -07004474
Damjan Marion7cd468a2016-12-19 23:05:39 +01004475 local_label++;
4476
4477 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004478 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004479 /* If we receive SIGTERM, stop now... */
4480 if (vam->do_exit)
4481 break;
4482 }
4483
4484 /* When testing multiple add/del ops, use a control-ping to sync */
4485 if (count > 1)
4486 {
Jon Loeliger2d23eca2017-02-01 13:09:58 -06004487 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004488 f64 after;
Jon Loeliger1f9191f2017-01-31 15:27:19 -06004489 f64 timeout;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004490
4491 /* Shut off async mode */
4492 vam->async_mode = 0;
4493
Dave Barach59b25652017-09-10 15:04:27 -04004494 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06004495 S (mp_ping);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004496
4497 timeout = vat_time_now (vam) + 1.0;
4498 while (vat_time_now (vam) < timeout)
4499 if (vam->result_ready == 1)
4500 goto out;
4501 vam->retval = -99;
4502
4503 out:
4504 if (vam->retval == -99)
4505 errmsg ("timeout");
4506
4507 if (vam->async_errors > 0)
4508 {
4509 errmsg ("%d asynchronous errors", vam->async_errors);
4510 vam->retval = -98;
4511 }
4512 vam->async_errors = 0;
4513 after = vat_time_now (vam);
4514
4515 /* slim chance, but we might have eaten SIGTERM on the first iteration */
4516 if (j > 0)
4517 count = j;
4518
4519 print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
4520 count, after - before, count / (after - before));
4521 }
4522 else
4523 {
Jon Loeliger56c7b012017-02-01 12:31:41 -06004524 int ret;
4525
Damjan Marion7cd468a2016-12-19 23:05:39 +01004526 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06004527 W (ret);
4528 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004529 }
4530
4531 /* Return the good/bad news */
4532 return (vam->retval);
Neale Ranns097fa662018-05-01 05:17:55 -07004533 return (0);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004534}
4535
4536static int
4537api_mpls_ip_bind_unbind (vat_main_t * vam)
4538{
4539 unformat_input_t *i = vam->input;
4540 vl_api_mpls_ip_bind_unbind_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004541 u32 ip_table_id = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004542 u8 is_bind = 1;
Neale Ranns097fa662018-05-01 05:17:55 -07004543 vl_api_prefix_t pfx;
4544 u8 prefix_set = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004545 mpls_label_t local_label = MPLS_LABEL_INVALID;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004546 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004547
4548 /* Parse args required to build the message */
4549 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4550 {
Neale Ranns097fa662018-05-01 05:17:55 -07004551 if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
4552 prefix_set = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004553 else if (unformat (i, "%d", &local_label))
4554 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004555 else if (unformat (i, "table-id %d", &ip_table_id))
4556 ;
4557 else if (unformat (i, "unbind"))
4558 is_bind = 0;
4559 else if (unformat (i, "bind"))
4560 is_bind = 1;
4561 else
4562 {
4563 clib_warning ("parse error '%U'", format_unformat_error, i);
4564 return -99;
4565 }
4566 }
4567
Neale Ranns097fa662018-05-01 05:17:55 -07004568 if (!prefix_set)
Damjan Marion7cd468a2016-12-19 23:05:39 +01004569 {
Neale Ranns097fa662018-05-01 05:17:55 -07004570 errmsg ("IP prefix not set");
Damjan Marion7cd468a2016-12-19 23:05:39 +01004571 return -99;
4572 }
4573
4574 if (MPLS_LABEL_INVALID == local_label)
4575 {
4576 errmsg ("missing label");
4577 return -99;
4578 }
4579
4580 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004581 M (MPLS_IP_BIND_UNBIND, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004582
Damjan Marion7cd468a2016-12-19 23:05:39 +01004583 mp->mb_is_bind = is_bind;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004584 mp->mb_ip_table_id = ntohl (ip_table_id);
4585 mp->mb_mpls_table_id = 0;
4586 mp->mb_label = ntohl (local_label);
Neale Ranns097fa662018-05-01 05:17:55 -07004587 clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
Damjan Marion7cd468a2016-12-19 23:05:39 +01004588
4589 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004590 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004591
4592 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06004593 W (ret);
4594 return ret;
Neale Ranns097fa662018-05-01 05:17:55 -07004595 return (0);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004596}
4597
4598static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01004599api_mpls_tunnel_add_del (vat_main_t * vam)
4600{
4601 unformat_input_t *i = vam->input;
4602 vl_api_mpls_tunnel_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004603
Neale Ranns097fa662018-05-01 05:17:55 -07004604 vl_api_fib_path_t paths[8];
Damjan Marion7cd468a2016-12-19 23:05:39 +01004605 u32 sw_if_index = ~0;
Neale Ranns097fa662018-05-01 05:17:55 -07004606 u8 path_count = 0;
4607 u8 l2_only = 0;
4608 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004609 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004610
4611 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4612 {
4613 if (unformat (i, "add"))
4614 is_add = 1;
John Lo06fda9c2018-10-03 16:32:44 -04004615 else
4616 if (unformat
4617 (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
4618 is_add = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004619 else if (unformat (i, "del sw_if_index %d", &sw_if_index))
4620 is_add = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004621 else if (unformat (i, "l2-only"))
4622 l2_only = 1;
Neale Ranns097fa662018-05-01 05:17:55 -07004623 else
4624 if (unformat
4625 (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
John Lo06fda9c2018-10-03 16:32:44 -04004626 {
Neale Ranns097fa662018-05-01 05:17:55 -07004627 path_count++;
4628 if (8 == path_count)
4629 {
4630 errmsg ("max 8 paths");
4631 return -99;
4632 }
John Lo06fda9c2018-10-03 16:32:44 -04004633 }
Damjan Marion7cd468a2016-12-19 23:05:39 +01004634 else
4635 {
4636 clib_warning ("parse error '%U'", format_unformat_error, i);
4637 return -99;
4638 }
4639 }
4640
Neale Ranns097fa662018-05-01 05:17:55 -07004641 M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004642
Damjan Marion7cd468a2016-12-19 23:05:39 +01004643 mp->mt_is_add = is_add;
Neale Ranns097fa662018-05-01 05:17:55 -07004644 mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
4645 mp->mt_tunnel.mt_l2_only = l2_only;
4646 mp->mt_tunnel.mt_is_multicast = 0;
4647 mp->mt_tunnel.mt_n_paths = path_count;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004648
Neale Ranns097fa662018-05-01 05:17:55 -07004649 clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
4650 sizeof (paths[0]) * path_count);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004651
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004652 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06004653 W (ret);
4654 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004655}
4656
4657static int
4658api_sw_interface_set_unnumbered (vat_main_t * vam)
4659{
4660 unformat_input_t *i = vam->input;
4661 vl_api_sw_interface_set_unnumbered_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004662 u32 sw_if_index;
4663 u32 unnum_sw_index = ~0;
4664 u8 is_add = 1;
4665 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004666 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004667
4668 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4669 {
4670 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4671 sw_if_index_set = 1;
4672 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4673 sw_if_index_set = 1;
4674 else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
4675 ;
4676 else if (unformat (i, "del"))
4677 is_add = 0;
4678 else
4679 {
4680 clib_warning ("parse error '%U'", format_unformat_error, i);
4681 return -99;
4682 }
4683 }
4684
4685 if (sw_if_index_set == 0)
4686 {
4687 errmsg ("missing interface name or sw_if_index");
4688 return -99;
4689 }
4690
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004691 M (SW_INTERFACE_SET_UNNUMBERED, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004692
4693 mp->sw_if_index = ntohl (sw_if_index);
4694 mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
4695 mp->is_add = is_add;
4696
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004697 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06004698 W (ret);
4699 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004700}
4701
Damjan Marion7cd468a2016-12-19 23:05:39 +01004702
4703static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01004704api_create_vlan_subif (vat_main_t * vam)
4705{
4706 unformat_input_t *i = vam->input;
4707 vl_api_create_vlan_subif_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004708 u32 sw_if_index;
4709 u8 sw_if_index_set = 0;
4710 u32 vlan_id;
4711 u8 vlan_id_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004712 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004713
4714 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4715 {
4716 if (unformat (i, "sw_if_index %d", &sw_if_index))
4717 sw_if_index_set = 1;
4718 else
4719 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4720 sw_if_index_set = 1;
4721 else if (unformat (i, "vlan %d", &vlan_id))
4722 vlan_id_set = 1;
4723 else
4724 {
4725 clib_warning ("parse error '%U'", format_unformat_error, i);
4726 return -99;
4727 }
4728 }
4729
4730 if (sw_if_index_set == 0)
4731 {
4732 errmsg ("missing interface name or sw_if_index");
4733 return -99;
4734 }
4735
4736 if (vlan_id_set == 0)
4737 {
4738 errmsg ("missing vlan_id");
4739 return -99;
4740 }
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004741 M (CREATE_VLAN_SUBIF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004742
4743 mp->sw_if_index = ntohl (sw_if_index);
4744 mp->vlan_id = ntohl (vlan_id);
4745
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004746 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06004747 W (ret);
4748 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004749}
4750
4751#define foreach_create_subif_bit \
4752_(no_tags) \
4753_(one_tag) \
4754_(two_tags) \
4755_(dot1ad) \
4756_(exact_match) \
4757_(default_sub) \
4758_(outer_vlan_id_any) \
4759_(inner_vlan_id_any)
4760
Jakub Grajciar053204a2019-03-18 13:17:53 +01004761#define foreach_create_subif_flag \
4762_(0, "no_tags") \
4763_(1, "one_tag") \
4764_(2, "two_tags") \
4765_(3, "dot1ad") \
4766_(4, "exact_match") \
4767_(5, "default_sub") \
4768_(6, "outer_vlan_id_any") \
4769_(7, "inner_vlan_id_any")
4770
Damjan Marion7cd468a2016-12-19 23:05:39 +01004771static int
4772api_create_subif (vat_main_t * vam)
4773{
4774 unformat_input_t *i = vam->input;
4775 vl_api_create_subif_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004776 u32 sw_if_index;
4777 u8 sw_if_index_set = 0;
4778 u32 sub_id;
4779 u8 sub_id_set = 0;
Jakub Grajciar053204a2019-03-18 13:17:53 +01004780 u32 __attribute__ ((unused)) no_tags = 0;
4781 u32 __attribute__ ((unused)) one_tag = 0;
4782 u32 __attribute__ ((unused)) two_tags = 0;
4783 u32 __attribute__ ((unused)) dot1ad = 0;
4784 u32 __attribute__ ((unused)) exact_match = 0;
4785 u32 __attribute__ ((unused)) default_sub = 0;
4786 u32 __attribute__ ((unused)) outer_vlan_id_any = 0;
4787 u32 __attribute__ ((unused)) inner_vlan_id_any = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004788 u32 tmp;
4789 u16 outer_vlan_id = 0;
4790 u16 inner_vlan_id = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004791 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004792
4793 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4794 {
4795 if (unformat (i, "sw_if_index %d", &sw_if_index))
4796 sw_if_index_set = 1;
4797 else
4798 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4799 sw_if_index_set = 1;
4800 else if (unformat (i, "sub_id %d", &sub_id))
4801 sub_id_set = 1;
4802 else if (unformat (i, "outer_vlan_id %d", &tmp))
4803 outer_vlan_id = tmp;
4804 else if (unformat (i, "inner_vlan_id %d", &tmp))
4805 inner_vlan_id = tmp;
4806
4807#define _(a) else if (unformat (i, #a)) a = 1 ;
4808 foreach_create_subif_bit
4809#undef _
4810 else
4811 {
4812 clib_warning ("parse error '%U'", format_unformat_error, i);
4813 return -99;
4814 }
4815 }
4816
4817 if (sw_if_index_set == 0)
4818 {
4819 errmsg ("missing interface name or sw_if_index");
4820 return -99;
4821 }
4822
4823 if (sub_id_set == 0)
4824 {
4825 errmsg ("missing sub_id");
4826 return -99;
4827 }
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004828 M (CREATE_SUBIF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004829
4830 mp->sw_if_index = ntohl (sw_if_index);
4831 mp->sub_id = ntohl (sub_id);
4832
Jakub Grajciar053204a2019-03-18 13:17:53 +01004833#define _(a,b) mp->sub_if_flags |= (1 << a);
4834 foreach_create_subif_flag;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004835#undef _
4836
4837 mp->outer_vlan_id = ntohs (outer_vlan_id);
4838 mp->inner_vlan_id = ntohs (inner_vlan_id);
4839
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004840 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06004841 W (ret);
4842 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004843}
4844
4845static int
Neale Ranns9db6ada2019-11-08 12:42:31 +00004846api_ip_table_replace_begin (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +01004847{
4848 unformat_input_t *i = vam->input;
Neale Ranns9db6ada2019-11-08 12:42:31 +00004849 vl_api_ip_table_replace_begin_t *mp;
4850 u32 table_id = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004851 u8 is_ipv6 = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004852
Jon Loeliger56c7b012017-02-01 12:31:41 -06004853 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004854 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4855 {
Neale Ranns9db6ada2019-11-08 12:42:31 +00004856 if (unformat (i, "table %d", &table_id))
4857 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004858 else if (unformat (i, "ipv6"))
4859 is_ipv6 = 1;
4860 else
4861 {
4862 clib_warning ("parse error '%U'", format_unformat_error, i);
4863 return -99;
4864 }
4865 }
4866
Neale Ranns9db6ada2019-11-08 12:42:31 +00004867 M (IP_TABLE_REPLACE_BEGIN, mp);
4868
4869 mp->table.table_id = ntohl (table_id);
4870 mp->table.is_ip6 = is_ipv6;
4871
4872 S (mp);
4873 W (ret);
4874 return ret;
4875}
4876
4877static int
4878api_ip_table_flush (vat_main_t * vam)
4879{
4880 unformat_input_t *i = vam->input;
4881 vl_api_ip_table_flush_t *mp;
4882 u32 table_id = 0;
4883 u8 is_ipv6 = 0;
4884
4885 int ret;
4886 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
Damjan Marion7cd468a2016-12-19 23:05:39 +01004887 {
Neale Ranns9db6ada2019-11-08 12:42:31 +00004888 if (unformat (i, "table %d", &table_id))
4889 ;
4890 else if (unformat (i, "ipv6"))
4891 is_ipv6 = 1;
4892 else
4893 {
4894 clib_warning ("parse error '%U'", format_unformat_error, i);
4895 return -99;
4896 }
Damjan Marion7cd468a2016-12-19 23:05:39 +01004897 }
4898
Neale Ranns9db6ada2019-11-08 12:42:31 +00004899 M (IP_TABLE_FLUSH, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004900
Neale Ranns9db6ada2019-11-08 12:42:31 +00004901 mp->table.table_id = ntohl (table_id);
4902 mp->table.is_ip6 = is_ipv6;
4903
4904 S (mp);
4905 W (ret);
4906 return ret;
4907}
4908
4909static int
4910api_ip_table_replace_end (vat_main_t * vam)
4911{
4912 unformat_input_t *i = vam->input;
4913 vl_api_ip_table_replace_end_t *mp;
4914 u32 table_id = 0;
4915 u8 is_ipv6 = 0;
4916
4917 int ret;
4918 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4919 {
4920 if (unformat (i, "table %d", &table_id))
4921 ;
4922 else if (unformat (i, "ipv6"))
4923 is_ipv6 = 1;
4924 else
4925 {
4926 clib_warning ("parse error '%U'", format_unformat_error, i);
4927 return -99;
4928 }
4929 }
4930
4931 M (IP_TABLE_REPLACE_END, mp);
4932
4933 mp->table.table_id = ntohl (table_id);
4934 mp->table.is_ip6 = is_ipv6;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004935
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004936 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06004937 W (ret);
4938 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004939}
4940
4941static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01004942api_set_ip_flow_hash (vat_main_t * vam)
4943{
4944 unformat_input_t *i = vam->input;
4945 vl_api_set_ip_flow_hash_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004946 u32 vrf_id = 0;
4947 u8 is_ipv6 = 0;
4948 u8 vrf_id_set = 0;
4949 u8 src = 0;
4950 u8 dst = 0;
4951 u8 sport = 0;
4952 u8 dport = 0;
4953 u8 proto = 0;
4954 u8 reverse = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004955 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004956
4957 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4958 {
4959 if (unformat (i, "vrf %d", &vrf_id))
4960 vrf_id_set = 1;
4961 else if (unformat (i, "ipv6"))
4962 is_ipv6 = 1;
4963 else if (unformat (i, "src"))
4964 src = 1;
4965 else if (unformat (i, "dst"))
4966 dst = 1;
4967 else if (unformat (i, "sport"))
4968 sport = 1;
4969 else if (unformat (i, "dport"))
4970 dport = 1;
4971 else if (unformat (i, "proto"))
4972 proto = 1;
4973 else if (unformat (i, "reverse"))
4974 reverse = 1;
4975
4976 else
4977 {
4978 clib_warning ("parse error '%U'", format_unformat_error, i);
4979 return -99;
4980 }
4981 }
4982
4983 if (vrf_id_set == 0)
4984 {
4985 errmsg ("missing vrf id");
4986 return -99;
4987 }
4988
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004989 M (SET_IP_FLOW_HASH, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004990 mp->src = src;
4991 mp->dst = dst;
4992 mp->sport = sport;
4993 mp->dport = dport;
4994 mp->proto = proto;
4995 mp->reverse = reverse;
4996 mp->vrf_id = ntohl (vrf_id);
4997 mp->is_ipv6 = is_ipv6;
4998
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004999 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06005000 W (ret);
5001 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005002}
5003
5004static int
5005api_sw_interface_ip6_enable_disable (vat_main_t * vam)
5006{
5007 unformat_input_t *i = vam->input;
5008 vl_api_sw_interface_ip6_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005009 u32 sw_if_index;
5010 u8 sw_if_index_set = 0;
5011 u8 enable = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005012 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005013
5014 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5015 {
5016 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5017 sw_if_index_set = 1;
5018 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5019 sw_if_index_set = 1;
5020 else if (unformat (i, "enable"))
5021 enable = 1;
5022 else if (unformat (i, "disable"))
5023 enable = 0;
5024 else
5025 {
5026 clib_warning ("parse error '%U'", format_unformat_error, i);
5027 return -99;
5028 }
5029 }
5030
5031 if (sw_if_index_set == 0)
5032 {
5033 errmsg ("missing interface name or sw_if_index");
5034 return -99;
5035 }
5036
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005037 M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005038
5039 mp->sw_if_index = ntohl (sw_if_index);
5040 mp->enable = enable;
5041
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005042 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06005043 W (ret);
5044 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005045}
5046
Damjan Marion7cd468a2016-12-19 23:05:39 +01005047
5048static int
5049api_l2_patch_add_del (vat_main_t * vam)
5050{
5051 unformat_input_t *i = vam->input;
5052 vl_api_l2_patch_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005053 u32 rx_sw_if_index;
5054 u8 rx_sw_if_index_set = 0;
5055 u32 tx_sw_if_index;
5056 u8 tx_sw_if_index_set = 0;
5057 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005058 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005059
5060 /* Parse args required to build the message */
5061 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5062 {
5063 if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5064 rx_sw_if_index_set = 1;
5065 else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5066 tx_sw_if_index_set = 1;
5067 else if (unformat (i, "rx"))
5068 {
5069 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5070 {
5071 if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5072 &rx_sw_if_index))
5073 rx_sw_if_index_set = 1;
5074 }
5075 else
5076 break;
5077 }
5078 else if (unformat (i, "tx"))
5079 {
5080 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5081 {
5082 if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5083 &tx_sw_if_index))
5084 tx_sw_if_index_set = 1;
5085 }
5086 else
5087 break;
5088 }
5089 else if (unformat (i, "del"))
5090 is_add = 0;
5091 else
5092 break;
5093 }
5094
5095 if (rx_sw_if_index_set == 0)
5096 {
5097 errmsg ("missing rx interface name or rx_sw_if_index");
5098 return -99;
5099 }
5100
5101 if (tx_sw_if_index_set == 0)
5102 {
5103 errmsg ("missing tx interface name or tx_sw_if_index");
5104 return -99;
5105 }
5106
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005107 M (L2_PATCH_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005108
5109 mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5110 mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5111 mp->is_add = is_add;
5112
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005113 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06005114 W (ret);
5115 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005116}
5117
Pablo Camarillofb380952016-12-07 18:34:18 +01005118u8 is_del;
5119u8 localsid_addr[16];
5120u8 end_psp;
5121u8 behavior;
5122u32 sw_if_index;
5123u32 vlan_index;
5124u32 fib_table;
5125u8 nh_addr[16];
5126
5127static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01005128api_ioam_enable (vat_main_t * vam)
5129{
5130 unformat_input_t *input = vam->input;
5131 vl_api_ioam_enable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005132 u32 id = 0;
5133 int has_trace_option = 0;
5134 int has_pot_option = 0;
5135 int has_seqno_option = 0;
5136 int has_analyse_option = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005137 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005138
5139 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
5140 {
5141 if (unformat (input, "trace"))
5142 has_trace_option = 1;
5143 else if (unformat (input, "pot"))
5144 has_pot_option = 1;
5145 else if (unformat (input, "seqno"))
5146 has_seqno_option = 1;
5147 else if (unformat (input, "analyse"))
5148 has_analyse_option = 1;
5149 else
5150 break;
5151 }
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005152 M (IOAM_ENABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005153 mp->id = htons (id);
5154 mp->seqno = has_seqno_option;
5155 mp->analyse = has_analyse_option;
5156 mp->pot_enable = has_pot_option;
5157 mp->trace_enable = has_trace_option;
5158
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005159 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06005160 W (ret);
5161 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005162}
5163
5164
5165static int
5166api_ioam_disable (vat_main_t * vam)
5167{
5168 vl_api_ioam_disable_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005169 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005170
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005171 M (IOAM_DISABLE, mp);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005172 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06005173 W (ret);
5174 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005175}
5176
Damjan Marion7cd468a2016-12-19 23:05:39 +01005177#define foreach_tcp_proto_field \
5178_(src_port) \
5179_(dst_port)
5180
5181#define foreach_udp_proto_field \
5182_(src_port) \
5183_(dst_port)
5184
5185#define foreach_ip4_proto_field \
5186_(src_address) \
5187_(dst_address) \
5188_(tos) \
5189_(length) \
5190_(fragment_id) \
5191_(ttl) \
5192_(protocol) \
5193_(checksum)
5194
Dave Barach4a3f69c2017-02-22 12:44:56 -05005195typedef struct
5196{
5197 u16 src_port, dst_port;
5198} tcpudp_header_t;
5199
5200#if VPP_API_TEST_BUILTIN == 0
Damjan Marion7cd468a2016-12-19 23:05:39 +01005201uword
5202unformat_tcp_mask (unformat_input_t * input, va_list * args)
5203{
5204 u8 **maskp = va_arg (*args, u8 **);
5205 u8 *mask = 0;
5206 u8 found_something = 0;
5207 tcp_header_t *tcp;
5208
5209#define _(a) u8 a=0;
5210 foreach_tcp_proto_field;
5211#undef _
5212
5213 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
5214 {
5215 if (0);
5216#define _(a) else if (unformat (input, #a)) a=1;
5217 foreach_tcp_proto_field
5218#undef _
5219 else
5220 break;
5221 }
5222
5223#define _(a) found_something += a;
5224 foreach_tcp_proto_field;
5225#undef _
5226
5227 if (found_something == 0)
5228 return 0;
5229
5230 vec_validate (mask, sizeof (*tcp) - 1);
5231
5232 tcp = (tcp_header_t *) mask;
5233
Dave Barachb7b92992018-10-17 10:38:51 -04005234#define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
Damjan Marion7cd468a2016-12-19 23:05:39 +01005235 foreach_tcp_proto_field;
5236#undef _
5237
5238 *maskp = mask;
5239 return 1;
5240}
5241
5242uword
5243unformat_udp_mask (unformat_input_t * input, va_list * args)
5244{
5245 u8 **maskp = va_arg (*args, u8 **);
5246 u8 *mask = 0;
5247 u8 found_something = 0;
5248 udp_header_t *udp;
5249
5250#define _(a) u8 a=0;
5251 foreach_udp_proto_field;
5252#undef _
5253
5254 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
5255 {
5256 if (0);
5257#define _(a) else if (unformat (input, #a)) a=1;
5258 foreach_udp_proto_field
5259#undef _
5260 else
5261 break;
5262 }
5263
5264#define _(a) found_something += a;
5265 foreach_udp_proto_field;
5266#undef _
5267
5268 if (found_something == 0)
5269 return 0;
5270
5271 vec_validate (mask, sizeof (*udp) - 1);
5272
5273 udp = (udp_header_t *) mask;
5274
Dave Barachb7b92992018-10-17 10:38:51 -04005275#define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
Damjan Marion7cd468a2016-12-19 23:05:39 +01005276 foreach_udp_proto_field;
5277#undef _
5278
5279 *maskp = mask;
5280 return 1;
5281}
5282
Damjan Marion7cd468a2016-12-19 23:05:39 +01005283uword
5284unformat_l4_mask (unformat_input_t * input, va_list * args)
5285{
5286 u8 **maskp = va_arg (*args, u8 **);
5287 u16 src_port = 0, dst_port = 0;
5288 tcpudp_header_t *tcpudp;
5289
5290 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
5291 {
5292 if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
5293 return 1;
5294 else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
5295 return 1;
5296 else if (unformat (input, "src_port"))
5297 src_port = 0xFFFF;
5298 else if (unformat (input, "dst_port"))
5299 dst_port = 0xFFFF;
5300 else
5301 return 0;
5302 }
5303
5304 if (!src_port && !dst_port)
5305 return 0;
5306
5307 u8 *mask = 0;
5308 vec_validate (mask, sizeof (tcpudp_header_t) - 1);
5309
5310 tcpudp = (tcpudp_header_t *) mask;
5311 tcpudp->src_port = src_port;
5312 tcpudp->dst_port = dst_port;
5313
5314 *maskp = mask;
5315
5316 return 1;
5317}
5318
5319uword
5320unformat_ip4_mask (unformat_input_t * input, va_list * args)
5321{
5322 u8 **maskp = va_arg (*args, u8 **);
5323 u8 *mask = 0;
5324 u8 found_something = 0;
5325 ip4_header_t *ip;
5326
5327#define _(a) u8 a=0;
5328 foreach_ip4_proto_field;
5329#undef _
5330 u8 version = 0;
5331 u8 hdr_length = 0;
5332
5333
5334 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
5335 {
5336 if (unformat (input, "version"))
5337 version = 1;
5338 else if (unformat (input, "hdr_length"))
5339 hdr_length = 1;
5340 else if (unformat (input, "src"))
5341 src_address = 1;
5342 else if (unformat (input, "dst"))
5343 dst_address = 1;
5344 else if (unformat (input, "proto"))
5345 protocol = 1;
5346
5347#define _(a) else if (unformat (input, #a)) a=1;
5348 foreach_ip4_proto_field
5349#undef _
5350 else
5351 break;
5352 }
5353
5354#define _(a) found_something += a;
5355 foreach_ip4_proto_field;
5356#undef _
5357
5358 if (found_something == 0)
5359 return 0;
5360
5361 vec_validate (mask, sizeof (*ip) - 1);
5362
5363 ip = (ip4_header_t *) mask;
5364
Dave Barachb7b92992018-10-17 10:38:51 -04005365#define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
Damjan Marion7cd468a2016-12-19 23:05:39 +01005366 foreach_ip4_proto_field;
5367#undef _
5368
5369 ip->ip_version_and_header_length = 0;
5370
5371 if (version)
5372 ip->ip_version_and_header_length |= 0xF0;
5373
5374 if (hdr_length)
5375 ip->ip_version_and_header_length |= 0x0F;
5376
5377 *maskp = mask;
5378 return 1;
5379}
5380
5381#define foreach_ip6_proto_field \
5382_(src_address) \
5383_(dst_address) \
5384_(payload_length) \
5385_(hop_limit) \
5386_(protocol)
5387
5388uword
5389unformat_ip6_mask (unformat_input_t * input, va_list * args)
5390{
5391 u8 **maskp = va_arg (*args, u8 **);
5392 u8 *mask = 0;
5393 u8 found_something = 0;
5394 ip6_header_t *ip;
5395 u32 ip_version_traffic_class_and_flow_label;
5396
5397#define _(a) u8 a=0;
5398 foreach_ip6_proto_field;
5399#undef _
5400 u8 version = 0;
5401 u8 traffic_class = 0;
5402 u8 flow_label = 0;
5403
5404 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
5405 {
5406 if (unformat (input, "version"))
5407 version = 1;
5408 else if (unformat (input, "traffic-class"))
5409 traffic_class = 1;
5410 else if (unformat (input, "flow-label"))
5411 flow_label = 1;
5412 else if (unformat (input, "src"))
5413 src_address = 1;
5414 else if (unformat (input, "dst"))
5415 dst_address = 1;
5416 else if (unformat (input, "proto"))
5417 protocol = 1;
5418
5419#define _(a) else if (unformat (input, #a)) a=1;
5420 foreach_ip6_proto_field
5421#undef _
5422 else
5423 break;
5424 }
5425
5426#define _(a) found_something += a;
5427 foreach_ip6_proto_field;
5428#undef _
5429
5430 if (found_something == 0)
5431 return 0;
5432
5433 vec_validate (mask, sizeof (*ip) - 1);
5434
5435 ip = (ip6_header_t *) mask;
5436
Dave Barachb7b92992018-10-17 10:38:51 -04005437#define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
Damjan Marion7cd468a2016-12-19 23:05:39 +01005438 foreach_ip6_proto_field;
5439#undef _
5440
5441 ip_version_traffic_class_and_flow_label = 0;
5442
5443 if (version)
5444 ip_version_traffic_class_and_flow_label |= 0xF0000000;
5445
5446 if (traffic_class)
5447 ip_version_traffic_class_and_flow_label |= 0x0FF00000;
5448
5449 if (flow_label)
5450 ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
5451
5452 ip->ip_version_traffic_class_and_flow_label =
5453 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
5454
5455 *maskp = mask;
5456 return 1;
5457}
5458
5459uword
5460unformat_l3_mask (unformat_input_t * input, va_list * args)
5461{
5462 u8 **maskp = va_arg (*args, u8 **);
5463
5464 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
5465 {
5466 if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
5467 return 1;
5468 else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
5469 return 1;
5470 else
5471 break;
5472 }
5473 return 0;
5474}
5475
5476uword
5477unformat_l2_mask (unformat_input_t * input, va_list * args)
5478{
5479 u8 **maskp = va_arg (*args, u8 **);
5480 u8 *mask = 0;
5481 u8 src = 0;
5482 u8 dst = 0;
5483 u8 proto = 0;
5484 u8 tag1 = 0;
5485 u8 tag2 = 0;
5486 u8 ignore_tag1 = 0;
5487 u8 ignore_tag2 = 0;
5488 u8 cos1 = 0;
5489 u8 cos2 = 0;
5490 u8 dot1q = 0;
5491 u8 dot1ad = 0;
5492 int len = 14;
5493
5494 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
5495 {
5496 if (unformat (input, "src"))
5497 src = 1;
5498 else if (unformat (input, "dst"))
5499 dst = 1;
5500 else if (unformat (input, "proto"))
5501 proto = 1;
5502 else if (unformat (input, "tag1"))
5503 tag1 = 1;
5504 else if (unformat (input, "tag2"))
5505 tag2 = 1;
5506 else if (unformat (input, "ignore-tag1"))
5507 ignore_tag1 = 1;
5508 else if (unformat (input, "ignore-tag2"))
5509 ignore_tag2 = 1;
5510 else if (unformat (input, "cos1"))
5511 cos1 = 1;
5512 else if (unformat (input, "cos2"))
5513 cos2 = 1;
5514 else if (unformat (input, "dot1q"))
5515 dot1q = 1;
5516 else if (unformat (input, "dot1ad"))
5517 dot1ad = 1;
5518 else
5519 break;
5520 }
5521 if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
5522 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
5523 return 0;
5524
5525 if (tag1 || ignore_tag1 || cos1 || dot1q)
5526 len = 18;
5527 if (tag2 || ignore_tag2 || cos2 || dot1ad)
5528 len = 22;
5529
5530 vec_validate (mask, len - 1);
5531
5532 if (dst)
Dave Barachb7b92992018-10-17 10:38:51 -04005533 clib_memset (mask, 0xff, 6);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005534
5535 if (src)
Dave Barachb7b92992018-10-17 10:38:51 -04005536 clib_memset (mask + 6, 0xff, 6);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005537
5538 if (tag2 || dot1ad)
5539 {
5540 /* inner vlan tag */
5541 if (tag2)
5542 {
5543 mask[19] = 0xff;
5544 mask[18] = 0x0f;
5545 }
5546 if (cos2)
5547 mask[18] |= 0xe0;
5548 if (proto)
5549 mask[21] = mask[20] = 0xff;
5550 if (tag1)
5551 {
5552 mask[15] = 0xff;
5553 mask[14] = 0x0f;
5554 }
5555 if (cos1)
5556 mask[14] |= 0xe0;
5557 *maskp = mask;
5558 return 1;
5559 }
5560 if (tag1 | dot1q)
5561 {
5562 if (tag1)
5563 {
5564 mask[15] = 0xff;
5565 mask[14] = 0x0f;
5566 }
5567 if (cos1)
5568 mask[14] |= 0xe0;
5569 if (proto)
5570 mask[16] = mask[17] = 0xff;
5571
5572 *maskp = mask;
5573 return 1;
5574 }
5575 if (cos2)
5576 mask[18] |= 0xe0;
5577 if (cos1)
5578 mask[14] |= 0xe0;
5579 if (proto)
5580 mask[12] = mask[13] = 0xff;
5581
5582 *maskp = mask;
5583 return 1;
5584}
5585
5586uword
5587unformat_classify_mask (unformat_input_t * input, va_list * args)
5588{
5589 u8 **maskp = va_arg (*args, u8 **);
5590 u32 *skipp = va_arg (*args, u32 *);
5591 u32 *matchp = va_arg (*args, u32 *);
5592 u32 match;
5593 u8 *mask = 0;
5594 u8 *l2 = 0;
5595 u8 *l3 = 0;
5596 u8 *l4 = 0;
5597 int i;
5598
5599 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
5600 {
5601 if (unformat (input, "hex %U", unformat_hex_string, &mask))
5602 ;
5603 else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
5604 ;
5605 else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
5606 ;
5607 else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
5608 ;
5609 else
5610 break;
5611 }
5612
5613 if (l4 && !l3)
5614 {
5615 vec_free (mask);
5616 vec_free (l2);
5617 vec_free (l4);
5618 return 0;
5619 }
5620
5621 if (mask || l2 || l3 || l4)
5622 {
5623 if (l2 || l3 || l4)
5624 {
5625 /* "With a free Ethernet header in every package" */
5626 if (l2 == 0)
5627 vec_validate (l2, 13);
5628 mask = l2;
5629 if (vec_len (l3))
5630 {
5631 vec_append (mask, l3);
5632 vec_free (l3);
5633 }
5634 if (vec_len (l4))
5635 {
5636 vec_append (mask, l4);
5637 vec_free (l4);
5638 }
5639 }
5640
5641 /* Scan forward looking for the first significant mask octet */
5642 for (i = 0; i < vec_len (mask); i++)
5643 if (mask[i])
5644 break;
5645
5646 /* compute (skip, match) params */
5647 *skipp = i / sizeof (u32x4);
5648 vec_delete (mask, *skipp * sizeof (u32x4), 0);
5649
5650 /* Pad mask to an even multiple of the vector size */
5651 while (vec_len (mask) % sizeof (u32x4))
5652 vec_add1 (mask, 0);
5653
5654 match = vec_len (mask) / sizeof (u32x4);
5655
5656 for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
5657 {
5658 u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
5659 if (*tmp || *(tmp + 1))
5660 break;
5661 match--;
5662 }
5663 if (match == 0)
5664 clib_warning ("BUG: match 0");
5665
5666 _vec_len (mask) = match * sizeof (u32x4);
5667
5668 *matchp = match;
5669 *maskp = mask;
5670
5671 return 1;
5672 }
5673
5674 return 0;
5675}
Dave Barach4a3f69c2017-02-22 12:44:56 -05005676#endif /* VPP_API_TEST_BUILTIN */
Damjan Marion7cd468a2016-12-19 23:05:39 +01005677
5678#define foreach_l2_next \
5679_(drop, DROP) \
5680_(ethernet, ETHERNET_INPUT) \
5681_(ip4, IP4_INPUT) \
5682_(ip6, IP6_INPUT)
5683
5684uword
5685unformat_l2_next_index (unformat_input_t * input, va_list * args)
5686{
5687 u32 *miss_next_indexp = va_arg (*args, u32 *);
5688 u32 next_index = 0;
5689 u32 tmp;
5690
5691#define _(n,N) \
5692 if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
5693 foreach_l2_next;
5694#undef _
5695
5696 if (unformat (input, "%d", &tmp))
5697 {
5698 next_index = tmp;
5699 goto out;
5700 }
5701
5702 return 0;
5703
5704out:
5705 *miss_next_indexp = next_index;
5706 return 1;
5707}
5708
5709#define foreach_ip_next \
5710_(drop, DROP) \
5711_(local, LOCAL) \
5712_(rewrite, REWRITE)
5713
5714uword
Dave Barach4a3f69c2017-02-22 12:44:56 -05005715api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
Damjan Marion7cd468a2016-12-19 23:05:39 +01005716{
5717 u32 *miss_next_indexp = va_arg (*args, u32 *);
5718 u32 next_index = 0;
5719 u32 tmp;
5720
5721#define _(n,N) \
5722 if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
5723 foreach_ip_next;
5724#undef _
5725
5726 if (unformat (input, "%d", &tmp))
5727 {
5728 next_index = tmp;
5729 goto out;
5730 }
5731
5732 return 0;
5733
5734out:
5735 *miss_next_indexp = next_index;
5736 return 1;
5737}
5738
5739#define foreach_acl_next \
5740_(deny, DENY)
5741
5742uword
Dave Barach4a3f69c2017-02-22 12:44:56 -05005743api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
Damjan Marion7cd468a2016-12-19 23:05:39 +01005744{
5745 u32 *miss_next_indexp = va_arg (*args, u32 *);
5746 u32 next_index = 0;
5747 u32 tmp;
5748
5749#define _(n,N) \
5750 if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
5751 foreach_acl_next;
5752#undef _
5753
5754 if (unformat (input, "permit"))
5755 {
5756 next_index = ~0;
5757 goto out;
5758 }
5759 else if (unformat (input, "%d", &tmp))
5760 {
5761 next_index = tmp;
5762 goto out;
5763 }
5764
5765 return 0;
5766
5767out:
5768 *miss_next_indexp = next_index;
5769 return 1;
5770}
5771
5772uword
5773unformat_policer_precolor (unformat_input_t * input, va_list * args)
5774{
5775 u32 *r = va_arg (*args, u32 *);
5776
5777 if (unformat (input, "conform-color"))
5778 *r = POLICE_CONFORM;
5779 else if (unformat (input, "exceed-color"))
5780 *r = POLICE_EXCEED;
5781 else
5782 return 0;
5783
5784 return 1;
5785}
5786
Dave Barach4a3f69c2017-02-22 12:44:56 -05005787#if VPP_API_TEST_BUILTIN == 0
Damjan Marion7cd468a2016-12-19 23:05:39 +01005788uword
5789unformat_l4_match (unformat_input_t * input, va_list * args)
5790{
5791 u8 **matchp = va_arg (*args, u8 **);
5792
5793 u8 *proto_header = 0;
5794 int src_port = 0;
5795 int dst_port = 0;
5796
5797 tcpudp_header_t h;
5798
5799 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
5800 {
5801 if (unformat (input, "src_port %d", &src_port))
5802 ;
5803 else if (unformat (input, "dst_port %d", &dst_port))
5804 ;
5805 else
5806 return 0;
5807 }
5808
5809 h.src_port = clib_host_to_net_u16 (src_port);
5810 h.dst_port = clib_host_to_net_u16 (dst_port);
5811 vec_validate (proto_header, sizeof (h) - 1);
5812 memcpy (proto_header, &h, sizeof (h));
5813
5814 *matchp = proto_header;
5815
5816 return 1;
5817}
5818
5819uword
5820unformat_ip4_match (unformat_input_t * input, va_list * args)
5821{
5822 u8 **matchp = va_arg (*args, u8 **);
5823 u8 *match = 0;
5824 ip4_header_t *ip;
5825 int version = 0;
5826 u32 version_val;
5827 int hdr_length = 0;
5828 u32 hdr_length_val;
5829 int src = 0, dst = 0;
5830 ip4_address_t src_val, dst_val;
5831 int proto = 0;
5832 u32 proto_val;
5833 int tos = 0;
5834 u32 tos_val;
5835 int length = 0;
5836 u32 length_val;
5837 int fragment_id = 0;
5838 u32 fragment_id_val;
5839 int ttl = 0;
5840 int ttl_val;
5841 int checksum = 0;
5842 u32 checksum_val;
5843
5844 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
5845 {
5846 if (unformat (input, "version %d", &version_val))
5847 version = 1;
5848 else if (unformat (input, "hdr_length %d", &hdr_length_val))
5849 hdr_length = 1;
5850 else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
5851 src = 1;
5852 else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
5853 dst = 1;
5854 else if (unformat (input, "proto %d", &proto_val))
5855 proto = 1;
5856 else if (unformat (input, "tos %d", &tos_val))
5857 tos = 1;
5858 else if (unformat (input, "length %d", &length_val))
5859 length = 1;
5860 else if (unformat (input, "fragment_id %d", &fragment_id_val))
5861 fragment_id = 1;
5862 else if (unformat (input, "ttl %d", &ttl_val))
5863 ttl = 1;
5864 else if (unformat (input, "checksum %d", &checksum_val))
5865 checksum = 1;
5866 else
5867 break;
5868 }
5869
5870 if (version + hdr_length + src + dst + proto + tos + length + fragment_id
5871 + ttl + checksum == 0)
5872 return 0;
5873
5874 /*
5875 * Aligned because we use the real comparison functions
5876 */
5877 vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
5878
5879 ip = (ip4_header_t *) match;
5880
5881 /* These are realistically matched in practice */
5882 if (src)
5883 ip->src_address.as_u32 = src_val.as_u32;
5884
5885 if (dst)
5886 ip->dst_address.as_u32 = dst_val.as_u32;
5887
5888 if (proto)
5889 ip->protocol = proto_val;
5890
5891
5892 /* These are not, but they're included for completeness */
5893 if (version)
5894 ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
5895
5896 if (hdr_length)
5897 ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
5898
5899 if (tos)
5900 ip->tos = tos_val;
5901
5902 if (length)
5903 ip->length = clib_host_to_net_u16 (length_val);
5904
5905 if (ttl)
5906 ip->ttl = ttl_val;
5907
5908 if (checksum)
5909 ip->checksum = clib_host_to_net_u16 (checksum_val);
5910
5911 *matchp = match;
5912 return 1;
5913}
5914
5915uword
5916unformat_ip6_match (unformat_input_t * input, va_list * args)
5917{
5918 u8 **matchp = va_arg (*args, u8 **);
5919 u8 *match = 0;
5920 ip6_header_t *ip;
5921 int version = 0;
5922 u32 version_val;
5923 u8 traffic_class = 0;
5924 u32 traffic_class_val = 0;
5925 u8 flow_label = 0;
5926 u8 flow_label_val;
5927 int src = 0, dst = 0;
5928 ip6_address_t src_val, dst_val;
5929 int proto = 0;
5930 u32 proto_val;
5931 int payload_length = 0;
5932 u32 payload_length_val;
5933 int hop_limit = 0;
5934 int hop_limit_val;
5935 u32 ip_version_traffic_class_and_flow_label;
5936
5937 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
5938 {
5939 if (unformat (input, "version %d", &version_val))
5940 version = 1;
5941 else if (unformat (input, "traffic_class %d", &traffic_class_val))
5942 traffic_class = 1;
5943 else if (unformat (input, "flow_label %d", &flow_label_val))
5944 flow_label = 1;
5945 else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
5946 src = 1;
5947 else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
5948 dst = 1;
5949 else if (unformat (input, "proto %d", &proto_val))
5950 proto = 1;
5951 else if (unformat (input, "payload_length %d", &payload_length_val))
5952 payload_length = 1;
5953 else if (unformat (input, "hop_limit %d", &hop_limit_val))
5954 hop_limit = 1;
5955 else
5956 break;
5957 }
5958
5959 if (version + traffic_class + flow_label + src + dst + proto +
5960 payload_length + hop_limit == 0)
5961 return 0;
5962
5963 /*
5964 * Aligned because we use the real comparison functions
5965 */
5966 vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
5967
5968 ip = (ip6_header_t *) match;
5969
5970 if (src)
5971 clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
5972
5973 if (dst)
5974 clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
5975
5976 if (proto)
5977 ip->protocol = proto_val;
5978
5979 ip_version_traffic_class_and_flow_label = 0;
5980
5981 if (version)
5982 ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
5983
5984 if (traffic_class)
5985 ip_version_traffic_class_and_flow_label |=
5986 (traffic_class_val & 0xFF) << 20;
5987
5988 if (flow_label)
5989 ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
5990
5991 ip->ip_version_traffic_class_and_flow_label =
5992 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
5993
5994 if (payload_length)
5995 ip->payload_length = clib_host_to_net_u16 (payload_length_val);
5996
5997 if (hop_limit)
5998 ip->hop_limit = hop_limit_val;
5999
6000 *matchp = match;
6001 return 1;
6002}
6003
6004uword
6005unformat_l3_match (unformat_input_t * input, va_list * args)
6006{
6007 u8 **matchp = va_arg (*args, u8 **);
6008
6009 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
6010 {
6011 if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
6012 return 1;
6013 else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
6014 return 1;
6015 else
6016 break;
6017 }
6018 return 0;
6019}
6020
6021uword
6022unformat_vlan_tag (unformat_input_t * input, va_list * args)
6023{
6024 u8 *tagp = va_arg (*args, u8 *);
6025 u32 tag;
6026
6027 if (unformat (input, "%d", &tag))
6028 {
6029 tagp[0] = (tag >> 8) & 0x0F;
6030 tagp[1] = tag & 0xFF;
6031 return 1;
6032 }
6033
6034 return 0;
6035}
6036
6037uword
6038unformat_l2_match (unformat_input_t * input, va_list * args)
6039{
6040 u8 **matchp = va_arg (*args, u8 **);
6041 u8 *match = 0;
6042 u8 src = 0;
6043 u8 src_val[6];
6044 u8 dst = 0;
6045 u8 dst_val[6];
6046 u8 proto = 0;
6047 u16 proto_val;
6048 u8 tag1 = 0;
6049 u8 tag1_val[2];
6050 u8 tag2 = 0;
6051 u8 tag2_val[2];
6052 int len = 14;
6053 u8 ignore_tag1 = 0;
6054 u8 ignore_tag2 = 0;
6055 u8 cos1 = 0;
6056 u8 cos2 = 0;
6057 u32 cos1_val = 0;
6058 u32 cos2_val = 0;
6059
6060 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
6061 {
6062 if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
6063 src = 1;
6064 else
6065 if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
6066 dst = 1;
6067 else if (unformat (input, "proto %U",
6068 unformat_ethernet_type_host_byte_order, &proto_val))
6069 proto = 1;
6070 else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
6071 tag1 = 1;
6072 else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
6073 tag2 = 1;
6074 else if (unformat (input, "ignore-tag1"))
6075 ignore_tag1 = 1;
6076 else if (unformat (input, "ignore-tag2"))
6077 ignore_tag2 = 1;
6078 else if (unformat (input, "cos1 %d", &cos1_val))
6079 cos1 = 1;
6080 else if (unformat (input, "cos2 %d", &cos2_val))
6081 cos2 = 1;
6082 else
6083 break;
6084 }
6085 if ((src + dst + proto + tag1 + tag2 +
6086 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
6087 return 0;
6088
6089 if (tag1 || ignore_tag1 || cos1)
6090 len = 18;
6091 if (tag2 || ignore_tag2 || cos2)
6092 len = 22;
6093
6094 vec_validate_aligned (match, len - 1, sizeof (u32x4));
6095
6096 if (dst)
6097 clib_memcpy (match, dst_val, 6);
6098
6099 if (src)
6100 clib_memcpy (match + 6, src_val, 6);
6101
6102 if (tag2)
6103 {
6104 /* inner vlan tag */
6105 match[19] = tag2_val[1];
6106 match[18] = tag2_val[0];
6107 if (cos2)
6108 match[18] |= (cos2_val & 0x7) << 5;
6109 if (proto)
6110 {
6111 match[21] = proto_val & 0xff;
6112 match[20] = proto_val >> 8;
6113 }
6114 if (tag1)
6115 {
6116 match[15] = tag1_val[1];
6117 match[14] = tag1_val[0];
6118 }
6119 if (cos1)
6120 match[14] |= (cos1_val & 0x7) << 5;
6121 *matchp = match;
6122 return 1;
6123 }
6124 if (tag1)
6125 {
6126 match[15] = tag1_val[1];
6127 match[14] = tag1_val[0];
6128 if (proto)
6129 {
6130 match[17] = proto_val & 0xff;
6131 match[16] = proto_val >> 8;
6132 }
6133 if (cos1)
6134 match[14] |= (cos1_val & 0x7) << 5;
6135
6136 *matchp = match;
6137 return 1;
6138 }
6139 if (cos2)
6140 match[18] |= (cos2_val & 0x7) << 5;
6141 if (cos1)
6142 match[14] |= (cos1_val & 0x7) << 5;
6143 if (proto)
6144 {
6145 match[13] = proto_val & 0xff;
6146 match[12] = proto_val >> 8;
6147 }
6148
6149 *matchp = match;
6150 return 1;
6151}
Igor Mikhailov (imichail)582caa32018-04-26 21:33:02 -07006152
6153uword
6154unformat_qos_source (unformat_input_t * input, va_list * args)
6155{
6156 int *qs = va_arg (*args, int *);
6157
6158 if (unformat (input, "ip"))
6159 *qs = QOS_SOURCE_IP;
6160 else if (unformat (input, "mpls"))
6161 *qs = QOS_SOURCE_MPLS;
6162 else if (unformat (input, "ext"))
6163 *qs = QOS_SOURCE_EXT;
6164 else if (unformat (input, "vlan"))
6165 *qs = QOS_SOURCE_VLAN;
6166 else
6167 return 0;
6168
6169 return 1;
6170}
Dave Barach4a3f69c2017-02-22 12:44:56 -05006171#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +01006172
6173uword
Dave Barach4a3f69c2017-02-22 12:44:56 -05006174api_unformat_classify_match (unformat_input_t * input, va_list * args)
Damjan Marion7cd468a2016-12-19 23:05:39 +01006175{
6176 u8 **matchp = va_arg (*args, u8 **);
6177 u32 skip_n_vectors = va_arg (*args, u32);
6178 u32 match_n_vectors = va_arg (*args, u32);
6179
6180 u8 *match = 0;
6181 u8 *l2 = 0;
6182 u8 *l3 = 0;
6183 u8 *l4 = 0;
6184
6185 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
6186 {
6187 if (unformat (input, "hex %U", unformat_hex_string, &match))
6188 ;
6189 else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
6190 ;
6191 else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
6192 ;
6193 else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
6194 ;
6195 else
6196 break;
6197 }
6198
6199 if (l4 && !l3)
6200 {
6201 vec_free (match);
6202 vec_free (l2);
6203 vec_free (l4);
6204 return 0;
6205 }
6206
6207 if (match || l2 || l3 || l4)
6208 {
6209 if (l2 || l3 || l4)
6210 {
6211 /* "Win a free Ethernet header in every packet" */
6212 if (l2 == 0)
6213 vec_validate_aligned (l2, 13, sizeof (u32x4));
6214 match = l2;
6215 if (vec_len (l3))
6216 {
6217 vec_append_aligned (match, l3, sizeof (u32x4));
6218 vec_free (l3);
6219 }
6220 if (vec_len (l4))
6221 {
6222 vec_append_aligned (match, l4, sizeof (u32x4));
6223 vec_free (l4);
6224 }
6225 }
6226
6227 /* Make sure the vector is big enough even if key is all 0's */
6228 vec_validate_aligned
6229 (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
6230 sizeof (u32x4));
6231
6232 /* Set size, include skipped vectors */
6233 _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
6234
6235 *matchp = match;
6236
6237 return 1;
6238 }
6239
6240 return 0;
6241}
6242
6243static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01006244api_get_node_index (vat_main_t * vam)
6245{
6246 unformat_input_t *i = vam->input;
6247 vl_api_get_node_index_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006248 u8 *name = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006249 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006250
6251 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6252 {
6253 if (unformat (i, "node %s", &name))
6254 ;
6255 else
6256 break;
6257 }
6258 if (name == 0)
6259 {
6260 errmsg ("node name required");
6261 return -99;
6262 }
6263 if (vec_len (name) >= ARRAY_LEN (mp->node_name))
6264 {
6265 errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
6266 return -99;
6267 }
6268
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006269 M (GET_NODE_INDEX, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006270 clib_memcpy (mp->node_name, name, vec_len (name));
6271 vec_free (name);
6272
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006273 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06006274 W (ret);
6275 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006276}
6277
6278static int
6279api_get_next_index (vat_main_t * vam)
6280{
6281 unformat_input_t *i = vam->input;
6282 vl_api_get_next_index_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006283 u8 *node_name = 0, *next_node_name = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006284 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006285
6286 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6287 {
6288 if (unformat (i, "node-name %s", &node_name))
6289 ;
6290 else if (unformat (i, "next-node-name %s", &next_node_name))
6291 break;
6292 }
6293
6294 if (node_name == 0)
6295 {
6296 errmsg ("node name required");
6297 return -99;
6298 }
6299 if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
6300 {
6301 errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
6302 return -99;
6303 }
6304
6305 if (next_node_name == 0)
6306 {
6307 errmsg ("next node name required");
6308 return -99;
6309 }
6310 if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
6311 {
6312 errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
6313 return -99;
6314 }
6315
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006316 M (GET_NEXT_INDEX, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006317 clib_memcpy (mp->node_name, node_name, vec_len (node_name));
6318 clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
6319 vec_free (node_name);
6320 vec_free (next_node_name);
6321
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006322 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06006323 W (ret);
6324 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006325}
6326
6327static int
6328api_add_node_next (vat_main_t * vam)
6329{
6330 unformat_input_t *i = vam->input;
6331 vl_api_add_node_next_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006332 u8 *name = 0;
6333 u8 *next = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006334 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006335
6336 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6337 {
6338 if (unformat (i, "node %s", &name))
6339 ;
6340 else if (unformat (i, "next %s", &next))
6341 ;
6342 else
6343 break;
6344 }
6345 if (name == 0)
6346 {
6347 errmsg ("node name required");
6348 return -99;
6349 }
6350 if (vec_len (name) >= ARRAY_LEN (mp->node_name))
6351 {
6352 errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
6353 return -99;
6354 }
6355 if (next == 0)
6356 {
6357 errmsg ("next node required");
6358 return -99;
6359 }
6360 if (vec_len (next) >= ARRAY_LEN (mp->next_name))
6361 {
6362 errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
6363 return -99;
6364 }
6365
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006366 M (ADD_NODE_NEXT, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006367 clib_memcpy (mp->node_name, name, vec_len (name));
6368 clib_memcpy (mp->next_name, next, vec_len (next));
6369 vec_free (name);
6370 vec_free (next);
6371
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006372 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06006373 W (ret);
6374 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006375}
6376
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01006377static void vl_api_sw_interface_virtio_pci_details_t_handler
6378 (vl_api_sw_interface_virtio_pci_details_t * mp)
6379{
6380 vat_main_t *vam = &vat_main;
6381
6382 typedef union
6383 {
6384 struct
6385 {
6386 u16 domain;
6387 u8 bus;
6388 u8 slot:5;
6389 u8 function:3;
6390 };
6391 u32 as_u32;
6392 } pci_addr_t;
6393 pci_addr_t addr;
Jakub Grajciar2c504f82019-09-26 10:34:41 +02006394
6395 addr.domain = ntohs (mp->pci_addr.domain);
6396 addr.bus = mp->pci_addr.bus;
6397 addr.slot = mp->pci_addr.slot;
6398 addr.function = mp->pci_addr.function;
6399
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01006400 u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
6401 addr.slot, addr.function);
6402
6403 print (vam->ofp,
6404 "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
6405 pci_addr, ntohl (mp->sw_if_index),
6406 ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
6407 format_ethernet_address, mp->mac_addr,
6408 clib_net_to_host_u64 (mp->features));
6409 vec_free (pci_addr);
6410}
6411
6412static void vl_api_sw_interface_virtio_pci_details_t_handler_json
6413 (vl_api_sw_interface_virtio_pci_details_t * mp)
6414{
6415 vat_main_t *vam = &vat_main;
6416 vat_json_node_t *node = NULL;
Jakub Grajciar2c504f82019-09-26 10:34:41 +02006417 vlib_pci_addr_t pci_addr;
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01006418
6419 if (VAT_JSON_ARRAY != vam->json_tree.type)
6420 {
6421 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6422 vat_json_init_array (&vam->json_tree);
6423 }
6424 node = vat_json_array_add (&vam->json_tree);
6425
Jakub Grajciar2c504f82019-09-26 10:34:41 +02006426 pci_addr.domain = ntohs (mp->pci_addr.domain);
6427 pci_addr.bus = mp->pci_addr.bus;
6428 pci_addr.slot = mp->pci_addr.slot;
6429 pci_addr.function = mp->pci_addr.function;
6430
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01006431 vat_json_init_object (node);
Jakub Grajciar2c504f82019-09-26 10:34:41 +02006432 vat_json_object_add_uint (node, "pci-addr", pci_addr.as_u32);
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01006433 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6434 vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
6435 vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
6436 vat_json_object_add_uint (node, "features",
6437 clib_net_to_host_u64 (mp->features));
6438 vat_json_object_add_string_copy (node, "mac_addr",
6439 format (0, "%U", format_ethernet_address,
6440 &mp->mac_addr));
6441}
6442
6443static int
6444api_sw_interface_virtio_pci_dump (vat_main_t * vam)
6445{
6446 vl_api_sw_interface_virtio_pci_dump_t *mp;
6447 vl_api_control_ping_t *mp_ping;
6448 int ret;
6449
6450 print (vam->ofp,
6451 "\n%-12s %-12s %-12s %-12s %-17s %-08s",
6452 "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
6453 "mac_addr", "features");
6454
6455 /* Get list of tap interfaces */
6456 M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
6457 S (mp);
6458
6459 /* Use a control ping for synchronization */
6460 MPING (CONTROL_PING, mp_ping);
6461 S (mp_ping);
6462
6463 W (ret);
6464 return ret;
6465}
6466
eyal bariaf86a482018-04-17 11:20:27 +03006467static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01006468api_l2_fib_clear_table (vat_main_t * vam)
6469{
6470// unformat_input_t * i = vam->input;
6471 vl_api_l2_fib_clear_table_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006472 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006473
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006474 M (L2_FIB_CLEAR_TABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006475
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006476 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06006477 W (ret);
6478 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006479}
6480
6481static int
6482api_l2_interface_efp_filter (vat_main_t * vam)
6483{
6484 unformat_input_t *i = vam->input;
6485 vl_api_l2_interface_efp_filter_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006486 u32 sw_if_index;
6487 u8 enable = 1;
6488 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006489 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006490
6491 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6492 {
6493 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6494 sw_if_index_set = 1;
6495 else if (unformat (i, "sw_if_index %d", &sw_if_index))
6496 sw_if_index_set = 1;
6497 else if (unformat (i, "enable"))
6498 enable = 1;
6499 else if (unformat (i, "disable"))
6500 enable = 0;
6501 else
6502 {
6503 clib_warning ("parse error '%U'", format_unformat_error, i);
6504 return -99;
6505 }
6506 }
6507
6508 if (sw_if_index_set == 0)
6509 {
6510 errmsg ("missing sw_if_index");
6511 return -99;
6512 }
6513
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006514 M (L2_INTERFACE_EFP_FILTER, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006515
6516 mp->sw_if_index = ntohl (sw_if_index);
6517 mp->enable_disable = enable;
6518
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006519 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06006520 W (ret);
6521 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006522}
6523
6524#define foreach_vtr_op \
6525_("disable", L2_VTR_DISABLED) \
6526_("push-1", L2_VTR_PUSH_1) \
6527_("push-2", L2_VTR_PUSH_2) \
6528_("pop-1", L2_VTR_POP_1) \
6529_("pop-2", L2_VTR_POP_2) \
6530_("translate-1-1", L2_VTR_TRANSLATE_1_1) \
6531_("translate-1-2", L2_VTR_TRANSLATE_1_2) \
6532_("translate-2-1", L2_VTR_TRANSLATE_2_1) \
6533_("translate-2-2", L2_VTR_TRANSLATE_2_2)
6534
6535static int
6536api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
6537{
6538 unformat_input_t *i = vam->input;
6539 vl_api_l2_interface_vlan_tag_rewrite_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006540 u32 sw_if_index;
6541 u8 sw_if_index_set = 0;
6542 u8 vtr_op_set = 0;
6543 u32 vtr_op = 0;
6544 u32 push_dot1q = 1;
6545 u32 tag1 = ~0;
6546 u32 tag2 = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006547 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006548
6549 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6550 {
6551 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6552 sw_if_index_set = 1;
6553 else if (unformat (i, "sw_if_index %d", &sw_if_index))
6554 sw_if_index_set = 1;
6555 else if (unformat (i, "vtr_op %d", &vtr_op))
6556 vtr_op_set = 1;
6557#define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
6558 foreach_vtr_op
6559#undef _
6560 else if (unformat (i, "push_dot1q %d", &push_dot1q))
6561 ;
6562 else if (unformat (i, "tag1 %d", &tag1))
6563 ;
6564 else if (unformat (i, "tag2 %d", &tag2))
6565 ;
6566 else
6567 {
6568 clib_warning ("parse error '%U'", format_unformat_error, i);
6569 return -99;
6570 }
6571 }
6572
6573 if ((sw_if_index_set == 0) || (vtr_op_set == 0))
6574 {
6575 errmsg ("missing vtr operation or sw_if_index");
6576 return -99;
6577 }
6578
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006579 M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
6580 mp->sw_if_index = ntohl (sw_if_index);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006581 mp->vtr_op = ntohl (vtr_op);
6582 mp->push_dot1q = ntohl (push_dot1q);
6583 mp->tag1 = ntohl (tag1);
6584 mp->tag2 = ntohl (tag2);
6585
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006586 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06006587 W (ret);
6588 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006589}
6590
6591static int
Filip Tehlar4f348df2021-06-22 12:18:17 +00006592api_show_version (vat_main_t *vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +01006593{
6594 vl_api_show_version_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006595 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006596
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006597 M (SHOW_VERSION, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006598
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006599 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06006600 W (ret);
6601 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006602}
6603
Filip Tehlar4f348df2021-06-22 12:18:17 +00006604static void
6605vl_api_l2_fib_table_details_t_handler (vl_api_l2_fib_table_details_t *mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01006606{
6607 vat_main_t *vam = &vat_main;
6608
Filip Tehlar4f348df2021-06-22 12:18:17 +00006609 print (vam->ofp,
6610 "%3" PRIu32 " %U %3" PRIu32 " %d %d %d",
Mohsin Kazmi57938f62017-10-27 21:28:07 +02006611 ntohl (mp->bd_id), format_ethernet_address, mp->mac,
Filip Tehlar4f348df2021-06-22 12:18:17 +00006612 ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac, mp->bvi_mac);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006613}
6614
Filip Tehlar4f348df2021-06-22 12:18:17 +00006615static void
6616vl_api_l2_fib_table_details_t_handler_json (vl_api_l2_fib_table_details_t *mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01006617{
6618 vat_main_t *vam = &vat_main;
6619 vat_json_node_t *node = NULL;
6620
6621 if (VAT_JSON_ARRAY != vam->json_tree.type)
6622 {
6623 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6624 vat_json_init_array (&vam->json_tree);
6625 }
6626 node = vat_json_array_add (&vam->json_tree);
6627
6628 vat_json_init_object (node);
6629 vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
Mohsin Kazmi57938f62017-10-27 21:28:07 +02006630 vat_json_object_add_bytes (node, "mac", mp->mac, 6);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006631 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6632 vat_json_object_add_uint (node, "static_mac", mp->static_mac);
6633 vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
6634 vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
6635}
6636
6637static int
Filip Tehlar4f348df2021-06-22 12:18:17 +00006638api_l2_fib_table_dump (vat_main_t *vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +01006639{
6640 unformat_input_t *i = vam->input;
6641 vl_api_l2_fib_table_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -06006642 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006643 u32 bd_id;
6644 u8 bd_id_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006645 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006646
6647 /* Parse args required to build the message */
6648 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6649 {
6650 if (unformat (i, "bd_id %d", &bd_id))
6651 bd_id_set = 1;
6652 else
6653 break;
6654 }
6655
6656 if (bd_id_set == 0)
6657 {
6658 errmsg ("missing bridge domain");
6659 return -99;
6660 }
6661
6662 print (vam->ofp, "BD-ID Mac Address sw-ndx Static Filter BVI");
6663
6664 /* Get list of l2 fib entries */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006665 M (L2_FIB_TABLE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006666
6667 mp->bd_id = ntohl (bd_id);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006668 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006669
6670 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -04006671 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06006672 S (mp_ping);
6673
Jon Loeliger56c7b012017-02-01 12:31:41 -06006674 W (ret);
6675 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006676}
6677
Damjan Marion7cd468a2016-12-19 23:05:39 +01006678static int
Filip Tehlar4f348df2021-06-22 12:18:17 +00006679api_interface_name_renumber (vat_main_t *vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +01006680{
6681 unformat_input_t *line_input = vam->input;
6682 vl_api_interface_name_renumber_t *mp;
6683 u32 sw_if_index = ~0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006684 u32 new_show_dev_instance = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006685 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006686
6687 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
6688 {
6689 if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
6690 &sw_if_index))
6691 ;
6692 else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
6693 ;
6694 else if (unformat (line_input, "new_show_dev_instance %d",
6695 &new_show_dev_instance))
6696 ;
6697 else
6698 break;
6699 }
6700
6701 if (sw_if_index == ~0)
6702 {
6703 errmsg ("missing interface name or sw_if_index");
6704 return -99;
6705 }
6706
6707 if (new_show_dev_instance == ~0)
6708 {
6709 errmsg ("missing new_show_dev_instance");
6710 return -99;
6711 }
6712
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006713 M (INTERFACE_NAME_RENUMBER, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006714
6715 mp->sw_if_index = ntohl (sw_if_index);
6716 mp->new_show_dev_instance = ntohl (new_show_dev_instance);
6717
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006718 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06006719 W (ret);
6720 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006721}
6722
6723static int
Filip Tehlar4f348df2021-06-22 12:18:17 +00006724api_want_l2_macs_events (vat_main_t *vam)
John Lo8d00fff2017-08-03 00:35:36 -04006725{
6726 unformat_input_t *line_input = vam->input;
6727 vl_api_want_l2_macs_events_t *mp;
6728 u8 enable_disable = 1;
6729 u32 scan_delay = 0;
6730 u32 max_macs_in_event = 0;
6731 u32 learn_limit = 0;
6732 int ret;
6733
6734 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
6735 {
6736 if (unformat (line_input, "learn-limit %d", &learn_limit))
6737 ;
6738 else if (unformat (line_input, "scan-delay %d", &scan_delay))
6739 ;
6740 else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
6741 ;
6742 else if (unformat (line_input, "disable"))
6743 enable_disable = 0;
6744 else
6745 break;
6746 }
6747
6748 M (WANT_L2_MACS_EVENTS, mp);
6749 mp->enable_disable = enable_disable;
6750 mp->pid = htonl (getpid ());
6751 mp->learn_limit = htonl (learn_limit);
6752 mp->scan_delay = (u8) scan_delay;
6753 mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
6754 S (mp);
6755 W (ret);
6756 return ret;
6757}
6758
6759static int
Filip Tehlar4f348df2021-06-22 12:18:17 +00006760api_ip_address_dump (vat_main_t *vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +01006761{
6762 unformat_input_t *i = vam->input;
6763 vl_api_ip_address_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -06006764 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006765 u32 sw_if_index = ~0;
6766 u8 sw_if_index_set = 0;
6767 u8 ipv4_set = 0;
6768 u8 ipv6_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006769 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006770
6771 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6772 {
6773 if (unformat (i, "sw_if_index %d", &sw_if_index))
6774 sw_if_index_set = 1;
Filip Tehlar4f348df2021-06-22 12:18:17 +00006775 else if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
Damjan Marion7cd468a2016-12-19 23:05:39 +01006776 sw_if_index_set = 1;
6777 else if (unformat (i, "ipv4"))
6778 ipv4_set = 1;
6779 else if (unformat (i, "ipv6"))
6780 ipv6_set = 1;
6781 else
6782 break;
6783 }
6784
6785 if (ipv4_set && ipv6_set)
6786 {
6787 errmsg ("ipv4 and ipv6 flags cannot be both set");
6788 return -99;
6789 }
6790
6791 if ((!ipv4_set) && (!ipv6_set))
6792 {
6793 errmsg ("no ipv4 nor ipv6 flag set");
6794 return -99;
6795 }
6796
6797 if (sw_if_index_set == 0)
6798 {
6799 errmsg ("missing interface name or sw_if_index");
6800 return -99;
6801 }
6802
6803 vam->current_sw_if_index = sw_if_index;
6804 vam->is_ipv6 = ipv6_set;
6805
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006806 M (IP_ADDRESS_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006807 mp->sw_if_index = ntohl (sw_if_index);
6808 mp->is_ipv6 = ipv6_set;
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006809 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006810
6811 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -04006812 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06006813 S (mp_ping);
6814
Jon Loeliger56c7b012017-02-01 12:31:41 -06006815 W (ret);
6816 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006817}
6818
6819static int
6820api_ip_dump (vat_main_t * vam)
6821{
6822 vl_api_ip_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -06006823 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006824 unformat_input_t *in = vam->input;
6825 int ipv4_set = 0;
6826 int ipv6_set = 0;
6827 int is_ipv6;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006828 int i;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006829 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006830
6831 while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
6832 {
6833 if (unformat (in, "ipv4"))
6834 ipv4_set = 1;
6835 else if (unformat (in, "ipv6"))
6836 ipv6_set = 1;
6837 else
6838 break;
6839 }
6840
6841 if (ipv4_set && ipv6_set)
6842 {
6843 errmsg ("ipv4 and ipv6 flags cannot be both set");
6844 return -99;
6845 }
6846
6847 if ((!ipv4_set) && (!ipv6_set))
6848 {
6849 errmsg ("no ipv4 nor ipv6 flag set");
6850 return -99;
6851 }
6852
6853 is_ipv6 = ipv6_set;
6854 vam->is_ipv6 = is_ipv6;
6855
6856 /* free old data */
6857 for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
6858 {
6859 vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
6860 }
6861 vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
6862
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006863 M (IP_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006864 mp->is_ipv6 = ipv6_set;
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006865 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006866
6867 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -04006868 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06006869 S (mp_ping);
6870
Jon Loeliger56c7b012017-02-01 12:31:41 -06006871 W (ret);
6872 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006873}
6874
6875static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01006876api_get_first_msg_id (vat_main_t * vam)
6877{
6878 vl_api_get_first_msg_id_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006879 unformat_input_t *i = vam->input;
6880 u8 *name;
6881 u8 name_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006882 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006883
6884 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6885 {
6886 if (unformat (i, "client %s", &name))
6887 name_set = 1;
6888 else
6889 break;
6890 }
6891
6892 if (name_set == 0)
6893 {
6894 errmsg ("missing client name");
6895 return -99;
6896 }
6897 vec_add1 (name, 0);
6898
6899 if (vec_len (name) > 63)
6900 {
6901 errmsg ("client name too long");
6902 return -99;
6903 }
6904
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006905 M (GET_FIRST_MSG_ID, mp);
Ole Troan7adaa222019-08-27 15:05:27 +02006906 clib_memcpy (mp->name, name, vec_len (name));
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006907 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06006908 W (ret);
6909 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006910}
6911
6912static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01006913api_get_node_graph (vat_main_t * vam)
6914{
6915 vl_api_get_node_graph_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006916 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006917
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006918 M (GET_NODE_GRAPH, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006919
6920 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006921 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006922 /* Wait for the reply */
Jon Loeliger56c7b012017-02-01 12:31:41 -06006923 W (ret);
6924 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006925}
6926
Neale Ranns097fa662018-05-01 05:17:55 -07006927static u8 *
6928format_fib_api_path_nh_proto (u8 * s, va_list * args)
Neale Ranns0f26c5a2017-03-01 15:12:11 -08006929{
Neale Ranns097fa662018-05-01 05:17:55 -07006930 vl_api_fib_path_nh_proto_t proto =
6931 va_arg (*args, vl_api_fib_path_nh_proto_t);
6932
6933 switch (proto)
6934 {
6935 case FIB_API_PATH_NH_PROTO_IP4:
6936 s = format (s, "ip4");
6937 break;
6938 case FIB_API_PATH_NH_PROTO_IP6:
6939 s = format (s, "ip6");
6940 break;
6941 case FIB_API_PATH_NH_PROTO_MPLS:
6942 s = format (s, "mpls");
6943 break;
6944 case FIB_API_PATH_NH_PROTO_BIER:
6945 s = format (s, "bier");
6946 break;
6947 case FIB_API_PATH_NH_PROTO_ETHERNET:
6948 s = format (s, "ethernet");
6949 break;
6950 }
6951
6952 return (s);
6953}
6954
6955static u8 *
6956format_vl_api_ip_address_union (u8 * s, va_list * args)
6957{
Jakub Grajciar7dd63e52020-03-19 08:03:55 +01006958 vl_api_address_family_t af = va_arg (*args, int);
Neale Ranns097fa662018-05-01 05:17:55 -07006959 const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
6960
6961 switch (af)
6962 {
6963 case ADDRESS_IP4:
6964 s = format (s, "%U", format_ip4_address, u->ip4);
6965 break;
6966 case ADDRESS_IP6:
6967 s = format (s, "%U", format_ip6_address, u->ip6);
6968 break;
6969 }
6970 return (s);
6971}
6972
6973static u8 *
6974format_vl_api_fib_path_type (u8 * s, va_list * args)
6975{
6976 vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
6977
6978 switch (t)
6979 {
6980 case FIB_API_PATH_TYPE_NORMAL:
6981 s = format (s, "normal");
6982 break;
6983 case FIB_API_PATH_TYPE_LOCAL:
6984 s = format (s, "local");
6985 break;
6986 case FIB_API_PATH_TYPE_DROP:
6987 s = format (s, "drop");
6988 break;
6989 case FIB_API_PATH_TYPE_UDP_ENCAP:
6990 s = format (s, "udp-encap");
6991 break;
6992 case FIB_API_PATH_TYPE_BIER_IMP:
6993 s = format (s, "bier-imp");
6994 break;
6995 case FIB_API_PATH_TYPE_ICMP_UNREACH:
6996 s = format (s, "unreach");
6997 break;
6998 case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
6999 s = format (s, "prohibit");
7000 break;
7001 case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
7002 s = format (s, "src-lookup");
7003 break;
7004 case FIB_API_PATH_TYPE_DVR:
7005 s = format (s, "dvr");
7006 break;
7007 case FIB_API_PATH_TYPE_INTERFACE_RX:
7008 s = format (s, "interface-rx");
7009 break;
7010 case FIB_API_PATH_TYPE_CLASSIFY:
7011 s = format (s, "classify");
7012 break;
7013 }
7014
7015 return (s);
7016}
7017
7018static void
7019vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
7020{
7021 print (vam->ofp,
7022 " weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
7023 ntohl (fp->weight), ntohl (fp->sw_if_index),
7024 format_vl_api_fib_path_type, fp->type,
7025 format_fib_api_path_nh_proto, fp->proto,
7026 format_vl_api_ip_address_union, &fp->nh.address);
Neale Ranns0f26c5a2017-03-01 15:12:11 -08007027}
7028
7029static void
7030vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
Neale Ranns31ed7442018-02-23 05:29:09 -08007031 vl_api_fib_path_t * fp)
Neale Ranns0f26c5a2017-03-01 15:12:11 -08007032{
7033 struct in_addr ip4;
7034 struct in6_addr ip6;
7035
7036 vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
7037 vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
Neale Ranns097fa662018-05-01 05:17:55 -07007038 vat_json_object_add_uint (node, "type", fp->type);
7039 vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
7040 if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
Neale Ranns0f26c5a2017-03-01 15:12:11 -08007041 {
Neale Ranns097fa662018-05-01 05:17:55 -07007042 clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
Neale Ranns0f26c5a2017-03-01 15:12:11 -08007043 vat_json_object_add_ip4 (node, "next_hop", ip4);
7044 }
Dave Barachc35f3e82020-04-02 10:44:09 -04007045 else if (fp->proto == FIB_API_PATH_NH_PROTO_IP6)
Neale Ranns0f26c5a2017-03-01 15:12:11 -08007046 {
Neale Ranns097fa662018-05-01 05:17:55 -07007047 clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
Neale Ranns0f26c5a2017-03-01 15:12:11 -08007048 vat_json_object_add_ip6 (node, "next_hop", ip6);
7049 }
7050}
7051
7052static void
7053vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01007054{
7055 vat_main_t *vam = &vat_main;
Neale Ranns097fa662018-05-01 05:17:55 -07007056 int count = ntohl (mp->mt_tunnel.mt_n_paths);
Neale Ranns31ed7442018-02-23 05:29:09 -08007057 vl_api_fib_path_t *fp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007058 i32 i;
7059
Neale Ranns097fa662018-05-01 05:17:55 -07007060 print (vam->ofp, "sw_if_index %d via:",
7061 ntohl (mp->mt_tunnel.mt_sw_if_index));
7062 fp = mp->mt_tunnel.mt_paths;
Neale Ranns0f26c5a2017-03-01 15:12:11 -08007063 for (i = 0; i < count; i++)
Damjan Marion7cd468a2016-12-19 23:05:39 +01007064 {
Neale Ranns097fa662018-05-01 05:17:55 -07007065 vl_api_fib_path_print (vam, fp);
Neale Ranns0f26c5a2017-03-01 15:12:11 -08007066 fp++;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007067 }
Neale Ranns0f26c5a2017-03-01 15:12:11 -08007068
Damjan Marion7cd468a2016-12-19 23:05:39 +01007069 print (vam->ofp, "");
7070}
7071
Neale Ranns0f26c5a2017-03-01 15:12:11 -08007072#define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
7073#define vl_api_mpls_tunnel_details_t_print vl_noop_handler
7074
7075static void
7076vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01007077{
7078 vat_main_t *vam = &vat_main;
7079 vat_json_node_t *node = NULL;
Neale Ranns097fa662018-05-01 05:17:55 -07007080 int count = ntohl (mp->mt_tunnel.mt_n_paths);
Neale Ranns31ed7442018-02-23 05:29:09 -08007081 vl_api_fib_path_t *fp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007082 i32 i;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007083
7084 if (VAT_JSON_ARRAY != vam->json_tree.type)
7085 {
7086 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7087 vat_json_init_array (&vam->json_tree);
7088 }
7089 node = vat_json_array_add (&vam->json_tree);
7090
7091 vat_json_init_object (node);
Neale Ranns097fa662018-05-01 05:17:55 -07007092 vat_json_object_add_uint (node, "sw_if_index",
7093 ntohl (mp->mt_tunnel.mt_sw_if_index));
Neale Ranns0f26c5a2017-03-01 15:12:11 -08007094
Neale Ranns097fa662018-05-01 05:17:55 -07007095 vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
Neale Ranns0f26c5a2017-03-01 15:12:11 -08007096
Neale Ranns097fa662018-05-01 05:17:55 -07007097 fp = mp->mt_tunnel.mt_paths;
Neale Ranns0f26c5a2017-03-01 15:12:11 -08007098 for (i = 0; i < count; i++)
Damjan Marion7cd468a2016-12-19 23:05:39 +01007099 {
Neale Ranns0f26c5a2017-03-01 15:12:11 -08007100 vl_api_mpls_fib_path_json_print (node, fp);
7101 fp++;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007102 }
7103}
7104
7105static int
7106api_mpls_tunnel_dump (vat_main_t * vam)
7107{
7108 vl_api_mpls_tunnel_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -06007109 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007110 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007111
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007112 M (MPLS_TUNNEL_DUMP, mp);
Neale Ranns097fa662018-05-01 05:17:55 -07007113
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007114 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007115
7116 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -04007117 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06007118 S (mp_ping);
7119
Jon Loeliger56c7b012017-02-01 12:31:41 -06007120 W (ret);
7121 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007122}
7123
Neale Ranns097fa662018-05-01 05:17:55 -07007124#define vl_api_mpls_table_details_t_endian vl_noop_handler
7125#define vl_api_mpls_table_details_t_print vl_noop_handler
Damjan Marion7cd468a2016-12-19 23:05:39 +01007126
Neale Ranns0f26c5a2017-03-01 15:12:11 -08007127
Damjan Marion7cd468a2016-12-19 23:05:39 +01007128static void
Neale Ranns097fa662018-05-01 05:17:55 -07007129vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01007130{
7131 vat_main_t *vam = &vat_main;
Neale Ranns097fa662018-05-01 05:17:55 -07007132
7133 print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
7134}
7135
7136static void vl_api_mpls_table_details_t_handler_json
7137 (vl_api_mpls_table_details_t * mp)
7138{
7139 vat_main_t *vam = &vat_main;
7140 vat_json_node_t *node = NULL;
7141
7142 if (VAT_JSON_ARRAY != vam->json_tree.type)
7143 {
7144 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7145 vat_json_init_array (&vam->json_tree);
7146 }
7147 node = vat_json_array_add (&vam->json_tree);
7148
7149 vat_json_init_object (node);
7150 vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
7151}
7152
7153static int
7154api_mpls_table_dump (vat_main_t * vam)
7155{
7156 vl_api_mpls_table_dump_t *mp;
7157 vl_api_control_ping_t *mp_ping;
7158 int ret;
7159
7160 M (MPLS_TABLE_DUMP, mp);
7161 S (mp);
7162
7163 /* Use a control ping for synchronization */
7164 MPING (CONTROL_PING, mp_ping);
7165 S (mp_ping);
7166
7167 W (ret);
7168 return ret;
7169}
7170
7171#define vl_api_mpls_route_details_t_endian vl_noop_handler
7172#define vl_api_mpls_route_details_t_print vl_noop_handler
7173
7174static void
7175vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
7176{
7177 vat_main_t *vam = &vat_main;
Dave Barach4bda2d92019-07-03 15:21:50 -04007178 int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
Neale Ranns31ed7442018-02-23 05:29:09 -08007179 vl_api_fib_path_t *fp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007180 int i;
7181
7182 print (vam->ofp,
7183 "table-id %d, label %u, ess_bit %u",
Neale Ranns097fa662018-05-01 05:17:55 -07007184 ntohl (mp->mr_route.mr_table_id),
7185 ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
7186 fp = mp->mr_route.mr_paths;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007187 for (i = 0; i < count; i++)
7188 {
Neale Ranns097fa662018-05-01 05:17:55 -07007189 vl_api_fib_path_print (vam, fp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007190 fp++;
7191 }
7192}
7193
Neale Ranns097fa662018-05-01 05:17:55 -07007194static void vl_api_mpls_route_details_t_handler_json
7195 (vl_api_mpls_route_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01007196{
7197 vat_main_t *vam = &vat_main;
Dave Barach4bda2d92019-07-03 15:21:50 -04007198 int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007199 vat_json_node_t *node = NULL;
Neale Ranns31ed7442018-02-23 05:29:09 -08007200 vl_api_fib_path_t *fp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007201 int i;
7202
7203 if (VAT_JSON_ARRAY != vam->json_tree.type)
7204 {
7205 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7206 vat_json_init_array (&vam->json_tree);
7207 }
7208 node = vat_json_array_add (&vam->json_tree);
7209
7210 vat_json_init_object (node);
Neale Ranns097fa662018-05-01 05:17:55 -07007211 vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
7212 vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
7213 vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
Damjan Marion7cd468a2016-12-19 23:05:39 +01007214 vat_json_object_add_uint (node, "path_count", count);
Neale Ranns097fa662018-05-01 05:17:55 -07007215 fp = mp->mr_route.mr_paths;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007216 for (i = 0; i < count; i++)
7217 {
Neale Ranns0f26c5a2017-03-01 15:12:11 -08007218 vl_api_mpls_fib_path_json_print (node, fp);
7219 fp++;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007220 }
7221}
7222
7223static int
Neale Ranns097fa662018-05-01 05:17:55 -07007224api_mpls_route_dump (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +01007225{
Neale Ranns097fa662018-05-01 05:17:55 -07007226 unformat_input_t *input = vam->input;
7227 vl_api_mpls_route_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -06007228 vl_api_control_ping_t *mp_ping;
Neale Ranns097fa662018-05-01 05:17:55 -07007229 u32 table_id;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007230 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007231
Neale Ranns097fa662018-05-01 05:17:55 -07007232 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7233 {
7234 if (unformat (input, "table_id %d", &table_id))
7235 ;
7236 else
7237 break;
7238 }
7239 if (table_id == ~0)
7240 {
7241 errmsg ("missing table id");
7242 return -99;
7243 }
7244
7245 M (MPLS_ROUTE_DUMP, mp);
7246
7247 mp->table.mt_table_id = ntohl (table_id);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007248 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007249
7250 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -04007251 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06007252 S (mp_ping);
7253
Jon Loeliger56c7b012017-02-01 12:31:41 -06007254 W (ret);
7255 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007256}
7257
Neale Ranns097fa662018-05-01 05:17:55 -07007258#define vl_api_ip_table_details_t_endian vl_noop_handler
7259#define vl_api_ip_table_details_t_print vl_noop_handler
Damjan Marion7cd468a2016-12-19 23:05:39 +01007260
7261static void
Neale Ranns097fa662018-05-01 05:17:55 -07007262vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01007263{
7264 vat_main_t *vam = &vat_main;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007265
7266 print (vam->ofp,
Neale Ranns097fa662018-05-01 05:17:55 -07007267 "%s; table-id %d, prefix %U/%d",
7268 mp->table.name, ntohl (mp->table.table_id));
Damjan Marion7cd468a2016-12-19 23:05:39 +01007269}
7270
Neale Ranns097fa662018-05-01 05:17:55 -07007271
7272static void vl_api_ip_table_details_t_handler_json
7273 (vl_api_ip_table_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01007274{
7275 vat_main_t *vam = &vat_main;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007276 vat_json_node_t *node = NULL;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007277
7278 if (VAT_JSON_ARRAY != vam->json_tree.type)
7279 {
7280 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7281 vat_json_init_array (&vam->json_tree);
7282 }
7283 node = vat_json_array_add (&vam->json_tree);
7284
7285 vat_json_init_object (node);
Neale Ranns097fa662018-05-01 05:17:55 -07007286 vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
Damjan Marion7cd468a2016-12-19 23:05:39 +01007287}
7288
7289static int
Neale Ranns097fa662018-05-01 05:17:55 -07007290api_ip_table_dump (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +01007291{
Neale Ranns097fa662018-05-01 05:17:55 -07007292 vl_api_ip_table_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -06007293 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007294 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007295
Neale Ranns097fa662018-05-01 05:17:55 -07007296 M (IP_TABLE_DUMP, mp);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007297 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007298
7299 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -04007300 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06007301 S (mp_ping);
7302
Jon Loeliger56c7b012017-02-01 12:31:41 -06007303 W (ret);
7304 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007305}
7306
Neale Ranns5a8123b2017-01-26 01:18:23 -08007307static int
Neale Ranns097fa662018-05-01 05:17:55 -07007308api_ip_mtable_dump (vat_main_t * vam)
Neale Ranns5a8123b2017-01-26 01:18:23 -08007309{
Neale Ranns097fa662018-05-01 05:17:55 -07007310 vl_api_ip_mtable_dump_t *mp;
Neale Ranns5a8123b2017-01-26 01:18:23 -08007311 vl_api_control_ping_t *mp_ping;
7312 int ret;
7313
Neale Ranns097fa662018-05-01 05:17:55 -07007314 M (IP_MTABLE_DUMP, mp);
7315 S (mp);
7316
7317 /* Use a control ping for synchronization */
7318 MPING (CONTROL_PING, mp_ping);
7319 S (mp_ping);
7320
7321 W (ret);
7322 return ret;
7323}
7324
7325static int
7326api_ip_mroute_dump (vat_main_t * vam)
7327{
7328 unformat_input_t *input = vam->input;
7329 vl_api_control_ping_t *mp_ping;
7330 vl_api_ip_mroute_dump_t *mp;
7331 int ret, is_ip6;
7332 u32 table_id;
7333
7334 is_ip6 = 0;
7335 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7336 {
7337 if (unformat (input, "table_id %d", &table_id))
7338 ;
7339 else if (unformat (input, "ip6"))
7340 is_ip6 = 1;
7341 else if (unformat (input, "ip4"))
7342 is_ip6 = 0;
7343 else
7344 break;
7345 }
7346 if (table_id == ~0)
7347 {
7348 errmsg ("missing table id");
7349 return -99;
7350 }
7351
7352 M (IP_MROUTE_DUMP, mp);
7353 mp->table.table_id = table_id;
7354 mp->table.is_ip6 = is_ip6;
Neale Ranns5a8123b2017-01-26 01:18:23 -08007355 S (mp);
7356
7357 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -04007358 MPING (CONTROL_PING, mp_ping);
Neale Ranns5a8123b2017-01-26 01:18:23 -08007359 S (mp_ping);
7360
7361 W (ret);
7362 return ret;
7363}
7364
Neale Ranns097fa662018-05-01 05:17:55 -07007365#define vl_api_ip_route_details_t_endian vl_noop_handler
7366#define vl_api_ip_route_details_t_print vl_noop_handler
Damjan Marion7cd468a2016-12-19 23:05:39 +01007367
7368static void
Neale Ranns097fa662018-05-01 05:17:55 -07007369vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01007370{
7371 vat_main_t *vam = &vat_main;
Neale Ranns097fa662018-05-01 05:17:55 -07007372 u8 count = mp->route.n_paths;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007373 vl_api_fib_path_t *fp;
7374 int i;
7375
7376 print (vam->ofp,
Neale Ranns097fa662018-05-01 05:17:55 -07007377 "table-id %d, prefix %U/%d",
7378 ntohl (mp->route.table_id),
Paul Vinciguerraab055082019-06-06 14:07:55 -04007379 format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007380 for (i = 0; i < count; i++)
7381 {
Neale Ranns097fa662018-05-01 05:17:55 -07007382 fp = &mp->route.paths[i];
7383
7384 vl_api_fib_path_print (vam, fp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007385 fp++;
7386 }
7387}
7388
Neale Ranns097fa662018-05-01 05:17:55 -07007389static void vl_api_ip_route_details_t_handler_json
7390 (vl_api_ip_route_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01007391{
7392 vat_main_t *vam = &vat_main;
Neale Ranns097fa662018-05-01 05:17:55 -07007393 u8 count = mp->route.n_paths;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007394 vat_json_node_t *node = NULL;
7395 struct in_addr ip4;
7396 struct in6_addr ip6;
7397 vl_api_fib_path_t *fp;
7398 int i;
7399
7400 if (VAT_JSON_ARRAY != vam->json_tree.type)
7401 {
7402 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7403 vat_json_init_array (&vam->json_tree);
7404 }
7405 node = vat_json_array_add (&vam->json_tree);
7406
7407 vat_json_init_object (node);
Neale Ranns097fa662018-05-01 05:17:55 -07007408 vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
7409 if (ADDRESS_IP6 == mp->route.prefix.address.af)
7410 {
7411 clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
7412 vat_json_object_add_ip6 (node, "prefix", ip6);
7413 }
7414 else
7415 {
7416 clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
7417 vat_json_object_add_ip4 (node, "prefix", ip4);
7418 }
Paul Vinciguerraab055082019-06-06 14:07:55 -04007419 vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007420 vat_json_object_add_uint (node, "path_count", count);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007421 for (i = 0; i < count; i++)
7422 {
Neale Ranns097fa662018-05-01 05:17:55 -07007423 fp = &mp->route.paths[i];
7424 vl_api_mpls_fib_path_json_print (node, fp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007425 }
7426}
7427
7428static int
Neale Ranns097fa662018-05-01 05:17:55 -07007429api_ip_route_dump (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +01007430{
Neale Ranns097fa662018-05-01 05:17:55 -07007431 unformat_input_t *input = vam->input;
7432 vl_api_ip_route_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -06007433 vl_api_control_ping_t *mp_ping;
Neale Ranns097fa662018-05-01 05:17:55 -07007434 u32 table_id;
7435 u8 is_ip6;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007436 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007437
Neale Ranns097fa662018-05-01 05:17:55 -07007438 is_ip6 = 0;
7439 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7440 {
7441 if (unformat (input, "table_id %d", &table_id))
7442 ;
7443 else if (unformat (input, "ip6"))
7444 is_ip6 = 1;
7445 else if (unformat (input, "ip4"))
7446 is_ip6 = 0;
7447 else
7448 break;
7449 }
7450 if (table_id == ~0)
7451 {
7452 errmsg ("missing table id");
7453 return -99;
7454 }
Damjan Marion7cd468a2016-12-19 23:05:39 +01007455
Neale Ranns097fa662018-05-01 05:17:55 -07007456 M (IP_ROUTE_DUMP, mp);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06007457
Neale Ranns097fa662018-05-01 05:17:55 -07007458 mp->table.table_id = table_id;
7459 mp->table.is_ip6 = is_ip6;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007460
Neale Ranns5a8123b2017-01-26 01:18:23 -08007461 S (mp);
7462
7463 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -04007464 MPING (CONTROL_PING, mp_ping);
Neale Ranns5a8123b2017-01-26 01:18:23 -08007465 S (mp_ping);
7466
7467 W (ret);
7468 return ret;
7469}
7470
Damjan Marion7cd468a2016-12-19 23:05:39 +01007471static int
7472api_sw_interface_span_enable_disable (vat_main_t * vam)
7473{
7474 unformat_input_t *i = vam->input;
7475 vl_api_sw_interface_span_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007476 u32 src_sw_if_index = ~0;
7477 u32 dst_sw_if_index = ~0;
7478 u8 state = 3;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007479 int ret;
Eyal Bari001fd402017-07-16 09:34:53 +03007480 u8 is_l2 = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007481
7482 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7483 {
7484 if (unformat
7485 (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
7486 ;
7487 else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
7488 ;
7489 else
7490 if (unformat
7491 (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
7492 ;
7493 else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
7494 ;
7495 else if (unformat (i, "disable"))
7496 state = 0;
7497 else if (unformat (i, "rx"))
7498 state = 1;
7499 else if (unformat (i, "tx"))
7500 state = 2;
7501 else if (unformat (i, "both"))
7502 state = 3;
Eyal Bari001fd402017-07-16 09:34:53 +03007503 else if (unformat (i, "l2"))
7504 is_l2 = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007505 else
7506 break;
7507 }
7508
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007509 M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007510
7511 mp->sw_if_index_from = htonl (src_sw_if_index);
7512 mp->sw_if_index_to = htonl (dst_sw_if_index);
7513 mp->state = state;
Eyal Bari001fd402017-07-16 09:34:53 +03007514 mp->is_l2 = is_l2;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007515
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007516 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007517 W (ret);
7518 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007519}
7520
7521static void
7522vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
7523 * mp)
7524{
7525 vat_main_t *vam = &vat_main;
7526 u8 *sw_if_from_name = 0;
7527 u8 *sw_if_to_name = 0;
7528 u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
7529 u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
7530 char *states[] = { "none", "rx", "tx", "both" };
7531 hash_pair_t *p;
7532
7533 /* *INDENT-OFF* */
7534 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
7535 ({
7536 if ((u32) p->value[0] == sw_if_index_from)
7537 {
7538 sw_if_from_name = (u8 *)(p->key);
7539 if (sw_if_to_name)
7540 break;
7541 }
7542 if ((u32) p->value[0] == sw_if_index_to)
7543 {
7544 sw_if_to_name = (u8 *)(p->key);
7545 if (sw_if_from_name)
7546 break;
7547 }
7548 }));
7549 /* *INDENT-ON* */
Jon Loeliger179ab362018-03-12 14:50:08 -05007550 print (vam->ofp, "%20s => %20s (%s) %s",
7551 sw_if_from_name, sw_if_to_name, states[mp->state],
7552 mp->is_l2 ? "l2" : "device");
Damjan Marion7cd468a2016-12-19 23:05:39 +01007553}
7554
7555static void
7556 vl_api_sw_interface_span_details_t_handler_json
7557 (vl_api_sw_interface_span_details_t * mp)
7558{
7559 vat_main_t *vam = &vat_main;
7560 vat_json_node_t *node = NULL;
7561 u8 *sw_if_from_name = 0;
7562 u8 *sw_if_to_name = 0;
7563 u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
7564 u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
7565 hash_pair_t *p;
7566
7567 /* *INDENT-OFF* */
7568 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
7569 ({
7570 if ((u32) p->value[0] == sw_if_index_from)
7571 {
7572 sw_if_from_name = (u8 *)(p->key);
7573 if (sw_if_to_name)
7574 break;
7575 }
7576 if ((u32) p->value[0] == sw_if_index_to)
7577 {
7578 sw_if_to_name = (u8 *)(p->key);
7579 if (sw_if_from_name)
7580 break;
7581 }
7582 }));
7583 /* *INDENT-ON* */
7584
7585 if (VAT_JSON_ARRAY != vam->json_tree.type)
7586 {
7587 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7588 vat_json_init_array (&vam->json_tree);
7589 }
7590 node = vat_json_array_add (&vam->json_tree);
7591
7592 vat_json_init_object (node);
7593 vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
7594 vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
7595 vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
Neale Ranns05b2bf22017-01-30 06:44:58 -08007596 if (0 != sw_if_to_name)
7597 {
7598 vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
7599 }
Damjan Marion7cd468a2016-12-19 23:05:39 +01007600 vat_json_object_add_uint (node, "state", mp->state);
Jon Loeliger179ab362018-03-12 14:50:08 -05007601 vat_json_object_add_uint (node, "is-l2", mp->is_l2);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007602}
7603
7604static int
7605api_sw_interface_span_dump (vat_main_t * vam)
7606{
Eyal Bari5b311202017-07-31 13:12:30 +03007607 unformat_input_t *input = vam->input;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007608 vl_api_sw_interface_span_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -06007609 vl_api_control_ping_t *mp_ping;
Eyal Bari5b311202017-07-31 13:12:30 +03007610 u8 is_l2 = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007611 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007612
Eyal Bari5b311202017-07-31 13:12:30 +03007613 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7614 {
7615 if (unformat (input, "l2"))
7616 is_l2 = 1;
7617 else
7618 break;
7619 }
7620
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007621 M (SW_INTERFACE_SPAN_DUMP, mp);
Eyal Bari5b311202017-07-31 13:12:30 +03007622 mp->is_l2 = is_l2;
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007623 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007624
7625 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -04007626 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06007627 S (mp_ping);
7628
Jon Loeliger56c7b012017-02-01 12:31:41 -06007629 W (ret);
7630 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007631}
7632
7633int
Damjan Marion7cd468a2016-12-19 23:05:39 +01007634api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
7635{
7636 unformat_input_t *input = vam->input;
7637 vl_api_ip_source_and_port_range_check_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007638
7639 u16 *low_ports = 0;
7640 u16 *high_ports = 0;
7641 u16 this_low;
7642 u16 this_hi;
Neale Ranns37029302018-08-10 05:30:06 -07007643 vl_api_prefix_t prefix;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007644 u32 tmp, tmp2;
7645 u8 prefix_set = 0;
7646 u32 vrf_id = ~0;
7647 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007648 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007649
7650 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7651 {
Neale Ranns37029302018-08-10 05:30:06 -07007652 if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
7653 prefix_set = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007654 else if (unformat (input, "vrf %d", &vrf_id))
7655 ;
7656 else if (unformat (input, "del"))
7657 is_add = 0;
7658 else if (unformat (input, "port %d", &tmp))
7659 {
7660 if (tmp == 0 || tmp > 65535)
7661 {
7662 errmsg ("port %d out of range", tmp);
7663 return -99;
7664 }
7665 this_low = tmp;
7666 this_hi = this_low + 1;
7667 vec_add1 (low_ports, this_low);
7668 vec_add1 (high_ports, this_hi);
7669 }
7670 else if (unformat (input, "range %d - %d", &tmp, &tmp2))
7671 {
7672 if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
7673 {
7674 errmsg ("incorrect range parameters");
7675 return -99;
7676 }
7677 this_low = tmp;
7678 /* Note: in debug CLI +1 is added to high before
7679 passing to real fn that does "the work"
7680 (ip_source_and_port_range_check_add_del).
7681 This fn is a wrapper around the binary API fn a
7682 control plane will call, which expects this increment
7683 to have occurred. Hence letting the binary API control
7684 plane fn do the increment for consistency between VAT
7685 and other control planes.
7686 */
7687 this_hi = tmp2;
7688 vec_add1 (low_ports, this_low);
7689 vec_add1 (high_ports, this_hi);
7690 }
7691 else
7692 break;
7693 }
7694
7695 if (prefix_set == 0)
7696 {
7697 errmsg ("<address>/<mask> not specified");
7698 return -99;
7699 }
7700
7701 if (vrf_id == ~0)
7702 {
7703 errmsg ("VRF ID required, not specified");
7704 return -99;
7705 }
7706
7707 if (vrf_id == 0)
7708 {
7709 errmsg
7710 ("VRF ID should not be default. Should be distinct VRF for this purpose.");
7711 return -99;
7712 }
7713
7714 if (vec_len (low_ports) == 0)
7715 {
7716 errmsg ("At least one port or port range required");
7717 return -99;
7718 }
7719
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007720 M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007721
7722 mp->is_add = is_add;
7723
Neale Ranns37029302018-08-10 05:30:06 -07007724 clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
Damjan Marion7cd468a2016-12-19 23:05:39 +01007725
Damjan Marion7cd468a2016-12-19 23:05:39 +01007726 mp->number_of_ranges = vec_len (low_ports);
7727
7728 clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
7729 vec_free (low_ports);
7730
7731 clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
7732 vec_free (high_ports);
7733
7734 mp->vrf_id = ntohl (vrf_id);
7735
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007736 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007737 W (ret);
7738 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007739}
7740
7741int
7742api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
7743{
7744 unformat_input_t *input = vam->input;
7745 vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007746 u32 sw_if_index = ~0;
7747 int vrf_set = 0;
7748 u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
7749 u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
7750 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007751 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007752
7753 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7754 {
7755 if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7756 ;
7757 else if (unformat (input, "sw_if_index %d", &sw_if_index))
7758 ;
7759 else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
7760 vrf_set = 1;
7761 else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
7762 vrf_set = 1;
7763 else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
7764 vrf_set = 1;
7765 else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
7766 vrf_set = 1;
7767 else if (unformat (input, "del"))
7768 is_add = 0;
7769 else
7770 break;
7771 }
7772
7773 if (sw_if_index == ~0)
7774 {
7775 errmsg ("Interface required but not specified");
7776 return -99;
7777 }
7778
7779 if (vrf_set == 0)
7780 {
7781 errmsg ("VRF ID required but not specified");
7782 return -99;
7783 }
7784
7785 if (tcp_out_vrf_id == 0
7786 || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
7787 {
7788 errmsg
7789 ("VRF ID should not be default. Should be distinct VRF for this purpose.");
7790 return -99;
7791 }
7792
7793 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007794 M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007795
7796 mp->sw_if_index = ntohl (sw_if_index);
7797 mp->is_add = is_add;
7798 mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
7799 mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
7800 mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
7801 mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
7802
7803 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007804 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007805
7806 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06007807 W (ret);
7808 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007809}
7810
7811static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01007812api_delete_subif (vat_main_t * vam)
7813{
7814 unformat_input_t *i = vam->input;
7815 vl_api_delete_subif_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007816 u32 sw_if_index = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007817 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007818
7819 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7820 {
7821 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7822 ;
7823 if (unformat (i, "sw_if_index %d", &sw_if_index))
7824 ;
7825 else
7826 break;
7827 }
7828
7829 if (sw_if_index == ~0)
7830 {
7831 errmsg ("missing sw_if_index");
7832 return -99;
7833 }
7834
7835 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007836 M (DELETE_SUBIF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007837 mp->sw_if_index = ntohl (sw_if_index);
7838
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007839 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007840 W (ret);
7841 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007842}
7843
7844#define foreach_pbb_vtr_op \
7845_("disable", L2_VTR_DISABLED) \
7846_("pop", L2_VTR_POP_2) \
7847_("push", L2_VTR_PUSH_2)
7848
7849static int
7850api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
7851{
7852 unformat_input_t *i = vam->input;
7853 vl_api_l2_interface_pbb_tag_rewrite_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007854 u32 sw_if_index = ~0, vtr_op = ~0;
7855 u16 outer_tag = ~0;
7856 u8 dmac[6], smac[6];
7857 u8 dmac_set = 0, smac_set = 0;
7858 u16 vlanid = 0;
7859 u32 sid = ~0;
7860 u32 tmp;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007861 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007862
7863 /* Shut up coverity */
Dave Barachb7b92992018-10-17 10:38:51 -04007864 clib_memset (dmac, 0, sizeof (dmac));
7865 clib_memset (smac, 0, sizeof (smac));
Damjan Marion7cd468a2016-12-19 23:05:39 +01007866
7867 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7868 {
7869 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7870 ;
7871 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7872 ;
7873 else if (unformat (i, "vtr_op %d", &vtr_op))
7874 ;
7875#define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
7876 foreach_pbb_vtr_op
7877#undef _
7878 else if (unformat (i, "translate_pbb_stag"))
7879 {
7880 if (unformat (i, "%d", &tmp))
7881 {
7882 vtr_op = L2_VTR_TRANSLATE_2_1;
7883 outer_tag = tmp;
7884 }
7885 else
7886 {
7887 errmsg
7888 ("translate_pbb_stag operation requires outer tag definition");
7889 return -99;
7890 }
7891 }
7892 else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
7893 dmac_set++;
7894 else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
7895 smac_set++;
7896 else if (unformat (i, "sid %d", &sid))
7897 ;
7898 else if (unformat (i, "vlanid %d", &tmp))
7899 vlanid = tmp;
7900 else
7901 {
7902 clib_warning ("parse error '%U'", format_unformat_error, i);
7903 return -99;
7904 }
7905 }
7906
7907 if ((sw_if_index == ~0) || (vtr_op == ~0))
7908 {
7909 errmsg ("missing sw_if_index or vtr operation");
7910 return -99;
7911 }
7912 if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
7913 && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
7914 {
7915 errmsg
7916 ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
7917 return -99;
7918 }
7919
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007920 M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007921 mp->sw_if_index = ntohl (sw_if_index);
7922 mp->vtr_op = ntohl (vtr_op);
7923 mp->outer_tag = ntohs (outer_tag);
7924 clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
7925 clib_memcpy (mp->b_smac, smac, sizeof (smac));
7926 mp->b_vlanid = ntohs (vlanid);
7927 mp->i_sid = ntohl (sid);
7928
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007929 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007930 W (ret);
7931 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007932}
7933
7934static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01007935api_sw_interface_tag_add_del (vat_main_t * vam)
7936{
7937 unformat_input_t *i = vam->input;
7938 vl_api_sw_interface_tag_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007939 u32 sw_if_index = ~0;
7940 u8 *tag = 0;
7941 u8 enable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007942 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007943
7944 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7945 {
7946 if (unformat (i, "tag %s", &tag))
7947 ;
7948 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7949 ;
7950 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7951 ;
7952 else if (unformat (i, "del"))
7953 enable = 0;
7954 else
7955 break;
7956 }
7957
7958 if (sw_if_index == ~0)
7959 {
7960 errmsg ("missing interface name or sw_if_index");
7961 return -99;
7962 }
7963
7964 if (enable && (tag == 0))
7965 {
7966 errmsg ("no tag specified");
7967 return -99;
7968 }
7969
7970 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007971 M (SW_INTERFACE_TAG_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007972 mp->sw_if_index = ntohl (sw_if_index);
7973 mp->is_add = enable;
7974 if (enable)
Ole Troane5ff5a32019-08-23 22:55:18 +02007975 strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007976 vec_free (tag);
7977
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007978 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007979 W (ret);
7980 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007981}
7982
Matthew Smithe0792fd2019-07-12 11:48:24 -05007983static int
7984api_sw_interface_add_del_mac_address (vat_main_t * vam)
7985{
7986 unformat_input_t *i = vam->input;
7987 vl_api_mac_address_t mac = { 0 };
7988 vl_api_sw_interface_add_del_mac_address_t *mp;
7989 u32 sw_if_index = ~0;
7990 u8 is_add = 1;
7991 u8 mac_set = 0;
7992 int ret;
7993
7994 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7995 {
7996 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7997 ;
7998 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7999 ;
8000 else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
8001 mac_set++;
8002 else if (unformat (i, "del"))
8003 is_add = 0;
8004 else
8005 break;
8006 }
8007
8008 if (sw_if_index == ~0)
8009 {
8010 errmsg ("missing interface name or sw_if_index");
8011 return -99;
8012 }
8013
8014 if (!mac_set)
8015 {
8016 errmsg ("missing MAC address");
8017 return -99;
8018 }
8019
8020 /* Construct the API message */
8021 M (SW_INTERFACE_ADD_DEL_MAC_ADDRESS, mp);
8022 mp->sw_if_index = ntohl (sw_if_index);
8023 mp->is_add = is_add;
8024 clib_memcpy (&mp->addr, &mac, sizeof (mac));
8025
8026 S (mp);
8027 W (ret);
8028 return ret;
8029}
8030
Damjan Marion7cd468a2016-12-19 23:05:39 +01008031static void vl_api_l2_xconnect_details_t_handler
8032 (vl_api_l2_xconnect_details_t * mp)
8033{
8034 vat_main_t *vam = &vat_main;
8035
8036 print (vam->ofp, "%15d%15d",
8037 ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
8038}
8039
8040static void vl_api_l2_xconnect_details_t_handler_json
8041 (vl_api_l2_xconnect_details_t * mp)
8042{
8043 vat_main_t *vam = &vat_main;
8044 vat_json_node_t *node = NULL;
8045
8046 if (VAT_JSON_ARRAY != vam->json_tree.type)
8047 {
8048 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
8049 vat_json_init_array (&vam->json_tree);
8050 }
8051 node = vat_json_array_add (&vam->json_tree);
8052
8053 vat_json_init_object (node);
8054 vat_json_object_add_uint (node, "rx_sw_if_index",
8055 ntohl (mp->rx_sw_if_index));
8056 vat_json_object_add_uint (node, "tx_sw_if_index",
8057 ntohl (mp->tx_sw_if_index));
8058}
8059
8060static int
8061api_l2_xconnect_dump (vat_main_t * vam)
8062{
8063 vl_api_l2_xconnect_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -06008064 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008065 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008066
8067 if (!vam->json_output)
8068 {
8069 print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
8070 }
8071
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008072 M (L2_XCONNECT_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008073
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008074 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008075
8076 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -04008077 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06008078 S (mp_ping);
8079
Jon Loeliger56c7b012017-02-01 12:31:41 -06008080 W (ret);
8081 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008082}
8083
8084static int
Ole Troand7231612018-06-07 10:17:57 +02008085api_hw_interface_set_mtu (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +01008086{
8087 unformat_input_t *i = vam->input;
Ole Troand7231612018-06-07 10:17:57 +02008088 vl_api_hw_interface_set_mtu_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008089 u32 sw_if_index = ~0;
8090 u32 mtu = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008091 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008092
8093 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8094 {
8095 if (unformat (i, "mtu %d", &mtu))
8096 ;
8097 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8098 ;
8099 else if (unformat (i, "sw_if_index %d", &sw_if_index))
8100 ;
8101 else
8102 break;
8103 }
8104
8105 if (sw_if_index == ~0)
8106 {
8107 errmsg ("missing interface name or sw_if_index");
8108 return -99;
8109 }
8110
8111 if (mtu == 0)
8112 {
8113 errmsg ("no mtu specified");
8114 return -99;
8115 }
8116
8117 /* Construct the API message */
Ole Troand7231612018-06-07 10:17:57 +02008118 M (HW_INTERFACE_SET_MTU, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008119 mp->sw_if_index = ntohl (sw_if_index);
8120 mp->mtu = ntohs ((u16) mtu);
8121
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008122 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008123 W (ret);
8124 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008125}
8126
Pavel Kotucek6899a302017-06-08 08:46:10 +02008127static int
Dave Barach3bbcfab2017-08-15 19:03:44 -04008128api_tcp_configure_src_addresses (vat_main_t * vam)
8129{
8130 vl_api_tcp_configure_src_addresses_t *mp;
8131 unformat_input_t *i = vam->input;
Neale Rannscbe25aa2019-09-30 10:53:31 +00008132 vl_api_address_t first, last;
Dave Barach3bbcfab2017-08-15 19:03:44 -04008133 u8 range_set = 0;
8134 u32 vrf_id = 0;
8135 int ret;
8136
8137 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8138 {
8139 if (unformat (i, "%U - %U",
Neale Rannscbe25aa2019-09-30 10:53:31 +00008140 unformat_vl_api_address, &first,
8141 unformat_vl_api_address, &last))
Dave Barach3bbcfab2017-08-15 19:03:44 -04008142 {
8143 if (range_set)
8144 {
8145 errmsg ("one range per message (range already set)");
8146 return -99;
8147 }
8148 range_set = 1;
8149 }
Dave Barach3bbcfab2017-08-15 19:03:44 -04008150 else if (unformat (i, "vrf %d", &vrf_id))
8151 ;
8152 else
8153 break;
8154 }
8155
8156 if (range_set == 0)
8157 {
8158 errmsg ("address range not set");
8159 return -99;
8160 }
8161
8162 M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
Neale Rannscbe25aa2019-09-30 10:53:31 +00008163
Dave Barach3bbcfab2017-08-15 19:03:44 -04008164 mp->vrf_id = ntohl (vrf_id);
Neale Rannscbe25aa2019-09-30 10:53:31 +00008165 clib_memcpy (&mp->first_address, &first, sizeof (first));
8166 clib_memcpy (&mp->last_address, &last, sizeof (last));
8167
Dave Barach3bbcfab2017-08-15 19:03:44 -04008168 S (mp);
8169 W (ret);
8170 return ret;
8171}
8172
Florin Coras6e8c6672017-11-10 09:03:54 -08008173static void vl_api_app_namespace_add_del_reply_t_handler
8174 (vl_api_app_namespace_add_del_reply_t * mp)
8175{
8176 vat_main_t *vam = &vat_main;
8177 i32 retval = ntohl (mp->retval);
8178 if (vam->async_mode)
8179 {
8180 vam->async_errors += (retval < 0);
8181 }
8182 else
8183 {
8184 vam->retval = retval;
8185 if (retval == 0)
8186 errmsg ("app ns index %d\n", ntohl (mp->appns_index));
8187 vam->result_ready = 1;
8188 }
8189}
8190
8191static void vl_api_app_namespace_add_del_reply_t_handler_json
8192 (vl_api_app_namespace_add_del_reply_t * mp)
8193{
8194 vat_main_t *vam = &vat_main;
8195 vat_json_node_t node;
8196
8197 vat_json_init_object (&node);
8198 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
8199 vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
8200
8201 vat_json_print (vam->ofp, &node);
8202 vat_json_free (&node);
8203
8204 vam->retval = ntohl (mp->retval);
8205 vam->result_ready = 1;
8206}
8207
Dave Barach3bbcfab2017-08-15 19:03:44 -04008208static int
Florin Corascea194d2017-10-02 00:18:51 -07008209api_app_namespace_add_del (vat_main_t * vam)
8210{
8211 vl_api_app_namespace_add_del_t *mp;
8212 unformat_input_t *i = vam->input;
8213 u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
8214 u32 sw_if_index, ip4_fib_id, ip6_fib_id;
8215 u64 secret;
8216 int ret;
8217
8218 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8219 {
8220 if (unformat (i, "id %_%v%_", &ns_id))
8221 ;
8222 else if (unformat (i, "secret %lu", &secret))
8223 secret_set = 1;
8224 else if (unformat (i, "sw_if_index %d", &sw_if_index))
8225 sw_if_index_set = 1;
8226 else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
8227 ;
8228 else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
8229 ;
8230 else
8231 break;
8232 }
8233 if (!ns_id || !secret_set || !sw_if_index_set)
8234 {
8235 errmsg ("namespace id, secret and sw_if_index must be set");
8236 return -99;
8237 }
8238 if (vec_len (ns_id) > 64)
8239 {
8240 errmsg ("namespace id too long");
8241 return -99;
8242 }
8243 M (APP_NAMESPACE_ADD_DEL, mp);
8244
Jakub Grajciarb4e5e502020-01-31 09:35:29 +01008245 vl_api_vec_to_api_string (ns_id, &mp->namespace_id);
Florin Coras9a9adb22017-10-26 08:16:59 -07008246 mp->secret = clib_host_to_net_u64 (secret);
Florin Corascea194d2017-10-02 00:18:51 -07008247 mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
8248 mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
8249 mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
8250 vec_free (ns_id);
8251 S (mp);
8252 W (ret);
8253 return ret;
8254}
8255
8256static int
Florin Coras90a63982017-12-19 04:50:01 -08008257api_sock_init_shm (vat_main_t * vam)
8258{
8259#if VPP_API_TEST_BUILTIN == 0
8260 unformat_input_t *i = vam->input;
8261 vl_api_shm_elem_config_t *config = 0;
8262 u64 size = 64 << 20;
8263 int rv;
8264
8265 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8266 {
8267 if (unformat (i, "size %U", unformat_memory_size, &size))
8268 ;
8269 else
8270 break;
8271 }
8272
Dave Barach78958722018-05-10 16:44:27 -04008273 /*
8274 * Canned custom ring allocator config.
8275 * Should probably parse all of this
8276 */
8277 vec_validate (config, 6);
Florin Coras90a63982017-12-19 04:50:01 -08008278 config[0].type = VL_API_VLIB_RING;
Florin Coras90a63982017-12-19 04:50:01 -08008279 config[0].size = 256;
Dave Barach78958722018-05-10 16:44:27 -04008280 config[0].count = 32;
8281
8282 config[1].type = VL_API_VLIB_RING;
Florin Coras90a63982017-12-19 04:50:01 -08008283 config[1].size = 1024;
Dave Barach78958722018-05-10 16:44:27 -04008284 config[1].count = 16;
8285
8286 config[2].type = VL_API_VLIB_RING;
Florin Coras90a63982017-12-19 04:50:01 -08008287 config[2].size = 4096;
Dave Barach78958722018-05-10 16:44:27 -04008288 config[2].count = 2;
8289
8290 config[3].type = VL_API_CLIENT_RING;
8291 config[3].size = 256;
8292 config[3].count = 32;
8293
8294 config[4].type = VL_API_CLIENT_RING;
8295 config[4].size = 1024;
8296 config[4].count = 16;
8297
8298 config[5].type = VL_API_CLIENT_RING;
8299 config[5].size = 4096;
8300 config[5].count = 2;
8301
8302 config[6].type = VL_API_QUEUE;
8303 config[6].count = 128;
8304 config[6].size = sizeof (uword);
8305
Tomasz Kulasek97dcf5b2019-01-31 18:26:32 +01008306 rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
Florin Coras90a63982017-12-19 04:50:01 -08008307 if (!rv)
8308 vam->client_index_invalid = 1;
8309 return rv;
8310#else
8311 return -99;
8312#endif
8313}
8314
Florin Coras6c36f532017-11-03 18:32:34 -07008315static void
8316vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
8317{
8318 vat_main_t *vam = &vat_main;
Jakub Grajciarb4e5e502020-01-31 09:35:29 +01008319 fib_prefix_t lcl, rmt;
Florin Coras6c36f532017-11-03 18:32:34 -07008320
Jakub Grajciarb4e5e502020-01-31 09:35:29 +01008321 ip_prefix_decode (&mp->lcl, &lcl);
8322 ip_prefix_decode (&mp->rmt, &rmt);
8323
8324 if (lcl.fp_proto == FIB_PROTOCOL_IP4)
Florin Coras6c36f532017-11-03 18:32:34 -07008325 {
Florin Corasc97a7392017-11-05 23:07:07 -08008326 print (vam->ofp,
8327 "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
Steven85dbac02017-11-07 16:29:53 -08008328 clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
Jakub Grajciarb4e5e502020-01-31 09:35:29 +01008329 mp->scope, format_ip4_address, &lcl.fp_addr.ip4, lcl.fp_len,
Steven85dbac02017-11-07 16:29:53 -08008330 clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
Jakub Grajciarb4e5e502020-01-31 09:35:29 +01008331 &rmt.fp_addr.ip4, rmt.fp_len,
8332 clib_net_to_host_u16 (mp->rmt_port),
Steven85dbac02017-11-07 16:29:53 -08008333 clib_net_to_host_u32 (mp->action_index), mp->tag);
Florin Coras6c36f532017-11-03 18:32:34 -07008334 }
8335 else
8336 {
Florin Corasc97a7392017-11-05 23:07:07 -08008337 print (vam->ofp,
8338 "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
Steven85dbac02017-11-07 16:29:53 -08008339 clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
Jakub Grajciarb4e5e502020-01-31 09:35:29 +01008340 mp->scope, format_ip6_address, &lcl.fp_addr.ip6, lcl.fp_len,
Steven85dbac02017-11-07 16:29:53 -08008341 clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
Jakub Grajciarb4e5e502020-01-31 09:35:29 +01008342 &rmt.fp_addr.ip6, rmt.fp_len,
8343 clib_net_to_host_u16 (mp->rmt_port),
Steven85dbac02017-11-07 16:29:53 -08008344 clib_net_to_host_u32 (mp->action_index), mp->tag);
Florin Coras6c36f532017-11-03 18:32:34 -07008345 }
8346}
8347
8348static void
8349vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
8350 mp)
8351{
8352 vat_main_t *vam = &vat_main;
8353 vat_json_node_t *node = NULL;
8354 struct in6_addr ip6;
8355 struct in_addr ip4;
8356
Jakub Grajciarb4e5e502020-01-31 09:35:29 +01008357 fib_prefix_t lcl, rmt;
8358
8359 ip_prefix_decode (&mp->lcl, &lcl);
8360 ip_prefix_decode (&mp->rmt, &rmt);
8361
Florin Coras6c36f532017-11-03 18:32:34 -07008362 if (VAT_JSON_ARRAY != vam->json_tree.type)
8363 {
8364 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
8365 vat_json_init_array (&vam->json_tree);
8366 }
8367 node = vat_json_array_add (&vam->json_tree);
8368 vat_json_init_object (node);
8369
Florin Coras6c36f532017-11-03 18:32:34 -07008370 vat_json_object_add_uint (node, "appns_index",
8371 clib_net_to_host_u32 (mp->appns_index));
8372 vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
8373 vat_json_object_add_uint (node, "scope", mp->scope);
8374 vat_json_object_add_uint (node, "action_index",
8375 clib_net_to_host_u32 (mp->action_index));
8376 vat_json_object_add_uint (node, "lcl_port",
8377 clib_net_to_host_u16 (mp->lcl_port));
8378 vat_json_object_add_uint (node, "rmt_port",
8379 clib_net_to_host_u16 (mp->rmt_port));
Jakub Grajciarb4e5e502020-01-31 09:35:29 +01008380 vat_json_object_add_uint (node, "lcl_plen", lcl.fp_len);
8381 vat_json_object_add_uint (node, "rmt_plen", rmt.fp_len);
Florin Corasc97a7392017-11-05 23:07:07 -08008382 vat_json_object_add_string_copy (node, "tag", mp->tag);
Jakub Grajciarb4e5e502020-01-31 09:35:29 +01008383 if (lcl.fp_proto == FIB_PROTOCOL_IP4)
Florin Coras6c36f532017-11-03 18:32:34 -07008384 {
Jakub Grajciarb4e5e502020-01-31 09:35:29 +01008385 clib_memcpy (&ip4, &lcl.fp_addr.ip4, sizeof (ip4));
Florin Coras6c36f532017-11-03 18:32:34 -07008386 vat_json_object_add_ip4 (node, "lcl_ip", ip4);
Jakub Grajciarb4e5e502020-01-31 09:35:29 +01008387 clib_memcpy (&ip4, &rmt.fp_addr.ip4, sizeof (ip4));
Florin Coras6c36f532017-11-03 18:32:34 -07008388 vat_json_object_add_ip4 (node, "rmt_ip", ip4);
8389 }
8390 else
8391 {
Jakub Grajciarb4e5e502020-01-31 09:35:29 +01008392 clib_memcpy (&ip6, &lcl.fp_addr.ip6, sizeof (ip6));
Florin Coras6c36f532017-11-03 18:32:34 -07008393 vat_json_object_add_ip6 (node, "lcl_ip", ip6);
Jakub Grajciarb4e5e502020-01-31 09:35:29 +01008394 clib_memcpy (&ip6, &rmt.fp_addr.ip6, sizeof (ip6));
Florin Coras6c36f532017-11-03 18:32:34 -07008395 vat_json_object_add_ip6 (node, "rmt_ip", ip6);
8396 }
8397}
8398
Florin Coras1c710452017-10-17 00:03:13 -07008399static int
8400api_session_rule_add_del (vat_main_t * vam)
8401{
8402 vl_api_session_rule_add_del_t *mp;
8403 unformat_input_t *i = vam->input;
8404 u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
8405 u32 appns_index = 0, scope = 0;
8406 ip4_address_t lcl_ip4, rmt_ip4;
8407 ip6_address_t lcl_ip6, rmt_ip6;
8408 u8 is_ip4 = 1, conn_set = 0;
Florin Corasc97a7392017-11-05 23:07:07 -08008409 u8 is_add = 1, *tag = 0;
Florin Coras1c710452017-10-17 00:03:13 -07008410 int ret;
Jakub Grajciarb4e5e502020-01-31 09:35:29 +01008411 fib_prefix_t lcl, rmt;
Florin Coras1c710452017-10-17 00:03:13 -07008412
8413 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8414 {
8415 if (unformat (i, "del"))
8416 is_add = 0;
8417 else if (unformat (i, "add"))
8418 ;
8419 else if (unformat (i, "proto tcp"))
8420 proto = 0;
8421 else if (unformat (i, "proto udp"))
8422 proto = 1;
8423 else if (unformat (i, "appns %d", &appns_index))
8424 ;
8425 else if (unformat (i, "scope %d", &scope))
8426 ;
Florin Corasc97a7392017-11-05 23:07:07 -08008427 else if (unformat (i, "tag %_%v%_", &tag))
8428 ;
Florin Coras1c710452017-10-17 00:03:13 -07008429 else
8430 if (unformat
8431 (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
8432 &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
8433 &rmt_port))
8434 {
8435 is_ip4 = 1;
8436 conn_set = 1;
8437 }
8438 else
8439 if (unformat
8440 (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
8441 &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
8442 &rmt_port))
8443 {
8444 is_ip4 = 0;
8445 conn_set = 1;
8446 }
8447 else if (unformat (i, "action %d", &action))
8448 ;
8449 else
8450 break;
8451 }
8452 if (proto == ~0 || !conn_set || action == ~0)
8453 {
8454 errmsg ("transport proto, connection and action must be set");
8455 return -99;
8456 }
8457
8458 if (scope > 3)
8459 {
8460 errmsg ("scope should be 0-3");
8461 return -99;
8462 }
8463
8464 M (SESSION_RULE_ADD_DEL, mp);
8465
Jakub Grajciarb4e5e502020-01-31 09:35:29 +01008466 clib_memset (&lcl, 0, sizeof (lcl));
8467 clib_memset (&rmt, 0, sizeof (rmt));
8468 if (is_ip4)
8469 {
8470 ip_set (&lcl.fp_addr, &lcl_ip4, 1);
8471 ip_set (&rmt.fp_addr, &rmt_ip4, 1);
8472 lcl.fp_len = lcl_plen;
8473 rmt.fp_len = rmt_plen;
8474 }
8475 else
8476 {
8477 ip_set (&lcl.fp_addr, &lcl_ip6, 0);
8478 ip_set (&rmt.fp_addr, &rmt_ip6, 0);
8479 lcl.fp_len = lcl_plen;
8480 rmt.fp_len = rmt_plen;
8481 }
8482
8483
8484 ip_prefix_encode (&lcl, &mp->lcl);
8485 ip_prefix_encode (&rmt, &mp->rmt);
Florin Corasc97a7392017-11-05 23:07:07 -08008486 mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
8487 mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
Jakub Grajciarb4e5e502020-01-31 09:35:29 +01008488 mp->transport_proto =
8489 proto ? TRANSPORT_PROTO_API_UDP : TRANSPORT_PROTO_API_TCP;
Florin Coras1c710452017-10-17 00:03:13 -07008490 mp->action_index = clib_host_to_net_u32 (action);
8491 mp->appns_index = clib_host_to_net_u32 (appns_index);
8492 mp->scope = scope;
8493 mp->is_add = is_add;
Florin Corasc97a7392017-11-05 23:07:07 -08008494 if (tag)
8495 {
8496 clib_memcpy (mp->tag, tag, vec_len (tag));
8497 vec_free (tag);
8498 }
Florin Coras1c710452017-10-17 00:03:13 -07008499
8500 S (mp);
8501 W (ret);
8502 return ret;
8503}
Dave Barach65457162017-10-10 17:53:14 -04008504
8505static int
Florin Coras6c36f532017-11-03 18:32:34 -07008506api_session_rules_dump (vat_main_t * vam)
8507{
8508 vl_api_session_rules_dump_t *mp;
8509 vl_api_control_ping_t *mp_ping;
8510 int ret;
8511
8512 if (!vam->json_output)
8513 {
8514 print (vam->ofp, "%=20s", "Session Rules");
8515 }
8516
8517 M (SESSION_RULES_DUMP, mp);
8518 /* send it... */
8519 S (mp);
8520
8521 /* Use a control ping for synchronization */
8522 MPING (CONTROL_PING, mp_ping);
8523 S (mp_ping);
8524
8525 /* Wait for a reply... */
8526 W (ret);
8527 return ret;
8528}
8529
8530static int
Florin Coras595992c2017-11-06 17:17:08 -08008531api_ip_container_proxy_add_del (vat_main_t * vam)
8532{
8533 vl_api_ip_container_proxy_add_del_t *mp;
8534 unformat_input_t *i = vam->input;
Neale Ranns37029302018-08-10 05:30:06 -07008535 u32 sw_if_index = ~0;
8536 vl_api_prefix_t pfx = { };
Florin Coras595992c2017-11-06 17:17:08 -08008537 u8 is_add = 1;
8538 int ret;
8539
8540 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8541 {
8542 if (unformat (i, "del"))
8543 is_add = 0;
8544 else if (unformat (i, "add"))
8545 ;
Neale Ranns37029302018-08-10 05:30:06 -07008546 if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8547 ;
Florin Coras595992c2017-11-06 17:17:08 -08008548 else if (unformat (i, "sw_if_index %u", &sw_if_index))
8549 ;
8550 else
8551 break;
8552 }
Paul Vinciguerraab055082019-06-06 14:07:55 -04008553 if (sw_if_index == ~0 || pfx.len == 0)
Florin Coras595992c2017-11-06 17:17:08 -08008554 {
8555 errmsg ("address and sw_if_index must be set");
8556 return -99;
8557 }
8558
8559 M (IP_CONTAINER_PROXY_ADD_DEL, mp);
8560
Florin Coras595992c2017-11-06 17:17:08 -08008561 mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
Florin Coras595992c2017-11-06 17:17:08 -08008562 mp->is_add = is_add;
Neale Ranns37029302018-08-10 05:30:06 -07008563 clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
Florin Coras595992c2017-11-06 17:17:08 -08008564
8565 S (mp);
8566 W (ret);
8567 return ret;
8568}
8569
8570static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01008571q_or_quit (vat_main_t * vam)
8572{
Dave Barachdef19da2017-02-22 17:29:20 -05008573#if VPP_API_TEST_BUILTIN == 0
Damjan Marion7cd468a2016-12-19 23:05:39 +01008574 longjmp (vam->jump_buf, 1);
Dave Barachdef19da2017-02-22 17:29:20 -05008575#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +01008576 return 0; /* not so much */
8577}
8578
8579static int
8580q (vat_main_t * vam)
8581{
8582 return q_or_quit (vam);
8583}
8584
8585static int
8586quit (vat_main_t * vam)
8587{
8588 return q_or_quit (vam);
8589}
8590
8591static int
8592comment (vat_main_t * vam)
8593{
8594 return 0;
8595}
8596
8597static int
Dave Barachb09f4d02019-07-15 16:00:03 -04008598elog_save (vat_main_t * vam)
8599{
8600#if VPP_API_TEST_BUILTIN == 0
8601 elog_main_t *em = &vam->elog_main;
8602 unformat_input_t *i = vam->input;
8603 char *file, *chroot_file;
8604 clib_error_t *error;
8605
8606 if (!unformat (i, "%s", &file))
8607 {
8608 errmsg ("expected file name, got `%U'", format_unformat_error, i);
8609 return 0;
8610 }
8611
8612 /* It's fairly hard to get "../oopsie" through unformat; just in case */
8613 if (strstr (file, "..") || index (file, '/'))
8614 {
8615 errmsg ("illegal characters in filename '%s'", file);
8616 return 0;
8617 }
8618
8619 chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
8620
8621 vec_free (file);
8622
8623 errmsg ("Saving %wd of %wd events to %s",
8624 elog_n_events_in_buffer (em),
8625 elog_buffer_capacity (em), chroot_file);
8626
8627 error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
8628 vec_free (chroot_file);
8629
8630 if (error)
8631 clib_error_report (error);
8632#else
8633 errmsg ("Use the vpp event loger...");
8634#endif
8635
8636 return 0;
8637}
8638
8639static int
8640elog_setup (vat_main_t * vam)
8641{
8642#if VPP_API_TEST_BUILTIN == 0
8643 elog_main_t *em = &vam->elog_main;
8644 unformat_input_t *i = vam->input;
8645 u32 nevents = 128 << 10;
8646
8647 (void) unformat (i, "nevents %d", &nevents);
8648
8649 elog_init (em, nevents);
8650 vl_api_set_elog_main (em);
8651 vl_api_set_elog_trace_api_messages (1);
8652 errmsg ("Event logger initialized with %u events", nevents);
8653#else
8654 errmsg ("Use the vpp event loger...");
8655#endif
8656 return 0;
8657}
8658
8659static int
8660elog_enable (vat_main_t * vam)
8661{
8662#if VPP_API_TEST_BUILTIN == 0
8663 elog_main_t *em = &vam->elog_main;
8664
8665 elog_enable_disable (em, 1 /* enable */ );
8666 vl_api_set_elog_trace_api_messages (1);
8667 errmsg ("Event logger enabled...");
8668#else
8669 errmsg ("Use the vpp event loger...");
8670#endif
8671 return 0;
8672}
8673
8674static int
8675elog_disable (vat_main_t * vam)
8676{
8677#if VPP_API_TEST_BUILTIN == 0
8678 elog_main_t *em = &vam->elog_main;
8679
8680 elog_enable_disable (em, 0 /* enable */ );
8681 vl_api_set_elog_trace_api_messages (1);
8682 errmsg ("Event logger disabled...");
8683#else
8684 errmsg ("Use the vpp event loger...");
8685#endif
8686 return 0;
8687}
8688
8689static int
Dave Barach048a4e52018-06-01 18:52:25 -04008690statseg (vat_main_t * vam)
8691{
8692 ssvm_private_t *ssvmp = &vam->stat_segment;
8693 ssvm_shared_header_t *shared_header = ssvmp->sh;
8694 vlib_counter_t **counters;
8695 u64 thread0_index1_packets;
8696 u64 thread0_index1_bytes;
8697 f64 vector_rate, input_rate;
8698 uword *p;
8699
8700 uword *counter_vector_by_name;
8701 if (vam->stat_segment_lockp == 0)
8702 {
8703 errmsg ("Stat segment not mapped...");
8704 return -99;
8705 }
8706
8707 /* look up "/if/rx for sw_if_index 1 as a test */
8708
8709 clib_spinlock_lock (vam->stat_segment_lockp);
8710
8711 counter_vector_by_name = (uword *) shared_header->opaque[1];
8712
8713 p = hash_get_mem (counter_vector_by_name, "/if/rx");
8714 if (p == 0)
8715 {
8716 clib_spinlock_unlock (vam->stat_segment_lockp);
8717 errmsg ("/if/tx not found?");
8718 return -99;
8719 }
8720
8721 /* Fish per-thread vector of combined counters from shared memory */
8722 counters = (vlib_counter_t **) p[0];
8723
8724 if (vec_len (counters[0]) < 2)
8725 {
8726 clib_spinlock_unlock (vam->stat_segment_lockp);
8727 errmsg ("/if/tx vector length %d", vec_len (counters[0]));
8728 return -99;
8729 }
8730
8731 /* Read thread 0 sw_if_index 1 counter */
8732 thread0_index1_packets = counters[0][1].packets;
8733 thread0_index1_bytes = counters[0][1].bytes;
8734
8735 p = hash_get_mem (counter_vector_by_name, "vector_rate");
8736 if (p == 0)
8737 {
8738 clib_spinlock_unlock (vam->stat_segment_lockp);
8739 errmsg ("vector_rate not found?");
8740 return -99;
8741 }
8742
8743 vector_rate = *(f64 *) (p[0]);
8744 p = hash_get_mem (counter_vector_by_name, "input_rate");
8745 if (p == 0)
8746 {
8747 clib_spinlock_unlock (vam->stat_segment_lockp);
8748 errmsg ("input_rate not found?");
8749 return -99;
8750 }
8751 input_rate = *(f64 *) (p[0]);
8752
8753 clib_spinlock_unlock (vam->stat_segment_lockp);
8754
8755 print (vam->ofp, "vector_rate %.2f input_rate %.2f",
8756 vector_rate, input_rate);
8757 print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
8758 thread0_index1_packets, thread0_index1_bytes);
8759
8760 return 0;
8761}
8762
8763static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01008764cmd_cmp (void *a1, void *a2)
8765{
8766 u8 **c1 = a1;
8767 u8 **c2 = a2;
8768
8769 return strcmp ((char *) (c1[0]), (char *) (c2[0]));
8770}
8771
8772static int
8773help (vat_main_t * vam)
8774{
8775 u8 **cmds = 0;
8776 u8 *name = 0;
8777 hash_pair_t *p;
8778 unformat_input_t *i = vam->input;
8779 int j;
8780
8781 if (unformat (i, "%s", &name))
8782 {
8783 uword *hs;
8784
8785 vec_add1 (name, 0);
8786
8787 hs = hash_get_mem (vam->help_by_name, name);
8788 if (hs)
8789 print (vam->ofp, "usage: %s %s", name, hs[0]);
8790 else
8791 print (vam->ofp, "No such msg / command '%s'", name);
8792 vec_free (name);
8793 return 0;
8794 }
8795
8796 print (vam->ofp, "Help is available for the following:");
8797
8798 /* *INDENT-OFF* */
8799 hash_foreach_pair (p, vam->function_by_name,
8800 ({
8801 vec_add1 (cmds, (u8 *)(p->key));
8802 }));
8803 /* *INDENT-ON* */
8804
8805 vec_sort_with_function (cmds, cmd_cmp);
8806
8807 for (j = 0; j < vec_len (cmds); j++)
8808 print (vam->ofp, "%s", cmds[j]);
8809
8810 vec_free (cmds);
8811 return 0;
8812}
8813
8814static int
8815set (vat_main_t * vam)
8816{
8817 u8 *name = 0, *value = 0;
8818 unformat_input_t *i = vam->input;
8819
8820 if (unformat (i, "%s", &name))
8821 {
8822 /* The input buffer is a vector, not a string. */
8823 value = vec_dup (i->buffer);
8824 vec_delete (value, i->index, 0);
8825 /* Almost certainly has a trailing newline */
8826 if (value[vec_len (value) - 1] == '\n')
8827 value[vec_len (value) - 1] = 0;
8828 /* Make sure it's a proper string, one way or the other */
8829 vec_add1 (value, 0);
8830 (void) clib_macro_set_value (&vam->macro_main,
8831 (char *) name, (char *) value);
8832 }
8833 else
8834 errmsg ("usage: set <name> <value>");
8835
8836 vec_free (name);
8837 vec_free (value);
8838 return 0;
8839}
8840
8841static int
8842unset (vat_main_t * vam)
8843{
8844 u8 *name = 0;
8845
8846 if (unformat (vam->input, "%s", &name))
8847 if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
8848 errmsg ("unset: %s wasn't set", name);
8849 vec_free (name);
8850 return 0;
8851}
8852
8853typedef struct
8854{
8855 u8 *name;
8856 u8 *value;
8857} macro_sort_t;
8858
8859
8860static int
8861macro_sort_cmp (void *a1, void *a2)
8862{
8863 macro_sort_t *s1 = a1;
8864 macro_sort_t *s2 = a2;
8865
8866 return strcmp ((char *) (s1->name), (char *) (s2->name));
8867}
8868
8869static int
8870dump_macro_table (vat_main_t * vam)
8871{
8872 macro_sort_t *sort_me = 0, *sm;
8873 int i;
8874 hash_pair_t *p;
8875
8876 /* *INDENT-OFF* */
8877 hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
8878 ({
8879 vec_add2 (sort_me, sm, 1);
8880 sm->name = (u8 *)(p->key);
8881 sm->value = (u8 *) (p->value[0]);
8882 }));
8883 /* *INDENT-ON* */
8884
8885 vec_sort_with_function (sort_me, macro_sort_cmp);
8886
8887 if (vec_len (sort_me))
8888 print (vam->ofp, "%-15s%s", "Name", "Value");
8889 else
8890 print (vam->ofp, "The macro table is empty...");
8891
8892 for (i = 0; i < vec_len (sort_me); i++)
8893 print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
8894 return 0;
8895}
8896
8897static int
8898dump_node_table (vat_main_t * vam)
8899{
8900 int i, j;
8901 vlib_node_t *node, *next_node;
8902
8903 if (vec_len (vam->graph_nodes) == 0)
8904 {
8905 print (vam->ofp, "Node table empty, issue get_node_graph...");
8906 return 0;
8907 }
8908
Dave Barach1ddbc012018-06-13 09:26:05 -04008909 for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
Damjan Marion7cd468a2016-12-19 23:05:39 +01008910 {
Dave Barach1ddbc012018-06-13 09:26:05 -04008911 node = vam->graph_nodes[0][i];
Damjan Marion7cd468a2016-12-19 23:05:39 +01008912 print (vam->ofp, "[%d] %s", i, node->name);
8913 for (j = 0; j < vec_len (node->next_nodes); j++)
8914 {
8915 if (node->next_nodes[j] != ~0)
8916 {
Dave Barach1ddbc012018-06-13 09:26:05 -04008917 next_node = vam->graph_nodes[0][node->next_nodes[j]];
Damjan Marion7cd468a2016-12-19 23:05:39 +01008918 print (vam->ofp, " [%d] %s", j, next_node->name);
8919 }
8920 }
8921 }
8922 return 0;
8923}
8924
8925static int
8926value_sort_cmp (void *a1, void *a2)
8927{
8928 name_sort_t *n1 = a1;
8929 name_sort_t *n2 = a2;
8930
8931 if (n1->value < n2->value)
8932 return -1;
8933 if (n1->value > n2->value)
8934 return 1;
8935 return 0;
8936}
8937
8938
8939static int
8940dump_msg_api_table (vat_main_t * vam)
8941{
Dave Barach39d69112019-11-27 11:42:13 -05008942 api_main_t *am = vlibapi_get_main ();
Damjan Marion7cd468a2016-12-19 23:05:39 +01008943 name_sort_t *nses = 0, *ns;
8944 hash_pair_t *hp;
8945 int i;
8946
8947 /* *INDENT-OFF* */
8948 hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
8949 ({
8950 vec_add2 (nses, ns, 1);
8951 ns->name = (u8 *)(hp->key);
8952 ns->value = (u32) hp->value[0];
8953 }));
8954 /* *INDENT-ON* */
8955
8956 vec_sort_with_function (nses, value_sort_cmp);
8957
8958 for (i = 0; i < vec_len (nses); i++)
8959 print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
8960 vec_free (nses);
8961 return 0;
8962}
8963
8964static int
8965get_msg_id (vat_main_t * vam)
8966{
8967 u8 *name_and_crc;
8968 u32 message_index;
8969
8970 if (unformat (vam->input, "%s", &name_and_crc))
8971 {
Florin Corase86a8ed2018-01-05 03:20:25 -08008972 message_index = vl_msg_api_get_msg_index (name_and_crc);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008973 if (message_index == ~0)
8974 {
8975 print (vam->ofp, " '%s' not found", name_and_crc);
8976 return 0;
8977 }
8978 print (vam->ofp, " '%s' has message index %d",
8979 name_and_crc, message_index);
8980 return 0;
8981 }
8982 errmsg ("name_and_crc required...");
8983 return 0;
8984}
8985
8986static int
8987search_node_table (vat_main_t * vam)
8988{
8989 unformat_input_t *line_input = vam->input;
8990 u8 *node_to_find;
8991 int j;
8992 vlib_node_t *node, *next_node;
8993 uword *p;
8994
8995 if (vam->graph_node_index_by_name == 0)
8996 {
8997 print (vam->ofp, "Node table empty, issue get_node_graph...");
8998 return 0;
8999 }
9000
9001 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9002 {
9003 if (unformat (line_input, "%s", &node_to_find))
9004 {
9005 vec_add1 (node_to_find, 0);
9006 p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
9007 if (p == 0)
9008 {
9009 print (vam->ofp, "%s not found...", node_to_find);
9010 goto out;
9011 }
Dave Barach1ddbc012018-06-13 09:26:05 -04009012 node = vam->graph_nodes[0][p[0]];
Damjan Marion7cd468a2016-12-19 23:05:39 +01009013 print (vam->ofp, "[%d] %s", p[0], node->name);
9014 for (j = 0; j < vec_len (node->next_nodes); j++)
9015 {
9016 if (node->next_nodes[j] != ~0)
9017 {
Dave Barach1ddbc012018-06-13 09:26:05 -04009018 next_node = vam->graph_nodes[0][node->next_nodes[j]];
Damjan Marion7cd468a2016-12-19 23:05:39 +01009019 print (vam->ofp, " [%d] %s", j, next_node->name);
9020 }
9021 }
9022 }
9023
9024 else
9025 {
9026 clib_warning ("parse error '%U'", format_unformat_error,
9027 line_input);
9028 return -99;
9029 }
9030
9031 out:
9032 vec_free (node_to_find);
9033
9034 }
9035
9036 return 0;
9037}
9038
9039
9040static int
9041script (vat_main_t * vam)
9042{
9043#if (VPP_API_TEST_BUILTIN==0)
9044 u8 *s = 0;
9045 char *save_current_file;
9046 unformat_input_t save_input;
9047 jmp_buf save_jump_buf;
9048 u32 save_line_number;
9049
9050 FILE *new_fp, *save_ifp;
9051
9052 if (unformat (vam->input, "%s", &s))
9053 {
9054 new_fp = fopen ((char *) s, "r");
9055 if (new_fp == 0)
9056 {
9057 errmsg ("Couldn't open script file %s", s);
9058 vec_free (s);
9059 return -99;
9060 }
9061 }
9062 else
9063 {
9064 errmsg ("Missing script name");
9065 return -99;
9066 }
9067
9068 clib_memcpy (&save_input, &vam->input, sizeof (save_input));
9069 clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
9070 save_ifp = vam->ifp;
9071 save_line_number = vam->input_line_number;
9072 save_current_file = (char *) vam->current_file;
9073
9074 vam->input_line_number = 0;
9075 vam->ifp = new_fp;
9076 vam->current_file = s;
9077 do_one_file (vam);
9078
Sirshak Dasb0861822018-05-29 21:13:21 -05009079 clib_memcpy (&vam->input, &save_input, sizeof (save_input));
Damjan Marion7cd468a2016-12-19 23:05:39 +01009080 clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
9081 vam->ifp = save_ifp;
9082 vam->input_line_number = save_line_number;
9083 vam->current_file = (u8 *) save_current_file;
9084 vec_free (s);
9085
9086 return 0;
9087#else
9088 clib_warning ("use the exec command...");
9089 return -99;
9090#endif
9091}
9092
9093static int
9094echo (vat_main_t * vam)
9095{
9096 print (vam->ofp, "%v", vam->input->buffer);
9097 return 0;
9098}
9099
9100/* List of API message constructors, CLI names map to api_xxx */
9101#define foreach_vpe_api_msg \
Jon Loeligerc83c3b72017-02-23 13:57:35 -06009102_(create_loopback,"[mac <mac-addr>] [instance <instance>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01009103_(sw_interface_dump,"") \
9104_(sw_interface_set_flags, \
9105 "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
9106_(sw_interface_add_del_address, \
9107 "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
Stevenad8015b2017-10-29 22:10:46 -07009108_(sw_interface_set_rx_mode, \
9109 "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
Mohsin Kazmi54f7c512018-08-23 18:28:11 +02009110_(sw_interface_set_rx_placement, \
9111 "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]") \
Mohsin Kazmif0b42f42018-09-10 18:11:00 +02009112_(sw_interface_rx_placement_dump, \
9113 "[<intfc> | sw_if_index <id>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01009114_(sw_interface_set_table, \
9115 "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]") \
9116_(sw_interface_set_mpls_enable, \
9117 "<intfc> | sw_if_index [disable | dis]") \
9118_(sw_interface_set_vpath, \
9119 "<intfc> | sw_if_index <id> enable | disable") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01009120_(sw_interface_set_l2_xconnect, \
9121 "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
9122 "enable | disable") \
9123_(sw_interface_set_l2_bridge, \
Eyal Barif24991c2017-04-05 05:33:21 +03009124 "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n" \
Damjan Marion7cd468a2016-12-19 23:05:39 +01009125 "[shg <split-horizon-group>] [bvi]\n" \
9126 "enable | disable") \
Eyal Barif24991c2017-04-05 05:33:21 +03009127_(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01009128_(bridge_domain_add_del, \
John Lo70bfcaf2017-11-14 13:19:26 -05009129 "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [mac-age 0-255] [bd-tag <text>] [del]\n") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01009130_(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n") \
9131_(l2fib_add_del, \
9132 "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
Eyal Barif24991c2017-04-05 05:33:21 +03009133_(l2fib_flush_bd, "bd_id <bridge-domain-id>") \
9134_(l2fib_flush_int, "<intfc> | sw_if_index <id>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01009135_(l2_flags, \
John Lo8d00fff2017-08-03 00:35:36 -04009136 "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01009137_(bridge_flags, \
9138 "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
Mohsin Kazmi518251b2020-09-01 17:17:44 +00009139_(virtio_pci_create_v2, \
Mohsin Kazmie347acb2020-09-28 10:26:33 +00009140 "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled [gro-coalesce] | csum-offload-enabled] [packed] [in-order] [buffering]") \
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01009141_(virtio_pci_delete, \
9142 "<vpp-if-name> | sw_if_index <id>") \
9143_(sw_interface_virtio_pci_dump, "") \
Neale Ranns28ab9cc2017-08-14 07:18:42 -07009144_(ip_table_add_del, \
John Loe166fd92018-09-13 14:08:59 -04009145 "table <n> [ipv6] [add | del]\n") \
Neale Ranns097fa662018-05-01 05:17:55 -07009146_(ip_route_add_del, \
John Lo22030432018-09-20 16:07:00 -04009147 "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
9148 "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
John Lo06fda9c2018-10-03 16:32:44 -04009149 "[weight <n>] [drop] [local] [classify <n>] [out-label <n>]\n" \
9150 "[multipath] [count <n>] [del]") \
Neale Ranns32e1c012016-11-22 17:07:28 +00009151_(ip_mroute_add_del, \
9152 "<src> <grp>/<mask> [table-id <n>]\n" \
9153 "[<intfc> | sw_if_index <id>] [local] [del]") \
Neale Ranns28ab9cc2017-08-14 07:18:42 -07009154_(mpls_table_add_del, \
John Loe166fd92018-09-13 14:08:59 -04009155 "table <n> [add | del]\n") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01009156_(mpls_route_add_del, \
John Loe166fd92018-09-13 14:08:59 -04009157 "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n" \
9158 "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n" \
9159 "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n" \
9160 "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n" \
John Lo06fda9c2018-10-03 16:32:44 -04009161 "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n" \
9162 "[count <n>] [del]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01009163_(mpls_ip_bind_unbind, \
9164 "<label> <addr/len>") \
9165_(mpls_tunnel_add_del, \
John Lo06fda9c2018-10-03 16:32:44 -04009166 "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
9167 "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n" \
9168 "[l2-only] [out-label <n>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01009169_(sw_interface_set_unnumbered, \
9170 "<intfc> | sw_if_index <id> unnum_if_index <id> [del]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01009171_(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>") \
9172_(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n" \
9173 "[outer_vlan_id <n>][inner_vlan_id <n>]\n" \
9174 "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n" \
9175 "[outer_vlan_id_any][inner_vlan_id_any]") \
Neale Ranns9db6ada2019-11-08 12:42:31 +00009176_(ip_table_replace_begin, "table <n> [ipv6]") \
9177_(ip_table_flush, "table <n> [ipv6]") \
9178_(ip_table_replace_end, "table <n> [ipv6]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01009179_(set_ip_flow_hash, \
9180 "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]") \
9181_(sw_interface_ip6_enable_disable, \
9182 "<intfc> | sw_if_index <id> enable | disable") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01009183_(l2_patch_add_del, \
9184 "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
9185 "enable | disable") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01009186_(get_node_index, "node <node-name") \
9187_(add_node_next, "node <node-name> next <next-node-name>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01009188_(l2_fib_clear_table, "") \
9189_(l2_interface_efp_filter, "sw_if_index <nn> enable | disable") \
9190_(l2_interface_vlan_tag_rewrite, \
9191 "<intfc> | sw_if_index <nn> \n" \
9192 "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n" \
9193 "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01009194_(show_version, "") \
Mohsin Kazmi5d64c782018-09-11 20:27:09 +02009195_(show_threads, "") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01009196_(l2_fib_table_dump, "bd_id <bridge-domain-id>") \
9197_(interface_name_renumber, \
9198 "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>") \
John Lo8d00fff2017-08-03 00:35:36 -04009199_(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01009200_(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)") \
9201_(ip_dump, "ipv4 | ipv6") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01009202_(delete_loopback,"sw_if_index <nn>") \
9203_(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
John Loe26c81f2019-01-07 15:16:33 -05009204_(bd_ip_mac_flush, "bd_id <bridge-domain-id>") \
9205_(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01009206_(want_interface_events, "enable|disable") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01009207_(get_first_msg_id, "client <name>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01009208_(get_node_graph, " ") \
9209_(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>") \
9210_(ioam_enable, "[trace] [pow] [ppc <encap|decap>]") \
9211_(ioam_disable, "") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01009212_(mpls_tunnel_dump, "tunnel_index <tunnel-id>") \
Neale Ranns097fa662018-05-01 05:17:55 -07009213_(mpls_table_dump, "") \
9214_(mpls_route_dump, "table-id <ID>") \
Eyal Bari001fd402017-07-16 09:34:53 +03009215_(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
Eyal Bari5b311202017-07-31 13:12:30 +03009216_(sw_interface_span_dump, "[l2]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01009217_(get_next_index, "node-name <node-name> next-node-name <node-name>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01009218_(ip_source_and_port_range_check_add_del, \
9219 "<ip-addr>/<mask> range <nn>-<nn> vrf <id>") \
9220_(ip_source_and_port_range_check_interface_add_del, \
9221 "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]" \
9222 "[udp-in-vrf <id>] [udp-out-vrf <id>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01009223_(delete_subif,"<intfc> | sw_if_index <nn>") \
9224_(l2_interface_pbb_tag_rewrite, \
9225 "<intfc> | sw_if_index <nn> \n" \
9226 "[disable | push | pop | translate_pbb_stag <outer_tag>] \n" \
9227 "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]") \
Neale Ranns097fa662018-05-01 05:17:55 -07009228_(ip_table_dump, "") \
9229_(ip_route_dump, "table-id [ip4|ip6]") \
9230_(ip_mtable_dump, "") \
9231_(ip_mroute_dump, "table-id [ip4|ip6]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01009232_(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>" \
9233"[disable]") \
Matthew Smithe0792fd2019-07-12 11:48:24 -05009234_(sw_interface_add_del_mac_address, "<intfc> | sw_if_index <nn> " \
9235 "mac <mac-address> [del]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01009236_(l2_xconnect_dump, "") \
Ole Troand7231612018-06-07 10:17:57 +02009237_(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>") \
Pavel Kotucek6899a302017-06-08 08:46:10 +02009238_(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]") \
Dave Barach59b25652017-09-10 15:04:27 -04009239_(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]") \
Florin Coras90a63982017-12-19 04:50:01 -08009240_(sock_init_shm, "size <nnn>") \
Florin Corascea194d2017-10-02 00:18:51 -07009241_(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
Florin Coras1c710452017-10-17 00:03:13 -07009242_(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> " \
9243 "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>") \
Florin Coras6c36f532017-11-03 18:32:34 -07009244_(session_rules_dump, "") \
Florin Coras595992c2017-11-06 17:17:08 -08009245_(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01009246
9247/* List of command functions, CLI names map directly to functions */
9248#define foreach_cli_function \
9249_(comment, "usage: comment <ignore-rest-of-line>") \
9250_(dump_interface_table, "usage: dump_interface_table") \
9251_(dump_sub_interface_table, "usage: dump_sub_interface_table") \
9252_(dump_ipv4_table, "usage: dump_ipv4_table") \
9253_(dump_ipv6_table, "usage: dump_ipv6_table") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01009254_(dump_macro_table, "usage: dump_macro_table ") \
9255_(dump_node_table, "usage: dump_node_table") \
9256_(dump_msg_api_table, "usage: dump_msg_api_table") \
Dave Barachb09f4d02019-07-15 16:00:03 -04009257_(elog_setup, "usage: elog_setup [nevents, default 128K]") \
9258_(elog_disable, "usage: elog_disable") \
9259_(elog_enable, "usage: elog_enable") \
9260_(elog_save, "usage: elog_save <filename>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01009261_(get_msg_id, "usage: get_msg_id name_and_crc") \
9262_(echo, "usage: echo <message>") \
9263_(exec, "usage: exec <vpe-debug-CLI-command>") \
9264_(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>") \
9265_(help, "usage: help") \
9266_(q, "usage: quit") \
9267_(quit, "usage: quit") \
9268_(search_node_table, "usage: search_node_table <name>...") \
9269_(set, "usage: set <variable-name> <value>") \
9270_(script, "usage: script <file-name>") \
Neale Ranns097fa662018-05-01 05:17:55 -07009271_(statseg, "usage: statseg") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01009272_(unset, "usage: unset <variable-name>")
Dave Barach048a4e52018-06-01 18:52:25 -04009273
Damjan Marion7cd468a2016-12-19 23:05:39 +01009274#define _(N,n) \
9275 static void vl_api_##n##_t_handler_uni \
9276 (vl_api_##n##_t * mp) \
9277 { \
9278 vat_main_t * vam = &vat_main; \
9279 if (vam->json_output) { \
9280 vl_api_##n##_t_handler_json(mp); \
9281 } else { \
9282 vl_api_##n##_t_handler(mp); \
9283 } \
9284 }
9285foreach_vpe_api_reply_msg;
Dave Baracha1a093d2017-03-02 13:13:23 -05009286#if VPP_API_TEST_BUILTIN == 0
9287foreach_standalone_reply_msg;
9288#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +01009289#undef _
9290
9291void
9292vat_api_hookup (vat_main_t * vam)
9293{
9294#define _(N,n) \
9295 vl_msg_api_set_handlers(VL_API_##N, #n, \
9296 vl_api_##n##_t_handler_uni, \
9297 vl_noop_handler, \
9298 vl_api_##n##_t_endian, \
9299 vl_api_##n##_t_print, \
9300 sizeof(vl_api_##n##_t), 1);
9301 foreach_vpe_api_reply_msg;
Dave Baracha1a093d2017-03-02 13:13:23 -05009302#if VPP_API_TEST_BUILTIN == 0
9303 foreach_standalone_reply_msg;
9304#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +01009305#undef _
9306
9307#if (VPP_API_TEST_BUILTIN==0)
9308 vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009309
9310 vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
9311
9312 vam->function_by_name = hash_create_string (0, sizeof (uword));
9313
9314 vam->help_by_name = hash_create_string (0, sizeof (uword));
Dave Barach45e4f362017-03-07 12:52:31 -05009315#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +01009316
9317 /* API messages we can send */
9318#define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
9319 foreach_vpe_api_msg;
9320#undef _
9321
9322 /* Help strings */
9323#define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
9324 foreach_vpe_api_msg;
9325#undef _
Damjan Marion7cd468a2016-12-19 23:05:39 +01009326
9327 /* CLI functions */
9328#define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
9329 foreach_cli_function;
9330#undef _
9331
9332 /* Help strings */
9333#define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
9334 foreach_cli_function;
9335#undef _
9336}
9337
Dave Baracha1a093d2017-03-02 13:13:23 -05009338#if VPP_API_TEST_BUILTIN
9339static clib_error_t *
9340vat_api_hookup_shim (vlib_main_t * vm)
9341{
9342 vat_api_hookup (&vat_main);
9343 return 0;
9344}
9345
9346VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
9347#endif
9348
Damjan Marion7cd468a2016-12-19 23:05:39 +01009349/*
9350 * fd.io coding-style-patch-verification: ON
9351 *
9352 * Local Variables:
9353 * eval: (c-set-style "gnu")
9354 * End:
9355 */