blob: ec800b46abde4b39e629dd3805c0c4949723e984 [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_(ip_source_and_port_range_check_add_del_reply) \
1907_(ip_source_and_port_range_check_interface_add_del_reply)\
1908_(delete_subif_reply) \
1909_(l2_interface_pbb_tag_rewrite_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01001910_(sw_interface_tag_add_del_reply) \
Matthew Smithe0792fd2019-07-12 11:48:24 -05001911_(sw_interface_add_del_mac_address_reply) \
Ole Troand7231612018-06-07 10:17:57 +02001912_(hw_interface_set_mtu_reply) \
Florin Coras595992c2017-11-06 17:17:08 -08001913_(session_rule_add_del_reply) \
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +01001914_(ip_container_proxy_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01001915
1916#define _(n) \
1917 static void vl_api_##n##_t_handler \
1918 (vl_api_##n##_t * mp) \
1919 { \
1920 vat_main_t * vam = &vat_main; \
1921 i32 retval = ntohl(mp->retval); \
1922 if (vam->async_mode) { \
1923 vam->async_errors += (retval < 0); \
1924 } else { \
1925 vam->retval = retval; \
1926 vam->result_ready = 1; \
1927 } \
1928 }
1929foreach_standard_reply_retval_handler;
1930#undef _
1931
1932#define _(n) \
1933 static void vl_api_##n##_t_handler_json \
1934 (vl_api_##n##_t * mp) \
1935 { \
1936 vat_main_t * vam = &vat_main; \
1937 vat_json_node_t node; \
1938 vat_json_init_object(&node); \
1939 vat_json_object_add_int(&node, "retval", ntohl(mp->retval)); \
1940 vat_json_print(vam->ofp, &node); \
1941 vam->retval = ntohl(mp->retval); \
1942 vam->result_ready = 1; \
1943 }
1944foreach_standard_reply_retval_handler;
1945#undef _
1946
1947/*
1948 * Table of message reply handlers, must include boilerplate handlers
1949 * we just generated
1950 */
1951
1952#define foreach_vpe_api_reply_msg \
1953_(CREATE_LOOPBACK_REPLY, create_loopback_reply) \
Jon Loeligerc83c3b72017-02-23 13:57:35 -06001954_(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01001955_(SW_INTERFACE_DETAILS, sw_interface_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01001956_(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply) \
1957_(CONTROL_PING_REPLY, control_ping_reply) \
1958_(CLI_REPLY, cli_reply) \
1959_(CLI_INBAND_REPLY, cli_inband_reply) \
1960_(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY, \
1961 sw_interface_add_del_address_reply) \
Stevenad8015b2017-10-29 22:10:46 -07001962_(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply) \
Mohsin Kazmi54f7c512018-08-23 18:28:11 +02001963_(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply) \
Mohsin Kazmif0b42f42018-09-10 18:11:00 +02001964_(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01001965_(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply) \
1966_(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
1967_(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01001968_(SW_INTERFACE_SET_L2_XCONNECT_REPLY, \
1969 sw_interface_set_l2_xconnect_reply) \
1970_(SW_INTERFACE_SET_L2_BRIDGE_REPLY, \
1971 sw_interface_set_l2_bridge_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01001972_(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply) \
1973_(BRIDGE_DOMAIN_DETAILS, bridge_domain_details) \
Eyal Barifead6702017-04-04 04:46:32 +03001974_(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01001975_(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply) \
Eyal Barif24991c2017-04-05 05:33:21 +03001976_(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply) \
1977_(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01001978_(L2_FLAGS_REPLY, l2_flags_reply) \
1979_(BRIDGE_FLAGS_REPLY, bridge_flags_reply) \
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01001980_(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply) \
Mohsin Kazmi518251b2020-09-01 17:17:44 +00001981_(VIRTIO_PCI_CREATE_V2_REPLY, virtio_pci_create_v2_reply) \
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01001982_(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply) \
1983_(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details) \
Neale Ranns097fa662018-05-01 05:17:55 -07001984_(IP_ROUTE_ADD_DEL_REPLY, ip_route_add_del_reply) \
Neale Ranns28ab9cc2017-08-14 07:18:42 -07001985_(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply) \
Neale Ranns9db6ada2019-11-08 12:42:31 +00001986_(IP_TABLE_REPLACE_BEGIN_REPLY, ip_table_replace_begin_reply) \
1987_(IP_TABLE_FLUSH_REPLY, ip_table_flush_reply) \
1988_(IP_TABLE_REPLACE_END_REPLY, ip_table_replace_end_reply) \
Neale Ranns32e1c012016-11-22 17:07:28 +00001989_(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply) \
Neale Ranns28ab9cc2017-08-14 07:18:42 -07001990_(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01001991_(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply) \
1992_(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01001993_(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply) \
1994_(SW_INTERFACE_SET_UNNUMBERED_REPLY, \
1995 sw_interface_set_unnumbered_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01001996_(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply) \
1997_(CREATE_SUBIF_REPLY, create_subif_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01001998_(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply) \
1999_(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY, \
2000 sw_interface_ip6_enable_disable_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01002001_(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01002002_(GET_NODE_INDEX_REPLY, get_node_index_reply) \
2003_(ADD_NODE_NEXT_REPLY, add_node_next_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01002004_(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply) \
2005_(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply) \
2006_(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01002007_(SHOW_VERSION_REPLY, show_version_reply) \
Mohsin Kazmi5d64c782018-09-11 20:27:09 +02002008_(SHOW_THREADS_REPLY, show_threads_reply) \
Ole Troan01384fe2017-05-12 11:55:35 +02002009_(L2_FIB_TABLE_DETAILS, l2_fib_table_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01002010_(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply) \
John Lo8d00fff2017-08-03 00:35:36 -04002011_(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply) \
2012_(L2_MACS_EVENT, l2_macs_event) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01002013_(IP_ADDRESS_DETAILS, ip_address_details) \
2014_(IP_DETAILS, ip_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01002015_(DELETE_LOOPBACK_REPLY, delete_loopback_reply) \
2016_(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply) \
John Loe26c81f2019-01-07 15:16:33 -05002017_(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply) \
Mohsin Kazmi5d82d2f2018-08-13 19:17:54 +02002018_(BD_IP_MAC_DETAILS, bd_ip_mac_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01002019_(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01002020_(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01002021_(GET_NODE_GRAPH_REPLY, get_node_graph_reply) \
2022_(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply) \
2023_(IOAM_ENABLE_REPLY, ioam_enable_reply) \
2024_(IOAM_DISABLE_REPLY, ioam_disable_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01002025_(MPLS_TUNNEL_DETAILS, mpls_tunnel_details) \
Neale Ranns097fa662018-05-01 05:17:55 -07002026_(MPLS_TABLE_DETAILS, mpls_table_details) \
2027_(MPLS_ROUTE_DETAILS, mpls_route_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01002028_(GET_NEXT_INDEX_REPLY, get_next_index_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01002029_(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY, \
2030 ip_source_and_port_range_check_add_del_reply) \
2031_(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY, \
2032 ip_source_and_port_range_check_interface_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01002033_(DELETE_SUBIF_REPLY, delete_subif_reply) \
2034_(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
Neale Ranns097fa662018-05-01 05:17:55 -07002035_(IP_TABLE_DETAILS, ip_table_details) \
2036_(IP_ROUTE_DETAILS, ip_route_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01002037_(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply) \
Matthew Smithe0792fd2019-07-12 11:48:24 -05002038_(SW_INTERFACE_ADD_DEL_MAC_ADDRESS_REPLY, sw_interface_add_del_mac_address_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01002039_(L2_XCONNECT_DETAILS, l2_xconnect_details) \
Ole Troand7231612018-06-07 10:17:57 +02002040_(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply) \
Pavel Kotucek6899a302017-06-08 08:46:10 +02002041_(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply) \
Dave Barach65457162017-10-10 17:53:14 -04002042_(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply) \
Florin Coras6c36f532017-11-03 18:32:34 -07002043_(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply) \
Florin Coras595992c2017-11-06 17:17:08 -08002044_(SESSION_RULES_DETAILS, session_rules_details) \
2045_(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01002046
Dave Baracha1a093d2017-03-02 13:13:23 -05002047#define foreach_standalone_reply_msg \
Ole Troanf49ba0e2018-11-13 14:04:50 +01002048_(SW_INTERFACE_EVENT, sw_interface_event)
Dave Baracha1a093d2017-03-02 13:13:23 -05002049
Damjan Marion7cd468a2016-12-19 23:05:39 +01002050typedef struct
2051{
2052 u8 *name;
2053 u32 value;
2054} name_sort_t;
2055
Damjan Marion7cd468a2016-12-19 23:05:39 +01002056#define STR_VTR_OP_CASE(op) \
2057 case L2_VTR_ ## op: \
2058 return "" # op;
2059
2060static const char *
2061str_vtr_op (u32 vtr_op)
2062{
2063 switch (vtr_op)
2064 {
2065 STR_VTR_OP_CASE (DISABLED);
2066 STR_VTR_OP_CASE (PUSH_1);
2067 STR_VTR_OP_CASE (PUSH_2);
2068 STR_VTR_OP_CASE (POP_1);
2069 STR_VTR_OP_CASE (POP_2);
2070 STR_VTR_OP_CASE (TRANSLATE_1_1);
2071 STR_VTR_OP_CASE (TRANSLATE_1_2);
2072 STR_VTR_OP_CASE (TRANSLATE_2_1);
2073 STR_VTR_OP_CASE (TRANSLATE_2_2);
2074 }
2075
2076 return "UNKNOWN";
2077}
2078
2079static int
2080dump_sub_interface_table (vat_main_t * vam)
2081{
2082 const sw_interface_subif_t *sub = NULL;
2083
2084 if (vam->json_output)
2085 {
2086 clib_warning
2087 ("JSON output supported only for VPE API calls and dump_stats_table");
2088 return -99;
2089 }
2090
2091 print (vam->ofp,
2092 "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
2093 "Interface", "sw_if_index",
2094 "sub id", "dot1ad", "tags", "outer id",
2095 "inner id", "exact", "default", "outer any", "inner any");
2096
2097 vec_foreach (sub, vam->sw_if_subif_table)
2098 {
2099 print (vam->ofp,
2100 "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
2101 sub->interface_name,
2102 sub->sw_if_index,
2103 sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
2104 sub->sub_number_of_tags, sub->sub_outer_vlan_id,
2105 sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
2106 sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
2107 if (sub->vtr_op != L2_VTR_DISABLED)
2108 {
2109 print (vam->ofp,
2110 " vlan-tag-rewrite - op: %-14s [ dot1q: %d "
2111 "tag1: %d tag2: %d ]",
2112 str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
2113 sub->vtr_tag1, sub->vtr_tag2);
2114 }
2115 }
2116
2117 return 0;
2118}
2119
2120static int
2121name_sort_cmp (void *a1, void *a2)
2122{
2123 name_sort_t *n1 = a1;
2124 name_sort_t *n2 = a2;
2125
2126 return strcmp ((char *) n1->name, (char *) n2->name);
2127}
2128
2129static int
2130dump_interface_table (vat_main_t * vam)
2131{
2132 hash_pair_t *p;
2133 name_sort_t *nses = 0, *ns;
2134
2135 if (vam->json_output)
2136 {
2137 clib_warning
2138 ("JSON output supported only for VPE API calls and dump_stats_table");
2139 return -99;
2140 }
2141
2142 /* *INDENT-OFF* */
2143 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
2144 ({
2145 vec_add2 (nses, ns, 1);
2146 ns->name = (u8 *)(p->key);
2147 ns->value = (u32) p->value[0];
2148 }));
2149 /* *INDENT-ON* */
2150
2151 vec_sort_with_function (nses, name_sort_cmp);
2152
2153 print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
2154 vec_foreach (ns, nses)
2155 {
2156 print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
2157 }
2158 vec_free (nses);
2159 return 0;
2160}
2161
2162static int
2163dump_ip_table (vat_main_t * vam, int is_ipv6)
2164{
2165 const ip_details_t *det = NULL;
2166 const ip_address_details_t *address = NULL;
2167 u32 i = ~0;
2168
2169 print (vam->ofp, "%-12s", "sw_if_index");
2170
2171 vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
2172 {
2173 i++;
2174 if (!det->present)
2175 {
2176 continue;
2177 }
2178 print (vam->ofp, "%-12d", i);
2179 print (vam->ofp, " %-30s%-13s", "Address", "Prefix length");
2180 if (!det->addr)
2181 {
2182 continue;
2183 }
2184 vec_foreach (address, det->addr)
2185 {
2186 print (vam->ofp,
2187 " %-30U%-13d",
2188 is_ipv6 ? format_ip6_address : format_ip4_address,
2189 address->ip, address->prefix_length);
2190 }
2191 }
2192
2193 return 0;
2194}
2195
2196static int
2197dump_ipv4_table (vat_main_t * vam)
2198{
2199 if (vam->json_output)
2200 {
2201 clib_warning
2202 ("JSON output supported only for VPE API calls and dump_stats_table");
2203 return -99;
2204 }
2205
2206 return dump_ip_table (vam, 0);
2207}
2208
2209static int
2210dump_ipv6_table (vat_main_t * vam)
2211{
2212 if (vam->json_output)
2213 {
2214 clib_warning
2215 ("JSON output supported only for VPE API calls and dump_stats_table");
2216 return -99;
2217 }
2218
2219 return dump_ip_table (vam, 1);
2220}
2221
Damjan Marion7cd468a2016-12-19 23:05:39 +01002222/*
Dave Barach59b25652017-09-10 15:04:27 -04002223 * Pass CLI buffers directly in the CLI_INBAND API message,
2224 * instead of an additional shared memory area.
Damjan Marion7cd468a2016-12-19 23:05:39 +01002225 */
2226static int
2227exec_inband (vat_main_t * vam)
2228{
2229 vl_api_cli_inband_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002230 unformat_input_t *i = vam->input;
Jon Loeliger56c7b012017-02-01 12:31:41 -06002231 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002232
2233 if (vec_len (i->buffer) == 0)
2234 return -1;
2235
2236 if (vam->exec_mode == 0 && unformat (i, "mode"))
2237 {
2238 vam->exec_mode = 1;
2239 return 0;
2240 }
2241 if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
2242 {
2243 vam->exec_mode = 0;
2244 return 0;
2245 }
2246
2247 /*
2248 * In order for the CLI command to work, it
2249 * must be a vector ending in \n, not a C-string ending
2250 * in \n\0.
2251 */
Jakub Grajciar2dbee932020-02-07 11:30:26 +01002252 M2 (CLI_INBAND, mp, vec_len (vam->input->buffer));
2253 vl_api_vec_to_api_string (vam->input->buffer, &mp->cmd);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002254
Jon Loeliger7bc770c2017-01-31 14:03:33 -06002255 S (mp);
Dave Barach59b25652017-09-10 15:04:27 -04002256 W (ret);
2257 /* json responses may or may not include a useful reply... */
2258 if (vec_len (vam->cmd_reply))
Dave Barachcf5e8482017-10-17 11:48:29 -04002259 print (vam->ofp, "%v", (char *) (vam->cmd_reply));
Jon Loeliger56c7b012017-02-01 12:31:41 -06002260 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002261}
2262
Dave Barach59b25652017-09-10 15:04:27 -04002263int
2264exec (vat_main_t * vam)
2265{
2266 return exec_inband (vam);
2267}
2268
Damjan Marion7cd468a2016-12-19 23:05:39 +01002269static int
2270api_create_loopback (vat_main_t * vam)
2271{
2272 unformat_input_t *i = vam->input;
2273 vl_api_create_loopback_t *mp;
Jon Loeligerc83c3b72017-02-23 13:57:35 -06002274 vl_api_create_loopback_instance_t *mp_lbi;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002275 u8 mac_address[6];
2276 u8 mac_set = 0;
Jon Loeligerc83c3b72017-02-23 13:57:35 -06002277 u8 is_specified = 0;
2278 u32 user_instance = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06002279 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002280
Dave Barachb7b92992018-10-17 10:38:51 -04002281 clib_memset (mac_address, 0, sizeof (mac_address));
Damjan Marion7cd468a2016-12-19 23:05:39 +01002282
2283 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2284 {
2285 if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
2286 mac_set = 1;
Jon Loeligerc83c3b72017-02-23 13:57:35 -06002287 if (unformat (i, "instance %d", &user_instance))
2288 is_specified = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002289 else
2290 break;
2291 }
2292
Jon Loeligerc83c3b72017-02-23 13:57:35 -06002293 if (is_specified)
2294 {
2295 M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
2296 mp_lbi->is_specified = is_specified;
2297 if (is_specified)
2298 mp_lbi->user_instance = htonl (user_instance);
2299 if (mac_set)
2300 clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
2301 S (mp_lbi);
2302 }
2303 else
2304 {
2305 /* Construct the API message */
2306 M (CREATE_LOOPBACK, mp);
2307 if (mac_set)
2308 clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
2309 S (mp);
2310 }
Damjan Marion7cd468a2016-12-19 23:05:39 +01002311
Jon Loeliger56c7b012017-02-01 12:31:41 -06002312 W (ret);
2313 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002314}
2315
2316static int
2317api_delete_loopback (vat_main_t * vam)
2318{
2319 unformat_input_t *i = vam->input;
2320 vl_api_delete_loopback_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002321 u32 sw_if_index = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06002322 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002323
2324 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2325 {
2326 if (unformat (i, "sw_if_index %d", &sw_if_index))
2327 ;
2328 else
2329 break;
2330 }
2331
2332 if (sw_if_index == ~0)
2333 {
2334 errmsg ("missing sw_if_index");
2335 return -99;
2336 }
2337
2338 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06002339 M (DELETE_LOOPBACK, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002340 mp->sw_if_index = ntohl (sw_if_index);
2341
Jon Loeliger7bc770c2017-01-31 14:03:33 -06002342 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06002343 W (ret);
2344 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002345}
2346
2347static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01002348api_want_interface_events (vat_main_t * vam)
2349{
2350 unformat_input_t *i = vam->input;
2351 vl_api_want_interface_events_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002352 int enable = -1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06002353 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002354
2355 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2356 {
2357 if (unformat (i, "enable"))
2358 enable = 1;
2359 else if (unformat (i, "disable"))
2360 enable = 0;
2361 else
2362 break;
2363 }
2364
2365 if (enable == -1)
2366 {
2367 errmsg ("missing enable|disable");
2368 return -99;
2369 }
2370
Jon Loeliger8a2aea32017-01-31 13:19:40 -06002371 M (WANT_INTERFACE_EVENTS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002372 mp->enable_disable = enable;
2373
2374 vam->interface_event_display = enable;
2375
Jon Loeliger7bc770c2017-01-31 14:03:33 -06002376 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06002377 W (ret);
2378 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002379}
2380
2381
2382/* Note: non-static, called once to set up the initial intfc table */
2383int
2384api_sw_interface_dump (vat_main_t * vam)
2385{
2386 vl_api_sw_interface_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -06002387 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002388 hash_pair_t *p;
2389 name_sort_t *nses = 0, *ns;
2390 sw_interface_subif_t *sub = NULL;
Jon Loeliger56c7b012017-02-01 12:31:41 -06002391 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002392
2393 /* Toss the old name table */
2394 /* *INDENT-OFF* */
2395 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
2396 ({
2397 vec_add2 (nses, ns, 1);
2398 ns->name = (u8 *)(p->key);
2399 ns->value = (u32) p->value[0];
2400 }));
2401 /* *INDENT-ON* */
2402
2403 hash_free (vam->sw_if_index_by_interface_name);
2404
2405 vec_foreach (ns, nses) vec_free (ns->name);
2406
2407 vec_free (nses);
2408
2409 vec_foreach (sub, vam->sw_if_subif_table)
2410 {
2411 vec_free (sub->interface_name);
2412 }
2413 vec_free (vam->sw_if_subif_table);
2414
2415 /* recreate the interface name hash table */
2416 vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
2417
Dave Barachf72212e2018-01-11 10:25:07 -05002418 /*
2419 * Ask for all interface names. Otherwise, the epic catalog of
2420 * name filters becomes ridiculously long, and vat ends up needing
2421 * to be taught about new interface types.
2422 */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06002423 M (SW_INTERFACE_DUMP, mp);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06002424 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002425
2426 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -04002427 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06002428 S (mp_ping);
2429
Jon Loeliger56c7b012017-02-01 12:31:41 -06002430 W (ret);
2431 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002432}
2433
2434static int
2435api_sw_interface_set_flags (vat_main_t * vam)
2436{
2437 unformat_input_t *i = vam->input;
2438 vl_api_sw_interface_set_flags_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002439 u32 sw_if_index;
2440 u8 sw_if_index_set = 0;
Neale Rannsa07bd702017-08-07 07:53:49 -07002441 u8 admin_up = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06002442 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002443
2444 /* Parse args required to build the message */
2445 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2446 {
2447 if (unformat (i, "admin-up"))
2448 admin_up = 1;
2449 else if (unformat (i, "admin-down"))
2450 admin_up = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002451 else
2452 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2453 sw_if_index_set = 1;
2454 else if (unformat (i, "sw_if_index %d", &sw_if_index))
2455 sw_if_index_set = 1;
2456 else
2457 break;
2458 }
2459
2460 if (sw_if_index_set == 0)
2461 {
2462 errmsg ("missing interface name or sw_if_index");
2463 return -99;
2464 }
2465
2466 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06002467 M (SW_INTERFACE_SET_FLAGS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002468 mp->sw_if_index = ntohl (sw_if_index);
Jakub Grajciar053204a2019-03-18 13:17:53 +01002469 mp->flags = ntohl ((admin_up) ? IF_STATUS_API_FLAG_ADMIN_UP : 0);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002470
2471 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06002472 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002473
2474 /* Wait for a reply, return the good/bad news... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06002475 W (ret);
2476 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002477}
2478
2479static int
Stevenad8015b2017-10-29 22:10:46 -07002480api_sw_interface_set_rx_mode (vat_main_t * vam)
2481{
2482 unformat_input_t *i = vam->input;
2483 vl_api_sw_interface_set_rx_mode_t *mp;
2484 u32 sw_if_index;
2485 u8 sw_if_index_set = 0;
2486 int ret;
2487 u8 queue_id_valid = 0;
2488 u32 queue_id;
Damjan Marioneabd4242020-10-07 20:59:07 +02002489 vnet_hw_if_rx_mode mode = VNET_HW_IF_RX_MODE_UNKNOWN;
Stevenad8015b2017-10-29 22:10:46 -07002490
2491 /* Parse args required to build the message */
2492 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2493 {
2494 if (unformat (i, "queue %d", &queue_id))
2495 queue_id_valid = 1;
2496 else if (unformat (i, "polling"))
Damjan Marioneabd4242020-10-07 20:59:07 +02002497 mode = VNET_HW_IF_RX_MODE_POLLING;
Stevenad8015b2017-10-29 22:10:46 -07002498 else if (unformat (i, "interrupt"))
Damjan Marioneabd4242020-10-07 20:59:07 +02002499 mode = VNET_HW_IF_RX_MODE_INTERRUPT;
Stevenad8015b2017-10-29 22:10:46 -07002500 else if (unformat (i, "adaptive"))
Damjan Marioneabd4242020-10-07 20:59:07 +02002501 mode = VNET_HW_IF_RX_MODE_ADAPTIVE;
Stevenad8015b2017-10-29 22:10:46 -07002502 else
2503 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2504 sw_if_index_set = 1;
2505 else if (unformat (i, "sw_if_index %d", &sw_if_index))
2506 sw_if_index_set = 1;
2507 else
2508 break;
2509 }
2510
2511 if (sw_if_index_set == 0)
2512 {
2513 errmsg ("missing interface name or sw_if_index");
2514 return -99;
2515 }
Damjan Marioneabd4242020-10-07 20:59:07 +02002516 if (mode == VNET_HW_IF_RX_MODE_UNKNOWN)
Stevenad8015b2017-10-29 22:10:46 -07002517 {
2518 errmsg ("missing rx-mode");
2519 return -99;
2520 }
2521
2522 /* Construct the API message */
2523 M (SW_INTERFACE_SET_RX_MODE, mp);
2524 mp->sw_if_index = ntohl (sw_if_index);
Jakub Grajciar053204a2019-03-18 13:17:53 +01002525 mp->mode = (vl_api_rx_mode_t) mode;
Stevenad8015b2017-10-29 22:10:46 -07002526 mp->queue_id_valid = queue_id_valid;
2527 mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
2528
2529 /* send it... */
2530 S (mp);
2531
2532 /* Wait for a reply, return the good/bad news... */
2533 W (ret);
2534 return ret;
2535}
2536
2537static int
Mohsin Kazmi54f7c512018-08-23 18:28:11 +02002538api_sw_interface_set_rx_placement (vat_main_t * vam)
2539{
2540 unformat_input_t *i = vam->input;
2541 vl_api_sw_interface_set_rx_placement_t *mp;
2542 u32 sw_if_index;
2543 u8 sw_if_index_set = 0;
2544 int ret;
2545 u8 is_main = 0;
2546 u32 queue_id, thread_index;
2547
2548 /* Parse args required to build the message */
2549 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2550 {
2551 if (unformat (i, "queue %d", &queue_id))
2552 ;
2553 else if (unformat (i, "main"))
2554 is_main = 1;
2555 else if (unformat (i, "worker %d", &thread_index))
2556 ;
2557 else
2558 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2559 sw_if_index_set = 1;
2560 else if (unformat (i, "sw_if_index %d", &sw_if_index))
2561 sw_if_index_set = 1;
2562 else
2563 break;
2564 }
2565
2566 if (sw_if_index_set == 0)
2567 {
2568 errmsg ("missing interface name or sw_if_index");
2569 return -99;
2570 }
2571
2572 if (is_main)
2573 thread_index = 0;
2574 /* Construct the API message */
2575 M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
2576 mp->sw_if_index = ntohl (sw_if_index);
2577 mp->worker_id = ntohl (thread_index);
2578 mp->queue_id = ntohl (queue_id);
2579 mp->is_main = is_main;
2580
2581 /* send it... */
2582 S (mp);
2583 /* Wait for a reply, return the good/bad news... */
2584 W (ret);
2585 return ret;
2586}
2587
Mohsin Kazmif0b42f42018-09-10 18:11:00 +02002588static void vl_api_sw_interface_rx_placement_details_t_handler
2589 (vl_api_sw_interface_rx_placement_details_t * mp)
2590{
2591 vat_main_t *vam = &vat_main;
2592 u32 worker_id = ntohl (mp->worker_id);
2593
2594 print (vam->ofp,
2595 "\n%-11d %-11s %-6d %-5d %-9s",
2596 ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
2597 worker_id, ntohl (mp->queue_id),
2598 (mp->mode ==
2599 1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
2600}
2601
2602static void vl_api_sw_interface_rx_placement_details_t_handler_json
2603 (vl_api_sw_interface_rx_placement_details_t * mp)
2604{
2605 vat_main_t *vam = &vat_main;
2606 vat_json_node_t *node = NULL;
2607
2608 if (VAT_JSON_ARRAY != vam->json_tree.type)
2609 {
2610 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2611 vat_json_init_array (&vam->json_tree);
2612 }
2613 node = vat_json_array_add (&vam->json_tree);
2614
2615 vat_json_init_object (node);
2616 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2617 vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
2618 vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
2619 vat_json_object_add_uint (node, "mode", mp->mode);
2620}
2621
2622static int
2623api_sw_interface_rx_placement_dump (vat_main_t * vam)
2624{
2625 unformat_input_t *i = vam->input;
2626 vl_api_sw_interface_rx_placement_dump_t *mp;
2627 vl_api_control_ping_t *mp_ping;
2628 int ret;
2629 u32 sw_if_index;
2630 u8 sw_if_index_set = 0;
2631
2632 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2633 {
2634 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2635 sw_if_index_set++;
2636 else if (unformat (i, "sw_if_index %d", &sw_if_index))
2637 sw_if_index_set++;
2638 else
2639 break;
2640 }
2641
2642 print (vam->ofp,
2643 "\n%-11s %-11s %-6s %-5s %-4s",
2644 "sw_if_index", "main/worker", "thread", "queue", "mode");
2645
2646 /* Dump Interface rx placement */
2647 M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
2648
2649 if (sw_if_index_set)
2650 mp->sw_if_index = htonl (sw_if_index);
2651 else
2652 mp->sw_if_index = ~0;
2653
2654 S (mp);
2655
2656 /* Use a control ping for synchronization */
2657 MPING (CONTROL_PING, mp_ping);
2658 S (mp_ping);
2659
2660 W (ret);
2661 return ret;
2662}
2663
Mohsin Kazmi54f7c512018-08-23 18:28:11 +02002664static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01002665api_sw_interface_clear_stats (vat_main_t * vam)
2666{
2667 unformat_input_t *i = vam->input;
2668 vl_api_sw_interface_clear_stats_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002669 u32 sw_if_index;
2670 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06002671 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002672
2673 /* Parse args required to build the message */
2674 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2675 {
2676 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2677 sw_if_index_set = 1;
2678 else if (unformat (i, "sw_if_index %d", &sw_if_index))
2679 sw_if_index_set = 1;
2680 else
2681 break;
2682 }
2683
2684 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06002685 M (SW_INTERFACE_CLEAR_STATS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002686
2687 if (sw_if_index_set == 1)
2688 mp->sw_if_index = ntohl (sw_if_index);
2689 else
2690 mp->sw_if_index = ~0;
2691
2692 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06002693 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002694
2695 /* Wait for a reply, return the good/bad news... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06002696 W (ret);
2697 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002698}
2699
Damjan Marion7cd468a2016-12-19 23:05:39 +01002700static int
2701api_sw_interface_add_del_address (vat_main_t * vam)
2702{
2703 unformat_input_t *i = vam->input;
2704 vl_api_sw_interface_add_del_address_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002705 u32 sw_if_index;
2706 u8 sw_if_index_set = 0;
2707 u8 is_add = 1, del_all = 0;
2708 u32 address_length = 0;
2709 u8 v4_address_set = 0;
2710 u8 v6_address_set = 0;
2711 ip4_address_t v4address;
2712 ip6_address_t v6address;
Jon Loeliger56c7b012017-02-01 12:31:41 -06002713 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002714
2715 /* Parse args required to build the message */
2716 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2717 {
2718 if (unformat (i, "del-all"))
2719 del_all = 1;
2720 else if (unformat (i, "del"))
2721 is_add = 0;
2722 else
2723 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2724 sw_if_index_set = 1;
2725 else if (unformat (i, "sw_if_index %d", &sw_if_index))
2726 sw_if_index_set = 1;
2727 else if (unformat (i, "%U/%d",
2728 unformat_ip4_address, &v4address, &address_length))
2729 v4_address_set = 1;
2730 else if (unformat (i, "%U/%d",
2731 unformat_ip6_address, &v6address, &address_length))
2732 v6_address_set = 1;
2733 else
2734 break;
2735 }
2736
2737 if (sw_if_index_set == 0)
2738 {
2739 errmsg ("missing interface name or sw_if_index");
2740 return -99;
2741 }
2742 if (v4_address_set && v6_address_set)
2743 {
2744 errmsg ("both v4 and v6 addresses set");
2745 return -99;
2746 }
2747 if (!v4_address_set && !v6_address_set && !del_all)
2748 {
2749 errmsg ("no addresses set");
2750 return -99;
2751 }
2752
2753 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06002754 M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002755
2756 mp->sw_if_index = ntohl (sw_if_index);
2757 mp->is_add = is_add;
2758 mp->del_all = del_all;
2759 if (v6_address_set)
2760 {
Jakub Grajciar053204a2019-03-18 13:17:53 +01002761 mp->prefix.address.af = ADDRESS_IP6;
2762 clib_memcpy (mp->prefix.address.un.ip6, &v6address, sizeof (v6address));
Damjan Marion7cd468a2016-12-19 23:05:39 +01002763 }
2764 else
2765 {
Jakub Grajciar053204a2019-03-18 13:17:53 +01002766 mp->prefix.address.af = ADDRESS_IP4;
2767 clib_memcpy (mp->prefix.address.un.ip4, &v4address, sizeof (v4address));
Damjan Marion7cd468a2016-12-19 23:05:39 +01002768 }
Jakub Grajciar053204a2019-03-18 13:17:53 +01002769 mp->prefix.len = address_length;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002770
2771 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06002772 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002773
2774 /* Wait for a reply, return good/bad news */
Jon Loeliger56c7b012017-02-01 12:31:41 -06002775 W (ret);
2776 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002777}
2778
2779static int
2780api_sw_interface_set_mpls_enable (vat_main_t * vam)
2781{
2782 unformat_input_t *i = vam->input;
2783 vl_api_sw_interface_set_mpls_enable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002784 u32 sw_if_index;
2785 u8 sw_if_index_set = 0;
2786 u8 enable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06002787 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002788
2789 /* Parse args required to build the message */
2790 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2791 {
2792 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2793 sw_if_index_set = 1;
2794 else if (unformat (i, "sw_if_index %d", &sw_if_index))
2795 sw_if_index_set = 1;
2796 else if (unformat (i, "disable"))
2797 enable = 0;
2798 else if (unformat (i, "dis"))
2799 enable = 0;
2800 else
2801 break;
2802 }
2803
2804 if (sw_if_index_set == 0)
2805 {
2806 errmsg ("missing interface name or sw_if_index");
2807 return -99;
2808 }
2809
2810 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06002811 M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002812
2813 mp->sw_if_index = ntohl (sw_if_index);
2814 mp->enable = enable;
2815
2816 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06002817 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002818
2819 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06002820 W (ret);
2821 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002822}
2823
2824static int
2825api_sw_interface_set_table (vat_main_t * vam)
2826{
2827 unformat_input_t *i = vam->input;
2828 vl_api_sw_interface_set_table_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002829 u32 sw_if_index, vrf_id = 0;
2830 u8 sw_if_index_set = 0;
2831 u8 is_ipv6 = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06002832 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002833
2834 /* Parse args required to build the message */
2835 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2836 {
2837 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2838 sw_if_index_set = 1;
2839 else if (unformat (i, "sw_if_index %d", &sw_if_index))
2840 sw_if_index_set = 1;
2841 else if (unformat (i, "vrf %d", &vrf_id))
2842 ;
2843 else if (unformat (i, "ipv6"))
2844 is_ipv6 = 1;
2845 else
2846 break;
2847 }
2848
2849 if (sw_if_index_set == 0)
2850 {
2851 errmsg ("missing interface name or sw_if_index");
2852 return -99;
2853 }
2854
2855 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06002856 M (SW_INTERFACE_SET_TABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002857
2858 mp->sw_if_index = ntohl (sw_if_index);
2859 mp->is_ipv6 = is_ipv6;
2860 mp->vrf_id = ntohl (vrf_id);
2861
2862 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06002863 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002864
2865 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06002866 W (ret);
2867 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002868}
2869
2870static void vl_api_sw_interface_get_table_reply_t_handler
2871 (vl_api_sw_interface_get_table_reply_t * mp)
2872{
2873 vat_main_t *vam = &vat_main;
2874
2875 print (vam->ofp, "%d", ntohl (mp->vrf_id));
2876
2877 vam->retval = ntohl (mp->retval);
2878 vam->result_ready = 1;
2879
2880}
2881
2882static void vl_api_sw_interface_get_table_reply_t_handler_json
2883 (vl_api_sw_interface_get_table_reply_t * mp)
2884{
2885 vat_main_t *vam = &vat_main;
2886 vat_json_node_t node;
2887
2888 vat_json_init_object (&node);
2889 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2890 vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
2891
2892 vat_json_print (vam->ofp, &node);
2893 vat_json_free (&node);
2894
2895 vam->retval = ntohl (mp->retval);
2896 vam->result_ready = 1;
2897}
2898
2899static int
2900api_sw_interface_get_table (vat_main_t * vam)
2901{
2902 unformat_input_t *i = vam->input;
2903 vl_api_sw_interface_get_table_t *mp;
2904 u32 sw_if_index;
2905 u8 sw_if_index_set = 0;
2906 u8 is_ipv6 = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06002907 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002908
2909 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2910 {
2911 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2912 sw_if_index_set = 1;
2913 else if (unformat (i, "sw_if_index %d", &sw_if_index))
2914 sw_if_index_set = 1;
2915 else if (unformat (i, "ipv6"))
2916 is_ipv6 = 1;
2917 else
2918 break;
2919 }
2920
2921 if (sw_if_index_set == 0)
2922 {
2923 errmsg ("missing interface name or sw_if_index");
2924 return -99;
2925 }
2926
Jon Loeliger8a2aea32017-01-31 13:19:40 -06002927 M (SW_INTERFACE_GET_TABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002928 mp->sw_if_index = htonl (sw_if_index);
2929 mp->is_ipv6 = is_ipv6;
2930
Jon Loeliger7bc770c2017-01-31 14:03:33 -06002931 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06002932 W (ret);
2933 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002934}
2935
2936static int
2937api_sw_interface_set_vpath (vat_main_t * vam)
2938{
2939 unformat_input_t *i = vam->input;
2940 vl_api_sw_interface_set_vpath_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002941 u32 sw_if_index = 0;
2942 u8 sw_if_index_set = 0;
2943 u8 is_enable = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06002944 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002945
2946 /* Parse args required to build the message */
2947 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2948 {
2949 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2950 sw_if_index_set = 1;
2951 else if (unformat (i, "sw_if_index %d", &sw_if_index))
2952 sw_if_index_set = 1;
2953 else if (unformat (i, "enable"))
2954 is_enable = 1;
2955 else if (unformat (i, "disable"))
2956 is_enable = 0;
2957 else
2958 break;
2959 }
2960
2961 if (sw_if_index_set == 0)
2962 {
2963 errmsg ("missing interface name or sw_if_index");
2964 return -99;
2965 }
2966
2967 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06002968 M (SW_INTERFACE_SET_VPATH, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002969
2970 mp->sw_if_index = ntohl (sw_if_index);
2971 mp->enable = is_enable;
2972
2973 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06002974 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002975
2976 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06002977 W (ret);
2978 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002979}
2980
2981static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01002982api_sw_interface_set_l2_xconnect (vat_main_t * vam)
2983{
2984 unformat_input_t *i = vam->input;
2985 vl_api_sw_interface_set_l2_xconnect_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002986 u32 rx_sw_if_index;
2987 u8 rx_sw_if_index_set = 0;
2988 u32 tx_sw_if_index;
2989 u8 tx_sw_if_index_set = 0;
2990 u8 enable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06002991 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002992
2993 /* Parse args required to build the message */
2994 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2995 {
2996 if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
2997 rx_sw_if_index_set = 1;
2998 else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
2999 tx_sw_if_index_set = 1;
3000 else if (unformat (i, "rx"))
3001 {
3002 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3003 {
3004 if (unformat (i, "%U", api_unformat_sw_if_index, vam,
3005 &rx_sw_if_index))
3006 rx_sw_if_index_set = 1;
3007 }
3008 else
3009 break;
3010 }
3011 else if (unformat (i, "tx"))
3012 {
3013 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3014 {
3015 if (unformat (i, "%U", api_unformat_sw_if_index, vam,
3016 &tx_sw_if_index))
3017 tx_sw_if_index_set = 1;
3018 }
3019 else
3020 break;
3021 }
3022 else if (unformat (i, "enable"))
3023 enable = 1;
3024 else if (unformat (i, "disable"))
3025 enable = 0;
3026 else
3027 break;
3028 }
3029
3030 if (rx_sw_if_index_set == 0)
3031 {
3032 errmsg ("missing rx interface name or rx_sw_if_index");
3033 return -99;
3034 }
3035
3036 if (enable && (tx_sw_if_index_set == 0))
3037 {
3038 errmsg ("missing tx interface name or tx_sw_if_index");
3039 return -99;
3040 }
3041
Jon Loeliger8a2aea32017-01-31 13:19:40 -06003042 M (SW_INTERFACE_SET_L2_XCONNECT, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003043
3044 mp->rx_sw_if_index = ntohl (rx_sw_if_index);
3045 mp->tx_sw_if_index = ntohl (tx_sw_if_index);
3046 mp->enable = enable;
3047
Jon Loeliger7bc770c2017-01-31 14:03:33 -06003048 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06003049 W (ret);
3050 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003051}
3052
3053static int
3054api_sw_interface_set_l2_bridge (vat_main_t * vam)
3055{
3056 unformat_input_t *i = vam->input;
3057 vl_api_sw_interface_set_l2_bridge_t *mp;
Neale Rannsb4743802018-09-05 09:13:57 -07003058 vl_api_l2_port_type_t port_type;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003059 u32 rx_sw_if_index;
3060 u8 rx_sw_if_index_set = 0;
3061 u32 bd_id;
3062 u8 bd_id_set = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003063 u32 shg = 0;
3064 u8 enable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06003065 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003066
Neale Rannsb4743802018-09-05 09:13:57 -07003067 port_type = L2_API_PORT_TYPE_NORMAL;
3068
Damjan Marion7cd468a2016-12-19 23:05:39 +01003069 /* Parse args required to build the message */
3070 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3071 {
3072 if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
3073 rx_sw_if_index_set = 1;
3074 else if (unformat (i, "bd_id %d", &bd_id))
3075 bd_id_set = 1;
3076 else
3077 if (unformat
3078 (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
3079 rx_sw_if_index_set = 1;
3080 else if (unformat (i, "shg %d", &shg))
3081 ;
3082 else if (unformat (i, "bvi"))
Neale Rannsb4743802018-09-05 09:13:57 -07003083 port_type = L2_API_PORT_TYPE_BVI;
3084 else if (unformat (i, "uu-fwd"))
3085 port_type = L2_API_PORT_TYPE_UU_FWD;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003086 else if (unformat (i, "enable"))
3087 enable = 1;
3088 else if (unformat (i, "disable"))
3089 enable = 0;
3090 else
3091 break;
3092 }
3093
3094 if (rx_sw_if_index_set == 0)
3095 {
3096 errmsg ("missing rx interface name or sw_if_index");
3097 return -99;
3098 }
3099
3100 if (enable && (bd_id_set == 0))
3101 {
3102 errmsg ("missing bridge domain");
3103 return -99;
3104 }
3105
Jon Loeliger8a2aea32017-01-31 13:19:40 -06003106 M (SW_INTERFACE_SET_L2_BRIDGE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003107
3108 mp->rx_sw_if_index = ntohl (rx_sw_if_index);
3109 mp->bd_id = ntohl (bd_id);
3110 mp->shg = (u8) shg;
Neale Rannsb4743802018-09-05 09:13:57 -07003111 mp->port_type = ntohl (port_type);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003112 mp->enable = enable;
3113
Jon Loeliger7bc770c2017-01-31 14:03:33 -06003114 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06003115 W (ret);
3116 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003117}
3118
3119static int
3120api_bridge_domain_dump (vat_main_t * vam)
3121{
3122 unformat_input_t *i = vam->input;
3123 vl_api_bridge_domain_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -06003124 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003125 u32 bd_id = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06003126 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003127
3128 /* Parse args required to build the message */
3129 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3130 {
3131 if (unformat (i, "bd_id %d", &bd_id))
3132 ;
3133 else
3134 break;
3135 }
3136
Jon Loeliger8a2aea32017-01-31 13:19:40 -06003137 M (BRIDGE_DOMAIN_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003138 mp->bd_id = ntohl (bd_id);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06003139 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003140
3141 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -04003142 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06003143 S (mp_ping);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003144
Jon Loeliger56c7b012017-02-01 12:31:41 -06003145 W (ret);
3146 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003147}
3148
3149static int
3150api_bridge_domain_add_del (vat_main_t * vam)
3151{
3152 unformat_input_t *i = vam->input;
3153 vl_api_bridge_domain_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003154 u32 bd_id = ~0;
3155 u8 is_add = 1;
3156 u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
Jerome Tollet50570ec2017-09-14 12:53:56 +01003157 u8 *bd_tag = NULL;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003158 u32 mac_age = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06003159 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003160
3161 /* Parse args required to build the message */
3162 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3163 {
3164 if (unformat (i, "bd_id %d", &bd_id))
3165 ;
3166 else if (unformat (i, "flood %d", &flood))
3167 ;
3168 else if (unformat (i, "uu-flood %d", &uu_flood))
3169 ;
3170 else if (unformat (i, "forward %d", &forward))
3171 ;
3172 else if (unformat (i, "learn %d", &learn))
3173 ;
3174 else if (unformat (i, "arp-term %d", &arp_term))
3175 ;
3176 else if (unformat (i, "mac-age %d", &mac_age))
3177 ;
Jerome Tollet50570ec2017-09-14 12:53:56 +01003178 else if (unformat (i, "bd-tag %s", &bd_tag))
3179 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003180 else if (unformat (i, "del"))
3181 {
3182 is_add = 0;
3183 flood = uu_flood = forward = learn = 0;
3184 }
3185 else
3186 break;
3187 }
3188
3189 if (bd_id == ~0)
3190 {
3191 errmsg ("missing bridge domain");
Jerome Tollet50570ec2017-09-14 12:53:56 +01003192 ret = -99;
3193 goto done;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003194 }
3195
3196 if (mac_age > 255)
3197 {
3198 errmsg ("mac age must be less than 256 ");
Jerome Tollet50570ec2017-09-14 12:53:56 +01003199 ret = -99;
3200 goto done;
3201 }
3202
John Lo70bfcaf2017-11-14 13:19:26 -05003203 if ((bd_tag) && (vec_len (bd_tag) > 63))
Jerome Tollet50570ec2017-09-14 12:53:56 +01003204 {
3205 errmsg ("bd-tag cannot be longer than 63");
3206 ret = -99;
3207 goto done;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003208 }
3209
Jon Loeliger8a2aea32017-01-31 13:19:40 -06003210 M (BRIDGE_DOMAIN_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003211
3212 mp->bd_id = ntohl (bd_id);
3213 mp->flood = flood;
3214 mp->uu_flood = uu_flood;
3215 mp->forward = forward;
3216 mp->learn = learn;
3217 mp->arp_term = arp_term;
3218 mp->is_add = is_add;
3219 mp->mac_age = (u8) mac_age;
Jerome Tollet50570ec2017-09-14 12:53:56 +01003220 if (bd_tag)
John Lo70bfcaf2017-11-14 13:19:26 -05003221 {
3222 clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
3223 mp->bd_tag[vec_len (bd_tag)] = 0;
3224 }
Jon Loeliger7bc770c2017-01-31 14:03:33 -06003225 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06003226 W (ret);
Jerome Tollet50570ec2017-09-14 12:53:56 +01003227
3228done:
3229 vec_free (bd_tag);
Jon Loeliger56c7b012017-02-01 12:31:41 -06003230 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003231}
3232
3233static int
Eyal Barif24991c2017-04-05 05:33:21 +03003234api_l2fib_flush_bd (vat_main_t * vam)
3235{
3236 unformat_input_t *i = vam->input;
3237 vl_api_l2fib_flush_bd_t *mp;
3238 u32 bd_id = ~0;
3239 int ret;
3240
3241 /* Parse args required to build the message */
3242 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3243 {
3244 if (unformat (i, "bd_id %d", &bd_id));
3245 else
3246 break;
3247 }
3248
3249 if (bd_id == ~0)
3250 {
3251 errmsg ("missing bridge domain");
3252 return -99;
3253 }
3254
3255 M (L2FIB_FLUSH_BD, mp);
3256
3257 mp->bd_id = htonl (bd_id);
3258
3259 S (mp);
3260 W (ret);
3261 return ret;
3262}
3263
3264static int
3265api_l2fib_flush_int (vat_main_t * vam)
3266{
3267 unformat_input_t *i = vam->input;
3268 vl_api_l2fib_flush_int_t *mp;
3269 u32 sw_if_index = ~0;
3270 int ret;
3271
3272 /* Parse args required to build the message */
3273 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3274 {
3275 if (unformat (i, "sw_if_index %d", &sw_if_index));
3276 else
3277 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
3278 else
3279 break;
3280 }
3281
3282 if (sw_if_index == ~0)
3283 {
3284 errmsg ("missing interface name or sw_if_index");
3285 return -99;
3286 }
3287
3288 M (L2FIB_FLUSH_INT, mp);
3289
3290 mp->sw_if_index = ntohl (sw_if_index);
3291
3292 S (mp);
3293 W (ret);
3294 return ret;
3295}
3296
3297static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01003298api_l2fib_add_del (vat_main_t * vam)
3299{
3300 unformat_input_t *i = vam->input;
3301 vl_api_l2fib_add_del_t *mp;
3302 f64 timeout;
Mohsin Kazmi57938f62017-10-27 21:28:07 +02003303 u8 mac[6] = { 0 };
Damjan Marion7cd468a2016-12-19 23:05:39 +01003304 u8 mac_set = 0;
3305 u32 bd_id;
3306 u8 bd_id_set = 0;
John Lo7dbd7262018-05-31 10:25:18 -04003307 u32 sw_if_index = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003308 u8 sw_if_index_set = 0;
3309 u8 is_add = 1;
3310 u8 static_mac = 0;
3311 u8 filter_mac = 0;
3312 u8 bvi_mac = 0;
3313 int count = 1;
3314 f64 before = 0;
3315 int j;
3316
3317 /* Parse args required to build the message */
3318 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3319 {
Mohsin Kazmi57938f62017-10-27 21:28:07 +02003320 if (unformat (i, "mac %U", unformat_ethernet_address, mac))
Damjan Marion7cd468a2016-12-19 23:05:39 +01003321 mac_set = 1;
3322 else if (unformat (i, "bd_id %d", &bd_id))
3323 bd_id_set = 1;
3324 else if (unformat (i, "sw_if_index %d", &sw_if_index))
3325 sw_if_index_set = 1;
3326 else if (unformat (i, "sw_if"))
3327 {
3328 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3329 {
3330 if (unformat
3331 (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
3332 sw_if_index_set = 1;
3333 }
3334 else
3335 break;
3336 }
3337 else if (unformat (i, "static"))
3338 static_mac = 1;
3339 else if (unformat (i, "filter"))
3340 {
3341 filter_mac = 1;
3342 static_mac = 1;
3343 }
3344 else if (unformat (i, "bvi"))
3345 {
3346 bvi_mac = 1;
3347 static_mac = 1;
3348 }
3349 else if (unformat (i, "del"))
3350 is_add = 0;
3351 else if (unformat (i, "count %d", &count))
3352 ;
3353 else
3354 break;
3355 }
3356
3357 if (mac_set == 0)
3358 {
3359 errmsg ("missing mac address");
3360 return -99;
3361 }
3362
3363 if (bd_id_set == 0)
3364 {
3365 errmsg ("missing bridge domain");
3366 return -99;
3367 }
3368
3369 if (is_add && sw_if_index_set == 0 && filter_mac == 0)
3370 {
3371 errmsg ("missing interface name or sw_if_index");
3372 return -99;
3373 }
3374
3375 if (count > 1)
3376 {
3377 /* Turn on async mode */
3378 vam->async_mode = 1;
3379 vam->async_errors = 0;
3380 before = vat_time_now (vam);
3381 }
3382
3383 for (j = 0; j < count; j++)
3384 {
Jon Loeliger8a2aea32017-01-31 13:19:40 -06003385 M (L2FIB_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003386
Mohsin Kazmi57938f62017-10-27 21:28:07 +02003387 clib_memcpy (mp->mac, mac, 6);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003388 mp->bd_id = ntohl (bd_id);
3389 mp->is_add = is_add;
John Lo7dbd7262018-05-31 10:25:18 -04003390 mp->sw_if_index = ntohl (sw_if_index);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003391
3392 if (is_add)
3393 {
Damjan Marion7cd468a2016-12-19 23:05:39 +01003394 mp->static_mac = static_mac;
3395 mp->filter_mac = filter_mac;
3396 mp->bvi_mac = bvi_mac;
3397 }
Mohsin Kazmi57938f62017-10-27 21:28:07 +02003398 increment_mac_address (mac);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003399 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06003400 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003401 }
3402
3403 if (count > 1)
3404 {
Jon Loeliger2d23eca2017-02-01 13:09:58 -06003405 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003406 f64 after;
3407
3408 /* Shut off async mode */
3409 vam->async_mode = 0;
3410
Dave Barach59b25652017-09-10 15:04:27 -04003411 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06003412 S (mp_ping);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003413
3414 timeout = vat_time_now (vam) + 1.0;
3415 while (vat_time_now (vam) < timeout)
3416 if (vam->result_ready == 1)
3417 goto out;
3418 vam->retval = -99;
3419
3420 out:
3421 if (vam->retval == -99)
3422 errmsg ("timeout");
3423
3424 if (vam->async_errors > 0)
3425 {
3426 errmsg ("%d asynchronous errors", vam->async_errors);
3427 vam->retval = -98;
3428 }
3429 vam->async_errors = 0;
3430 after = vat_time_now (vam);
3431
3432 print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
3433 count, after - before, count / (after - before));
3434 }
3435 else
3436 {
Jon Loeliger56c7b012017-02-01 12:31:41 -06003437 int ret;
3438
Damjan Marion7cd468a2016-12-19 23:05:39 +01003439 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06003440 W (ret);
3441 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003442 }
3443 /* Return the good/bad news */
3444 return (vam->retval);
3445}
3446
3447static int
Eyal Barifead6702017-04-04 04:46:32 +03003448api_bridge_domain_set_mac_age (vat_main_t * vam)
3449{
3450 unformat_input_t *i = vam->input;
3451 vl_api_bridge_domain_set_mac_age_t *mp;
3452 u32 bd_id = ~0;
3453 u32 mac_age = 0;
3454 int ret;
3455
3456 /* Parse args required to build the message */
3457 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3458 {
3459 if (unformat (i, "bd_id %d", &bd_id));
3460 else if (unformat (i, "mac-age %d", &mac_age));
3461 else
3462 break;
3463 }
3464
3465 if (bd_id == ~0)
3466 {
3467 errmsg ("missing bridge domain");
3468 return -99;
3469 }
3470
3471 if (mac_age > 255)
3472 {
3473 errmsg ("mac age must be less than 256 ");
3474 return -99;
3475 }
3476
3477 M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
3478
3479 mp->bd_id = htonl (bd_id);
3480 mp->mac_age = (u8) mac_age;
3481
3482 S (mp);
3483 W (ret);
3484 return ret;
3485}
3486
3487static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01003488api_l2_flags (vat_main_t * vam)
3489{
3490 unformat_input_t *i = vam->input;
3491 vl_api_l2_flags_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003492 u32 sw_if_index;
John Lo8d00fff2017-08-03 00:35:36 -04003493 u32 flags = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003494 u8 sw_if_index_set = 0;
John Lo8d00fff2017-08-03 00:35:36 -04003495 u8 is_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06003496 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003497
3498 /* Parse args required to build the message */
3499 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3500 {
3501 if (unformat (i, "sw_if_index %d", &sw_if_index))
3502 sw_if_index_set = 1;
3503 else if (unformat (i, "sw_if"))
3504 {
3505 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3506 {
3507 if (unformat
3508 (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
3509 sw_if_index_set = 1;
3510 }
3511 else
3512 break;
3513 }
3514 else if (unformat (i, "learn"))
John Lo8d00fff2017-08-03 00:35:36 -04003515 flags |= L2_LEARN;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003516 else if (unformat (i, "forward"))
John Lo8d00fff2017-08-03 00:35:36 -04003517 flags |= L2_FWD;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003518 else if (unformat (i, "flood"))
John Lo8d00fff2017-08-03 00:35:36 -04003519 flags |= L2_FLOOD;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003520 else if (unformat (i, "uu-flood"))
John Lo8d00fff2017-08-03 00:35:36 -04003521 flags |= L2_UU_FLOOD;
3522 else if (unformat (i, "arp-term"))
3523 flags |= L2_ARP_TERM;
3524 else if (unformat (i, "off"))
3525 is_set = 0;
3526 else if (unformat (i, "disable"))
3527 is_set = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003528 else
3529 break;
3530 }
3531
3532 if (sw_if_index_set == 0)
3533 {
3534 errmsg ("missing interface name or sw_if_index");
3535 return -99;
3536 }
3537
Jon Loeliger8a2aea32017-01-31 13:19:40 -06003538 M (L2_FLAGS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003539
3540 mp->sw_if_index = ntohl (sw_if_index);
John Lo8d00fff2017-08-03 00:35:36 -04003541 mp->feature_bitmap = ntohl (flags);
3542 mp->is_set = is_set;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003543
Jon Loeliger7bc770c2017-01-31 14:03:33 -06003544 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06003545 W (ret);
3546 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003547}
3548
3549static int
3550api_bridge_flags (vat_main_t * vam)
3551{
3552 unformat_input_t *i = vam->input;
3553 vl_api_bridge_flags_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003554 u32 bd_id;
3555 u8 bd_id_set = 0;
3556 u8 is_set = 1;
Neale Rannsb4743802018-09-05 09:13:57 -07003557 bd_flags_t flags = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06003558 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003559
3560 /* Parse args required to build the message */
3561 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3562 {
3563 if (unformat (i, "bd_id %d", &bd_id))
3564 bd_id_set = 1;
3565 else if (unformat (i, "learn"))
Neale Rannsb4743802018-09-05 09:13:57 -07003566 flags |= BRIDGE_API_FLAG_LEARN;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003567 else if (unformat (i, "forward"))
Neale Rannsb4743802018-09-05 09:13:57 -07003568 flags |= BRIDGE_API_FLAG_FWD;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003569 else if (unformat (i, "flood"))
Neale Rannsb4743802018-09-05 09:13:57 -07003570 flags |= BRIDGE_API_FLAG_FLOOD;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003571 else if (unformat (i, "uu-flood"))
Neale Rannsb4743802018-09-05 09:13:57 -07003572 flags |= BRIDGE_API_FLAG_UU_FLOOD;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003573 else if (unformat (i, "arp-term"))
Neale Rannsb4743802018-09-05 09:13:57 -07003574 flags |= BRIDGE_API_FLAG_ARP_TERM;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003575 else if (unformat (i, "off"))
3576 is_set = 0;
3577 else if (unformat (i, "disable"))
3578 is_set = 0;
3579 else
3580 break;
3581 }
3582
3583 if (bd_id_set == 0)
3584 {
3585 errmsg ("missing bridge domain");
3586 return -99;
3587 }
3588
Jon Loeliger8a2aea32017-01-31 13:19:40 -06003589 M (BRIDGE_FLAGS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003590
3591 mp->bd_id = ntohl (bd_id);
Neale Rannsb4743802018-09-05 09:13:57 -07003592 mp->flags = ntohl (flags);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003593 mp->is_set = is_set;
3594
Jon Loeliger7bc770c2017-01-31 14:03:33 -06003595 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06003596 W (ret);
3597 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003598}
3599
3600static int
3601api_bd_ip_mac_add_del (vat_main_t * vam)
3602{
Neale Ranns4d5b9172018-10-24 02:57:49 -07003603 vl_api_address_t ip = VL_API_ZERO_ADDRESS;
Ole Troan8006c6a2018-12-17 12:02:26 +01003604 vl_api_mac_address_t mac = { 0 };
Damjan Marion7cd468a2016-12-19 23:05:39 +01003605 unformat_input_t *i = vam->input;
3606 vl_api_bd_ip_mac_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003607 u32 bd_id;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003608 u8 is_add = 1;
3609 u8 bd_id_set = 0;
3610 u8 ip_set = 0;
3611 u8 mac_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06003612 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003613
3614
3615 /* Parse args required to build the message */
3616 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3617 {
3618 if (unformat (i, "bd_id %d", &bd_id))
3619 {
3620 bd_id_set++;
3621 }
Neale Ranns4d5b9172018-10-24 02:57:49 -07003622 else if (unformat (i, "%U", unformat_vl_api_address, &ip))
Damjan Marion7cd468a2016-12-19 23:05:39 +01003623 {
3624 ip_set++;
3625 }
Neale Ranns4d5b9172018-10-24 02:57:49 -07003626 else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
Damjan Marion7cd468a2016-12-19 23:05:39 +01003627 {
3628 mac_set++;
3629 }
3630 else if (unformat (i, "del"))
3631 is_add = 0;
3632 else
3633 break;
3634 }
3635
3636 if (bd_id_set == 0)
3637 {
3638 errmsg ("missing bridge domain");
3639 return -99;
3640 }
3641 else if (ip_set == 0)
3642 {
3643 errmsg ("missing IP address");
3644 return -99;
3645 }
3646 else if (mac_set == 0)
3647 {
3648 errmsg ("missing MAC address");
3649 return -99;
3650 }
3651
Jon Loeliger8a2aea32017-01-31 13:19:40 -06003652 M (BD_IP_MAC_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003653
Neale Rannsbc764c82019-06-19 07:07:13 -07003654 mp->entry.bd_id = ntohl (bd_id);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003655 mp->is_add = is_add;
Neale Ranns4d5b9172018-10-24 02:57:49 -07003656
Neale Rannsbc764c82019-06-19 07:07:13 -07003657 clib_memcpy (&mp->entry.ip, &ip, sizeof (ip));
3658 clib_memcpy (&mp->entry.mac, &mac, sizeof (mac));
Neale Ranns4d5b9172018-10-24 02:57:49 -07003659
Jon Loeliger7bc770c2017-01-31 14:03:33 -06003660 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06003661 W (ret);
3662 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003663}
3664
John Loe26c81f2019-01-07 15:16:33 -05003665static int
3666api_bd_ip_mac_flush (vat_main_t * vam)
3667{
3668 unformat_input_t *i = vam->input;
3669 vl_api_bd_ip_mac_flush_t *mp;
3670 u32 bd_id;
3671 u8 bd_id_set = 0;
3672 int ret;
3673
3674 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3675 {
3676 if (unformat (i, "bd_id %d", &bd_id))
3677 {
3678 bd_id_set++;
3679 }
3680 else
3681 break;
3682 }
3683
3684 if (bd_id_set == 0)
3685 {
3686 errmsg ("missing bridge domain");
3687 return -99;
3688 }
3689
3690 M (BD_IP_MAC_FLUSH, mp);
3691
3692 mp->bd_id = ntohl (bd_id);
3693
3694 S (mp);
3695 W (ret);
3696 return ret;
3697}
3698
Mohsin Kazmi5d82d2f2018-08-13 19:17:54 +02003699static void vl_api_bd_ip_mac_details_t_handler
3700 (vl_api_bd_ip_mac_details_t * mp)
3701{
3702 vat_main_t *vam = &vat_main;
Mohsin Kazmi5d82d2f2018-08-13 19:17:54 +02003703
3704 print (vam->ofp,
Neale Rannsbc764c82019-06-19 07:07:13 -07003705 "\n%-5d %U %U",
3706 ntohl (mp->entry.bd_id),
3707 format_vl_api_mac_address, mp->entry.mac,
3708 format_vl_api_address, &mp->entry.ip);
Mohsin Kazmi5d82d2f2018-08-13 19:17:54 +02003709}
3710
3711static void vl_api_bd_ip_mac_details_t_handler_json
3712 (vl_api_bd_ip_mac_details_t * mp)
3713{
3714 vat_main_t *vam = &vat_main;
3715 vat_json_node_t *node = NULL;
3716
3717 if (VAT_JSON_ARRAY != vam->json_tree.type)
3718 {
3719 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3720 vat_json_init_array (&vam->json_tree);
3721 }
3722 node = vat_json_array_add (&vam->json_tree);
3723
3724 vat_json_init_object (node);
Neale Rannsbc764c82019-06-19 07:07:13 -07003725 vat_json_object_add_uint (node, "bd_id", ntohl (mp->entry.bd_id));
Mohsin Kazmi5d82d2f2018-08-13 19:17:54 +02003726 vat_json_object_add_string_copy (node, "mac_address",
Neale Rannsbc764c82019-06-19 07:07:13 -07003727 format (0, "%U", format_vl_api_mac_address,
3728 &mp->entry.mac));
Mohsin Kazmi5d82d2f2018-08-13 19:17:54 +02003729 u8 *ip = 0;
3730
Neale Rannsbc764c82019-06-19 07:07:13 -07003731 ip = format (0, "%U", format_vl_api_address, &mp->entry.ip);
Mohsin Kazmi5d82d2f2018-08-13 19:17:54 +02003732 vat_json_object_add_string_copy (node, "ip_address", ip);
3733 vec_free (ip);
3734}
3735
3736static int
3737api_bd_ip_mac_dump (vat_main_t * vam)
3738{
3739 unformat_input_t *i = vam->input;
3740 vl_api_bd_ip_mac_dump_t *mp;
3741 vl_api_control_ping_t *mp_ping;
3742 int ret;
3743 u32 bd_id;
3744 u8 bd_id_set = 0;
3745
3746 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3747 {
3748 if (unformat (i, "bd_id %d", &bd_id))
3749 {
3750 bd_id_set++;
3751 }
3752 else
3753 break;
3754 }
3755
3756 print (vam->ofp,
3757 "\n%-5s %-7s %-20s %-30s",
3758 "bd_id", "is_ipv6", "mac_address", "ip_address");
3759
3760 /* Dump Bridge Domain Ip to Mac entries */
3761 M (BD_IP_MAC_DUMP, mp);
3762
3763 if (bd_id_set)
3764 mp->bd_id = htonl (bd_id);
3765 else
3766 mp->bd_id = ~0;
3767
3768 S (mp);
3769
3770 /* Use a control ping for synchronization */
3771 MPING (CONTROL_PING, mp_ping);
3772 S (mp_ping);
3773
3774 W (ret);
3775 return ret;
3776}
3777
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01003778uword
jialv01082ebeb2019-09-10 00:23:55 +08003779unformat_vlib_pci_addr (unformat_input_t * input, va_list * args)
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01003780{
jialv01082ebeb2019-09-10 00:23:55 +08003781 vlib_pci_addr_t *addr = va_arg (*args, vlib_pci_addr_t *);
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01003782 u32 x[4];
3783
3784 if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
3785 return 0;
3786
3787 addr->domain = x[0];
3788 addr->bus = x[1];
3789 addr->slot = x[2];
3790 addr->function = x[3];
3791
3792 return 1;
3793}
3794
3795static int
Mohsin Kazmi518251b2020-09-01 17:17:44 +00003796api_virtio_pci_create_v2 (vat_main_t * vam)
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01003797{
3798 unformat_input_t *i = vam->input;
Mohsin Kazmi518251b2020-09-01 17:17:44 +00003799 vl_api_virtio_pci_create_v2_t *mp;
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01003800 u8 mac_address[6];
3801 u8 random_mac = 1;
3802 u32 pci_addr = 0;
3803 u64 features = (u64) ~ (0ULL);
Mohsin Kazmi518251b2020-09-01 17:17:44 +00003804 u32 virtio_flags = 0;
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01003805 int ret;
3806
3807 clib_memset (mac_address, 0, sizeof (mac_address));
3808
3809 /* Parse args required to build the message */
3810 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3811 {
3812 if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
3813 {
3814 random_mac = 0;
3815 }
jialv01082ebeb2019-09-10 00:23:55 +08003816 else if (unformat (i, "pci-addr %U", unformat_vlib_pci_addr, &pci_addr))
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01003817 ;
3818 else if (unformat (i, "features 0x%llx", &features))
3819 ;
Mohsin Kazmibbd6b742019-05-02 13:54:59 +02003820 else if (unformat (i, "gso-enabled"))
Mohsin Kazmi518251b2020-09-01 17:17:44 +00003821 virtio_flags |= VIRTIO_API_FLAG_GSO;
Mohsin Kazmi6d4af892020-01-03 15:11:53 +00003822 else if (unformat (i, "csum-offload-enabled"))
Mohsin Kazmi518251b2020-09-01 17:17:44 +00003823 virtio_flags |= VIRTIO_API_FLAG_CSUM_OFFLOAD;
3824 else if (unformat (i, "gro-coalesce"))
3825 virtio_flags |= VIRTIO_API_FLAG_GRO_COALESCE;
3826 else if (unformat (i, "packed"))
3827 virtio_flags |= VIRTIO_API_FLAG_PACKED;
3828 else if (unformat (i, "in-order"))
3829 virtio_flags |= VIRTIO_API_FLAG_IN_ORDER;
Mohsin Kazmie347acb2020-09-28 10:26:33 +00003830 else if (unformat (i, "buffering"))
3831 virtio_flags |= VIRTIO_API_FLAG_BUFFERING;
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01003832 else
3833 break;
3834 }
3835
3836 if (pci_addr == 0)
3837 {
3838 errmsg ("pci address must be non zero. ");
3839 return -99;
3840 }
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01003841
3842 /* Construct the API message */
Mohsin Kazmi518251b2020-09-01 17:17:44 +00003843 M (VIRTIO_PCI_CREATE_V2, mp);
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01003844
3845 mp->use_random_mac = random_mac;
3846
Jakub Grajciar2c504f82019-09-26 10:34:41 +02003847 mp->pci_addr.domain = htons (((vlib_pci_addr_t) pci_addr).domain);
3848 mp->pci_addr.bus = ((vlib_pci_addr_t) pci_addr).bus;
3849 mp->pci_addr.slot = ((vlib_pci_addr_t) pci_addr).slot;
3850 mp->pci_addr.function = ((vlib_pci_addr_t) pci_addr).function;
3851
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01003852 mp->features = clib_host_to_net_u64 (features);
Mohsin Kazmi518251b2020-09-01 17:17:44 +00003853 mp->virtio_flags = clib_host_to_net_u32 (virtio_flags);
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01003854
3855 if (random_mac == 0)
3856 clib_memcpy (mp->mac_address, mac_address, 6);
3857
3858 /* send it... */
3859 S (mp);
3860
3861 /* Wait for a reply... */
3862 W (ret);
3863 return ret;
3864}
3865
3866static int
3867api_virtio_pci_delete (vat_main_t * vam)
3868{
3869 unformat_input_t *i = vam->input;
3870 vl_api_virtio_pci_delete_t *mp;
3871 u32 sw_if_index = ~0;
3872 u8 sw_if_index_set = 0;
3873 int ret;
3874
3875 /* Parse args required to build the message */
3876 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3877 {
3878 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
3879 sw_if_index_set = 1;
3880 else if (unformat (i, "sw_if_index %d", &sw_if_index))
3881 sw_if_index_set = 1;
3882 else
3883 break;
3884 }
3885
3886 if (sw_if_index_set == 0)
3887 {
3888 errmsg ("missing vpp interface name. ");
3889 return -99;
3890 }
3891
3892 /* Construct the API message */
3893 M (VIRTIO_PCI_DELETE, mp);
3894
3895 mp->sw_if_index = htonl (sw_if_index);
3896
3897 /* send it... */
3898 S (mp);
3899
3900 /* Wait for a reply... */
3901 W (ret);
3902 return ret;
3903}
3904
Damjan Marion8389fb92017-10-13 18:29:53 +02003905static int
Neale Ranns28ab9cc2017-08-14 07:18:42 -07003906api_ip_table_add_del (vat_main_t * vam)
3907{
3908 unformat_input_t *i = vam->input;
3909 vl_api_ip_table_add_del_t *mp;
3910 u32 table_id = ~0;
3911 u8 is_ipv6 = 0;
3912 u8 is_add = 1;
3913 int ret = 0;
3914
3915 /* Parse args required to build the message */
3916 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3917 {
3918 if (unformat (i, "ipv6"))
3919 is_ipv6 = 1;
3920 else if (unformat (i, "del"))
3921 is_add = 0;
3922 else if (unformat (i, "add"))
3923 is_add = 1;
3924 else if (unformat (i, "table %d", &table_id))
3925 ;
3926 else
3927 {
3928 clib_warning ("parse error '%U'", format_unformat_error, i);
3929 return -99;
3930 }
3931 }
3932
3933 if (~0 == table_id)
3934 {
3935 errmsg ("missing table-ID");
3936 return -99;
3937 }
3938
3939 /* Construct the API message */
3940 M (IP_TABLE_ADD_DEL, mp);
3941
Neale Ranns097fa662018-05-01 05:17:55 -07003942 mp->table.table_id = ntohl (table_id);
3943 mp->table.is_ip6 = is_ipv6;
Neale Ranns28ab9cc2017-08-14 07:18:42 -07003944 mp->is_add = is_add;
3945
3946 /* send it... */
3947 S (mp);
3948
3949 /* Wait for a reply... */
3950 W (ret);
3951
3952 return ret;
3953}
3954
Neale Ranns097fa662018-05-01 05:17:55 -07003955uword
3956unformat_fib_path (unformat_input_t * input, va_list * args)
3957{
3958 vat_main_t *vam = va_arg (*args, vat_main_t *);
3959 vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
3960 u32 weight, preference;
3961 mpls_label_t out_label;
3962
3963 clib_memset (path, 0, sizeof (*path));
3964 path->weight = 1;
3965 path->sw_if_index = ~0;
3966 path->rpf_id = ~0;
3967 path->n_labels = 0;
3968
3969 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
3970 {
3971 if (unformat (input, "%U %U",
3972 unformat_vl_api_ip4_address,
3973 &path->nh.address.ip4,
3974 api_unformat_sw_if_index, vam, &path->sw_if_index))
3975 {
3976 path->proto = FIB_API_PATH_NH_PROTO_IP4;
3977 }
3978 else if (unformat (input, "%U %U",
3979 unformat_vl_api_ip6_address,
3980 &path->nh.address.ip6,
3981 api_unformat_sw_if_index, vam, &path->sw_if_index))
3982 {
3983 path->proto = FIB_API_PATH_NH_PROTO_IP6;
3984 }
3985 else if (unformat (input, "weight %u", &weight))
3986 {
3987 path->weight = weight;
3988 }
3989 else if (unformat (input, "preference %u", &preference))
3990 {
3991 path->preference = preference;
3992 }
3993 else if (unformat (input, "%U next-hop-table %d",
3994 unformat_vl_api_ip4_address,
3995 &path->nh.address.ip4, &path->table_id))
3996 {
3997 path->proto = FIB_API_PATH_NH_PROTO_IP4;
3998 }
3999 else if (unformat (input, "%U next-hop-table %d",
4000 unformat_vl_api_ip6_address,
4001 &path->nh.address.ip6, &path->table_id))
4002 {
4003 path->proto = FIB_API_PATH_NH_PROTO_IP6;
4004 }
4005 else if (unformat (input, "%U",
4006 unformat_vl_api_ip4_address, &path->nh.address.ip4))
4007 {
4008 /*
4009 * the recursive next-hops are by default in the default table
4010 */
4011 path->table_id = 0;
4012 path->sw_if_index = ~0;
4013 path->proto = FIB_API_PATH_NH_PROTO_IP4;
4014 }
4015 else if (unformat (input, "%U",
4016 unformat_vl_api_ip6_address, &path->nh.address.ip6))
4017 {
4018 /*
4019 * the recursive next-hops are by default in the default table
4020 */
4021 path->table_id = 0;
4022 path->sw_if_index = ~0;
4023 path->proto = FIB_API_PATH_NH_PROTO_IP6;
4024 }
4025 else if (unformat (input, "resolve-via-host"))
4026 {
4027 path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
4028 }
4029 else if (unformat (input, "resolve-via-attached"))
4030 {
4031 path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
4032 }
4033 else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
4034 {
4035 path->type = FIB_API_PATH_TYPE_LOCAL;
4036 path->sw_if_index = ~0;
4037 path->proto = FIB_API_PATH_NH_PROTO_IP4;
4038 }
4039 else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
4040 {
4041 path->type = FIB_API_PATH_TYPE_LOCAL;
4042 path->sw_if_index = ~0;
4043 path->proto = FIB_API_PATH_NH_PROTO_IP6;
4044 }
4045 else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
4046 ;
4047 else if (unformat (input, "via-label %d", &path->nh.via_label))
4048 {
4049 path->proto = FIB_API_PATH_NH_PROTO_MPLS;
4050 path->sw_if_index = ~0;
4051 }
4052 else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
4053 {
4054 path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
4055 path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
4056 }
4057 else if (unformat (input, "local"))
4058 {
4059 path->type = FIB_API_PATH_TYPE_LOCAL;
4060 }
4061 else if (unformat (input, "out-labels"))
4062 {
4063 while (unformat (input, "%d", &out_label))
4064 {
4065 path->label_stack[path->n_labels].label = out_label;
4066 path->label_stack[path->n_labels].is_uniform = 0;
4067 path->label_stack[path->n_labels].ttl = 64;
4068 path->n_labels++;
4069 }
4070 }
4071 else if (unformat (input, "via"))
4072 {
4073 /* new path, back up and return */
4074 unformat_put_input (input);
4075 unformat_put_input (input);
4076 unformat_put_input (input);
4077 unformat_put_input (input);
4078 break;
4079 }
4080 else
4081 {
4082 return (0);
4083 }
4084 }
4085
4086 path->proto = ntohl (path->proto);
4087 path->type = ntohl (path->type);
4088 path->flags = ntohl (path->flags);
4089 path->table_id = ntohl (path->table_id);
4090 path->sw_if_index = ntohl (path->sw_if_index);
4091
4092 return (1);
4093}
4094
Neale Ranns28ab9cc2017-08-14 07:18:42 -07004095static int
Neale Ranns097fa662018-05-01 05:17:55 -07004096api_ip_route_add_del (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +01004097{
4098 unformat_input_t *i = vam->input;
Neale Ranns097fa662018-05-01 05:17:55 -07004099 vl_api_ip_route_add_del_t *mp;
4100 u32 vrf_id = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004101 u8 is_add = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004102 u8 is_multipath = 0;
Neale Ranns097fa662018-05-01 05:17:55 -07004103 u8 prefix_set = 0;
4104 u8 path_count = 0;
4105 vl_api_prefix_t pfx = { };
4106 vl_api_fib_path_t paths[8];
Damjan Marion7cd468a2016-12-19 23:05:39 +01004107 int count = 1;
4108 int j;
4109 f64 before = 0;
4110 u32 random_add_del = 0;
4111 u32 *random_vector = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004112 u32 random_seed = 0xdeaddabe;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004113
4114 /* Parse args required to build the message */
4115 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4116 {
Neale Ranns097fa662018-05-01 05:17:55 -07004117 if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
4118 prefix_set = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004119 else if (unformat (i, "del"))
4120 is_add = 0;
4121 else if (unformat (i, "add"))
4122 is_add = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004123 else if (unformat (i, "vrf %d", &vrf_id))
4124 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004125 else if (unformat (i, "count %d", &count))
4126 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004127 else if (unformat (i, "random"))
4128 random_add_del = 1;
Neale Ranns097fa662018-05-01 05:17:55 -07004129 else if (unformat (i, "multipath"))
4130 is_multipath = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004131 else if (unformat (i, "seed %d", &random_seed))
4132 ;
4133 else
Neale Ranns097fa662018-05-01 05:17:55 -07004134 if (unformat
4135 (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
4136 {
4137 path_count++;
4138 if (8 == path_count)
4139 {
4140 errmsg ("max 8 paths");
4141 return -99;
4142 }
4143 }
4144 else
Damjan Marion7cd468a2016-12-19 23:05:39 +01004145 {
4146 clib_warning ("parse error '%U'", format_unformat_error, i);
4147 return -99;
4148 }
4149 }
4150
Neale Ranns097fa662018-05-01 05:17:55 -07004151 if (!path_count)
Damjan Marion7cd468a2016-12-19 23:05:39 +01004152 {
Neale Ranns097fa662018-05-01 05:17:55 -07004153 errmsg ("specify a path; via ...");
Damjan Marion7cd468a2016-12-19 23:05:39 +01004154 return -99;
4155 }
Neale Ranns097fa662018-05-01 05:17:55 -07004156 if (prefix_set == 0)
Damjan Marion7cd468a2016-12-19 23:05:39 +01004157 {
Neale Ranns097fa662018-05-01 05:17:55 -07004158 errmsg ("missing prefix");
Damjan Marion7cd468a2016-12-19 23:05:39 +01004159 return -99;
4160 }
4161
4162 /* Generate a pile of unique, random routes */
4163 if (random_add_del)
4164 {
Neale Ranns097fa662018-05-01 05:17:55 -07004165 ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004166 u32 this_random_address;
Neale Ranns097fa662018-05-01 05:17:55 -07004167 uword *random_hash;
4168
Damjan Marion7cd468a2016-12-19 23:05:39 +01004169 random_hash = hash_create (count, sizeof (uword));
4170
Neale Ranns097fa662018-05-01 05:17:55 -07004171 hash_set (random_hash, i->as_u32, 1);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004172 for (j = 0; j <= count; j++)
4173 {
4174 do
4175 {
4176 this_random_address = random_u32 (&random_seed);
4177 this_random_address =
4178 clib_host_to_net_u32 (this_random_address);
4179 }
4180 while (hash_get (random_hash, this_random_address));
4181 vec_add1 (random_vector, this_random_address);
4182 hash_set (random_hash, this_random_address, 1);
4183 }
4184 hash_free (random_hash);
Neale Ranns097fa662018-05-01 05:17:55 -07004185 set_ip4_address (&pfx.address, random_vector[0]);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004186 }
4187
4188 if (count > 1)
4189 {
4190 /* Turn on async mode */
4191 vam->async_mode = 1;
4192 vam->async_errors = 0;
4193 before = vat_time_now (vam);
4194 }
4195
4196 for (j = 0; j < count; j++)
4197 {
4198 /* Construct the API message */
Neale Ranns097fa662018-05-01 05:17:55 -07004199 M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004200
4201 mp->is_add = is_add;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004202 mp->is_multipath = is_multipath;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004203
Neale Ranns097fa662018-05-01 05:17:55 -07004204 clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
4205 mp->route.table_id = ntohl (vrf_id);
4206 mp->route.n_paths = path_count;
4207
4208 clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
4209
4210 if (random_add_del)
4211 set_ip4_address (&pfx.address, random_vector[j + 1]);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004212 else
Neale Ranns097fa662018-05-01 05:17:55 -07004213 increment_address (&pfx.address);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004214 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004215 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004216 /* If we receive SIGTERM, stop now... */
4217 if (vam->do_exit)
4218 break;
4219 }
4220
4221 /* When testing multiple add/del ops, use a control-ping to sync */
4222 if (count > 1)
4223 {
Jon Loeliger2d23eca2017-02-01 13:09:58 -06004224 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004225 f64 after;
Jon Loeliger1f9191f2017-01-31 15:27:19 -06004226 f64 timeout;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004227
4228 /* Shut off async mode */
4229 vam->async_mode = 0;
4230
Dave Barach59b25652017-09-10 15:04:27 -04004231 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06004232 S (mp_ping);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004233
4234 timeout = vat_time_now (vam) + 1.0;
4235 while (vat_time_now (vam) < timeout)
4236 if (vam->result_ready == 1)
4237 goto out;
4238 vam->retval = -99;
4239
4240 out:
4241 if (vam->retval == -99)
4242 errmsg ("timeout");
4243
4244 if (vam->async_errors > 0)
4245 {
4246 errmsg ("%d asynchronous errors", vam->async_errors);
4247 vam->retval = -98;
4248 }
4249 vam->async_errors = 0;
4250 after = vat_time_now (vam);
4251
4252 /* slim chance, but we might have eaten SIGTERM on the first iteration */
4253 if (j > 0)
4254 count = j;
4255
4256 print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
4257 count, after - before, count / (after - before));
4258 }
4259 else
4260 {
Jon Loeliger56c7b012017-02-01 12:31:41 -06004261 int ret;
4262
Damjan Marion7cd468a2016-12-19 23:05:39 +01004263 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06004264 W (ret);
4265 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004266 }
4267
4268 /* Return the good/bad news */
4269 return (vam->retval);
4270}
4271
4272static int
Neale Ranns32e1c012016-11-22 17:07:28 +00004273api_ip_mroute_add_del (vat_main_t * vam)
4274{
4275 unformat_input_t *i = vam->input;
Neale Ranns097fa662018-05-01 05:17:55 -07004276 u8 path_set = 0, prefix_set = 0, is_add = 1;
Neale Ranns32e1c012016-11-22 17:07:28 +00004277 vl_api_ip_mroute_add_del_t *mp;
Neale Ranns32e1c012016-11-22 17:07:28 +00004278 mfib_entry_flags_t eflags = 0;
Neale Ranns097fa662018-05-01 05:17:55 -07004279 vl_api_mfib_path_t path;
4280 vl_api_mprefix_t pfx = { };
4281 u32 vrf_id = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004282 int ret;
Neale Ranns32e1c012016-11-22 17:07:28 +00004283
4284 /* Parse args required to build the message */
4285 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4286 {
Neale Ranns097fa662018-05-01 05:17:55 -07004287 if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
Neale Ranns32e1c012016-11-22 17:07:28 +00004288 {
Neale Ranns097fa662018-05-01 05:17:55 -07004289 prefix_set = 1;
4290 pfx.grp_address_length = htons (pfx.grp_address_length);
Neale Ranns32e1c012016-11-22 17:07:28 +00004291 }
4292 else if (unformat (i, "del"))
4293 is_add = 0;
4294 else if (unformat (i, "add"))
4295 is_add = 1;
4296 else if (unformat (i, "vrf %d", &vrf_id))
4297 ;
Neale Ranns097fa662018-05-01 05:17:55 -07004298 else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
4299 path.itf_flags = htonl (path.itf_flags);
Neale Ranns32e1c012016-11-22 17:07:28 +00004300 else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
4301 ;
Neale Ranns097fa662018-05-01 05:17:55 -07004302 else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
4303 path_set = 1;
Neale Ranns32e1c012016-11-22 17:07:28 +00004304 else
4305 {
4306 clib_warning ("parse error '%U'", format_unformat_error, i);
4307 return -99;
4308 }
4309 }
4310
Neale Ranns097fa662018-05-01 05:17:55 -07004311 if (prefix_set == 0)
Neale Ranns32e1c012016-11-22 17:07:28 +00004312 {
4313 errmsg ("missing addresses\n");
4314 return -99;
4315 }
Neale Ranns097fa662018-05-01 05:17:55 -07004316 if (path_set == 0)
4317 {
4318 errmsg ("missing path\n");
4319 return -99;
4320 }
Neale Ranns32e1c012016-11-22 17:07:28 +00004321
4322 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004323 M (IP_MROUTE_ADD_DEL, mp);
Neale Ranns32e1c012016-11-22 17:07:28 +00004324
Neale Ranns32e1c012016-11-22 17:07:28 +00004325 mp->is_add = is_add;
Neale Ranns097fa662018-05-01 05:17:55 -07004326 mp->is_multipath = 1;
Neale Ranns32e1c012016-11-22 17:07:28 +00004327
Neale Ranns097fa662018-05-01 05:17:55 -07004328 clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
4329 mp->route.table_id = htonl (vrf_id);
4330 mp->route.n_paths = 1;
4331 mp->route.entry_flags = htonl (eflags);
Neale Ranns32e1c012016-11-22 17:07:28 +00004332
Neale Ranns097fa662018-05-01 05:17:55 -07004333 clib_memcpy (&mp->route.paths, &path, sizeof (path));
Neale Ranns32e1c012016-11-22 17:07:28 +00004334
4335 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004336 S (mp);
Neale Ranns32e1c012016-11-22 17:07:28 +00004337 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06004338 W (ret);
4339 return ret;
Neale Ranns32e1c012016-11-22 17:07:28 +00004340}
4341
4342static int
Neale Ranns28ab9cc2017-08-14 07:18:42 -07004343api_mpls_table_add_del (vat_main_t * vam)
4344{
4345 unformat_input_t *i = vam->input;
4346 vl_api_mpls_table_add_del_t *mp;
4347 u32 table_id = ~0;
4348 u8 is_add = 1;
4349 int ret = 0;
4350
4351 /* Parse args required to build the message */
4352 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4353 {
Florin Corasd0a59722017-10-15 17:41:21 +00004354 if (unformat (i, "table %d", &table_id))
4355 ;
4356 else if (unformat (i, "del"))
Neale Ranns28ab9cc2017-08-14 07:18:42 -07004357 is_add = 0;
4358 else if (unformat (i, "add"))
4359 is_add = 1;
4360 else
4361 {
4362 clib_warning ("parse error '%U'", format_unformat_error, i);
4363 return -99;
4364 }
4365 }
4366
4367 if (~0 == table_id)
4368 {
4369 errmsg ("missing table-ID");
4370 return -99;
4371 }
4372
4373 /* Construct the API message */
4374 M (MPLS_TABLE_ADD_DEL, mp);
4375
Neale Ranns097fa662018-05-01 05:17:55 -07004376 mp->mt_table.mt_table_id = ntohl (table_id);
Neale Ranns28ab9cc2017-08-14 07:18:42 -07004377 mp->mt_is_add = is_add;
4378
4379 /* send it... */
4380 S (mp);
4381
4382 /* Wait for a reply... */
4383 W (ret);
4384
4385 return ret;
4386}
4387
4388static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01004389api_mpls_route_add_del (vat_main_t * vam)
4390{
Neale Ranns097fa662018-05-01 05:17:55 -07004391 u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
4392 mpls_label_t local_label = MPLS_LABEL_INVALID;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004393 unformat_input_t *i = vam->input;
4394 vl_api_mpls_route_add_del_t *mp;
Neale Ranns097fa662018-05-01 05:17:55 -07004395 vl_api_fib_path_t paths[8];
4396 int count = 1, j;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004397 f64 before = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004398
4399 /* Parse args required to build the message */
4400 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4401 {
Neale Ranns097fa662018-05-01 05:17:55 -07004402 if (unformat (i, "%d", &local_label))
Damjan Marion7cd468a2016-12-19 23:05:39 +01004403 ;
4404 else if (unformat (i, "eos"))
4405 is_eos = 1;
4406 else if (unformat (i, "non-eos"))
4407 is_eos = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004408 else if (unformat (i, "del"))
4409 is_add = 0;
4410 else if (unformat (i, "add"))
4411 is_add = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004412 else if (unformat (i, "multipath"))
4413 is_multipath = 1;
4414 else if (unformat (i, "count %d", &count))
4415 ;
John Loe166fd92018-09-13 14:08:59 -04004416 else
4417 if (unformat
Neale Ranns097fa662018-05-01 05:17:55 -07004418 (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
John Loe166fd92018-09-13 14:08:59 -04004419 {
Neale Ranns097fa662018-05-01 05:17:55 -07004420 path_count++;
4421 if (8 == path_count)
4422 {
4423 errmsg ("max 8 paths");
4424 return -99;
4425 }
John Loe166fd92018-09-13 14:08:59 -04004426 }
Damjan Marion7cd468a2016-12-19 23:05:39 +01004427 else
4428 {
4429 clib_warning ("parse error '%U'", format_unformat_error, i);
4430 return -99;
4431 }
4432 }
4433
Neale Ranns097fa662018-05-01 05:17:55 -07004434 if (!path_count)
Damjan Marion7cd468a2016-12-19 23:05:39 +01004435 {
Neale Ranns097fa662018-05-01 05:17:55 -07004436 errmsg ("specify a path; via ...");
Damjan Marion7cd468a2016-12-19 23:05:39 +01004437 return -99;
4438 }
4439
4440 if (MPLS_LABEL_INVALID == local_label)
4441 {
4442 errmsg ("missing label");
4443 return -99;
4444 }
4445
4446 if (count > 1)
4447 {
4448 /* Turn on async mode */
4449 vam->async_mode = 1;
4450 vam->async_errors = 0;
4451 before = vat_time_now (vam);
4452 }
4453
4454 for (j = 0; j < count; j++)
4455 {
4456 /* Construct the API message */
Neale Ranns097fa662018-05-01 05:17:55 -07004457 M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004458
4459 mp->mr_is_add = is_add;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004460 mp->mr_is_multipath = is_multipath;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004461
Neale Ranns097fa662018-05-01 05:17:55 -07004462 mp->mr_route.mr_label = local_label;
4463 mp->mr_route.mr_eos = is_eos;
4464 mp->mr_route.mr_table_id = 0;
4465 mp->mr_route.mr_n_paths = path_count;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004466
Neale Ranns097fa662018-05-01 05:17:55 -07004467 clib_memcpy (&mp->mr_route.mr_paths, paths,
4468 sizeof (paths[0]) * path_count);
Neale Rannsda78f952017-05-24 09:15:43 -07004469
Damjan Marion7cd468a2016-12-19 23:05:39 +01004470 local_label++;
4471
4472 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004473 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004474 /* If we receive SIGTERM, stop now... */
4475 if (vam->do_exit)
4476 break;
4477 }
4478
4479 /* When testing multiple add/del ops, use a control-ping to sync */
4480 if (count > 1)
4481 {
Jon Loeliger2d23eca2017-02-01 13:09:58 -06004482 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004483 f64 after;
Jon Loeliger1f9191f2017-01-31 15:27:19 -06004484 f64 timeout;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004485
4486 /* Shut off async mode */
4487 vam->async_mode = 0;
4488
Dave Barach59b25652017-09-10 15:04:27 -04004489 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06004490 S (mp_ping);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004491
4492 timeout = vat_time_now (vam) + 1.0;
4493 while (vat_time_now (vam) < timeout)
4494 if (vam->result_ready == 1)
4495 goto out;
4496 vam->retval = -99;
4497
4498 out:
4499 if (vam->retval == -99)
4500 errmsg ("timeout");
4501
4502 if (vam->async_errors > 0)
4503 {
4504 errmsg ("%d asynchronous errors", vam->async_errors);
4505 vam->retval = -98;
4506 }
4507 vam->async_errors = 0;
4508 after = vat_time_now (vam);
4509
4510 /* slim chance, but we might have eaten SIGTERM on the first iteration */
4511 if (j > 0)
4512 count = j;
4513
4514 print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
4515 count, after - before, count / (after - before));
4516 }
4517 else
4518 {
Jon Loeliger56c7b012017-02-01 12:31:41 -06004519 int ret;
4520
Damjan Marion7cd468a2016-12-19 23:05:39 +01004521 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06004522 W (ret);
4523 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004524 }
4525
4526 /* Return the good/bad news */
4527 return (vam->retval);
Neale Ranns097fa662018-05-01 05:17:55 -07004528 return (0);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004529}
4530
4531static int
4532api_mpls_ip_bind_unbind (vat_main_t * vam)
4533{
4534 unformat_input_t *i = vam->input;
4535 vl_api_mpls_ip_bind_unbind_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004536 u32 ip_table_id = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004537 u8 is_bind = 1;
Neale Ranns097fa662018-05-01 05:17:55 -07004538 vl_api_prefix_t pfx;
4539 u8 prefix_set = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004540 mpls_label_t local_label = MPLS_LABEL_INVALID;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004541 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004542
4543 /* Parse args required to build the message */
4544 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4545 {
Neale Ranns097fa662018-05-01 05:17:55 -07004546 if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
4547 prefix_set = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004548 else if (unformat (i, "%d", &local_label))
4549 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004550 else if (unformat (i, "table-id %d", &ip_table_id))
4551 ;
4552 else if (unformat (i, "unbind"))
4553 is_bind = 0;
4554 else if (unformat (i, "bind"))
4555 is_bind = 1;
4556 else
4557 {
4558 clib_warning ("parse error '%U'", format_unformat_error, i);
4559 return -99;
4560 }
4561 }
4562
Neale Ranns097fa662018-05-01 05:17:55 -07004563 if (!prefix_set)
Damjan Marion7cd468a2016-12-19 23:05:39 +01004564 {
Neale Ranns097fa662018-05-01 05:17:55 -07004565 errmsg ("IP prefix not set");
Damjan Marion7cd468a2016-12-19 23:05:39 +01004566 return -99;
4567 }
4568
4569 if (MPLS_LABEL_INVALID == local_label)
4570 {
4571 errmsg ("missing label");
4572 return -99;
4573 }
4574
4575 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004576 M (MPLS_IP_BIND_UNBIND, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004577
Damjan Marion7cd468a2016-12-19 23:05:39 +01004578 mp->mb_is_bind = is_bind;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004579 mp->mb_ip_table_id = ntohl (ip_table_id);
4580 mp->mb_mpls_table_id = 0;
4581 mp->mb_label = ntohl (local_label);
Neale Ranns097fa662018-05-01 05:17:55 -07004582 clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
Damjan Marion7cd468a2016-12-19 23:05:39 +01004583
4584 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004585 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004586
4587 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06004588 W (ret);
4589 return ret;
Neale Ranns097fa662018-05-01 05:17:55 -07004590 return (0);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004591}
4592
4593static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01004594api_mpls_tunnel_add_del (vat_main_t * vam)
4595{
4596 unformat_input_t *i = vam->input;
4597 vl_api_mpls_tunnel_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004598
Neale Ranns097fa662018-05-01 05:17:55 -07004599 vl_api_fib_path_t paths[8];
Damjan Marion7cd468a2016-12-19 23:05:39 +01004600 u32 sw_if_index = ~0;
Neale Ranns097fa662018-05-01 05:17:55 -07004601 u8 path_count = 0;
4602 u8 l2_only = 0;
4603 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004604 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004605
4606 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4607 {
4608 if (unformat (i, "add"))
4609 is_add = 1;
John Lo06fda9c2018-10-03 16:32:44 -04004610 else
4611 if (unformat
4612 (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
4613 is_add = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004614 else if (unformat (i, "del sw_if_index %d", &sw_if_index))
4615 is_add = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004616 else if (unformat (i, "l2-only"))
4617 l2_only = 1;
Neale Ranns097fa662018-05-01 05:17:55 -07004618 else
4619 if (unformat
4620 (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
John Lo06fda9c2018-10-03 16:32:44 -04004621 {
Neale Ranns097fa662018-05-01 05:17:55 -07004622 path_count++;
4623 if (8 == path_count)
4624 {
4625 errmsg ("max 8 paths");
4626 return -99;
4627 }
John Lo06fda9c2018-10-03 16:32:44 -04004628 }
Damjan Marion7cd468a2016-12-19 23:05:39 +01004629 else
4630 {
4631 clib_warning ("parse error '%U'", format_unformat_error, i);
4632 return -99;
4633 }
4634 }
4635
Neale Ranns097fa662018-05-01 05:17:55 -07004636 M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004637
Damjan Marion7cd468a2016-12-19 23:05:39 +01004638 mp->mt_is_add = is_add;
Neale Ranns097fa662018-05-01 05:17:55 -07004639 mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
4640 mp->mt_tunnel.mt_l2_only = l2_only;
4641 mp->mt_tunnel.mt_is_multicast = 0;
4642 mp->mt_tunnel.mt_n_paths = path_count;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004643
Neale Ranns097fa662018-05-01 05:17:55 -07004644 clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
4645 sizeof (paths[0]) * path_count);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004646
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004647 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06004648 W (ret);
4649 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004650}
4651
4652static int
4653api_sw_interface_set_unnumbered (vat_main_t * vam)
4654{
4655 unformat_input_t *i = vam->input;
4656 vl_api_sw_interface_set_unnumbered_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004657 u32 sw_if_index;
4658 u32 unnum_sw_index = ~0;
4659 u8 is_add = 1;
4660 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004661 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004662
4663 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4664 {
4665 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4666 sw_if_index_set = 1;
4667 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4668 sw_if_index_set = 1;
4669 else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
4670 ;
4671 else if (unformat (i, "del"))
4672 is_add = 0;
4673 else
4674 {
4675 clib_warning ("parse error '%U'", format_unformat_error, i);
4676 return -99;
4677 }
4678 }
4679
4680 if (sw_if_index_set == 0)
4681 {
4682 errmsg ("missing interface name or sw_if_index");
4683 return -99;
4684 }
4685
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004686 M (SW_INTERFACE_SET_UNNUMBERED, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004687
4688 mp->sw_if_index = ntohl (sw_if_index);
4689 mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
4690 mp->is_add = is_add;
4691
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004692 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06004693 W (ret);
4694 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004695}
4696
Damjan Marion7cd468a2016-12-19 23:05:39 +01004697
4698static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01004699api_create_vlan_subif (vat_main_t * vam)
4700{
4701 unformat_input_t *i = vam->input;
4702 vl_api_create_vlan_subif_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004703 u32 sw_if_index;
4704 u8 sw_if_index_set = 0;
4705 u32 vlan_id;
4706 u8 vlan_id_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004707 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004708
4709 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4710 {
4711 if (unformat (i, "sw_if_index %d", &sw_if_index))
4712 sw_if_index_set = 1;
4713 else
4714 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4715 sw_if_index_set = 1;
4716 else if (unformat (i, "vlan %d", &vlan_id))
4717 vlan_id_set = 1;
4718 else
4719 {
4720 clib_warning ("parse error '%U'", format_unformat_error, i);
4721 return -99;
4722 }
4723 }
4724
4725 if (sw_if_index_set == 0)
4726 {
4727 errmsg ("missing interface name or sw_if_index");
4728 return -99;
4729 }
4730
4731 if (vlan_id_set == 0)
4732 {
4733 errmsg ("missing vlan_id");
4734 return -99;
4735 }
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004736 M (CREATE_VLAN_SUBIF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004737
4738 mp->sw_if_index = ntohl (sw_if_index);
4739 mp->vlan_id = ntohl (vlan_id);
4740
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004741 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06004742 W (ret);
4743 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004744}
4745
4746#define foreach_create_subif_bit \
4747_(no_tags) \
4748_(one_tag) \
4749_(two_tags) \
4750_(dot1ad) \
4751_(exact_match) \
4752_(default_sub) \
4753_(outer_vlan_id_any) \
4754_(inner_vlan_id_any)
4755
Jakub Grajciar053204a2019-03-18 13:17:53 +01004756#define foreach_create_subif_flag \
4757_(0, "no_tags") \
4758_(1, "one_tag") \
4759_(2, "two_tags") \
4760_(3, "dot1ad") \
4761_(4, "exact_match") \
4762_(5, "default_sub") \
4763_(6, "outer_vlan_id_any") \
4764_(7, "inner_vlan_id_any")
4765
Damjan Marion7cd468a2016-12-19 23:05:39 +01004766static int
4767api_create_subif (vat_main_t * vam)
4768{
4769 unformat_input_t *i = vam->input;
4770 vl_api_create_subif_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004771 u32 sw_if_index;
4772 u8 sw_if_index_set = 0;
4773 u32 sub_id;
4774 u8 sub_id_set = 0;
Jakub Grajciar053204a2019-03-18 13:17:53 +01004775 u32 __attribute__ ((unused)) no_tags = 0;
4776 u32 __attribute__ ((unused)) one_tag = 0;
4777 u32 __attribute__ ((unused)) two_tags = 0;
4778 u32 __attribute__ ((unused)) dot1ad = 0;
4779 u32 __attribute__ ((unused)) exact_match = 0;
4780 u32 __attribute__ ((unused)) default_sub = 0;
4781 u32 __attribute__ ((unused)) outer_vlan_id_any = 0;
4782 u32 __attribute__ ((unused)) inner_vlan_id_any = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004783 u32 tmp;
4784 u16 outer_vlan_id = 0;
4785 u16 inner_vlan_id = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004786 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004787
4788 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4789 {
4790 if (unformat (i, "sw_if_index %d", &sw_if_index))
4791 sw_if_index_set = 1;
4792 else
4793 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4794 sw_if_index_set = 1;
4795 else if (unformat (i, "sub_id %d", &sub_id))
4796 sub_id_set = 1;
4797 else if (unformat (i, "outer_vlan_id %d", &tmp))
4798 outer_vlan_id = tmp;
4799 else if (unformat (i, "inner_vlan_id %d", &tmp))
4800 inner_vlan_id = tmp;
4801
4802#define _(a) else if (unformat (i, #a)) a = 1 ;
4803 foreach_create_subif_bit
4804#undef _
4805 else
4806 {
4807 clib_warning ("parse error '%U'", format_unformat_error, i);
4808 return -99;
4809 }
4810 }
4811
4812 if (sw_if_index_set == 0)
4813 {
4814 errmsg ("missing interface name or sw_if_index");
4815 return -99;
4816 }
4817
4818 if (sub_id_set == 0)
4819 {
4820 errmsg ("missing sub_id");
4821 return -99;
4822 }
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004823 M (CREATE_SUBIF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004824
4825 mp->sw_if_index = ntohl (sw_if_index);
4826 mp->sub_id = ntohl (sub_id);
4827
Jakub Grajciar053204a2019-03-18 13:17:53 +01004828#define _(a,b) mp->sub_if_flags |= (1 << a);
4829 foreach_create_subif_flag;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004830#undef _
4831
4832 mp->outer_vlan_id = ntohs (outer_vlan_id);
4833 mp->inner_vlan_id = ntohs (inner_vlan_id);
4834
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004835 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06004836 W (ret);
4837 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004838}
4839
4840static int
Neale Ranns9db6ada2019-11-08 12:42:31 +00004841api_ip_table_replace_begin (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +01004842{
4843 unformat_input_t *i = vam->input;
Neale Ranns9db6ada2019-11-08 12:42:31 +00004844 vl_api_ip_table_replace_begin_t *mp;
4845 u32 table_id = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004846 u8 is_ipv6 = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004847
Jon Loeliger56c7b012017-02-01 12:31:41 -06004848 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004849 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4850 {
Neale Ranns9db6ada2019-11-08 12:42:31 +00004851 if (unformat (i, "table %d", &table_id))
4852 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004853 else if (unformat (i, "ipv6"))
4854 is_ipv6 = 1;
4855 else
4856 {
4857 clib_warning ("parse error '%U'", format_unformat_error, i);
4858 return -99;
4859 }
4860 }
4861
Neale Ranns9db6ada2019-11-08 12:42:31 +00004862 M (IP_TABLE_REPLACE_BEGIN, mp);
4863
4864 mp->table.table_id = ntohl (table_id);
4865 mp->table.is_ip6 = is_ipv6;
4866
4867 S (mp);
4868 W (ret);
4869 return ret;
4870}
4871
4872static int
4873api_ip_table_flush (vat_main_t * vam)
4874{
4875 unformat_input_t *i = vam->input;
4876 vl_api_ip_table_flush_t *mp;
4877 u32 table_id = 0;
4878 u8 is_ipv6 = 0;
4879
4880 int ret;
4881 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
Damjan Marion7cd468a2016-12-19 23:05:39 +01004882 {
Neale Ranns9db6ada2019-11-08 12:42:31 +00004883 if (unformat (i, "table %d", &table_id))
4884 ;
4885 else if (unformat (i, "ipv6"))
4886 is_ipv6 = 1;
4887 else
4888 {
4889 clib_warning ("parse error '%U'", format_unformat_error, i);
4890 return -99;
4891 }
Damjan Marion7cd468a2016-12-19 23:05:39 +01004892 }
4893
Neale Ranns9db6ada2019-11-08 12:42:31 +00004894 M (IP_TABLE_FLUSH, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004895
Neale Ranns9db6ada2019-11-08 12:42:31 +00004896 mp->table.table_id = ntohl (table_id);
4897 mp->table.is_ip6 = is_ipv6;
4898
4899 S (mp);
4900 W (ret);
4901 return ret;
4902}
4903
4904static int
4905api_ip_table_replace_end (vat_main_t * vam)
4906{
4907 unformat_input_t *i = vam->input;
4908 vl_api_ip_table_replace_end_t *mp;
4909 u32 table_id = 0;
4910 u8 is_ipv6 = 0;
4911
4912 int ret;
4913 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4914 {
4915 if (unformat (i, "table %d", &table_id))
4916 ;
4917 else if (unformat (i, "ipv6"))
4918 is_ipv6 = 1;
4919 else
4920 {
4921 clib_warning ("parse error '%U'", format_unformat_error, i);
4922 return -99;
4923 }
4924 }
4925
4926 M (IP_TABLE_REPLACE_END, mp);
4927
4928 mp->table.table_id = ntohl (table_id);
4929 mp->table.is_ip6 = is_ipv6;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004930
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004931 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06004932 W (ret);
4933 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004934}
4935
4936static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01004937api_set_ip_flow_hash (vat_main_t * vam)
4938{
4939 unformat_input_t *i = vam->input;
4940 vl_api_set_ip_flow_hash_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004941 u32 vrf_id = 0;
4942 u8 is_ipv6 = 0;
4943 u8 vrf_id_set = 0;
4944 u8 src = 0;
4945 u8 dst = 0;
4946 u8 sport = 0;
4947 u8 dport = 0;
4948 u8 proto = 0;
4949 u8 reverse = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004950 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004951
4952 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4953 {
4954 if (unformat (i, "vrf %d", &vrf_id))
4955 vrf_id_set = 1;
4956 else if (unformat (i, "ipv6"))
4957 is_ipv6 = 1;
4958 else if (unformat (i, "src"))
4959 src = 1;
4960 else if (unformat (i, "dst"))
4961 dst = 1;
4962 else if (unformat (i, "sport"))
4963 sport = 1;
4964 else if (unformat (i, "dport"))
4965 dport = 1;
4966 else if (unformat (i, "proto"))
4967 proto = 1;
4968 else if (unformat (i, "reverse"))
4969 reverse = 1;
4970
4971 else
4972 {
4973 clib_warning ("parse error '%U'", format_unformat_error, i);
4974 return -99;
4975 }
4976 }
4977
4978 if (vrf_id_set == 0)
4979 {
4980 errmsg ("missing vrf id");
4981 return -99;
4982 }
4983
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004984 M (SET_IP_FLOW_HASH, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004985 mp->src = src;
4986 mp->dst = dst;
4987 mp->sport = sport;
4988 mp->dport = dport;
4989 mp->proto = proto;
4990 mp->reverse = reverse;
4991 mp->vrf_id = ntohl (vrf_id);
4992 mp->is_ipv6 = is_ipv6;
4993
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004994 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06004995 W (ret);
4996 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004997}
4998
4999static int
5000api_sw_interface_ip6_enable_disable (vat_main_t * vam)
5001{
5002 unformat_input_t *i = vam->input;
5003 vl_api_sw_interface_ip6_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005004 u32 sw_if_index;
5005 u8 sw_if_index_set = 0;
5006 u8 enable = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005007 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005008
5009 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5010 {
5011 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5012 sw_if_index_set = 1;
5013 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5014 sw_if_index_set = 1;
5015 else if (unformat (i, "enable"))
5016 enable = 1;
5017 else if (unformat (i, "disable"))
5018 enable = 0;
5019 else
5020 {
5021 clib_warning ("parse error '%U'", format_unformat_error, i);
5022 return -99;
5023 }
5024 }
5025
5026 if (sw_if_index_set == 0)
5027 {
5028 errmsg ("missing interface name or sw_if_index");
5029 return -99;
5030 }
5031
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005032 M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005033
5034 mp->sw_if_index = ntohl (sw_if_index);
5035 mp->enable = enable;
5036
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005037 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06005038 W (ret);
5039 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005040}
5041
Damjan Marion7cd468a2016-12-19 23:05:39 +01005042
5043static int
5044api_l2_patch_add_del (vat_main_t * vam)
5045{
5046 unformat_input_t *i = vam->input;
5047 vl_api_l2_patch_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005048 u32 rx_sw_if_index;
5049 u8 rx_sw_if_index_set = 0;
5050 u32 tx_sw_if_index;
5051 u8 tx_sw_if_index_set = 0;
5052 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005053 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005054
5055 /* Parse args required to build the message */
5056 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5057 {
5058 if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5059 rx_sw_if_index_set = 1;
5060 else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5061 tx_sw_if_index_set = 1;
5062 else if (unformat (i, "rx"))
5063 {
5064 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5065 {
5066 if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5067 &rx_sw_if_index))
5068 rx_sw_if_index_set = 1;
5069 }
5070 else
5071 break;
5072 }
5073 else if (unformat (i, "tx"))
5074 {
5075 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5076 {
5077 if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5078 &tx_sw_if_index))
5079 tx_sw_if_index_set = 1;
5080 }
5081 else
5082 break;
5083 }
5084 else if (unformat (i, "del"))
5085 is_add = 0;
5086 else
5087 break;
5088 }
5089
5090 if (rx_sw_if_index_set == 0)
5091 {
5092 errmsg ("missing rx interface name or rx_sw_if_index");
5093 return -99;
5094 }
5095
5096 if (tx_sw_if_index_set == 0)
5097 {
5098 errmsg ("missing tx interface name or tx_sw_if_index");
5099 return -99;
5100 }
5101
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005102 M (L2_PATCH_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005103
5104 mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5105 mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5106 mp->is_add = is_add;
5107
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005108 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06005109 W (ret);
5110 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005111}
5112
Pablo Camarillofb380952016-12-07 18:34:18 +01005113u8 is_del;
5114u8 localsid_addr[16];
5115u8 end_psp;
5116u8 behavior;
5117u32 sw_if_index;
5118u32 vlan_index;
5119u32 fib_table;
5120u8 nh_addr[16];
5121
5122static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01005123api_ioam_enable (vat_main_t * vam)
5124{
5125 unformat_input_t *input = vam->input;
5126 vl_api_ioam_enable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005127 u32 id = 0;
5128 int has_trace_option = 0;
5129 int has_pot_option = 0;
5130 int has_seqno_option = 0;
5131 int has_analyse_option = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005132 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005133
5134 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
5135 {
5136 if (unformat (input, "trace"))
5137 has_trace_option = 1;
5138 else if (unformat (input, "pot"))
5139 has_pot_option = 1;
5140 else if (unformat (input, "seqno"))
5141 has_seqno_option = 1;
5142 else if (unformat (input, "analyse"))
5143 has_analyse_option = 1;
5144 else
5145 break;
5146 }
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005147 M (IOAM_ENABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005148 mp->id = htons (id);
5149 mp->seqno = has_seqno_option;
5150 mp->analyse = has_analyse_option;
5151 mp->pot_enable = has_pot_option;
5152 mp->trace_enable = has_trace_option;
5153
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005154 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06005155 W (ret);
5156 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005157}
5158
5159
5160static int
5161api_ioam_disable (vat_main_t * vam)
5162{
5163 vl_api_ioam_disable_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005164 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005165
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005166 M (IOAM_DISABLE, mp);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005167 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06005168 W (ret);
5169 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005170}
5171
Damjan Marion7cd468a2016-12-19 23:05:39 +01005172#define foreach_tcp_proto_field \
5173_(src_port) \
5174_(dst_port)
5175
5176#define foreach_udp_proto_field \
5177_(src_port) \
5178_(dst_port)
5179
5180#define foreach_ip4_proto_field \
5181_(src_address) \
5182_(dst_address) \
5183_(tos) \
5184_(length) \
5185_(fragment_id) \
5186_(ttl) \
5187_(protocol) \
5188_(checksum)
5189
Dave Barach4a3f69c2017-02-22 12:44:56 -05005190typedef struct
5191{
5192 u16 src_port, dst_port;
5193} tcpudp_header_t;
5194
5195#if VPP_API_TEST_BUILTIN == 0
Damjan Marion7cd468a2016-12-19 23:05:39 +01005196uword
5197unformat_tcp_mask (unformat_input_t * input, va_list * args)
5198{
5199 u8 **maskp = va_arg (*args, u8 **);
5200 u8 *mask = 0;
5201 u8 found_something = 0;
5202 tcp_header_t *tcp;
5203
5204#define _(a) u8 a=0;
5205 foreach_tcp_proto_field;
5206#undef _
5207
5208 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
5209 {
5210 if (0);
5211#define _(a) else if (unformat (input, #a)) a=1;
5212 foreach_tcp_proto_field
5213#undef _
5214 else
5215 break;
5216 }
5217
5218#define _(a) found_something += a;
5219 foreach_tcp_proto_field;
5220#undef _
5221
5222 if (found_something == 0)
5223 return 0;
5224
5225 vec_validate (mask, sizeof (*tcp) - 1);
5226
5227 tcp = (tcp_header_t *) mask;
5228
Dave Barachb7b92992018-10-17 10:38:51 -04005229#define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
Damjan Marion7cd468a2016-12-19 23:05:39 +01005230 foreach_tcp_proto_field;
5231#undef _
5232
5233 *maskp = mask;
5234 return 1;
5235}
5236
5237uword
5238unformat_udp_mask (unformat_input_t * input, va_list * args)
5239{
5240 u8 **maskp = va_arg (*args, u8 **);
5241 u8 *mask = 0;
5242 u8 found_something = 0;
5243 udp_header_t *udp;
5244
5245#define _(a) u8 a=0;
5246 foreach_udp_proto_field;
5247#undef _
5248
5249 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
5250 {
5251 if (0);
5252#define _(a) else if (unformat (input, #a)) a=1;
5253 foreach_udp_proto_field
5254#undef _
5255 else
5256 break;
5257 }
5258
5259#define _(a) found_something += a;
5260 foreach_udp_proto_field;
5261#undef _
5262
5263 if (found_something == 0)
5264 return 0;
5265
5266 vec_validate (mask, sizeof (*udp) - 1);
5267
5268 udp = (udp_header_t *) mask;
5269
Dave Barachb7b92992018-10-17 10:38:51 -04005270#define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
Damjan Marion7cd468a2016-12-19 23:05:39 +01005271 foreach_udp_proto_field;
5272#undef _
5273
5274 *maskp = mask;
5275 return 1;
5276}
5277
Damjan Marion7cd468a2016-12-19 23:05:39 +01005278uword
5279unformat_l4_mask (unformat_input_t * input, va_list * args)
5280{
5281 u8 **maskp = va_arg (*args, u8 **);
5282 u16 src_port = 0, dst_port = 0;
5283 tcpudp_header_t *tcpudp;
5284
5285 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
5286 {
5287 if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
5288 return 1;
5289 else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
5290 return 1;
5291 else if (unformat (input, "src_port"))
5292 src_port = 0xFFFF;
5293 else if (unformat (input, "dst_port"))
5294 dst_port = 0xFFFF;
5295 else
5296 return 0;
5297 }
5298
5299 if (!src_port && !dst_port)
5300 return 0;
5301
5302 u8 *mask = 0;
5303 vec_validate (mask, sizeof (tcpudp_header_t) - 1);
5304
5305 tcpudp = (tcpudp_header_t *) mask;
5306 tcpudp->src_port = src_port;
5307 tcpudp->dst_port = dst_port;
5308
5309 *maskp = mask;
5310
5311 return 1;
5312}
5313
5314uword
5315unformat_ip4_mask (unformat_input_t * input, va_list * args)
5316{
5317 u8 **maskp = va_arg (*args, u8 **);
5318 u8 *mask = 0;
5319 u8 found_something = 0;
5320 ip4_header_t *ip;
5321
5322#define _(a) u8 a=0;
5323 foreach_ip4_proto_field;
5324#undef _
5325 u8 version = 0;
5326 u8 hdr_length = 0;
5327
5328
5329 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
5330 {
5331 if (unformat (input, "version"))
5332 version = 1;
5333 else if (unformat (input, "hdr_length"))
5334 hdr_length = 1;
5335 else if (unformat (input, "src"))
5336 src_address = 1;
5337 else if (unformat (input, "dst"))
5338 dst_address = 1;
5339 else if (unformat (input, "proto"))
5340 protocol = 1;
5341
5342#define _(a) else if (unformat (input, #a)) a=1;
5343 foreach_ip4_proto_field
5344#undef _
5345 else
5346 break;
5347 }
5348
5349#define _(a) found_something += a;
5350 foreach_ip4_proto_field;
5351#undef _
5352
5353 if (found_something == 0)
5354 return 0;
5355
5356 vec_validate (mask, sizeof (*ip) - 1);
5357
5358 ip = (ip4_header_t *) mask;
5359
Dave Barachb7b92992018-10-17 10:38:51 -04005360#define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
Damjan Marion7cd468a2016-12-19 23:05:39 +01005361 foreach_ip4_proto_field;
5362#undef _
5363
5364 ip->ip_version_and_header_length = 0;
5365
5366 if (version)
5367 ip->ip_version_and_header_length |= 0xF0;
5368
5369 if (hdr_length)
5370 ip->ip_version_and_header_length |= 0x0F;
5371
5372 *maskp = mask;
5373 return 1;
5374}
5375
5376#define foreach_ip6_proto_field \
5377_(src_address) \
5378_(dst_address) \
5379_(payload_length) \
5380_(hop_limit) \
5381_(protocol)
5382
5383uword
5384unformat_ip6_mask (unformat_input_t * input, va_list * args)
5385{
5386 u8 **maskp = va_arg (*args, u8 **);
5387 u8 *mask = 0;
5388 u8 found_something = 0;
5389 ip6_header_t *ip;
5390 u32 ip_version_traffic_class_and_flow_label;
5391
5392#define _(a) u8 a=0;
5393 foreach_ip6_proto_field;
5394#undef _
5395 u8 version = 0;
5396 u8 traffic_class = 0;
5397 u8 flow_label = 0;
5398
5399 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
5400 {
5401 if (unformat (input, "version"))
5402 version = 1;
5403 else if (unformat (input, "traffic-class"))
5404 traffic_class = 1;
5405 else if (unformat (input, "flow-label"))
5406 flow_label = 1;
5407 else if (unformat (input, "src"))
5408 src_address = 1;
5409 else if (unformat (input, "dst"))
5410 dst_address = 1;
5411 else if (unformat (input, "proto"))
5412 protocol = 1;
5413
5414#define _(a) else if (unformat (input, #a)) a=1;
5415 foreach_ip6_proto_field
5416#undef _
5417 else
5418 break;
5419 }
5420
5421#define _(a) found_something += a;
5422 foreach_ip6_proto_field;
5423#undef _
5424
5425 if (found_something == 0)
5426 return 0;
5427
5428 vec_validate (mask, sizeof (*ip) - 1);
5429
5430 ip = (ip6_header_t *) mask;
5431
Dave Barachb7b92992018-10-17 10:38:51 -04005432#define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
Damjan Marion7cd468a2016-12-19 23:05:39 +01005433 foreach_ip6_proto_field;
5434#undef _
5435
5436 ip_version_traffic_class_and_flow_label = 0;
5437
5438 if (version)
5439 ip_version_traffic_class_and_flow_label |= 0xF0000000;
5440
5441 if (traffic_class)
5442 ip_version_traffic_class_and_flow_label |= 0x0FF00000;
5443
5444 if (flow_label)
5445 ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
5446
5447 ip->ip_version_traffic_class_and_flow_label =
5448 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
5449
5450 *maskp = mask;
5451 return 1;
5452}
5453
5454uword
5455unformat_l3_mask (unformat_input_t * input, va_list * args)
5456{
5457 u8 **maskp = va_arg (*args, u8 **);
5458
5459 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
5460 {
5461 if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
5462 return 1;
5463 else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
5464 return 1;
5465 else
5466 break;
5467 }
5468 return 0;
5469}
5470
5471uword
5472unformat_l2_mask (unformat_input_t * input, va_list * args)
5473{
5474 u8 **maskp = va_arg (*args, u8 **);
5475 u8 *mask = 0;
5476 u8 src = 0;
5477 u8 dst = 0;
5478 u8 proto = 0;
5479 u8 tag1 = 0;
5480 u8 tag2 = 0;
5481 u8 ignore_tag1 = 0;
5482 u8 ignore_tag2 = 0;
5483 u8 cos1 = 0;
5484 u8 cos2 = 0;
5485 u8 dot1q = 0;
5486 u8 dot1ad = 0;
5487 int len = 14;
5488
5489 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
5490 {
5491 if (unformat (input, "src"))
5492 src = 1;
5493 else if (unformat (input, "dst"))
5494 dst = 1;
5495 else if (unformat (input, "proto"))
5496 proto = 1;
5497 else if (unformat (input, "tag1"))
5498 tag1 = 1;
5499 else if (unformat (input, "tag2"))
5500 tag2 = 1;
5501 else if (unformat (input, "ignore-tag1"))
5502 ignore_tag1 = 1;
5503 else if (unformat (input, "ignore-tag2"))
5504 ignore_tag2 = 1;
5505 else if (unformat (input, "cos1"))
5506 cos1 = 1;
5507 else if (unformat (input, "cos2"))
5508 cos2 = 1;
5509 else if (unformat (input, "dot1q"))
5510 dot1q = 1;
5511 else if (unformat (input, "dot1ad"))
5512 dot1ad = 1;
5513 else
5514 break;
5515 }
5516 if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
5517 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
5518 return 0;
5519
5520 if (tag1 || ignore_tag1 || cos1 || dot1q)
5521 len = 18;
5522 if (tag2 || ignore_tag2 || cos2 || dot1ad)
5523 len = 22;
5524
5525 vec_validate (mask, len - 1);
5526
5527 if (dst)
Dave Barachb7b92992018-10-17 10:38:51 -04005528 clib_memset (mask, 0xff, 6);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005529
5530 if (src)
Dave Barachb7b92992018-10-17 10:38:51 -04005531 clib_memset (mask + 6, 0xff, 6);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005532
5533 if (tag2 || dot1ad)
5534 {
5535 /* inner vlan tag */
5536 if (tag2)
5537 {
5538 mask[19] = 0xff;
5539 mask[18] = 0x0f;
5540 }
5541 if (cos2)
5542 mask[18] |= 0xe0;
5543 if (proto)
5544 mask[21] = mask[20] = 0xff;
5545 if (tag1)
5546 {
5547 mask[15] = 0xff;
5548 mask[14] = 0x0f;
5549 }
5550 if (cos1)
5551 mask[14] |= 0xe0;
5552 *maskp = mask;
5553 return 1;
5554 }
5555 if (tag1 | dot1q)
5556 {
5557 if (tag1)
5558 {
5559 mask[15] = 0xff;
5560 mask[14] = 0x0f;
5561 }
5562 if (cos1)
5563 mask[14] |= 0xe0;
5564 if (proto)
5565 mask[16] = mask[17] = 0xff;
5566
5567 *maskp = mask;
5568 return 1;
5569 }
5570 if (cos2)
5571 mask[18] |= 0xe0;
5572 if (cos1)
5573 mask[14] |= 0xe0;
5574 if (proto)
5575 mask[12] = mask[13] = 0xff;
5576
5577 *maskp = mask;
5578 return 1;
5579}
5580
5581uword
5582unformat_classify_mask (unformat_input_t * input, va_list * args)
5583{
5584 u8 **maskp = va_arg (*args, u8 **);
5585 u32 *skipp = va_arg (*args, u32 *);
5586 u32 *matchp = va_arg (*args, u32 *);
5587 u32 match;
5588 u8 *mask = 0;
5589 u8 *l2 = 0;
5590 u8 *l3 = 0;
5591 u8 *l4 = 0;
5592 int i;
5593
5594 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
5595 {
5596 if (unformat (input, "hex %U", unformat_hex_string, &mask))
5597 ;
5598 else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
5599 ;
5600 else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
5601 ;
5602 else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
5603 ;
5604 else
5605 break;
5606 }
5607
5608 if (l4 && !l3)
5609 {
5610 vec_free (mask);
5611 vec_free (l2);
5612 vec_free (l4);
5613 return 0;
5614 }
5615
5616 if (mask || l2 || l3 || l4)
5617 {
5618 if (l2 || l3 || l4)
5619 {
5620 /* "With a free Ethernet header in every package" */
5621 if (l2 == 0)
5622 vec_validate (l2, 13);
5623 mask = l2;
5624 if (vec_len (l3))
5625 {
5626 vec_append (mask, l3);
5627 vec_free (l3);
5628 }
5629 if (vec_len (l4))
5630 {
5631 vec_append (mask, l4);
5632 vec_free (l4);
5633 }
5634 }
5635
5636 /* Scan forward looking for the first significant mask octet */
5637 for (i = 0; i < vec_len (mask); i++)
5638 if (mask[i])
5639 break;
5640
5641 /* compute (skip, match) params */
5642 *skipp = i / sizeof (u32x4);
5643 vec_delete (mask, *skipp * sizeof (u32x4), 0);
5644
5645 /* Pad mask to an even multiple of the vector size */
5646 while (vec_len (mask) % sizeof (u32x4))
5647 vec_add1 (mask, 0);
5648
5649 match = vec_len (mask) / sizeof (u32x4);
5650
5651 for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
5652 {
5653 u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
5654 if (*tmp || *(tmp + 1))
5655 break;
5656 match--;
5657 }
5658 if (match == 0)
5659 clib_warning ("BUG: match 0");
5660
5661 _vec_len (mask) = match * sizeof (u32x4);
5662
5663 *matchp = match;
5664 *maskp = mask;
5665
5666 return 1;
5667 }
5668
5669 return 0;
5670}
Dave Barach4a3f69c2017-02-22 12:44:56 -05005671#endif /* VPP_API_TEST_BUILTIN */
Damjan Marion7cd468a2016-12-19 23:05:39 +01005672
5673#define foreach_l2_next \
5674_(drop, DROP) \
5675_(ethernet, ETHERNET_INPUT) \
5676_(ip4, IP4_INPUT) \
5677_(ip6, IP6_INPUT)
5678
5679uword
5680unformat_l2_next_index (unformat_input_t * input, va_list * args)
5681{
5682 u32 *miss_next_indexp = va_arg (*args, u32 *);
5683 u32 next_index = 0;
5684 u32 tmp;
5685
5686#define _(n,N) \
5687 if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
5688 foreach_l2_next;
5689#undef _
5690
5691 if (unformat (input, "%d", &tmp))
5692 {
5693 next_index = tmp;
5694 goto out;
5695 }
5696
5697 return 0;
5698
5699out:
5700 *miss_next_indexp = next_index;
5701 return 1;
5702}
5703
5704#define foreach_ip_next \
5705_(drop, DROP) \
5706_(local, LOCAL) \
5707_(rewrite, REWRITE)
5708
5709uword
Dave Barach4a3f69c2017-02-22 12:44:56 -05005710api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
Damjan Marion7cd468a2016-12-19 23:05:39 +01005711{
5712 u32 *miss_next_indexp = va_arg (*args, u32 *);
5713 u32 next_index = 0;
5714 u32 tmp;
5715
5716#define _(n,N) \
5717 if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
5718 foreach_ip_next;
5719#undef _
5720
5721 if (unformat (input, "%d", &tmp))
5722 {
5723 next_index = tmp;
5724 goto out;
5725 }
5726
5727 return 0;
5728
5729out:
5730 *miss_next_indexp = next_index;
5731 return 1;
5732}
5733
5734#define foreach_acl_next \
5735_(deny, DENY)
5736
5737uword
Dave Barach4a3f69c2017-02-22 12:44:56 -05005738api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
Damjan Marion7cd468a2016-12-19 23:05:39 +01005739{
5740 u32 *miss_next_indexp = va_arg (*args, u32 *);
5741 u32 next_index = 0;
5742 u32 tmp;
5743
5744#define _(n,N) \
5745 if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
5746 foreach_acl_next;
5747#undef _
5748
5749 if (unformat (input, "permit"))
5750 {
5751 next_index = ~0;
5752 goto out;
5753 }
5754 else if (unformat (input, "%d", &tmp))
5755 {
5756 next_index = tmp;
5757 goto out;
5758 }
5759
5760 return 0;
5761
5762out:
5763 *miss_next_indexp = next_index;
5764 return 1;
5765}
5766
5767uword
5768unformat_policer_precolor (unformat_input_t * input, va_list * args)
5769{
5770 u32 *r = va_arg (*args, u32 *);
5771
5772 if (unformat (input, "conform-color"))
5773 *r = POLICE_CONFORM;
5774 else if (unformat (input, "exceed-color"))
5775 *r = POLICE_EXCEED;
5776 else
5777 return 0;
5778
5779 return 1;
5780}
5781
Dave Barach4a3f69c2017-02-22 12:44:56 -05005782#if VPP_API_TEST_BUILTIN == 0
Damjan Marion7cd468a2016-12-19 23:05:39 +01005783uword
5784unformat_l4_match (unformat_input_t * input, va_list * args)
5785{
5786 u8 **matchp = va_arg (*args, u8 **);
5787
5788 u8 *proto_header = 0;
5789 int src_port = 0;
5790 int dst_port = 0;
5791
5792 tcpudp_header_t h;
5793
5794 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
5795 {
5796 if (unformat (input, "src_port %d", &src_port))
5797 ;
5798 else if (unformat (input, "dst_port %d", &dst_port))
5799 ;
5800 else
5801 return 0;
5802 }
5803
5804 h.src_port = clib_host_to_net_u16 (src_port);
5805 h.dst_port = clib_host_to_net_u16 (dst_port);
5806 vec_validate (proto_header, sizeof (h) - 1);
5807 memcpy (proto_header, &h, sizeof (h));
5808
5809 *matchp = proto_header;
5810
5811 return 1;
5812}
5813
5814uword
5815unformat_ip4_match (unformat_input_t * input, va_list * args)
5816{
5817 u8 **matchp = va_arg (*args, u8 **);
5818 u8 *match = 0;
5819 ip4_header_t *ip;
5820 int version = 0;
5821 u32 version_val;
5822 int hdr_length = 0;
5823 u32 hdr_length_val;
5824 int src = 0, dst = 0;
5825 ip4_address_t src_val, dst_val;
5826 int proto = 0;
5827 u32 proto_val;
5828 int tos = 0;
5829 u32 tos_val;
5830 int length = 0;
5831 u32 length_val;
5832 int fragment_id = 0;
5833 u32 fragment_id_val;
5834 int ttl = 0;
5835 int ttl_val;
5836 int checksum = 0;
5837 u32 checksum_val;
5838
5839 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
5840 {
5841 if (unformat (input, "version %d", &version_val))
5842 version = 1;
5843 else if (unformat (input, "hdr_length %d", &hdr_length_val))
5844 hdr_length = 1;
5845 else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
5846 src = 1;
5847 else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
5848 dst = 1;
5849 else if (unformat (input, "proto %d", &proto_val))
5850 proto = 1;
5851 else if (unformat (input, "tos %d", &tos_val))
5852 tos = 1;
5853 else if (unformat (input, "length %d", &length_val))
5854 length = 1;
5855 else if (unformat (input, "fragment_id %d", &fragment_id_val))
5856 fragment_id = 1;
5857 else if (unformat (input, "ttl %d", &ttl_val))
5858 ttl = 1;
5859 else if (unformat (input, "checksum %d", &checksum_val))
5860 checksum = 1;
5861 else
5862 break;
5863 }
5864
5865 if (version + hdr_length + src + dst + proto + tos + length + fragment_id
5866 + ttl + checksum == 0)
5867 return 0;
5868
5869 /*
5870 * Aligned because we use the real comparison functions
5871 */
5872 vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
5873
5874 ip = (ip4_header_t *) match;
5875
5876 /* These are realistically matched in practice */
5877 if (src)
5878 ip->src_address.as_u32 = src_val.as_u32;
5879
5880 if (dst)
5881 ip->dst_address.as_u32 = dst_val.as_u32;
5882
5883 if (proto)
5884 ip->protocol = proto_val;
5885
5886
5887 /* These are not, but they're included for completeness */
5888 if (version)
5889 ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
5890
5891 if (hdr_length)
5892 ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
5893
5894 if (tos)
5895 ip->tos = tos_val;
5896
5897 if (length)
5898 ip->length = clib_host_to_net_u16 (length_val);
5899
5900 if (ttl)
5901 ip->ttl = ttl_val;
5902
5903 if (checksum)
5904 ip->checksum = clib_host_to_net_u16 (checksum_val);
5905
5906 *matchp = match;
5907 return 1;
5908}
5909
5910uword
5911unformat_ip6_match (unformat_input_t * input, va_list * args)
5912{
5913 u8 **matchp = va_arg (*args, u8 **);
5914 u8 *match = 0;
5915 ip6_header_t *ip;
5916 int version = 0;
5917 u32 version_val;
5918 u8 traffic_class = 0;
5919 u32 traffic_class_val = 0;
5920 u8 flow_label = 0;
5921 u8 flow_label_val;
5922 int src = 0, dst = 0;
5923 ip6_address_t src_val, dst_val;
5924 int proto = 0;
5925 u32 proto_val;
5926 int payload_length = 0;
5927 u32 payload_length_val;
5928 int hop_limit = 0;
5929 int hop_limit_val;
5930 u32 ip_version_traffic_class_and_flow_label;
5931
5932 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
5933 {
5934 if (unformat (input, "version %d", &version_val))
5935 version = 1;
5936 else if (unformat (input, "traffic_class %d", &traffic_class_val))
5937 traffic_class = 1;
5938 else if (unformat (input, "flow_label %d", &flow_label_val))
5939 flow_label = 1;
5940 else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
5941 src = 1;
5942 else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
5943 dst = 1;
5944 else if (unformat (input, "proto %d", &proto_val))
5945 proto = 1;
5946 else if (unformat (input, "payload_length %d", &payload_length_val))
5947 payload_length = 1;
5948 else if (unformat (input, "hop_limit %d", &hop_limit_val))
5949 hop_limit = 1;
5950 else
5951 break;
5952 }
5953
5954 if (version + traffic_class + flow_label + src + dst + proto +
5955 payload_length + hop_limit == 0)
5956 return 0;
5957
5958 /*
5959 * Aligned because we use the real comparison functions
5960 */
5961 vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
5962
5963 ip = (ip6_header_t *) match;
5964
5965 if (src)
5966 clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
5967
5968 if (dst)
5969 clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
5970
5971 if (proto)
5972 ip->protocol = proto_val;
5973
5974 ip_version_traffic_class_and_flow_label = 0;
5975
5976 if (version)
5977 ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
5978
5979 if (traffic_class)
5980 ip_version_traffic_class_and_flow_label |=
5981 (traffic_class_val & 0xFF) << 20;
5982
5983 if (flow_label)
5984 ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
5985
5986 ip->ip_version_traffic_class_and_flow_label =
5987 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
5988
5989 if (payload_length)
5990 ip->payload_length = clib_host_to_net_u16 (payload_length_val);
5991
5992 if (hop_limit)
5993 ip->hop_limit = hop_limit_val;
5994
5995 *matchp = match;
5996 return 1;
5997}
5998
5999uword
6000unformat_l3_match (unformat_input_t * input, va_list * args)
6001{
6002 u8 **matchp = va_arg (*args, u8 **);
6003
6004 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
6005 {
6006 if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
6007 return 1;
6008 else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
6009 return 1;
6010 else
6011 break;
6012 }
6013 return 0;
6014}
6015
6016uword
6017unformat_vlan_tag (unformat_input_t * input, va_list * args)
6018{
6019 u8 *tagp = va_arg (*args, u8 *);
6020 u32 tag;
6021
6022 if (unformat (input, "%d", &tag))
6023 {
6024 tagp[0] = (tag >> 8) & 0x0F;
6025 tagp[1] = tag & 0xFF;
6026 return 1;
6027 }
6028
6029 return 0;
6030}
6031
6032uword
6033unformat_l2_match (unformat_input_t * input, va_list * args)
6034{
6035 u8 **matchp = va_arg (*args, u8 **);
6036 u8 *match = 0;
6037 u8 src = 0;
6038 u8 src_val[6];
6039 u8 dst = 0;
6040 u8 dst_val[6];
6041 u8 proto = 0;
6042 u16 proto_val;
6043 u8 tag1 = 0;
6044 u8 tag1_val[2];
6045 u8 tag2 = 0;
6046 u8 tag2_val[2];
6047 int len = 14;
6048 u8 ignore_tag1 = 0;
6049 u8 ignore_tag2 = 0;
6050 u8 cos1 = 0;
6051 u8 cos2 = 0;
6052 u32 cos1_val = 0;
6053 u32 cos2_val = 0;
6054
6055 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
6056 {
6057 if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
6058 src = 1;
6059 else
6060 if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
6061 dst = 1;
6062 else if (unformat (input, "proto %U",
6063 unformat_ethernet_type_host_byte_order, &proto_val))
6064 proto = 1;
6065 else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
6066 tag1 = 1;
6067 else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
6068 tag2 = 1;
6069 else if (unformat (input, "ignore-tag1"))
6070 ignore_tag1 = 1;
6071 else if (unformat (input, "ignore-tag2"))
6072 ignore_tag2 = 1;
6073 else if (unformat (input, "cos1 %d", &cos1_val))
6074 cos1 = 1;
6075 else if (unformat (input, "cos2 %d", &cos2_val))
6076 cos2 = 1;
6077 else
6078 break;
6079 }
6080 if ((src + dst + proto + tag1 + tag2 +
6081 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
6082 return 0;
6083
6084 if (tag1 || ignore_tag1 || cos1)
6085 len = 18;
6086 if (tag2 || ignore_tag2 || cos2)
6087 len = 22;
6088
6089 vec_validate_aligned (match, len - 1, sizeof (u32x4));
6090
6091 if (dst)
6092 clib_memcpy (match, dst_val, 6);
6093
6094 if (src)
6095 clib_memcpy (match + 6, src_val, 6);
6096
6097 if (tag2)
6098 {
6099 /* inner vlan tag */
6100 match[19] = tag2_val[1];
6101 match[18] = tag2_val[0];
6102 if (cos2)
6103 match[18] |= (cos2_val & 0x7) << 5;
6104 if (proto)
6105 {
6106 match[21] = proto_val & 0xff;
6107 match[20] = proto_val >> 8;
6108 }
6109 if (tag1)
6110 {
6111 match[15] = tag1_val[1];
6112 match[14] = tag1_val[0];
6113 }
6114 if (cos1)
6115 match[14] |= (cos1_val & 0x7) << 5;
6116 *matchp = match;
6117 return 1;
6118 }
6119 if (tag1)
6120 {
6121 match[15] = tag1_val[1];
6122 match[14] = tag1_val[0];
6123 if (proto)
6124 {
6125 match[17] = proto_val & 0xff;
6126 match[16] = proto_val >> 8;
6127 }
6128 if (cos1)
6129 match[14] |= (cos1_val & 0x7) << 5;
6130
6131 *matchp = match;
6132 return 1;
6133 }
6134 if (cos2)
6135 match[18] |= (cos2_val & 0x7) << 5;
6136 if (cos1)
6137 match[14] |= (cos1_val & 0x7) << 5;
6138 if (proto)
6139 {
6140 match[13] = proto_val & 0xff;
6141 match[12] = proto_val >> 8;
6142 }
6143
6144 *matchp = match;
6145 return 1;
6146}
Igor Mikhailov (imichail)582caa32018-04-26 21:33:02 -07006147
6148uword
6149unformat_qos_source (unformat_input_t * input, va_list * args)
6150{
6151 int *qs = va_arg (*args, int *);
6152
6153 if (unformat (input, "ip"))
6154 *qs = QOS_SOURCE_IP;
6155 else if (unformat (input, "mpls"))
6156 *qs = QOS_SOURCE_MPLS;
6157 else if (unformat (input, "ext"))
6158 *qs = QOS_SOURCE_EXT;
6159 else if (unformat (input, "vlan"))
6160 *qs = QOS_SOURCE_VLAN;
6161 else
6162 return 0;
6163
6164 return 1;
6165}
Dave Barach4a3f69c2017-02-22 12:44:56 -05006166#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +01006167
6168uword
Dave Barach4a3f69c2017-02-22 12:44:56 -05006169api_unformat_classify_match (unformat_input_t * input, va_list * args)
Damjan Marion7cd468a2016-12-19 23:05:39 +01006170{
6171 u8 **matchp = va_arg (*args, u8 **);
6172 u32 skip_n_vectors = va_arg (*args, u32);
6173 u32 match_n_vectors = va_arg (*args, u32);
6174
6175 u8 *match = 0;
6176 u8 *l2 = 0;
6177 u8 *l3 = 0;
6178 u8 *l4 = 0;
6179
6180 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
6181 {
6182 if (unformat (input, "hex %U", unformat_hex_string, &match))
6183 ;
6184 else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
6185 ;
6186 else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
6187 ;
6188 else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
6189 ;
6190 else
6191 break;
6192 }
6193
6194 if (l4 && !l3)
6195 {
6196 vec_free (match);
6197 vec_free (l2);
6198 vec_free (l4);
6199 return 0;
6200 }
6201
6202 if (match || l2 || l3 || l4)
6203 {
6204 if (l2 || l3 || l4)
6205 {
6206 /* "Win a free Ethernet header in every packet" */
6207 if (l2 == 0)
6208 vec_validate_aligned (l2, 13, sizeof (u32x4));
6209 match = l2;
6210 if (vec_len (l3))
6211 {
6212 vec_append_aligned (match, l3, sizeof (u32x4));
6213 vec_free (l3);
6214 }
6215 if (vec_len (l4))
6216 {
6217 vec_append_aligned (match, l4, sizeof (u32x4));
6218 vec_free (l4);
6219 }
6220 }
6221
6222 /* Make sure the vector is big enough even if key is all 0's */
6223 vec_validate_aligned
6224 (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
6225 sizeof (u32x4));
6226
6227 /* Set size, include skipped vectors */
6228 _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
6229
6230 *matchp = match;
6231
6232 return 1;
6233 }
6234
6235 return 0;
6236}
6237
6238static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01006239api_get_node_index (vat_main_t * vam)
6240{
6241 unformat_input_t *i = vam->input;
6242 vl_api_get_node_index_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006243 u8 *name = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006244 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006245
6246 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6247 {
6248 if (unformat (i, "node %s", &name))
6249 ;
6250 else
6251 break;
6252 }
6253 if (name == 0)
6254 {
6255 errmsg ("node name required");
6256 return -99;
6257 }
6258 if (vec_len (name) >= ARRAY_LEN (mp->node_name))
6259 {
6260 errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
6261 return -99;
6262 }
6263
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006264 M (GET_NODE_INDEX, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006265 clib_memcpy (mp->node_name, name, vec_len (name));
6266 vec_free (name);
6267
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006268 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06006269 W (ret);
6270 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006271}
6272
6273static int
6274api_get_next_index (vat_main_t * vam)
6275{
6276 unformat_input_t *i = vam->input;
6277 vl_api_get_next_index_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006278 u8 *node_name = 0, *next_node_name = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006279 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006280
6281 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6282 {
6283 if (unformat (i, "node-name %s", &node_name))
6284 ;
6285 else if (unformat (i, "next-node-name %s", &next_node_name))
6286 break;
6287 }
6288
6289 if (node_name == 0)
6290 {
6291 errmsg ("node name required");
6292 return -99;
6293 }
6294 if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
6295 {
6296 errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
6297 return -99;
6298 }
6299
6300 if (next_node_name == 0)
6301 {
6302 errmsg ("next node name required");
6303 return -99;
6304 }
6305 if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
6306 {
6307 errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
6308 return -99;
6309 }
6310
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006311 M (GET_NEXT_INDEX, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006312 clib_memcpy (mp->node_name, node_name, vec_len (node_name));
6313 clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
6314 vec_free (node_name);
6315 vec_free (next_node_name);
6316
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006317 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06006318 W (ret);
6319 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006320}
6321
6322static int
6323api_add_node_next (vat_main_t * vam)
6324{
6325 unformat_input_t *i = vam->input;
6326 vl_api_add_node_next_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006327 u8 *name = 0;
6328 u8 *next = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006329 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006330
6331 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6332 {
6333 if (unformat (i, "node %s", &name))
6334 ;
6335 else if (unformat (i, "next %s", &next))
6336 ;
6337 else
6338 break;
6339 }
6340 if (name == 0)
6341 {
6342 errmsg ("node name required");
6343 return -99;
6344 }
6345 if (vec_len (name) >= ARRAY_LEN (mp->node_name))
6346 {
6347 errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
6348 return -99;
6349 }
6350 if (next == 0)
6351 {
6352 errmsg ("next node required");
6353 return -99;
6354 }
6355 if (vec_len (next) >= ARRAY_LEN (mp->next_name))
6356 {
6357 errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
6358 return -99;
6359 }
6360
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006361 M (ADD_NODE_NEXT, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006362 clib_memcpy (mp->node_name, name, vec_len (name));
6363 clib_memcpy (mp->next_name, next, vec_len (next));
6364 vec_free (name);
6365 vec_free (next);
6366
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006367 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06006368 W (ret);
6369 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006370}
6371
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01006372static void vl_api_sw_interface_virtio_pci_details_t_handler
6373 (vl_api_sw_interface_virtio_pci_details_t * mp)
6374{
6375 vat_main_t *vam = &vat_main;
6376
6377 typedef union
6378 {
6379 struct
6380 {
6381 u16 domain;
6382 u8 bus;
6383 u8 slot:5;
6384 u8 function:3;
6385 };
6386 u32 as_u32;
6387 } pci_addr_t;
6388 pci_addr_t addr;
Jakub Grajciar2c504f82019-09-26 10:34:41 +02006389
6390 addr.domain = ntohs (mp->pci_addr.domain);
6391 addr.bus = mp->pci_addr.bus;
6392 addr.slot = mp->pci_addr.slot;
6393 addr.function = mp->pci_addr.function;
6394
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01006395 u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
6396 addr.slot, addr.function);
6397
6398 print (vam->ofp,
6399 "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
6400 pci_addr, ntohl (mp->sw_if_index),
6401 ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
6402 format_ethernet_address, mp->mac_addr,
6403 clib_net_to_host_u64 (mp->features));
6404 vec_free (pci_addr);
6405}
6406
6407static void vl_api_sw_interface_virtio_pci_details_t_handler_json
6408 (vl_api_sw_interface_virtio_pci_details_t * mp)
6409{
6410 vat_main_t *vam = &vat_main;
6411 vat_json_node_t *node = NULL;
Jakub Grajciar2c504f82019-09-26 10:34:41 +02006412 vlib_pci_addr_t pci_addr;
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01006413
6414 if (VAT_JSON_ARRAY != vam->json_tree.type)
6415 {
6416 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6417 vat_json_init_array (&vam->json_tree);
6418 }
6419 node = vat_json_array_add (&vam->json_tree);
6420
Jakub Grajciar2c504f82019-09-26 10:34:41 +02006421 pci_addr.domain = ntohs (mp->pci_addr.domain);
6422 pci_addr.bus = mp->pci_addr.bus;
6423 pci_addr.slot = mp->pci_addr.slot;
6424 pci_addr.function = mp->pci_addr.function;
6425
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01006426 vat_json_init_object (node);
Jakub Grajciar2c504f82019-09-26 10:34:41 +02006427 vat_json_object_add_uint (node, "pci-addr", pci_addr.as_u32);
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01006428 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6429 vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
6430 vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
6431 vat_json_object_add_uint (node, "features",
6432 clib_net_to_host_u64 (mp->features));
6433 vat_json_object_add_string_copy (node, "mac_addr",
6434 format (0, "%U", format_ethernet_address,
6435 &mp->mac_addr));
6436}
6437
6438static int
6439api_sw_interface_virtio_pci_dump (vat_main_t * vam)
6440{
6441 vl_api_sw_interface_virtio_pci_dump_t *mp;
6442 vl_api_control_ping_t *mp_ping;
6443 int ret;
6444
6445 print (vam->ofp,
6446 "\n%-12s %-12s %-12s %-12s %-17s %-08s",
6447 "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
6448 "mac_addr", "features");
6449
6450 /* Get list of tap interfaces */
6451 M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
6452 S (mp);
6453
6454 /* Use a control ping for synchronization */
6455 MPING (CONTROL_PING, mp_ping);
6456 S (mp_ping);
6457
6458 W (ret);
6459 return ret;
6460}
6461
eyal bariaf86a482018-04-17 11:20:27 +03006462static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01006463api_l2_fib_clear_table (vat_main_t * vam)
6464{
6465// unformat_input_t * i = vam->input;
6466 vl_api_l2_fib_clear_table_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006467 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006468
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006469 M (L2_FIB_CLEAR_TABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006470
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006471 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06006472 W (ret);
6473 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006474}
6475
6476static int
6477api_l2_interface_efp_filter (vat_main_t * vam)
6478{
6479 unformat_input_t *i = vam->input;
6480 vl_api_l2_interface_efp_filter_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006481 u32 sw_if_index;
6482 u8 enable = 1;
6483 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006484 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006485
6486 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6487 {
6488 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6489 sw_if_index_set = 1;
6490 else if (unformat (i, "sw_if_index %d", &sw_if_index))
6491 sw_if_index_set = 1;
6492 else if (unformat (i, "enable"))
6493 enable = 1;
6494 else if (unformat (i, "disable"))
6495 enable = 0;
6496 else
6497 {
6498 clib_warning ("parse error '%U'", format_unformat_error, i);
6499 return -99;
6500 }
6501 }
6502
6503 if (sw_if_index_set == 0)
6504 {
6505 errmsg ("missing sw_if_index");
6506 return -99;
6507 }
6508
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006509 M (L2_INTERFACE_EFP_FILTER, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006510
6511 mp->sw_if_index = ntohl (sw_if_index);
6512 mp->enable_disable = enable;
6513
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006514 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06006515 W (ret);
6516 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006517}
6518
6519#define foreach_vtr_op \
6520_("disable", L2_VTR_DISABLED) \
6521_("push-1", L2_VTR_PUSH_1) \
6522_("push-2", L2_VTR_PUSH_2) \
6523_("pop-1", L2_VTR_POP_1) \
6524_("pop-2", L2_VTR_POP_2) \
6525_("translate-1-1", L2_VTR_TRANSLATE_1_1) \
6526_("translate-1-2", L2_VTR_TRANSLATE_1_2) \
6527_("translate-2-1", L2_VTR_TRANSLATE_2_1) \
6528_("translate-2-2", L2_VTR_TRANSLATE_2_2)
6529
6530static int
6531api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
6532{
6533 unformat_input_t *i = vam->input;
6534 vl_api_l2_interface_vlan_tag_rewrite_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006535 u32 sw_if_index;
6536 u8 sw_if_index_set = 0;
6537 u8 vtr_op_set = 0;
6538 u32 vtr_op = 0;
6539 u32 push_dot1q = 1;
6540 u32 tag1 = ~0;
6541 u32 tag2 = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006542 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006543
6544 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6545 {
6546 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6547 sw_if_index_set = 1;
6548 else if (unformat (i, "sw_if_index %d", &sw_if_index))
6549 sw_if_index_set = 1;
6550 else if (unformat (i, "vtr_op %d", &vtr_op))
6551 vtr_op_set = 1;
6552#define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
6553 foreach_vtr_op
6554#undef _
6555 else if (unformat (i, "push_dot1q %d", &push_dot1q))
6556 ;
6557 else if (unformat (i, "tag1 %d", &tag1))
6558 ;
6559 else if (unformat (i, "tag2 %d", &tag2))
6560 ;
6561 else
6562 {
6563 clib_warning ("parse error '%U'", format_unformat_error, i);
6564 return -99;
6565 }
6566 }
6567
6568 if ((sw_if_index_set == 0) || (vtr_op_set == 0))
6569 {
6570 errmsg ("missing vtr operation or sw_if_index");
6571 return -99;
6572 }
6573
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006574 M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
6575 mp->sw_if_index = ntohl (sw_if_index);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006576 mp->vtr_op = ntohl (vtr_op);
6577 mp->push_dot1q = ntohl (push_dot1q);
6578 mp->tag1 = ntohl (tag1);
6579 mp->tag2 = ntohl (tag2);
6580
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006581 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06006582 W (ret);
6583 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006584}
6585
6586static int
Filip Tehlar4f348df2021-06-22 12:18:17 +00006587api_show_version (vat_main_t *vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +01006588{
6589 vl_api_show_version_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006590 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006591
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006592 M (SHOW_VERSION, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006593
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006594 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06006595 W (ret);
6596 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006597}
6598
Filip Tehlar4f348df2021-06-22 12:18:17 +00006599static void
6600vl_api_l2_fib_table_details_t_handler (vl_api_l2_fib_table_details_t *mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01006601{
6602 vat_main_t *vam = &vat_main;
6603
Filip Tehlar4f348df2021-06-22 12:18:17 +00006604 print (vam->ofp,
6605 "%3" PRIu32 " %U %3" PRIu32 " %d %d %d",
Mohsin Kazmi57938f62017-10-27 21:28:07 +02006606 ntohl (mp->bd_id), format_ethernet_address, mp->mac,
Filip Tehlar4f348df2021-06-22 12:18:17 +00006607 ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac, mp->bvi_mac);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006608}
6609
Filip Tehlar4f348df2021-06-22 12:18:17 +00006610static void
6611vl_api_l2_fib_table_details_t_handler_json (vl_api_l2_fib_table_details_t *mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01006612{
6613 vat_main_t *vam = &vat_main;
6614 vat_json_node_t *node = NULL;
6615
6616 if (VAT_JSON_ARRAY != vam->json_tree.type)
6617 {
6618 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6619 vat_json_init_array (&vam->json_tree);
6620 }
6621 node = vat_json_array_add (&vam->json_tree);
6622
6623 vat_json_init_object (node);
6624 vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
Mohsin Kazmi57938f62017-10-27 21:28:07 +02006625 vat_json_object_add_bytes (node, "mac", mp->mac, 6);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006626 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6627 vat_json_object_add_uint (node, "static_mac", mp->static_mac);
6628 vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
6629 vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
6630}
6631
6632static int
Filip Tehlar4f348df2021-06-22 12:18:17 +00006633api_l2_fib_table_dump (vat_main_t *vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +01006634{
6635 unformat_input_t *i = vam->input;
6636 vl_api_l2_fib_table_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -06006637 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006638 u32 bd_id;
6639 u8 bd_id_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006640 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006641
6642 /* Parse args required to build the message */
6643 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6644 {
6645 if (unformat (i, "bd_id %d", &bd_id))
6646 bd_id_set = 1;
6647 else
6648 break;
6649 }
6650
6651 if (bd_id_set == 0)
6652 {
6653 errmsg ("missing bridge domain");
6654 return -99;
6655 }
6656
6657 print (vam->ofp, "BD-ID Mac Address sw-ndx Static Filter BVI");
6658
6659 /* Get list of l2 fib entries */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006660 M (L2_FIB_TABLE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006661
6662 mp->bd_id = ntohl (bd_id);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006663 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006664
6665 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -04006666 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06006667 S (mp_ping);
6668
Jon Loeliger56c7b012017-02-01 12:31:41 -06006669 W (ret);
6670 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006671}
6672
Damjan Marion7cd468a2016-12-19 23:05:39 +01006673static int
Filip Tehlar4f348df2021-06-22 12:18:17 +00006674api_interface_name_renumber (vat_main_t *vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +01006675{
6676 unformat_input_t *line_input = vam->input;
6677 vl_api_interface_name_renumber_t *mp;
6678 u32 sw_if_index = ~0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006679 u32 new_show_dev_instance = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006680 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006681
6682 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
6683 {
6684 if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
6685 &sw_if_index))
6686 ;
6687 else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
6688 ;
6689 else if (unformat (line_input, "new_show_dev_instance %d",
6690 &new_show_dev_instance))
6691 ;
6692 else
6693 break;
6694 }
6695
6696 if (sw_if_index == ~0)
6697 {
6698 errmsg ("missing interface name or sw_if_index");
6699 return -99;
6700 }
6701
6702 if (new_show_dev_instance == ~0)
6703 {
6704 errmsg ("missing new_show_dev_instance");
6705 return -99;
6706 }
6707
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006708 M (INTERFACE_NAME_RENUMBER, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006709
6710 mp->sw_if_index = ntohl (sw_if_index);
6711 mp->new_show_dev_instance = ntohl (new_show_dev_instance);
6712
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006713 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06006714 W (ret);
6715 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006716}
6717
6718static int
Filip Tehlar4f348df2021-06-22 12:18:17 +00006719api_want_l2_macs_events (vat_main_t *vam)
John Lo8d00fff2017-08-03 00:35:36 -04006720{
6721 unformat_input_t *line_input = vam->input;
6722 vl_api_want_l2_macs_events_t *mp;
6723 u8 enable_disable = 1;
6724 u32 scan_delay = 0;
6725 u32 max_macs_in_event = 0;
6726 u32 learn_limit = 0;
6727 int ret;
6728
6729 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
6730 {
6731 if (unformat (line_input, "learn-limit %d", &learn_limit))
6732 ;
6733 else if (unformat (line_input, "scan-delay %d", &scan_delay))
6734 ;
6735 else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
6736 ;
6737 else if (unformat (line_input, "disable"))
6738 enable_disable = 0;
6739 else
6740 break;
6741 }
6742
6743 M (WANT_L2_MACS_EVENTS, mp);
6744 mp->enable_disable = enable_disable;
6745 mp->pid = htonl (getpid ());
6746 mp->learn_limit = htonl (learn_limit);
6747 mp->scan_delay = (u8) scan_delay;
6748 mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
6749 S (mp);
6750 W (ret);
6751 return ret;
6752}
6753
6754static int
Filip Tehlar4f348df2021-06-22 12:18:17 +00006755api_ip_address_dump (vat_main_t *vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +01006756{
6757 unformat_input_t *i = vam->input;
6758 vl_api_ip_address_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -06006759 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006760 u32 sw_if_index = ~0;
6761 u8 sw_if_index_set = 0;
6762 u8 ipv4_set = 0;
6763 u8 ipv6_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006764 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006765
6766 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6767 {
6768 if (unformat (i, "sw_if_index %d", &sw_if_index))
6769 sw_if_index_set = 1;
Filip Tehlar4f348df2021-06-22 12:18:17 +00006770 else if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
Damjan Marion7cd468a2016-12-19 23:05:39 +01006771 sw_if_index_set = 1;
6772 else if (unformat (i, "ipv4"))
6773 ipv4_set = 1;
6774 else if (unformat (i, "ipv6"))
6775 ipv6_set = 1;
6776 else
6777 break;
6778 }
6779
6780 if (ipv4_set && ipv6_set)
6781 {
6782 errmsg ("ipv4 and ipv6 flags cannot be both set");
6783 return -99;
6784 }
6785
6786 if ((!ipv4_set) && (!ipv6_set))
6787 {
6788 errmsg ("no ipv4 nor ipv6 flag set");
6789 return -99;
6790 }
6791
6792 if (sw_if_index_set == 0)
6793 {
6794 errmsg ("missing interface name or sw_if_index");
6795 return -99;
6796 }
6797
6798 vam->current_sw_if_index = sw_if_index;
6799 vam->is_ipv6 = ipv6_set;
6800
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006801 M (IP_ADDRESS_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006802 mp->sw_if_index = ntohl (sw_if_index);
6803 mp->is_ipv6 = ipv6_set;
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006804 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006805
6806 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -04006807 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06006808 S (mp_ping);
6809
Jon Loeliger56c7b012017-02-01 12:31:41 -06006810 W (ret);
6811 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006812}
6813
6814static int
6815api_ip_dump (vat_main_t * vam)
6816{
6817 vl_api_ip_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -06006818 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006819 unformat_input_t *in = vam->input;
6820 int ipv4_set = 0;
6821 int ipv6_set = 0;
6822 int is_ipv6;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006823 int i;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006824 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006825
6826 while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
6827 {
6828 if (unformat (in, "ipv4"))
6829 ipv4_set = 1;
6830 else if (unformat (in, "ipv6"))
6831 ipv6_set = 1;
6832 else
6833 break;
6834 }
6835
6836 if (ipv4_set && ipv6_set)
6837 {
6838 errmsg ("ipv4 and ipv6 flags cannot be both set");
6839 return -99;
6840 }
6841
6842 if ((!ipv4_set) && (!ipv6_set))
6843 {
6844 errmsg ("no ipv4 nor ipv6 flag set");
6845 return -99;
6846 }
6847
6848 is_ipv6 = ipv6_set;
6849 vam->is_ipv6 = is_ipv6;
6850
6851 /* free old data */
6852 for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
6853 {
6854 vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
6855 }
6856 vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
6857
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006858 M (IP_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006859 mp->is_ipv6 = ipv6_set;
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006860 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006861
6862 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -04006863 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06006864 S (mp_ping);
6865
Jon Loeliger56c7b012017-02-01 12:31:41 -06006866 W (ret);
6867 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006868}
6869
6870static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01006871api_get_first_msg_id (vat_main_t * vam)
6872{
6873 vl_api_get_first_msg_id_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006874 unformat_input_t *i = vam->input;
6875 u8 *name;
6876 u8 name_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006877 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006878
6879 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6880 {
6881 if (unformat (i, "client %s", &name))
6882 name_set = 1;
6883 else
6884 break;
6885 }
6886
6887 if (name_set == 0)
6888 {
6889 errmsg ("missing client name");
6890 return -99;
6891 }
6892 vec_add1 (name, 0);
6893
6894 if (vec_len (name) > 63)
6895 {
6896 errmsg ("client name too long");
6897 return -99;
6898 }
6899
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006900 M (GET_FIRST_MSG_ID, mp);
Ole Troan7adaa222019-08-27 15:05:27 +02006901 clib_memcpy (mp->name, name, vec_len (name));
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006902 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06006903 W (ret);
6904 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006905}
6906
6907static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01006908api_get_node_graph (vat_main_t * vam)
6909{
6910 vl_api_get_node_graph_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006911 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006912
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006913 M (GET_NODE_GRAPH, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006914
6915 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006916 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006917 /* Wait for the reply */
Jon Loeliger56c7b012017-02-01 12:31:41 -06006918 W (ret);
6919 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006920}
6921
Neale Ranns097fa662018-05-01 05:17:55 -07006922static u8 *
6923format_fib_api_path_nh_proto (u8 * s, va_list * args)
Neale Ranns0f26c5a2017-03-01 15:12:11 -08006924{
Neale Ranns097fa662018-05-01 05:17:55 -07006925 vl_api_fib_path_nh_proto_t proto =
6926 va_arg (*args, vl_api_fib_path_nh_proto_t);
6927
6928 switch (proto)
6929 {
6930 case FIB_API_PATH_NH_PROTO_IP4:
6931 s = format (s, "ip4");
6932 break;
6933 case FIB_API_PATH_NH_PROTO_IP6:
6934 s = format (s, "ip6");
6935 break;
6936 case FIB_API_PATH_NH_PROTO_MPLS:
6937 s = format (s, "mpls");
6938 break;
6939 case FIB_API_PATH_NH_PROTO_BIER:
6940 s = format (s, "bier");
6941 break;
6942 case FIB_API_PATH_NH_PROTO_ETHERNET:
6943 s = format (s, "ethernet");
6944 break;
6945 }
6946
6947 return (s);
6948}
6949
6950static u8 *
6951format_vl_api_ip_address_union (u8 * s, va_list * args)
6952{
Jakub Grajciar7dd63e52020-03-19 08:03:55 +01006953 vl_api_address_family_t af = va_arg (*args, int);
Neale Ranns097fa662018-05-01 05:17:55 -07006954 const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
6955
6956 switch (af)
6957 {
6958 case ADDRESS_IP4:
6959 s = format (s, "%U", format_ip4_address, u->ip4);
6960 break;
6961 case ADDRESS_IP6:
6962 s = format (s, "%U", format_ip6_address, u->ip6);
6963 break;
6964 }
6965 return (s);
6966}
6967
6968static u8 *
6969format_vl_api_fib_path_type (u8 * s, va_list * args)
6970{
6971 vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
6972
6973 switch (t)
6974 {
6975 case FIB_API_PATH_TYPE_NORMAL:
6976 s = format (s, "normal");
6977 break;
6978 case FIB_API_PATH_TYPE_LOCAL:
6979 s = format (s, "local");
6980 break;
6981 case FIB_API_PATH_TYPE_DROP:
6982 s = format (s, "drop");
6983 break;
6984 case FIB_API_PATH_TYPE_UDP_ENCAP:
6985 s = format (s, "udp-encap");
6986 break;
6987 case FIB_API_PATH_TYPE_BIER_IMP:
6988 s = format (s, "bier-imp");
6989 break;
6990 case FIB_API_PATH_TYPE_ICMP_UNREACH:
6991 s = format (s, "unreach");
6992 break;
6993 case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
6994 s = format (s, "prohibit");
6995 break;
6996 case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
6997 s = format (s, "src-lookup");
6998 break;
6999 case FIB_API_PATH_TYPE_DVR:
7000 s = format (s, "dvr");
7001 break;
7002 case FIB_API_PATH_TYPE_INTERFACE_RX:
7003 s = format (s, "interface-rx");
7004 break;
7005 case FIB_API_PATH_TYPE_CLASSIFY:
7006 s = format (s, "classify");
7007 break;
7008 }
7009
7010 return (s);
7011}
7012
7013static void
7014vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
7015{
7016 print (vam->ofp,
7017 " weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
7018 ntohl (fp->weight), ntohl (fp->sw_if_index),
7019 format_vl_api_fib_path_type, fp->type,
7020 format_fib_api_path_nh_proto, fp->proto,
7021 format_vl_api_ip_address_union, &fp->nh.address);
Neale Ranns0f26c5a2017-03-01 15:12:11 -08007022}
7023
7024static void
7025vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
Neale Ranns31ed7442018-02-23 05:29:09 -08007026 vl_api_fib_path_t * fp)
Neale Ranns0f26c5a2017-03-01 15:12:11 -08007027{
7028 struct in_addr ip4;
7029 struct in6_addr ip6;
7030
7031 vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
7032 vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
Neale Ranns097fa662018-05-01 05:17:55 -07007033 vat_json_object_add_uint (node, "type", fp->type);
7034 vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
7035 if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
Neale Ranns0f26c5a2017-03-01 15:12:11 -08007036 {
Neale Ranns097fa662018-05-01 05:17:55 -07007037 clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
Neale Ranns0f26c5a2017-03-01 15:12:11 -08007038 vat_json_object_add_ip4 (node, "next_hop", ip4);
7039 }
Dave Barachc35f3e82020-04-02 10:44:09 -04007040 else if (fp->proto == FIB_API_PATH_NH_PROTO_IP6)
Neale Ranns0f26c5a2017-03-01 15:12:11 -08007041 {
Neale Ranns097fa662018-05-01 05:17:55 -07007042 clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
Neale Ranns0f26c5a2017-03-01 15:12:11 -08007043 vat_json_object_add_ip6 (node, "next_hop", ip6);
7044 }
7045}
7046
7047static void
7048vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01007049{
7050 vat_main_t *vam = &vat_main;
Neale Ranns097fa662018-05-01 05:17:55 -07007051 int count = ntohl (mp->mt_tunnel.mt_n_paths);
Neale Ranns31ed7442018-02-23 05:29:09 -08007052 vl_api_fib_path_t *fp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007053 i32 i;
7054
Neale Ranns097fa662018-05-01 05:17:55 -07007055 print (vam->ofp, "sw_if_index %d via:",
7056 ntohl (mp->mt_tunnel.mt_sw_if_index));
7057 fp = mp->mt_tunnel.mt_paths;
Neale Ranns0f26c5a2017-03-01 15:12:11 -08007058 for (i = 0; i < count; i++)
Damjan Marion7cd468a2016-12-19 23:05:39 +01007059 {
Neale Ranns097fa662018-05-01 05:17:55 -07007060 vl_api_fib_path_print (vam, fp);
Neale Ranns0f26c5a2017-03-01 15:12:11 -08007061 fp++;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007062 }
Neale Ranns0f26c5a2017-03-01 15:12:11 -08007063
Damjan Marion7cd468a2016-12-19 23:05:39 +01007064 print (vam->ofp, "");
7065}
7066
Neale Ranns0f26c5a2017-03-01 15:12:11 -08007067#define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
7068#define vl_api_mpls_tunnel_details_t_print vl_noop_handler
7069
7070static void
7071vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01007072{
7073 vat_main_t *vam = &vat_main;
7074 vat_json_node_t *node = NULL;
Neale Ranns097fa662018-05-01 05:17:55 -07007075 int count = ntohl (mp->mt_tunnel.mt_n_paths);
Neale Ranns31ed7442018-02-23 05:29:09 -08007076 vl_api_fib_path_t *fp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007077 i32 i;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007078
7079 if (VAT_JSON_ARRAY != vam->json_tree.type)
7080 {
7081 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7082 vat_json_init_array (&vam->json_tree);
7083 }
7084 node = vat_json_array_add (&vam->json_tree);
7085
7086 vat_json_init_object (node);
Neale Ranns097fa662018-05-01 05:17:55 -07007087 vat_json_object_add_uint (node, "sw_if_index",
7088 ntohl (mp->mt_tunnel.mt_sw_if_index));
Neale Ranns0f26c5a2017-03-01 15:12:11 -08007089
Neale Ranns097fa662018-05-01 05:17:55 -07007090 vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
Neale Ranns0f26c5a2017-03-01 15:12:11 -08007091
Neale Ranns097fa662018-05-01 05:17:55 -07007092 fp = mp->mt_tunnel.mt_paths;
Neale Ranns0f26c5a2017-03-01 15:12:11 -08007093 for (i = 0; i < count; i++)
Damjan Marion7cd468a2016-12-19 23:05:39 +01007094 {
Neale Ranns0f26c5a2017-03-01 15:12:11 -08007095 vl_api_mpls_fib_path_json_print (node, fp);
7096 fp++;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007097 }
7098}
7099
7100static int
7101api_mpls_tunnel_dump (vat_main_t * vam)
7102{
7103 vl_api_mpls_tunnel_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -06007104 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007105 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007106
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007107 M (MPLS_TUNNEL_DUMP, mp);
Neale Ranns097fa662018-05-01 05:17:55 -07007108
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007109 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007110
7111 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -04007112 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06007113 S (mp_ping);
7114
Jon Loeliger56c7b012017-02-01 12:31:41 -06007115 W (ret);
7116 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007117}
7118
Neale Ranns097fa662018-05-01 05:17:55 -07007119#define vl_api_mpls_table_details_t_endian vl_noop_handler
7120#define vl_api_mpls_table_details_t_print vl_noop_handler
Damjan Marion7cd468a2016-12-19 23:05:39 +01007121
Neale Ranns0f26c5a2017-03-01 15:12:11 -08007122
Damjan Marion7cd468a2016-12-19 23:05:39 +01007123static void
Neale Ranns097fa662018-05-01 05:17:55 -07007124vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01007125{
7126 vat_main_t *vam = &vat_main;
Neale Ranns097fa662018-05-01 05:17:55 -07007127
7128 print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
7129}
7130
7131static void vl_api_mpls_table_details_t_handler_json
7132 (vl_api_mpls_table_details_t * mp)
7133{
7134 vat_main_t *vam = &vat_main;
7135 vat_json_node_t *node = NULL;
7136
7137 if (VAT_JSON_ARRAY != vam->json_tree.type)
7138 {
7139 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7140 vat_json_init_array (&vam->json_tree);
7141 }
7142 node = vat_json_array_add (&vam->json_tree);
7143
7144 vat_json_init_object (node);
7145 vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
7146}
7147
7148static int
7149api_mpls_table_dump (vat_main_t * vam)
7150{
7151 vl_api_mpls_table_dump_t *mp;
7152 vl_api_control_ping_t *mp_ping;
7153 int ret;
7154
7155 M (MPLS_TABLE_DUMP, mp);
7156 S (mp);
7157
7158 /* Use a control ping for synchronization */
7159 MPING (CONTROL_PING, mp_ping);
7160 S (mp_ping);
7161
7162 W (ret);
7163 return ret;
7164}
7165
7166#define vl_api_mpls_route_details_t_endian vl_noop_handler
7167#define vl_api_mpls_route_details_t_print vl_noop_handler
7168
7169static void
7170vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
7171{
7172 vat_main_t *vam = &vat_main;
Dave Barach4bda2d92019-07-03 15:21:50 -04007173 int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
Neale Ranns31ed7442018-02-23 05:29:09 -08007174 vl_api_fib_path_t *fp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007175 int i;
7176
7177 print (vam->ofp,
7178 "table-id %d, label %u, ess_bit %u",
Neale Ranns097fa662018-05-01 05:17:55 -07007179 ntohl (mp->mr_route.mr_table_id),
7180 ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
7181 fp = mp->mr_route.mr_paths;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007182 for (i = 0; i < count; i++)
7183 {
Neale Ranns097fa662018-05-01 05:17:55 -07007184 vl_api_fib_path_print (vam, fp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007185 fp++;
7186 }
7187}
7188
Neale Ranns097fa662018-05-01 05:17:55 -07007189static void vl_api_mpls_route_details_t_handler_json
7190 (vl_api_mpls_route_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01007191{
7192 vat_main_t *vam = &vat_main;
Dave Barach4bda2d92019-07-03 15:21:50 -04007193 int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007194 vat_json_node_t *node = NULL;
Neale Ranns31ed7442018-02-23 05:29:09 -08007195 vl_api_fib_path_t *fp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007196 int i;
7197
7198 if (VAT_JSON_ARRAY != vam->json_tree.type)
7199 {
7200 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7201 vat_json_init_array (&vam->json_tree);
7202 }
7203 node = vat_json_array_add (&vam->json_tree);
7204
7205 vat_json_init_object (node);
Neale Ranns097fa662018-05-01 05:17:55 -07007206 vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
7207 vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
7208 vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
Damjan Marion7cd468a2016-12-19 23:05:39 +01007209 vat_json_object_add_uint (node, "path_count", count);
Neale Ranns097fa662018-05-01 05:17:55 -07007210 fp = mp->mr_route.mr_paths;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007211 for (i = 0; i < count; i++)
7212 {
Neale Ranns0f26c5a2017-03-01 15:12:11 -08007213 vl_api_mpls_fib_path_json_print (node, fp);
7214 fp++;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007215 }
7216}
7217
7218static int
Neale Ranns097fa662018-05-01 05:17:55 -07007219api_mpls_route_dump (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +01007220{
Neale Ranns097fa662018-05-01 05:17:55 -07007221 unformat_input_t *input = vam->input;
7222 vl_api_mpls_route_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -06007223 vl_api_control_ping_t *mp_ping;
Neale Ranns097fa662018-05-01 05:17:55 -07007224 u32 table_id;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007225 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007226
Neale Ranns097fa662018-05-01 05:17:55 -07007227 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7228 {
7229 if (unformat (input, "table_id %d", &table_id))
7230 ;
7231 else
7232 break;
7233 }
7234 if (table_id == ~0)
7235 {
7236 errmsg ("missing table id");
7237 return -99;
7238 }
7239
7240 M (MPLS_ROUTE_DUMP, mp);
7241
7242 mp->table.mt_table_id = ntohl (table_id);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007243 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007244
7245 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -04007246 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06007247 S (mp_ping);
7248
Jon Loeliger56c7b012017-02-01 12:31:41 -06007249 W (ret);
7250 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007251}
7252
Neale Ranns097fa662018-05-01 05:17:55 -07007253#define vl_api_ip_table_details_t_endian vl_noop_handler
7254#define vl_api_ip_table_details_t_print vl_noop_handler
Damjan Marion7cd468a2016-12-19 23:05:39 +01007255
7256static void
Neale Ranns097fa662018-05-01 05:17:55 -07007257vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01007258{
7259 vat_main_t *vam = &vat_main;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007260
7261 print (vam->ofp,
Neale Ranns097fa662018-05-01 05:17:55 -07007262 "%s; table-id %d, prefix %U/%d",
7263 mp->table.name, ntohl (mp->table.table_id));
Damjan Marion7cd468a2016-12-19 23:05:39 +01007264}
7265
Neale Ranns097fa662018-05-01 05:17:55 -07007266
7267static void vl_api_ip_table_details_t_handler_json
7268 (vl_api_ip_table_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01007269{
7270 vat_main_t *vam = &vat_main;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007271 vat_json_node_t *node = NULL;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007272
7273 if (VAT_JSON_ARRAY != vam->json_tree.type)
7274 {
7275 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7276 vat_json_init_array (&vam->json_tree);
7277 }
7278 node = vat_json_array_add (&vam->json_tree);
7279
7280 vat_json_init_object (node);
Neale Ranns097fa662018-05-01 05:17:55 -07007281 vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
Damjan Marion7cd468a2016-12-19 23:05:39 +01007282}
7283
7284static int
Neale Ranns097fa662018-05-01 05:17:55 -07007285api_ip_table_dump (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +01007286{
Neale Ranns097fa662018-05-01 05:17:55 -07007287 vl_api_ip_table_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -06007288 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007289 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007290
Neale Ranns097fa662018-05-01 05:17:55 -07007291 M (IP_TABLE_DUMP, mp);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007292 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007293
7294 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -04007295 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06007296 S (mp_ping);
7297
Jon Loeliger56c7b012017-02-01 12:31:41 -06007298 W (ret);
7299 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007300}
7301
Neale Ranns5a8123b2017-01-26 01:18:23 -08007302static int
Neale Ranns097fa662018-05-01 05:17:55 -07007303api_ip_mtable_dump (vat_main_t * vam)
Neale Ranns5a8123b2017-01-26 01:18:23 -08007304{
Neale Ranns097fa662018-05-01 05:17:55 -07007305 vl_api_ip_mtable_dump_t *mp;
Neale Ranns5a8123b2017-01-26 01:18:23 -08007306 vl_api_control_ping_t *mp_ping;
7307 int ret;
7308
Neale Ranns097fa662018-05-01 05:17:55 -07007309 M (IP_MTABLE_DUMP, mp);
7310 S (mp);
7311
7312 /* Use a control ping for synchronization */
7313 MPING (CONTROL_PING, mp_ping);
7314 S (mp_ping);
7315
7316 W (ret);
7317 return ret;
7318}
7319
7320static int
7321api_ip_mroute_dump (vat_main_t * vam)
7322{
7323 unformat_input_t *input = vam->input;
7324 vl_api_control_ping_t *mp_ping;
7325 vl_api_ip_mroute_dump_t *mp;
7326 int ret, is_ip6;
7327 u32 table_id;
7328
7329 is_ip6 = 0;
7330 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7331 {
7332 if (unformat (input, "table_id %d", &table_id))
7333 ;
7334 else if (unformat (input, "ip6"))
7335 is_ip6 = 1;
7336 else if (unformat (input, "ip4"))
7337 is_ip6 = 0;
7338 else
7339 break;
7340 }
7341 if (table_id == ~0)
7342 {
7343 errmsg ("missing table id");
7344 return -99;
7345 }
7346
7347 M (IP_MROUTE_DUMP, mp);
7348 mp->table.table_id = table_id;
7349 mp->table.is_ip6 = is_ip6;
Neale Ranns5a8123b2017-01-26 01:18:23 -08007350 S (mp);
7351
7352 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -04007353 MPING (CONTROL_PING, mp_ping);
Neale Ranns5a8123b2017-01-26 01:18:23 -08007354 S (mp_ping);
7355
7356 W (ret);
7357 return ret;
7358}
7359
Neale Ranns097fa662018-05-01 05:17:55 -07007360#define vl_api_ip_route_details_t_endian vl_noop_handler
7361#define vl_api_ip_route_details_t_print vl_noop_handler
Damjan Marion7cd468a2016-12-19 23:05:39 +01007362
7363static void
Neale Ranns097fa662018-05-01 05:17:55 -07007364vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01007365{
7366 vat_main_t *vam = &vat_main;
Neale Ranns097fa662018-05-01 05:17:55 -07007367 u8 count = mp->route.n_paths;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007368 vl_api_fib_path_t *fp;
7369 int i;
7370
7371 print (vam->ofp,
Neale Ranns097fa662018-05-01 05:17:55 -07007372 "table-id %d, prefix %U/%d",
7373 ntohl (mp->route.table_id),
Paul Vinciguerraab055082019-06-06 14:07:55 -04007374 format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007375 for (i = 0; i < count; i++)
7376 {
Neale Ranns097fa662018-05-01 05:17:55 -07007377 fp = &mp->route.paths[i];
7378
7379 vl_api_fib_path_print (vam, fp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007380 fp++;
7381 }
7382}
7383
Neale Ranns097fa662018-05-01 05:17:55 -07007384static void vl_api_ip_route_details_t_handler_json
7385 (vl_api_ip_route_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01007386{
7387 vat_main_t *vam = &vat_main;
Neale Ranns097fa662018-05-01 05:17:55 -07007388 u8 count = mp->route.n_paths;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007389 vat_json_node_t *node = NULL;
7390 struct in_addr ip4;
7391 struct in6_addr ip6;
7392 vl_api_fib_path_t *fp;
7393 int i;
7394
7395 if (VAT_JSON_ARRAY != vam->json_tree.type)
7396 {
7397 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7398 vat_json_init_array (&vam->json_tree);
7399 }
7400 node = vat_json_array_add (&vam->json_tree);
7401
7402 vat_json_init_object (node);
Neale Ranns097fa662018-05-01 05:17:55 -07007403 vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
7404 if (ADDRESS_IP6 == mp->route.prefix.address.af)
7405 {
7406 clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
7407 vat_json_object_add_ip6 (node, "prefix", ip6);
7408 }
7409 else
7410 {
7411 clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
7412 vat_json_object_add_ip4 (node, "prefix", ip4);
7413 }
Paul Vinciguerraab055082019-06-06 14:07:55 -04007414 vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007415 vat_json_object_add_uint (node, "path_count", count);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007416 for (i = 0; i < count; i++)
7417 {
Neale Ranns097fa662018-05-01 05:17:55 -07007418 fp = &mp->route.paths[i];
7419 vl_api_mpls_fib_path_json_print (node, fp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007420 }
7421}
7422
7423static int
Neale Ranns097fa662018-05-01 05:17:55 -07007424api_ip_route_dump (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +01007425{
Neale Ranns097fa662018-05-01 05:17:55 -07007426 unformat_input_t *input = vam->input;
7427 vl_api_ip_route_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -06007428 vl_api_control_ping_t *mp_ping;
Neale Ranns097fa662018-05-01 05:17:55 -07007429 u32 table_id;
7430 u8 is_ip6;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007431 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007432
Neale Ranns097fa662018-05-01 05:17:55 -07007433 is_ip6 = 0;
7434 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7435 {
7436 if (unformat (input, "table_id %d", &table_id))
7437 ;
7438 else if (unformat (input, "ip6"))
7439 is_ip6 = 1;
7440 else if (unformat (input, "ip4"))
7441 is_ip6 = 0;
7442 else
7443 break;
7444 }
7445 if (table_id == ~0)
7446 {
7447 errmsg ("missing table id");
7448 return -99;
7449 }
Damjan Marion7cd468a2016-12-19 23:05:39 +01007450
Neale Ranns097fa662018-05-01 05:17:55 -07007451 M (IP_ROUTE_DUMP, mp);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06007452
Neale Ranns097fa662018-05-01 05:17:55 -07007453 mp->table.table_id = table_id;
7454 mp->table.is_ip6 = is_ip6;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007455
Neale Ranns5a8123b2017-01-26 01:18:23 -08007456 S (mp);
7457
7458 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -04007459 MPING (CONTROL_PING, mp_ping);
Neale Ranns5a8123b2017-01-26 01:18:23 -08007460 S (mp_ping);
7461
7462 W (ret);
7463 return ret;
7464}
7465
Damjan Marion7cd468a2016-12-19 23:05:39 +01007466int
Damjan Marion7cd468a2016-12-19 23:05:39 +01007467api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
7468{
7469 unformat_input_t *input = vam->input;
7470 vl_api_ip_source_and_port_range_check_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007471
7472 u16 *low_ports = 0;
7473 u16 *high_ports = 0;
7474 u16 this_low;
7475 u16 this_hi;
Neale Ranns37029302018-08-10 05:30:06 -07007476 vl_api_prefix_t prefix;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007477 u32 tmp, tmp2;
7478 u8 prefix_set = 0;
7479 u32 vrf_id = ~0;
7480 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007481 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007482
7483 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7484 {
Neale Ranns37029302018-08-10 05:30:06 -07007485 if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
7486 prefix_set = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007487 else if (unformat (input, "vrf %d", &vrf_id))
7488 ;
7489 else if (unformat (input, "del"))
7490 is_add = 0;
7491 else if (unformat (input, "port %d", &tmp))
7492 {
7493 if (tmp == 0 || tmp > 65535)
7494 {
7495 errmsg ("port %d out of range", tmp);
7496 return -99;
7497 }
7498 this_low = tmp;
7499 this_hi = this_low + 1;
7500 vec_add1 (low_ports, this_low);
7501 vec_add1 (high_ports, this_hi);
7502 }
7503 else if (unformat (input, "range %d - %d", &tmp, &tmp2))
7504 {
7505 if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
7506 {
7507 errmsg ("incorrect range parameters");
7508 return -99;
7509 }
7510 this_low = tmp;
7511 /* Note: in debug CLI +1 is added to high before
7512 passing to real fn that does "the work"
7513 (ip_source_and_port_range_check_add_del).
7514 This fn is a wrapper around the binary API fn a
7515 control plane will call, which expects this increment
7516 to have occurred. Hence letting the binary API control
7517 plane fn do the increment for consistency between VAT
7518 and other control planes.
7519 */
7520 this_hi = tmp2;
7521 vec_add1 (low_ports, this_low);
7522 vec_add1 (high_ports, this_hi);
7523 }
7524 else
7525 break;
7526 }
7527
7528 if (prefix_set == 0)
7529 {
7530 errmsg ("<address>/<mask> not specified");
7531 return -99;
7532 }
7533
7534 if (vrf_id == ~0)
7535 {
7536 errmsg ("VRF ID required, not specified");
7537 return -99;
7538 }
7539
7540 if (vrf_id == 0)
7541 {
7542 errmsg
7543 ("VRF ID should not be default. Should be distinct VRF for this purpose.");
7544 return -99;
7545 }
7546
7547 if (vec_len (low_ports) == 0)
7548 {
7549 errmsg ("At least one port or port range required");
7550 return -99;
7551 }
7552
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007553 M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007554
7555 mp->is_add = is_add;
7556
Neale Ranns37029302018-08-10 05:30:06 -07007557 clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
Damjan Marion7cd468a2016-12-19 23:05:39 +01007558
Damjan Marion7cd468a2016-12-19 23:05:39 +01007559 mp->number_of_ranges = vec_len (low_ports);
7560
7561 clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
7562 vec_free (low_ports);
7563
7564 clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
7565 vec_free (high_ports);
7566
7567 mp->vrf_id = ntohl (vrf_id);
7568
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007569 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007570 W (ret);
7571 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007572}
7573
7574int
7575api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
7576{
7577 unformat_input_t *input = vam->input;
7578 vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007579 u32 sw_if_index = ~0;
7580 int vrf_set = 0;
7581 u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
7582 u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
7583 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007584 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007585
7586 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7587 {
7588 if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7589 ;
7590 else if (unformat (input, "sw_if_index %d", &sw_if_index))
7591 ;
7592 else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
7593 vrf_set = 1;
7594 else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
7595 vrf_set = 1;
7596 else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
7597 vrf_set = 1;
7598 else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
7599 vrf_set = 1;
7600 else if (unformat (input, "del"))
7601 is_add = 0;
7602 else
7603 break;
7604 }
7605
7606 if (sw_if_index == ~0)
7607 {
7608 errmsg ("Interface required but not specified");
7609 return -99;
7610 }
7611
7612 if (vrf_set == 0)
7613 {
7614 errmsg ("VRF ID required but not specified");
7615 return -99;
7616 }
7617
7618 if (tcp_out_vrf_id == 0
7619 || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
7620 {
7621 errmsg
7622 ("VRF ID should not be default. Should be distinct VRF for this purpose.");
7623 return -99;
7624 }
7625
7626 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007627 M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007628
7629 mp->sw_if_index = ntohl (sw_if_index);
7630 mp->is_add = is_add;
7631 mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
7632 mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
7633 mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
7634 mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
7635
7636 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007637 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007638
7639 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06007640 W (ret);
7641 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007642}
7643
7644static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01007645api_delete_subif (vat_main_t * vam)
7646{
7647 unformat_input_t *i = vam->input;
7648 vl_api_delete_subif_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007649 u32 sw_if_index = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007650 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007651
7652 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7653 {
7654 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7655 ;
7656 if (unformat (i, "sw_if_index %d", &sw_if_index))
7657 ;
7658 else
7659 break;
7660 }
7661
7662 if (sw_if_index == ~0)
7663 {
7664 errmsg ("missing sw_if_index");
7665 return -99;
7666 }
7667
7668 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007669 M (DELETE_SUBIF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007670 mp->sw_if_index = ntohl (sw_if_index);
7671
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007672 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007673 W (ret);
7674 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007675}
7676
7677#define foreach_pbb_vtr_op \
7678_("disable", L2_VTR_DISABLED) \
7679_("pop", L2_VTR_POP_2) \
7680_("push", L2_VTR_PUSH_2)
7681
7682static int
7683api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
7684{
7685 unformat_input_t *i = vam->input;
7686 vl_api_l2_interface_pbb_tag_rewrite_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007687 u32 sw_if_index = ~0, vtr_op = ~0;
7688 u16 outer_tag = ~0;
7689 u8 dmac[6], smac[6];
7690 u8 dmac_set = 0, smac_set = 0;
7691 u16 vlanid = 0;
7692 u32 sid = ~0;
7693 u32 tmp;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007694 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007695
7696 /* Shut up coverity */
Dave Barachb7b92992018-10-17 10:38:51 -04007697 clib_memset (dmac, 0, sizeof (dmac));
7698 clib_memset (smac, 0, sizeof (smac));
Damjan Marion7cd468a2016-12-19 23:05:39 +01007699
7700 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7701 {
7702 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7703 ;
7704 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7705 ;
7706 else if (unformat (i, "vtr_op %d", &vtr_op))
7707 ;
7708#define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
7709 foreach_pbb_vtr_op
7710#undef _
7711 else if (unformat (i, "translate_pbb_stag"))
7712 {
7713 if (unformat (i, "%d", &tmp))
7714 {
7715 vtr_op = L2_VTR_TRANSLATE_2_1;
7716 outer_tag = tmp;
7717 }
7718 else
7719 {
7720 errmsg
7721 ("translate_pbb_stag operation requires outer tag definition");
7722 return -99;
7723 }
7724 }
7725 else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
7726 dmac_set++;
7727 else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
7728 smac_set++;
7729 else if (unformat (i, "sid %d", &sid))
7730 ;
7731 else if (unformat (i, "vlanid %d", &tmp))
7732 vlanid = tmp;
7733 else
7734 {
7735 clib_warning ("parse error '%U'", format_unformat_error, i);
7736 return -99;
7737 }
7738 }
7739
7740 if ((sw_if_index == ~0) || (vtr_op == ~0))
7741 {
7742 errmsg ("missing sw_if_index or vtr operation");
7743 return -99;
7744 }
7745 if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
7746 && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
7747 {
7748 errmsg
7749 ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
7750 return -99;
7751 }
7752
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007753 M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007754 mp->sw_if_index = ntohl (sw_if_index);
7755 mp->vtr_op = ntohl (vtr_op);
7756 mp->outer_tag = ntohs (outer_tag);
7757 clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
7758 clib_memcpy (mp->b_smac, smac, sizeof (smac));
7759 mp->b_vlanid = ntohs (vlanid);
7760 mp->i_sid = ntohl (sid);
7761
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007762 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007763 W (ret);
7764 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007765}
7766
7767static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01007768api_sw_interface_tag_add_del (vat_main_t * vam)
7769{
7770 unformat_input_t *i = vam->input;
7771 vl_api_sw_interface_tag_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007772 u32 sw_if_index = ~0;
7773 u8 *tag = 0;
7774 u8 enable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007775 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007776
7777 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7778 {
7779 if (unformat (i, "tag %s", &tag))
7780 ;
7781 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7782 ;
7783 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7784 ;
7785 else if (unformat (i, "del"))
7786 enable = 0;
7787 else
7788 break;
7789 }
7790
7791 if (sw_if_index == ~0)
7792 {
7793 errmsg ("missing interface name or sw_if_index");
7794 return -99;
7795 }
7796
7797 if (enable && (tag == 0))
7798 {
7799 errmsg ("no tag specified");
7800 return -99;
7801 }
7802
7803 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007804 M (SW_INTERFACE_TAG_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007805 mp->sw_if_index = ntohl (sw_if_index);
7806 mp->is_add = enable;
7807 if (enable)
Ole Troane5ff5a32019-08-23 22:55:18 +02007808 strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007809 vec_free (tag);
7810
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007811 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007812 W (ret);
7813 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007814}
7815
Matthew Smithe0792fd2019-07-12 11:48:24 -05007816static int
7817api_sw_interface_add_del_mac_address (vat_main_t * vam)
7818{
7819 unformat_input_t *i = vam->input;
7820 vl_api_mac_address_t mac = { 0 };
7821 vl_api_sw_interface_add_del_mac_address_t *mp;
7822 u32 sw_if_index = ~0;
7823 u8 is_add = 1;
7824 u8 mac_set = 0;
7825 int ret;
7826
7827 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7828 {
7829 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7830 ;
7831 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7832 ;
7833 else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7834 mac_set++;
7835 else if (unformat (i, "del"))
7836 is_add = 0;
7837 else
7838 break;
7839 }
7840
7841 if (sw_if_index == ~0)
7842 {
7843 errmsg ("missing interface name or sw_if_index");
7844 return -99;
7845 }
7846
7847 if (!mac_set)
7848 {
7849 errmsg ("missing MAC address");
7850 return -99;
7851 }
7852
7853 /* Construct the API message */
7854 M (SW_INTERFACE_ADD_DEL_MAC_ADDRESS, mp);
7855 mp->sw_if_index = ntohl (sw_if_index);
7856 mp->is_add = is_add;
7857 clib_memcpy (&mp->addr, &mac, sizeof (mac));
7858
7859 S (mp);
7860 W (ret);
7861 return ret;
7862}
7863
Damjan Marion7cd468a2016-12-19 23:05:39 +01007864static void vl_api_l2_xconnect_details_t_handler
7865 (vl_api_l2_xconnect_details_t * mp)
7866{
7867 vat_main_t *vam = &vat_main;
7868
7869 print (vam->ofp, "%15d%15d",
7870 ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
7871}
7872
7873static void vl_api_l2_xconnect_details_t_handler_json
7874 (vl_api_l2_xconnect_details_t * mp)
7875{
7876 vat_main_t *vam = &vat_main;
7877 vat_json_node_t *node = NULL;
7878
7879 if (VAT_JSON_ARRAY != vam->json_tree.type)
7880 {
7881 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7882 vat_json_init_array (&vam->json_tree);
7883 }
7884 node = vat_json_array_add (&vam->json_tree);
7885
7886 vat_json_init_object (node);
7887 vat_json_object_add_uint (node, "rx_sw_if_index",
7888 ntohl (mp->rx_sw_if_index));
7889 vat_json_object_add_uint (node, "tx_sw_if_index",
7890 ntohl (mp->tx_sw_if_index));
7891}
7892
7893static int
7894api_l2_xconnect_dump (vat_main_t * vam)
7895{
7896 vl_api_l2_xconnect_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -06007897 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007898 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007899
7900 if (!vam->json_output)
7901 {
7902 print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
7903 }
7904
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007905 M (L2_XCONNECT_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007906
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007907 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007908
7909 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -04007910 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06007911 S (mp_ping);
7912
Jon Loeliger56c7b012017-02-01 12:31:41 -06007913 W (ret);
7914 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007915}
7916
7917static int
Ole Troand7231612018-06-07 10:17:57 +02007918api_hw_interface_set_mtu (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +01007919{
7920 unformat_input_t *i = vam->input;
Ole Troand7231612018-06-07 10:17:57 +02007921 vl_api_hw_interface_set_mtu_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007922 u32 sw_if_index = ~0;
7923 u32 mtu = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007924 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007925
7926 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7927 {
7928 if (unformat (i, "mtu %d", &mtu))
7929 ;
7930 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7931 ;
7932 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7933 ;
7934 else
7935 break;
7936 }
7937
7938 if (sw_if_index == ~0)
7939 {
7940 errmsg ("missing interface name or sw_if_index");
7941 return -99;
7942 }
7943
7944 if (mtu == 0)
7945 {
7946 errmsg ("no mtu specified");
7947 return -99;
7948 }
7949
7950 /* Construct the API message */
Ole Troand7231612018-06-07 10:17:57 +02007951 M (HW_INTERFACE_SET_MTU, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007952 mp->sw_if_index = ntohl (sw_if_index);
7953 mp->mtu = ntohs ((u16) mtu);
7954
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007955 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007956 W (ret);
7957 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007958}
7959
Florin Coras6e8c6672017-11-10 09:03:54 -08007960static void vl_api_app_namespace_add_del_reply_t_handler
7961 (vl_api_app_namespace_add_del_reply_t * mp)
7962{
7963 vat_main_t *vam = &vat_main;
7964 i32 retval = ntohl (mp->retval);
7965 if (vam->async_mode)
7966 {
7967 vam->async_errors += (retval < 0);
7968 }
7969 else
7970 {
7971 vam->retval = retval;
7972 if (retval == 0)
7973 errmsg ("app ns index %d\n", ntohl (mp->appns_index));
7974 vam->result_ready = 1;
7975 }
7976}
7977
7978static void vl_api_app_namespace_add_del_reply_t_handler_json
7979 (vl_api_app_namespace_add_del_reply_t * mp)
7980{
7981 vat_main_t *vam = &vat_main;
7982 vat_json_node_t node;
7983
7984 vat_json_init_object (&node);
7985 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
7986 vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
7987
7988 vat_json_print (vam->ofp, &node);
7989 vat_json_free (&node);
7990
7991 vam->retval = ntohl (mp->retval);
7992 vam->result_ready = 1;
7993}
7994
Dave Barach3bbcfab2017-08-15 19:03:44 -04007995static int
Florin Corascea194d2017-10-02 00:18:51 -07007996api_app_namespace_add_del (vat_main_t * vam)
7997{
7998 vl_api_app_namespace_add_del_t *mp;
7999 unformat_input_t *i = vam->input;
8000 u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
8001 u32 sw_if_index, ip4_fib_id, ip6_fib_id;
8002 u64 secret;
8003 int ret;
8004
8005 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8006 {
8007 if (unformat (i, "id %_%v%_", &ns_id))
8008 ;
8009 else if (unformat (i, "secret %lu", &secret))
8010 secret_set = 1;
8011 else if (unformat (i, "sw_if_index %d", &sw_if_index))
8012 sw_if_index_set = 1;
8013 else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
8014 ;
8015 else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
8016 ;
8017 else
8018 break;
8019 }
8020 if (!ns_id || !secret_set || !sw_if_index_set)
8021 {
8022 errmsg ("namespace id, secret and sw_if_index must be set");
8023 return -99;
8024 }
8025 if (vec_len (ns_id) > 64)
8026 {
8027 errmsg ("namespace id too long");
8028 return -99;
8029 }
8030 M (APP_NAMESPACE_ADD_DEL, mp);
8031
Jakub Grajciarb4e5e502020-01-31 09:35:29 +01008032 vl_api_vec_to_api_string (ns_id, &mp->namespace_id);
Florin Coras9a9adb22017-10-26 08:16:59 -07008033 mp->secret = clib_host_to_net_u64 (secret);
Florin Corascea194d2017-10-02 00:18:51 -07008034 mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
8035 mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
8036 mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
8037 vec_free (ns_id);
8038 S (mp);
8039 W (ret);
8040 return ret;
8041}
8042
8043static int
Florin Coras90a63982017-12-19 04:50:01 -08008044api_sock_init_shm (vat_main_t * vam)
8045{
8046#if VPP_API_TEST_BUILTIN == 0
8047 unformat_input_t *i = vam->input;
8048 vl_api_shm_elem_config_t *config = 0;
8049 u64 size = 64 << 20;
8050 int rv;
8051
8052 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8053 {
8054 if (unformat (i, "size %U", unformat_memory_size, &size))
8055 ;
8056 else
8057 break;
8058 }
8059
Dave Barach78958722018-05-10 16:44:27 -04008060 /*
8061 * Canned custom ring allocator config.
8062 * Should probably parse all of this
8063 */
8064 vec_validate (config, 6);
Florin Coras90a63982017-12-19 04:50:01 -08008065 config[0].type = VL_API_VLIB_RING;
Florin Coras90a63982017-12-19 04:50:01 -08008066 config[0].size = 256;
Dave Barach78958722018-05-10 16:44:27 -04008067 config[0].count = 32;
8068
8069 config[1].type = VL_API_VLIB_RING;
Florin Coras90a63982017-12-19 04:50:01 -08008070 config[1].size = 1024;
Dave Barach78958722018-05-10 16:44:27 -04008071 config[1].count = 16;
8072
8073 config[2].type = VL_API_VLIB_RING;
Florin Coras90a63982017-12-19 04:50:01 -08008074 config[2].size = 4096;
Dave Barach78958722018-05-10 16:44:27 -04008075 config[2].count = 2;
8076
8077 config[3].type = VL_API_CLIENT_RING;
8078 config[3].size = 256;
8079 config[3].count = 32;
8080
8081 config[4].type = VL_API_CLIENT_RING;
8082 config[4].size = 1024;
8083 config[4].count = 16;
8084
8085 config[5].type = VL_API_CLIENT_RING;
8086 config[5].size = 4096;
8087 config[5].count = 2;
8088
8089 config[6].type = VL_API_QUEUE;
8090 config[6].count = 128;
8091 config[6].size = sizeof (uword);
8092
Tomasz Kulasek97dcf5b2019-01-31 18:26:32 +01008093 rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
Florin Coras90a63982017-12-19 04:50:01 -08008094 if (!rv)
8095 vam->client_index_invalid = 1;
8096 return rv;
8097#else
8098 return -99;
8099#endif
8100}
8101
Florin Coras6c36f532017-11-03 18:32:34 -07008102static void
8103vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
8104{
8105 vat_main_t *vam = &vat_main;
Jakub Grajciarb4e5e502020-01-31 09:35:29 +01008106 fib_prefix_t lcl, rmt;
Florin Coras6c36f532017-11-03 18:32:34 -07008107
Jakub Grajciarb4e5e502020-01-31 09:35:29 +01008108 ip_prefix_decode (&mp->lcl, &lcl);
8109 ip_prefix_decode (&mp->rmt, &rmt);
8110
8111 if (lcl.fp_proto == FIB_PROTOCOL_IP4)
Florin Coras6c36f532017-11-03 18:32:34 -07008112 {
Florin Corasc97a7392017-11-05 23:07:07 -08008113 print (vam->ofp,
8114 "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
Steven85dbac02017-11-07 16:29:53 -08008115 clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
Jakub Grajciarb4e5e502020-01-31 09:35:29 +01008116 mp->scope, format_ip4_address, &lcl.fp_addr.ip4, lcl.fp_len,
Steven85dbac02017-11-07 16:29:53 -08008117 clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
Jakub Grajciarb4e5e502020-01-31 09:35:29 +01008118 &rmt.fp_addr.ip4, rmt.fp_len,
8119 clib_net_to_host_u16 (mp->rmt_port),
Steven85dbac02017-11-07 16:29:53 -08008120 clib_net_to_host_u32 (mp->action_index), mp->tag);
Florin Coras6c36f532017-11-03 18:32:34 -07008121 }
8122 else
8123 {
Florin Corasc97a7392017-11-05 23:07:07 -08008124 print (vam->ofp,
8125 "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
Steven85dbac02017-11-07 16:29:53 -08008126 clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
Jakub Grajciarb4e5e502020-01-31 09:35:29 +01008127 mp->scope, format_ip6_address, &lcl.fp_addr.ip6, lcl.fp_len,
Steven85dbac02017-11-07 16:29:53 -08008128 clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
Jakub Grajciarb4e5e502020-01-31 09:35:29 +01008129 &rmt.fp_addr.ip6, rmt.fp_len,
8130 clib_net_to_host_u16 (mp->rmt_port),
Steven85dbac02017-11-07 16:29:53 -08008131 clib_net_to_host_u32 (mp->action_index), mp->tag);
Florin Coras6c36f532017-11-03 18:32:34 -07008132 }
8133}
8134
8135static void
8136vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
8137 mp)
8138{
8139 vat_main_t *vam = &vat_main;
8140 vat_json_node_t *node = NULL;
8141 struct in6_addr ip6;
8142 struct in_addr ip4;
8143
Jakub Grajciarb4e5e502020-01-31 09:35:29 +01008144 fib_prefix_t lcl, rmt;
8145
8146 ip_prefix_decode (&mp->lcl, &lcl);
8147 ip_prefix_decode (&mp->rmt, &rmt);
8148
Florin Coras6c36f532017-11-03 18:32:34 -07008149 if (VAT_JSON_ARRAY != vam->json_tree.type)
8150 {
8151 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
8152 vat_json_init_array (&vam->json_tree);
8153 }
8154 node = vat_json_array_add (&vam->json_tree);
8155 vat_json_init_object (node);
8156
Florin Coras6c36f532017-11-03 18:32:34 -07008157 vat_json_object_add_uint (node, "appns_index",
8158 clib_net_to_host_u32 (mp->appns_index));
8159 vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
8160 vat_json_object_add_uint (node, "scope", mp->scope);
8161 vat_json_object_add_uint (node, "action_index",
8162 clib_net_to_host_u32 (mp->action_index));
8163 vat_json_object_add_uint (node, "lcl_port",
8164 clib_net_to_host_u16 (mp->lcl_port));
8165 vat_json_object_add_uint (node, "rmt_port",
8166 clib_net_to_host_u16 (mp->rmt_port));
Jakub Grajciarb4e5e502020-01-31 09:35:29 +01008167 vat_json_object_add_uint (node, "lcl_plen", lcl.fp_len);
8168 vat_json_object_add_uint (node, "rmt_plen", rmt.fp_len);
Florin Corasc97a7392017-11-05 23:07:07 -08008169 vat_json_object_add_string_copy (node, "tag", mp->tag);
Jakub Grajciarb4e5e502020-01-31 09:35:29 +01008170 if (lcl.fp_proto == FIB_PROTOCOL_IP4)
Florin Coras6c36f532017-11-03 18:32:34 -07008171 {
Jakub Grajciarb4e5e502020-01-31 09:35:29 +01008172 clib_memcpy (&ip4, &lcl.fp_addr.ip4, sizeof (ip4));
Florin Coras6c36f532017-11-03 18:32:34 -07008173 vat_json_object_add_ip4 (node, "lcl_ip", ip4);
Jakub Grajciarb4e5e502020-01-31 09:35:29 +01008174 clib_memcpy (&ip4, &rmt.fp_addr.ip4, sizeof (ip4));
Florin Coras6c36f532017-11-03 18:32:34 -07008175 vat_json_object_add_ip4 (node, "rmt_ip", ip4);
8176 }
8177 else
8178 {
Jakub Grajciarb4e5e502020-01-31 09:35:29 +01008179 clib_memcpy (&ip6, &lcl.fp_addr.ip6, sizeof (ip6));
Florin Coras6c36f532017-11-03 18:32:34 -07008180 vat_json_object_add_ip6 (node, "lcl_ip", ip6);
Jakub Grajciarb4e5e502020-01-31 09:35:29 +01008181 clib_memcpy (&ip6, &rmt.fp_addr.ip6, sizeof (ip6));
Florin Coras6c36f532017-11-03 18:32:34 -07008182 vat_json_object_add_ip6 (node, "rmt_ip", ip6);
8183 }
8184}
8185
Florin Coras1c710452017-10-17 00:03:13 -07008186static int
8187api_session_rule_add_del (vat_main_t * vam)
8188{
8189 vl_api_session_rule_add_del_t *mp;
8190 unformat_input_t *i = vam->input;
8191 u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
8192 u32 appns_index = 0, scope = 0;
8193 ip4_address_t lcl_ip4, rmt_ip4;
8194 ip6_address_t lcl_ip6, rmt_ip6;
8195 u8 is_ip4 = 1, conn_set = 0;
Florin Corasc97a7392017-11-05 23:07:07 -08008196 u8 is_add = 1, *tag = 0;
Florin Coras1c710452017-10-17 00:03:13 -07008197 int ret;
Jakub Grajciarb4e5e502020-01-31 09:35:29 +01008198 fib_prefix_t lcl, rmt;
Florin Coras1c710452017-10-17 00:03:13 -07008199
8200 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8201 {
8202 if (unformat (i, "del"))
8203 is_add = 0;
8204 else if (unformat (i, "add"))
8205 ;
8206 else if (unformat (i, "proto tcp"))
8207 proto = 0;
8208 else if (unformat (i, "proto udp"))
8209 proto = 1;
8210 else if (unformat (i, "appns %d", &appns_index))
8211 ;
8212 else if (unformat (i, "scope %d", &scope))
8213 ;
Florin Corasc97a7392017-11-05 23:07:07 -08008214 else if (unformat (i, "tag %_%v%_", &tag))
8215 ;
Florin Coras1c710452017-10-17 00:03:13 -07008216 else
8217 if (unformat
8218 (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
8219 &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
8220 &rmt_port))
8221 {
8222 is_ip4 = 1;
8223 conn_set = 1;
8224 }
8225 else
8226 if (unformat
8227 (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
8228 &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
8229 &rmt_port))
8230 {
8231 is_ip4 = 0;
8232 conn_set = 1;
8233 }
8234 else if (unformat (i, "action %d", &action))
8235 ;
8236 else
8237 break;
8238 }
8239 if (proto == ~0 || !conn_set || action == ~0)
8240 {
8241 errmsg ("transport proto, connection and action must be set");
8242 return -99;
8243 }
8244
8245 if (scope > 3)
8246 {
8247 errmsg ("scope should be 0-3");
8248 return -99;
8249 }
8250
8251 M (SESSION_RULE_ADD_DEL, mp);
8252
Jakub Grajciarb4e5e502020-01-31 09:35:29 +01008253 clib_memset (&lcl, 0, sizeof (lcl));
8254 clib_memset (&rmt, 0, sizeof (rmt));
8255 if (is_ip4)
8256 {
8257 ip_set (&lcl.fp_addr, &lcl_ip4, 1);
8258 ip_set (&rmt.fp_addr, &rmt_ip4, 1);
8259 lcl.fp_len = lcl_plen;
8260 rmt.fp_len = rmt_plen;
8261 }
8262 else
8263 {
8264 ip_set (&lcl.fp_addr, &lcl_ip6, 0);
8265 ip_set (&rmt.fp_addr, &rmt_ip6, 0);
8266 lcl.fp_len = lcl_plen;
8267 rmt.fp_len = rmt_plen;
8268 }
8269
8270
8271 ip_prefix_encode (&lcl, &mp->lcl);
8272 ip_prefix_encode (&rmt, &mp->rmt);
Florin Corasc97a7392017-11-05 23:07:07 -08008273 mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
8274 mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
Jakub Grajciarb4e5e502020-01-31 09:35:29 +01008275 mp->transport_proto =
8276 proto ? TRANSPORT_PROTO_API_UDP : TRANSPORT_PROTO_API_TCP;
Florin Coras1c710452017-10-17 00:03:13 -07008277 mp->action_index = clib_host_to_net_u32 (action);
8278 mp->appns_index = clib_host_to_net_u32 (appns_index);
8279 mp->scope = scope;
8280 mp->is_add = is_add;
Florin Corasc97a7392017-11-05 23:07:07 -08008281 if (tag)
8282 {
8283 clib_memcpy (mp->tag, tag, vec_len (tag));
8284 vec_free (tag);
8285 }
Florin Coras1c710452017-10-17 00:03:13 -07008286
8287 S (mp);
8288 W (ret);
8289 return ret;
8290}
Dave Barach65457162017-10-10 17:53:14 -04008291
8292static int
Florin Coras6c36f532017-11-03 18:32:34 -07008293api_session_rules_dump (vat_main_t * vam)
8294{
8295 vl_api_session_rules_dump_t *mp;
8296 vl_api_control_ping_t *mp_ping;
8297 int ret;
8298
8299 if (!vam->json_output)
8300 {
8301 print (vam->ofp, "%=20s", "Session Rules");
8302 }
8303
8304 M (SESSION_RULES_DUMP, mp);
8305 /* send it... */
8306 S (mp);
8307
8308 /* Use a control ping for synchronization */
8309 MPING (CONTROL_PING, mp_ping);
8310 S (mp_ping);
8311
8312 /* Wait for a reply... */
8313 W (ret);
8314 return ret;
8315}
8316
8317static int
Florin Coras595992c2017-11-06 17:17:08 -08008318api_ip_container_proxy_add_del (vat_main_t * vam)
8319{
8320 vl_api_ip_container_proxy_add_del_t *mp;
8321 unformat_input_t *i = vam->input;
Neale Ranns37029302018-08-10 05:30:06 -07008322 u32 sw_if_index = ~0;
8323 vl_api_prefix_t pfx = { };
Florin Coras595992c2017-11-06 17:17:08 -08008324 u8 is_add = 1;
8325 int ret;
8326
8327 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8328 {
8329 if (unformat (i, "del"))
8330 is_add = 0;
8331 else if (unformat (i, "add"))
8332 ;
Neale Ranns37029302018-08-10 05:30:06 -07008333 if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8334 ;
Florin Coras595992c2017-11-06 17:17:08 -08008335 else if (unformat (i, "sw_if_index %u", &sw_if_index))
8336 ;
8337 else
8338 break;
8339 }
Paul Vinciguerraab055082019-06-06 14:07:55 -04008340 if (sw_if_index == ~0 || pfx.len == 0)
Florin Coras595992c2017-11-06 17:17:08 -08008341 {
8342 errmsg ("address and sw_if_index must be set");
8343 return -99;
8344 }
8345
8346 M (IP_CONTAINER_PROXY_ADD_DEL, mp);
8347
Florin Coras595992c2017-11-06 17:17:08 -08008348 mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
Florin Coras595992c2017-11-06 17:17:08 -08008349 mp->is_add = is_add;
Neale Ranns37029302018-08-10 05:30:06 -07008350 clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
Florin Coras595992c2017-11-06 17:17:08 -08008351
8352 S (mp);
8353 W (ret);
8354 return ret;
8355}
8356
8357static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01008358q_or_quit (vat_main_t * vam)
8359{
Dave Barachdef19da2017-02-22 17:29:20 -05008360#if VPP_API_TEST_BUILTIN == 0
Damjan Marion7cd468a2016-12-19 23:05:39 +01008361 longjmp (vam->jump_buf, 1);
Dave Barachdef19da2017-02-22 17:29:20 -05008362#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +01008363 return 0; /* not so much */
8364}
8365
8366static int
8367q (vat_main_t * vam)
8368{
8369 return q_or_quit (vam);
8370}
8371
8372static int
8373quit (vat_main_t * vam)
8374{
8375 return q_or_quit (vam);
8376}
8377
8378static int
8379comment (vat_main_t * vam)
8380{
8381 return 0;
8382}
8383
8384static int
Dave Barachb09f4d02019-07-15 16:00:03 -04008385elog_save (vat_main_t * vam)
8386{
8387#if VPP_API_TEST_BUILTIN == 0
8388 elog_main_t *em = &vam->elog_main;
8389 unformat_input_t *i = vam->input;
8390 char *file, *chroot_file;
8391 clib_error_t *error;
8392
8393 if (!unformat (i, "%s", &file))
8394 {
8395 errmsg ("expected file name, got `%U'", format_unformat_error, i);
8396 return 0;
8397 }
8398
8399 /* It's fairly hard to get "../oopsie" through unformat; just in case */
8400 if (strstr (file, "..") || index (file, '/'))
8401 {
8402 errmsg ("illegal characters in filename '%s'", file);
8403 return 0;
8404 }
8405
8406 chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
8407
8408 vec_free (file);
8409
8410 errmsg ("Saving %wd of %wd events to %s",
8411 elog_n_events_in_buffer (em),
8412 elog_buffer_capacity (em), chroot_file);
8413
8414 error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
8415 vec_free (chroot_file);
8416
8417 if (error)
8418 clib_error_report (error);
8419#else
8420 errmsg ("Use the vpp event loger...");
8421#endif
8422
8423 return 0;
8424}
8425
8426static int
8427elog_setup (vat_main_t * vam)
8428{
8429#if VPP_API_TEST_BUILTIN == 0
8430 elog_main_t *em = &vam->elog_main;
8431 unformat_input_t *i = vam->input;
8432 u32 nevents = 128 << 10;
8433
8434 (void) unformat (i, "nevents %d", &nevents);
8435
8436 elog_init (em, nevents);
8437 vl_api_set_elog_main (em);
8438 vl_api_set_elog_trace_api_messages (1);
8439 errmsg ("Event logger initialized with %u events", nevents);
8440#else
8441 errmsg ("Use the vpp event loger...");
8442#endif
8443 return 0;
8444}
8445
8446static int
8447elog_enable (vat_main_t * vam)
8448{
8449#if VPP_API_TEST_BUILTIN == 0
8450 elog_main_t *em = &vam->elog_main;
8451
8452 elog_enable_disable (em, 1 /* enable */ );
8453 vl_api_set_elog_trace_api_messages (1);
8454 errmsg ("Event logger enabled...");
8455#else
8456 errmsg ("Use the vpp event loger...");
8457#endif
8458 return 0;
8459}
8460
8461static int
8462elog_disable (vat_main_t * vam)
8463{
8464#if VPP_API_TEST_BUILTIN == 0
8465 elog_main_t *em = &vam->elog_main;
8466
8467 elog_enable_disable (em, 0 /* enable */ );
8468 vl_api_set_elog_trace_api_messages (1);
8469 errmsg ("Event logger disabled...");
8470#else
8471 errmsg ("Use the vpp event loger...");
8472#endif
8473 return 0;
8474}
8475
8476static int
Dave Barach048a4e52018-06-01 18:52:25 -04008477statseg (vat_main_t * vam)
8478{
8479 ssvm_private_t *ssvmp = &vam->stat_segment;
8480 ssvm_shared_header_t *shared_header = ssvmp->sh;
8481 vlib_counter_t **counters;
8482 u64 thread0_index1_packets;
8483 u64 thread0_index1_bytes;
8484 f64 vector_rate, input_rate;
8485 uword *p;
8486
8487 uword *counter_vector_by_name;
8488 if (vam->stat_segment_lockp == 0)
8489 {
8490 errmsg ("Stat segment not mapped...");
8491 return -99;
8492 }
8493
8494 /* look up "/if/rx for sw_if_index 1 as a test */
8495
8496 clib_spinlock_lock (vam->stat_segment_lockp);
8497
8498 counter_vector_by_name = (uword *) shared_header->opaque[1];
8499
8500 p = hash_get_mem (counter_vector_by_name, "/if/rx");
8501 if (p == 0)
8502 {
8503 clib_spinlock_unlock (vam->stat_segment_lockp);
8504 errmsg ("/if/tx not found?");
8505 return -99;
8506 }
8507
8508 /* Fish per-thread vector of combined counters from shared memory */
8509 counters = (vlib_counter_t **) p[0];
8510
8511 if (vec_len (counters[0]) < 2)
8512 {
8513 clib_spinlock_unlock (vam->stat_segment_lockp);
8514 errmsg ("/if/tx vector length %d", vec_len (counters[0]));
8515 return -99;
8516 }
8517
8518 /* Read thread 0 sw_if_index 1 counter */
8519 thread0_index1_packets = counters[0][1].packets;
8520 thread0_index1_bytes = counters[0][1].bytes;
8521
8522 p = hash_get_mem (counter_vector_by_name, "vector_rate");
8523 if (p == 0)
8524 {
8525 clib_spinlock_unlock (vam->stat_segment_lockp);
8526 errmsg ("vector_rate not found?");
8527 return -99;
8528 }
8529
8530 vector_rate = *(f64 *) (p[0]);
8531 p = hash_get_mem (counter_vector_by_name, "input_rate");
8532 if (p == 0)
8533 {
8534 clib_spinlock_unlock (vam->stat_segment_lockp);
8535 errmsg ("input_rate not found?");
8536 return -99;
8537 }
8538 input_rate = *(f64 *) (p[0]);
8539
8540 clib_spinlock_unlock (vam->stat_segment_lockp);
8541
8542 print (vam->ofp, "vector_rate %.2f input_rate %.2f",
8543 vector_rate, input_rate);
8544 print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
8545 thread0_index1_packets, thread0_index1_bytes);
8546
8547 return 0;
8548}
8549
8550static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01008551cmd_cmp (void *a1, void *a2)
8552{
8553 u8 **c1 = a1;
8554 u8 **c2 = a2;
8555
8556 return strcmp ((char *) (c1[0]), (char *) (c2[0]));
8557}
8558
8559static int
8560help (vat_main_t * vam)
8561{
8562 u8 **cmds = 0;
8563 u8 *name = 0;
8564 hash_pair_t *p;
8565 unformat_input_t *i = vam->input;
8566 int j;
8567
8568 if (unformat (i, "%s", &name))
8569 {
8570 uword *hs;
8571
8572 vec_add1 (name, 0);
8573
8574 hs = hash_get_mem (vam->help_by_name, name);
8575 if (hs)
8576 print (vam->ofp, "usage: %s %s", name, hs[0]);
8577 else
8578 print (vam->ofp, "No such msg / command '%s'", name);
8579 vec_free (name);
8580 return 0;
8581 }
8582
8583 print (vam->ofp, "Help is available for the following:");
8584
8585 /* *INDENT-OFF* */
8586 hash_foreach_pair (p, vam->function_by_name,
8587 ({
8588 vec_add1 (cmds, (u8 *)(p->key));
8589 }));
8590 /* *INDENT-ON* */
8591
8592 vec_sort_with_function (cmds, cmd_cmp);
8593
8594 for (j = 0; j < vec_len (cmds); j++)
8595 print (vam->ofp, "%s", cmds[j]);
8596
8597 vec_free (cmds);
8598 return 0;
8599}
8600
8601static int
8602set (vat_main_t * vam)
8603{
8604 u8 *name = 0, *value = 0;
8605 unformat_input_t *i = vam->input;
8606
8607 if (unformat (i, "%s", &name))
8608 {
8609 /* The input buffer is a vector, not a string. */
8610 value = vec_dup (i->buffer);
8611 vec_delete (value, i->index, 0);
8612 /* Almost certainly has a trailing newline */
8613 if (value[vec_len (value) - 1] == '\n')
8614 value[vec_len (value) - 1] = 0;
8615 /* Make sure it's a proper string, one way or the other */
8616 vec_add1 (value, 0);
8617 (void) clib_macro_set_value (&vam->macro_main,
8618 (char *) name, (char *) value);
8619 }
8620 else
8621 errmsg ("usage: set <name> <value>");
8622
8623 vec_free (name);
8624 vec_free (value);
8625 return 0;
8626}
8627
8628static int
8629unset (vat_main_t * vam)
8630{
8631 u8 *name = 0;
8632
8633 if (unformat (vam->input, "%s", &name))
8634 if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
8635 errmsg ("unset: %s wasn't set", name);
8636 vec_free (name);
8637 return 0;
8638}
8639
8640typedef struct
8641{
8642 u8 *name;
8643 u8 *value;
8644} macro_sort_t;
8645
8646
8647static int
8648macro_sort_cmp (void *a1, void *a2)
8649{
8650 macro_sort_t *s1 = a1;
8651 macro_sort_t *s2 = a2;
8652
8653 return strcmp ((char *) (s1->name), (char *) (s2->name));
8654}
8655
8656static int
8657dump_macro_table (vat_main_t * vam)
8658{
8659 macro_sort_t *sort_me = 0, *sm;
8660 int i;
8661 hash_pair_t *p;
8662
8663 /* *INDENT-OFF* */
8664 hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
8665 ({
8666 vec_add2 (sort_me, sm, 1);
8667 sm->name = (u8 *)(p->key);
8668 sm->value = (u8 *) (p->value[0]);
8669 }));
8670 /* *INDENT-ON* */
8671
8672 vec_sort_with_function (sort_me, macro_sort_cmp);
8673
8674 if (vec_len (sort_me))
8675 print (vam->ofp, "%-15s%s", "Name", "Value");
8676 else
8677 print (vam->ofp, "The macro table is empty...");
8678
8679 for (i = 0; i < vec_len (sort_me); i++)
8680 print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
8681 return 0;
8682}
8683
8684static int
8685dump_node_table (vat_main_t * vam)
8686{
8687 int i, j;
8688 vlib_node_t *node, *next_node;
8689
8690 if (vec_len (vam->graph_nodes) == 0)
8691 {
8692 print (vam->ofp, "Node table empty, issue get_node_graph...");
8693 return 0;
8694 }
8695
Dave Barach1ddbc012018-06-13 09:26:05 -04008696 for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
Damjan Marion7cd468a2016-12-19 23:05:39 +01008697 {
Dave Barach1ddbc012018-06-13 09:26:05 -04008698 node = vam->graph_nodes[0][i];
Damjan Marion7cd468a2016-12-19 23:05:39 +01008699 print (vam->ofp, "[%d] %s", i, node->name);
8700 for (j = 0; j < vec_len (node->next_nodes); j++)
8701 {
8702 if (node->next_nodes[j] != ~0)
8703 {
Dave Barach1ddbc012018-06-13 09:26:05 -04008704 next_node = vam->graph_nodes[0][node->next_nodes[j]];
Damjan Marion7cd468a2016-12-19 23:05:39 +01008705 print (vam->ofp, " [%d] %s", j, next_node->name);
8706 }
8707 }
8708 }
8709 return 0;
8710}
8711
8712static int
8713value_sort_cmp (void *a1, void *a2)
8714{
8715 name_sort_t *n1 = a1;
8716 name_sort_t *n2 = a2;
8717
8718 if (n1->value < n2->value)
8719 return -1;
8720 if (n1->value > n2->value)
8721 return 1;
8722 return 0;
8723}
8724
8725
8726static int
8727dump_msg_api_table (vat_main_t * vam)
8728{
Dave Barach39d69112019-11-27 11:42:13 -05008729 api_main_t *am = vlibapi_get_main ();
Damjan Marion7cd468a2016-12-19 23:05:39 +01008730 name_sort_t *nses = 0, *ns;
8731 hash_pair_t *hp;
8732 int i;
8733
8734 /* *INDENT-OFF* */
8735 hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
8736 ({
8737 vec_add2 (nses, ns, 1);
8738 ns->name = (u8 *)(hp->key);
8739 ns->value = (u32) hp->value[0];
8740 }));
8741 /* *INDENT-ON* */
8742
8743 vec_sort_with_function (nses, value_sort_cmp);
8744
8745 for (i = 0; i < vec_len (nses); i++)
8746 print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
8747 vec_free (nses);
8748 return 0;
8749}
8750
8751static int
8752get_msg_id (vat_main_t * vam)
8753{
8754 u8 *name_and_crc;
8755 u32 message_index;
8756
8757 if (unformat (vam->input, "%s", &name_and_crc))
8758 {
Florin Corase86a8ed2018-01-05 03:20:25 -08008759 message_index = vl_msg_api_get_msg_index (name_and_crc);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008760 if (message_index == ~0)
8761 {
8762 print (vam->ofp, " '%s' not found", name_and_crc);
8763 return 0;
8764 }
8765 print (vam->ofp, " '%s' has message index %d",
8766 name_and_crc, message_index);
8767 return 0;
8768 }
8769 errmsg ("name_and_crc required...");
8770 return 0;
8771}
8772
8773static int
8774search_node_table (vat_main_t * vam)
8775{
8776 unformat_input_t *line_input = vam->input;
8777 u8 *node_to_find;
8778 int j;
8779 vlib_node_t *node, *next_node;
8780 uword *p;
8781
8782 if (vam->graph_node_index_by_name == 0)
8783 {
8784 print (vam->ofp, "Node table empty, issue get_node_graph...");
8785 return 0;
8786 }
8787
8788 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
8789 {
8790 if (unformat (line_input, "%s", &node_to_find))
8791 {
8792 vec_add1 (node_to_find, 0);
8793 p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
8794 if (p == 0)
8795 {
8796 print (vam->ofp, "%s not found...", node_to_find);
8797 goto out;
8798 }
Dave Barach1ddbc012018-06-13 09:26:05 -04008799 node = vam->graph_nodes[0][p[0]];
Damjan Marion7cd468a2016-12-19 23:05:39 +01008800 print (vam->ofp, "[%d] %s", p[0], node->name);
8801 for (j = 0; j < vec_len (node->next_nodes); j++)
8802 {
8803 if (node->next_nodes[j] != ~0)
8804 {
Dave Barach1ddbc012018-06-13 09:26:05 -04008805 next_node = vam->graph_nodes[0][node->next_nodes[j]];
Damjan Marion7cd468a2016-12-19 23:05:39 +01008806 print (vam->ofp, " [%d] %s", j, next_node->name);
8807 }
8808 }
8809 }
8810
8811 else
8812 {
8813 clib_warning ("parse error '%U'", format_unformat_error,
8814 line_input);
8815 return -99;
8816 }
8817
8818 out:
8819 vec_free (node_to_find);
8820
8821 }
8822
8823 return 0;
8824}
8825
8826
8827static int
8828script (vat_main_t * vam)
8829{
8830#if (VPP_API_TEST_BUILTIN==0)
8831 u8 *s = 0;
8832 char *save_current_file;
8833 unformat_input_t save_input;
8834 jmp_buf save_jump_buf;
8835 u32 save_line_number;
8836
8837 FILE *new_fp, *save_ifp;
8838
8839 if (unformat (vam->input, "%s", &s))
8840 {
8841 new_fp = fopen ((char *) s, "r");
8842 if (new_fp == 0)
8843 {
8844 errmsg ("Couldn't open script file %s", s);
8845 vec_free (s);
8846 return -99;
8847 }
8848 }
8849 else
8850 {
8851 errmsg ("Missing script name");
8852 return -99;
8853 }
8854
8855 clib_memcpy (&save_input, &vam->input, sizeof (save_input));
8856 clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
8857 save_ifp = vam->ifp;
8858 save_line_number = vam->input_line_number;
8859 save_current_file = (char *) vam->current_file;
8860
8861 vam->input_line_number = 0;
8862 vam->ifp = new_fp;
8863 vam->current_file = s;
8864 do_one_file (vam);
8865
Sirshak Dasb0861822018-05-29 21:13:21 -05008866 clib_memcpy (&vam->input, &save_input, sizeof (save_input));
Damjan Marion7cd468a2016-12-19 23:05:39 +01008867 clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
8868 vam->ifp = save_ifp;
8869 vam->input_line_number = save_line_number;
8870 vam->current_file = (u8 *) save_current_file;
8871 vec_free (s);
8872
8873 return 0;
8874#else
8875 clib_warning ("use the exec command...");
8876 return -99;
8877#endif
8878}
8879
8880static int
8881echo (vat_main_t * vam)
8882{
8883 print (vam->ofp, "%v", vam->input->buffer);
8884 return 0;
8885}
8886
8887/* List of API message constructors, CLI names map to api_xxx */
8888#define foreach_vpe_api_msg \
Jon Loeligerc83c3b72017-02-23 13:57:35 -06008889_(create_loopback,"[mac <mac-addr>] [instance <instance>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01008890_(sw_interface_dump,"") \
8891_(sw_interface_set_flags, \
8892 "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
8893_(sw_interface_add_del_address, \
8894 "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
Stevenad8015b2017-10-29 22:10:46 -07008895_(sw_interface_set_rx_mode, \
8896 "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
Mohsin Kazmi54f7c512018-08-23 18:28:11 +02008897_(sw_interface_set_rx_placement, \
8898 "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]") \
Mohsin Kazmif0b42f42018-09-10 18:11:00 +02008899_(sw_interface_rx_placement_dump, \
8900 "[<intfc> | sw_if_index <id>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01008901_(sw_interface_set_table, \
8902 "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]") \
8903_(sw_interface_set_mpls_enable, \
8904 "<intfc> | sw_if_index [disable | dis]") \
8905_(sw_interface_set_vpath, \
8906 "<intfc> | sw_if_index <id> enable | disable") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01008907_(sw_interface_set_l2_xconnect, \
8908 "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
8909 "enable | disable") \
8910_(sw_interface_set_l2_bridge, \
Eyal Barif24991c2017-04-05 05:33:21 +03008911 "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n" \
Damjan Marion7cd468a2016-12-19 23:05:39 +01008912 "[shg <split-horizon-group>] [bvi]\n" \
8913 "enable | disable") \
Eyal Barif24991c2017-04-05 05:33:21 +03008914_(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01008915_(bridge_domain_add_del, \
John Lo70bfcaf2017-11-14 13:19:26 -05008916 "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 +01008917_(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n") \
8918_(l2fib_add_del, \
8919 "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 +03008920_(l2fib_flush_bd, "bd_id <bridge-domain-id>") \
8921_(l2fib_flush_int, "<intfc> | sw_if_index <id>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01008922_(l2_flags, \
John Lo8d00fff2017-08-03 00:35:36 -04008923 "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01008924_(bridge_flags, \
8925 "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
Mohsin Kazmi518251b2020-09-01 17:17:44 +00008926_(virtio_pci_create_v2, \
Mohsin Kazmie347acb2020-09-28 10:26:33 +00008927 "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 +01008928_(virtio_pci_delete, \
8929 "<vpp-if-name> | sw_if_index <id>") \
8930_(sw_interface_virtio_pci_dump, "") \
Neale Ranns28ab9cc2017-08-14 07:18:42 -07008931_(ip_table_add_del, \
John Loe166fd92018-09-13 14:08:59 -04008932 "table <n> [ipv6] [add | del]\n") \
Neale Ranns097fa662018-05-01 05:17:55 -07008933_(ip_route_add_del, \
John Lo22030432018-09-20 16:07:00 -04008934 "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
8935 "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
John Lo06fda9c2018-10-03 16:32:44 -04008936 "[weight <n>] [drop] [local] [classify <n>] [out-label <n>]\n" \
8937 "[multipath] [count <n>] [del]") \
Neale Ranns32e1c012016-11-22 17:07:28 +00008938_(ip_mroute_add_del, \
8939 "<src> <grp>/<mask> [table-id <n>]\n" \
8940 "[<intfc> | sw_if_index <id>] [local] [del]") \
Neale Ranns28ab9cc2017-08-14 07:18:42 -07008941_(mpls_table_add_del, \
John Loe166fd92018-09-13 14:08:59 -04008942 "table <n> [add | del]\n") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01008943_(mpls_route_add_del, \
John Loe166fd92018-09-13 14:08:59 -04008944 "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n" \
8945 "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n" \
8946 "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n" \
8947 "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n" \
John Lo06fda9c2018-10-03 16:32:44 -04008948 "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n" \
8949 "[count <n>] [del]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01008950_(mpls_ip_bind_unbind, \
8951 "<label> <addr/len>") \
8952_(mpls_tunnel_add_del, \
John Lo06fda9c2018-10-03 16:32:44 -04008953 "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
8954 "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n" \
8955 "[l2-only] [out-label <n>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01008956_(sw_interface_set_unnumbered, \
8957 "<intfc> | sw_if_index <id> unnum_if_index <id> [del]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01008958_(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>") \
8959_(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n" \
8960 "[outer_vlan_id <n>][inner_vlan_id <n>]\n" \
8961 "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n" \
8962 "[outer_vlan_id_any][inner_vlan_id_any]") \
Neale Ranns9db6ada2019-11-08 12:42:31 +00008963_(ip_table_replace_begin, "table <n> [ipv6]") \
8964_(ip_table_flush, "table <n> [ipv6]") \
8965_(ip_table_replace_end, "table <n> [ipv6]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01008966_(set_ip_flow_hash, \
8967 "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]") \
8968_(sw_interface_ip6_enable_disable, \
8969 "<intfc> | sw_if_index <id> enable | disable") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01008970_(l2_patch_add_del, \
8971 "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
8972 "enable | disable") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01008973_(get_node_index, "node <node-name") \
8974_(add_node_next, "node <node-name> next <next-node-name>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01008975_(l2_fib_clear_table, "") \
8976_(l2_interface_efp_filter, "sw_if_index <nn> enable | disable") \
8977_(l2_interface_vlan_tag_rewrite, \
8978 "<intfc> | sw_if_index <nn> \n" \
8979 "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n" \
8980 "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01008981_(show_version, "") \
Mohsin Kazmi5d64c782018-09-11 20:27:09 +02008982_(show_threads, "") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01008983_(l2_fib_table_dump, "bd_id <bridge-domain-id>") \
8984_(interface_name_renumber, \
8985 "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>") \
John Lo8d00fff2017-08-03 00:35:36 -04008986_(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01008987_(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)") \
8988_(ip_dump, "ipv4 | ipv6") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01008989_(delete_loopback,"sw_if_index <nn>") \
8990_(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
John Loe26c81f2019-01-07 15:16:33 -05008991_(bd_ip_mac_flush, "bd_id <bridge-domain-id>") \
8992_(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01008993_(want_interface_events, "enable|disable") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01008994_(get_first_msg_id, "client <name>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01008995_(get_node_graph, " ") \
8996_(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>") \
8997_(ioam_enable, "[trace] [pow] [ppc <encap|decap>]") \
8998_(ioam_disable, "") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01008999_(mpls_tunnel_dump, "tunnel_index <tunnel-id>") \
Neale Ranns097fa662018-05-01 05:17:55 -07009000_(mpls_table_dump, "") \
9001_(mpls_route_dump, "table-id <ID>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01009002_(get_next_index, "node-name <node-name> next-node-name <node-name>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01009003_(ip_source_and_port_range_check_add_del, \
9004 "<ip-addr>/<mask> range <nn>-<nn> vrf <id>") \
9005_(ip_source_and_port_range_check_interface_add_del, \
9006 "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]" \
9007 "[udp-in-vrf <id>] [udp-out-vrf <id>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01009008_(delete_subif,"<intfc> | sw_if_index <nn>") \
9009_(l2_interface_pbb_tag_rewrite, \
9010 "<intfc> | sw_if_index <nn> \n" \
9011 "[disable | push | pop | translate_pbb_stag <outer_tag>] \n" \
9012 "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]") \
Neale Ranns097fa662018-05-01 05:17:55 -07009013_(ip_table_dump, "") \
9014_(ip_route_dump, "table-id [ip4|ip6]") \
9015_(ip_mtable_dump, "") \
9016_(ip_mroute_dump, "table-id [ip4|ip6]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01009017_(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>" \
9018"[disable]") \
Matthew Smithe0792fd2019-07-12 11:48:24 -05009019_(sw_interface_add_del_mac_address, "<intfc> | sw_if_index <nn> " \
9020 "mac <mac-address> [del]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01009021_(l2_xconnect_dump, "") \
Ole Troand7231612018-06-07 10:17:57 +02009022_(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>") \
Pavel Kotucek6899a302017-06-08 08:46:10 +02009023_(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]") \
Florin Coras90a63982017-12-19 04:50:01 -08009024_(sock_init_shm, "size <nnn>") \
Florin Corascea194d2017-10-02 00:18:51 -07009025_(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
Florin Coras1c710452017-10-17 00:03:13 -07009026_(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> " \
9027 "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>") \
Florin Coras6c36f532017-11-03 18:32:34 -07009028_(session_rules_dump, "") \
Florin Coras595992c2017-11-06 17:17:08 -08009029_(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01009030
9031/* List of command functions, CLI names map directly to functions */
9032#define foreach_cli_function \
9033_(comment, "usage: comment <ignore-rest-of-line>") \
9034_(dump_interface_table, "usage: dump_interface_table") \
9035_(dump_sub_interface_table, "usage: dump_sub_interface_table") \
9036_(dump_ipv4_table, "usage: dump_ipv4_table") \
9037_(dump_ipv6_table, "usage: dump_ipv6_table") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01009038_(dump_macro_table, "usage: dump_macro_table ") \
9039_(dump_node_table, "usage: dump_node_table") \
9040_(dump_msg_api_table, "usage: dump_msg_api_table") \
Dave Barachb09f4d02019-07-15 16:00:03 -04009041_(elog_setup, "usage: elog_setup [nevents, default 128K]") \
9042_(elog_disable, "usage: elog_disable") \
9043_(elog_enable, "usage: elog_enable") \
9044_(elog_save, "usage: elog_save <filename>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01009045_(get_msg_id, "usage: get_msg_id name_and_crc") \
9046_(echo, "usage: echo <message>") \
9047_(exec, "usage: exec <vpe-debug-CLI-command>") \
9048_(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>") \
9049_(help, "usage: help") \
9050_(q, "usage: quit") \
9051_(quit, "usage: quit") \
9052_(search_node_table, "usage: search_node_table <name>...") \
9053_(set, "usage: set <variable-name> <value>") \
9054_(script, "usage: script <file-name>") \
Neale Ranns097fa662018-05-01 05:17:55 -07009055_(statseg, "usage: statseg") \
Damjan Marion7cd468a2016-12-19 23:05:39 +01009056_(unset, "usage: unset <variable-name>")
Dave Barach048a4e52018-06-01 18:52:25 -04009057
Damjan Marion7cd468a2016-12-19 23:05:39 +01009058#define _(N,n) \
9059 static void vl_api_##n##_t_handler_uni \
9060 (vl_api_##n##_t * mp) \
9061 { \
9062 vat_main_t * vam = &vat_main; \
9063 if (vam->json_output) { \
9064 vl_api_##n##_t_handler_json(mp); \
9065 } else { \
9066 vl_api_##n##_t_handler(mp); \
9067 } \
9068 }
9069foreach_vpe_api_reply_msg;
Dave Baracha1a093d2017-03-02 13:13:23 -05009070#if VPP_API_TEST_BUILTIN == 0
9071foreach_standalone_reply_msg;
9072#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +01009073#undef _
9074
9075void
9076vat_api_hookup (vat_main_t * vam)
9077{
9078#define _(N,n) \
9079 vl_msg_api_set_handlers(VL_API_##N, #n, \
9080 vl_api_##n##_t_handler_uni, \
9081 vl_noop_handler, \
9082 vl_api_##n##_t_endian, \
9083 vl_api_##n##_t_print, \
9084 sizeof(vl_api_##n##_t), 1);
9085 foreach_vpe_api_reply_msg;
Dave Baracha1a093d2017-03-02 13:13:23 -05009086#if VPP_API_TEST_BUILTIN == 0
9087 foreach_standalone_reply_msg;
9088#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +01009089#undef _
9090
9091#if (VPP_API_TEST_BUILTIN==0)
9092 vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009093
9094 vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
9095
9096 vam->function_by_name = hash_create_string (0, sizeof (uword));
9097
9098 vam->help_by_name = hash_create_string (0, sizeof (uword));
Dave Barach45e4f362017-03-07 12:52:31 -05009099#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +01009100
9101 /* API messages we can send */
9102#define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
9103 foreach_vpe_api_msg;
9104#undef _
9105
9106 /* Help strings */
9107#define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
9108 foreach_vpe_api_msg;
9109#undef _
Damjan Marion7cd468a2016-12-19 23:05:39 +01009110
9111 /* CLI functions */
9112#define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
9113 foreach_cli_function;
9114#undef _
9115
9116 /* Help strings */
9117#define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
9118 foreach_cli_function;
9119#undef _
9120}
9121
Dave Baracha1a093d2017-03-02 13:13:23 -05009122#if VPP_API_TEST_BUILTIN
9123static clib_error_t *
9124vat_api_hookup_shim (vlib_main_t * vm)
9125{
9126 vat_api_hookup (&vat_main);
9127 return 0;
9128}
9129
9130VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
9131#endif
9132
Damjan Marion7cd468a2016-12-19 23:05:39 +01009133/*
9134 * fd.io coding-style-patch-verification: ON
9135 *
9136 * Local Variables:
9137 * eval: (c-set-style "gnu")
9138 * End:
9139 */