blob: 366e60e12909a157ad23a1d2892ce6424a40910f [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>
Damjan Marion7cd468a2016-12-19 23:05:39 +010030#include <vnet/vxlan/vxlan.h>
31#include <vnet/gre/gre.h>
32#include <vnet/vxlan-gpe/vxlan_gpe.h>
Florin Corasb040f982020-10-20 14:59:43 -070033#include <vnet/udp/udp_local.h>
Damjan Marion7cd468a2016-12-19 23:05:39 +010034
35#include <vpp/api/vpe_msg_enum.h>
36#include <vnet/l2/l2_classify.h>
37#include <vnet/l2/l2_vtr.h>
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +010038#include <vnet/classify/in_out_acl.h>
Damjan Marion7cd468a2016-12-19 23:05:39 +010039#include <vnet/classify/policer_classify.h>
40#include <vnet/classify/flow_classify.h>
41#include <vnet/mpls/mpls.h>
42#include <vnet/ipsec/ipsec.h>
Damjan Marion7cd468a2016-12-19 23:05:39 +010043#include <inttypes.h>
Damjan Marion7cd468a2016-12-19 23:05:39 +010044#include <vnet/ip/ip6_hop_by_hop.h>
45#include <vnet/ip/ip_source_and_port_range_check.h>
46#include <vnet/policer/xlate.h>
47#include <vnet/span/span.h>
48#include <vnet/policer/policer.h>
49#include <vnet/policer/police.h>
Neale Ranns32e1c012016-11-22 17:07:28 +000050#include <vnet/mfib/mfib_types.h>
Steven9cd2d7a2017-12-20 12:43:01 -080051#include <vnet/bonding/node.h>
Igor Mikhailov (imichail)582caa32018-04-26 21:33:02 -070052#include <vnet/qos/qos_types.h>
Neale Ranns37029302018-08-10 05:30:06 -070053#include <vnet/ethernet/ethernet_types_api.h>
54#include <vnet/ip/ip_types_api.h>
Damjan Marion7cd468a2016-12-19 23:05:39 +010055#include "vat/json_format.h"
Neale Ranns86327be2018-11-02 09:14:01 -070056#include <vnet/ip/ip_types_api.h>
57#include <vnet/ethernet/ethernet_types_api.h>
Damjan Marion7cd468a2016-12-19 23:05:39 +010058
59#include <inttypes.h>
60#include <sys/stat.h>
61
62#define vl_typedefs /* define message structures */
63#include <vpp/api/vpe_all_api_h.h>
64#undef vl_typedefs
65
66/* declare message handlers for each api */
67
68#define vl_endianfun /* define message structures */
69#include <vpp/api/vpe_all_api_h.h>
70#undef vl_endianfun
71
72/* instantiate all the print functions we know about */
Dave Barachf35a0722019-06-12 16:50:38 -040073#if VPP_API_TEST_BUILTIN == 0
Damjan Marion7cd468a2016-12-19 23:05:39 +010074#define vl_print(handle, ...)
Dave Barachf35a0722019-06-12 16:50:38 -040075#else
76#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
77#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +010078#define vl_printfun
79#include <vpp/api/vpe_all_api_h.h>
80#undef vl_printfun
81
Dave Barach2d6b2d62017-01-25 16:32:08 -050082#define __plugin_msg_base 0
Dave Barachfe6bdfd2017-01-20 19:50:09 -050083#include <vlibapi/vat_helper_macros.h>
84
Ole Troan33a58172019-09-04 09:12:29 +020085#include <vnet/format_fns.h>
86
Dave Barachb09f4d02019-07-15 16:00:03 -040087void vl_api_set_elog_main (elog_main_t * m);
88int vl_api_set_elog_trace_api_messages (int enable);
89
Dave Barach59b25652017-09-10 15:04:27 -040090#if VPP_API_TEST_BUILTIN == 0
91#include <netdb.h>
92
93u32
94vl (void *p)
95{
96 return vec_len (p);
97}
98
99int
100vat_socket_connect (vat_main_t * vam)
101{
Florin Coras66a10032018-12-21 16:23:09 -0800102 int rv;
Dave Barach69eeadc2020-04-14 09:52:26 -0400103 api_main_t *am = vlibapi_get_main ();
Florin Coras90a63982017-12-19 04:50:01 -0800104 vam->socket_client_main = &socket_client_main;
Florin Coras66a10032018-12-21 16:23:09 -0800105 if ((rv = vl_socket_client_connect ((char *) vam->socket_name,
106 "vpp_api_test",
107 0 /* default socket rx, tx buffer */ )))
108 return rv;
Dave Barach69eeadc2020-04-14 09:52:26 -0400109
Florin Coras66a10032018-12-21 16:23:09 -0800110 /* vpp expects the client index in network order */
111 vam->my_client_index = htonl (socket_client_main.client_index);
Dave Barach69eeadc2020-04-14 09:52:26 -0400112 am->my_client_index = vam->my_client_index;
Florin Coras66a10032018-12-21 16:23:09 -0800113 return 0;
Dave Barach59b25652017-09-10 15:04:27 -0400114}
115#else /* vpp built-in case, we don't do sockets... */
116int
117vat_socket_connect (vat_main_t * vam)
118{
119 return 0;
120}
121
Florin Coras90a63982017-12-19 04:50:01 -0800122int
123vl_socket_client_read (int wait)
Dave Barach59b25652017-09-10 15:04:27 -0400124{
Florin Coras90a63982017-12-19 04:50:01 -0800125 return -1;
Dave Barach59b25652017-09-10 15:04:27 -0400126};
Florin Coras90a63982017-12-19 04:50:01 -0800127
128int
129vl_socket_client_write ()
130{
131 return -1;
132};
133
134void *
135vl_socket_client_msg_alloc (int nbytes)
136{
137 return 0;
138}
Dave Barach59b25652017-09-10 15:04:27 -0400139#endif
140
141
Dave Barachfe6bdfd2017-01-20 19:50:09 -0500142f64
143vat_time_now (vat_main_t * vam)
144{
145#if VPP_API_TEST_BUILTIN
146 return vlib_time_now (vam->vlib_main);
147#else
148 return clib_time_now (&vam->clib_time);
149#endif
150}
151
152void
153errmsg (char *fmt, ...)
154{
155 vat_main_t *vam = &vat_main;
156 va_list va;
157 u8 *s;
158
159 va_start (va, fmt);
160 s = va_format (0, fmt, &va);
161 va_end (va);
162
163 vec_add1 (s, 0);
164
165#if VPP_API_TEST_BUILTIN
166 vlib_cli_output (vam->vlib_main, (char *) s);
167#else
168 {
169 if (vam->ifp != stdin)
170 fformat (vam->ofp, "%s(%d): \n", vam->current_file,
171 vam->input_line_number);
Dave Barachb09f4d02019-07-15 16:00:03 -0400172 else
173 fformat (vam->ofp, "%s\n", (char *) s);
Dave Barachfe6bdfd2017-01-20 19:50:09 -0500174 fflush (vam->ofp);
175 }
176#endif
177
178 vec_free (s);
179}
180
Dave Barach4a3f69c2017-02-22 12:44:56 -0500181#if VPP_API_TEST_BUILTIN == 0
Damjan Marion7cd468a2016-12-19 23:05:39 +0100182static uword
183api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
184{
185 vat_main_t *vam = va_arg (*args, vat_main_t *);
186 u32 *result = va_arg (*args, u32 *);
187 u8 *if_name;
188 uword *p;
189
190 if (!unformat (input, "%s", &if_name))
191 return 0;
192
193 p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
194 if (p == 0)
195 return 0;
196 *result = p[0];
197 return 1;
198}
199
eyal bariaf86a482018-04-17 11:20:27 +0300200static uword
201api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
202{
203 return 0;
204}
205
Damjan Marion7cd468a2016-12-19 23:05:39 +0100206/* Parse an IP4 address %d.%d.%d.%d. */
207uword
208unformat_ip4_address (unformat_input_t * input, va_list * args)
209{
210 u8 *result = va_arg (*args, u8 *);
211 unsigned a[4];
212
213 if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
214 return 0;
215
216 if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
217 return 0;
218
219 result[0] = a[0];
220 result[1] = a[1];
221 result[2] = a[2];
222 result[3] = a[3];
223
224 return 1;
225}
226
227uword
228unformat_ethernet_address (unformat_input_t * input, va_list * args)
229{
230 u8 *result = va_arg (*args, u8 *);
231 u32 i, a[6];
232
233 if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
234 &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
235 return 0;
236
237 /* Check range. */
238 for (i = 0; i < 6; i++)
239 if (a[i] >= (1 << 8))
240 return 0;
241
242 for (i = 0; i < 6; i++)
243 result[i] = a[i];
244
245 return 1;
246}
247
248/* Returns ethernet type as an int in host byte order. */
249uword
250unformat_ethernet_type_host_byte_order (unformat_input_t * input,
251 va_list * args)
252{
253 u16 *result = va_arg (*args, u16 *);
254 int type;
255
256 /* Numeric type. */
257 if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
258 {
259 if (type >= (1 << 16))
260 return 0;
261 *result = type;
262 return 1;
263 }
264 return 0;
265}
266
Jakub Grajciar23a386b2020-02-26 11:01:43 +0100267/* Parse an IP46 address. */
268uword
269unformat_ip46_address (unformat_input_t * input, va_list * args)
270{
271 ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
272 ip46_type_t type = va_arg (*args, ip46_type_t);
273 if ((type != IP46_TYPE_IP6) &&
274 unformat (input, "%U", unformat_ip4_address, &ip46->ip4))
275 {
276 ip46_address_mask_ip4 (ip46);
277 return 1;
278 }
279 else if ((type != IP46_TYPE_IP4) &&
280 unformat (input, "%U", unformat_ip6_address, &ip46->ip6))
281 {
282 return 1;
283 }
284 return 0;
285}
286
Damjan Marion7cd468a2016-12-19 23:05:39 +0100287/* Parse an IP6 address. */
288uword
289unformat_ip6_address (unformat_input_t * input, va_list * args)
290{
291 ip6_address_t *result = va_arg (*args, ip6_address_t *);
292 u16 hex_quads[8];
293 uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
294 uword c, n_colon, double_colon_index;
295
296 n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
297 double_colon_index = ARRAY_LEN (hex_quads);
298 while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
299 {
300 hex_digit = 16;
301 if (c >= '0' && c <= '9')
302 hex_digit = c - '0';
303 else if (c >= 'a' && c <= 'f')
304 hex_digit = c + 10 - 'a';
305 else if (c >= 'A' && c <= 'F')
306 hex_digit = c + 10 - 'A';
307 else if (c == ':' && n_colon < 2)
308 n_colon++;
309 else
310 {
311 unformat_put_input (input);
312 break;
313 }
314
315 /* Too many hex quads. */
316 if (n_hex_quads >= ARRAY_LEN (hex_quads))
317 return 0;
318
319 if (hex_digit < 16)
320 {
321 hex_quad = (hex_quad << 4) | hex_digit;
322
323 /* Hex quad must fit in 16 bits. */
324 if (n_hex_digits >= 4)
325 return 0;
326
327 n_colon = 0;
328 n_hex_digits++;
329 }
330
331 /* Save position of :: */
332 if (n_colon == 2)
333 {
334 /* More than one :: ? */
335 if (double_colon_index < ARRAY_LEN (hex_quads))
336 return 0;
337 double_colon_index = n_hex_quads;
338 }
339
340 if (n_colon > 0 && n_hex_digits > 0)
341 {
342 hex_quads[n_hex_quads++] = hex_quad;
343 hex_quad = 0;
344 n_hex_digits = 0;
345 }
346 }
347
348 if (n_hex_digits > 0)
349 hex_quads[n_hex_quads++] = hex_quad;
350
351 {
352 word i;
353
354 /* Expand :: to appropriate number of zero hex quads. */
355 if (double_colon_index < ARRAY_LEN (hex_quads))
356 {
357 word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
358
359 for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
360 hex_quads[n_zero + i] = hex_quads[i];
361
362 for (i = 0; i < n_zero; i++)
363 hex_quads[double_colon_index + i] = 0;
364
365 n_hex_quads = ARRAY_LEN (hex_quads);
366 }
367
368 /* Too few hex quads given. */
369 if (n_hex_quads < ARRAY_LEN (hex_quads))
370 return 0;
371
372 for (i = 0; i < ARRAY_LEN (hex_quads); i++)
373 result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
374
375 return 1;
376 }
377}
378
379uword
380unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
381{
382 u32 *r = va_arg (*args, u32 *);
383
384 if (0);
385#define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
386 foreach_ipsec_policy_action
387#undef _
388 else
389 return 0;
390 return 1;
391}
392
Damjan Marion7cd468a2016-12-19 23:05:39 +0100393u8 *
394format_ipsec_crypto_alg (u8 * s, va_list * args)
395{
396 u32 i = va_arg (*args, u32);
397 u8 *t = 0;
398
399 switch (i)
400 {
401#define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
402 foreach_ipsec_crypto_alg
403#undef _
404 default:
405 return format (s, "unknown");
406 }
407 return format (s, "%s", t);
408}
409
Damjan Marion7cd468a2016-12-19 23:05:39 +0100410u8 *
411format_ipsec_integ_alg (u8 * s, va_list * args)
412{
413 u32 i = va_arg (*args, u32);
414 u8 *t = 0;
415
416 switch (i)
417 {
418#define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
419 foreach_ipsec_integ_alg
420#undef _
421 default:
422 return format (s, "unknown");
423 }
424 return format (s, "%s", t);
425}
426
Dave Barach4a3f69c2017-02-22 12:44:56 -0500427#else /* VPP_API_TEST_BUILTIN == 1 */
428static uword
429api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
430{
Benoît Ganne49ee6842019-04-30 11:50:46 +0200431 vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
Dave Barach4a3f69c2017-02-22 12:44:56 -0500432 vnet_main_t *vnm = vnet_get_main ();
433 u32 *result = va_arg (*args, u32 *);
Dave Barach4a3f69c2017-02-22 12:44:56 -0500434
eyal bariaf86a482018-04-17 11:20:27 +0300435 return unformat (input, "%U", unformat_vnet_sw_interface, vnm, result);
Dave Barach4a3f69c2017-02-22 12:44:56 -0500436}
eyal bariaf86a482018-04-17 11:20:27 +0300437
438static uword
439api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
440{
Benoît Ganne49ee6842019-04-30 11:50:46 +0200441 vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
eyal bariaf86a482018-04-17 11:20:27 +0300442 vnet_main_t *vnm = vnet_get_main ();
443 u32 *result = va_arg (*args, u32 *);
444
445 return unformat (input, "%U", unformat_vnet_hw_interface, vnm, result);
446}
447
Damjan Marion7cd468a2016-12-19 23:05:39 +0100448#endif /* VPP_API_TEST_BUILTIN */
449
Neale Ranns17dcec02019-01-09 21:22:20 -0800450uword
451unformat_ipsec_api_crypto_alg (unformat_input_t * input, va_list * args)
452{
453 u32 *r = va_arg (*args, u32 *);
454
455 if (0);
456#define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_CRYPTO_ALG_##f;
457 foreach_ipsec_crypto_alg
458#undef _
459 else
460 return 0;
461 return 1;
462}
463
464uword
465unformat_ipsec_api_integ_alg (unformat_input_t * input, va_list * args)
466{
467 u32 *r = va_arg (*args, u32 *);
468
469 if (0);
470#define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_INTEG_ALG_##f;
471 foreach_ipsec_integ_alg
472#undef _
473 else
474 return 0;
475 return 1;
476}
477
Damjan Marion7cd468a2016-12-19 23:05:39 +0100478static uword
479unformat_policer_rate_type (unformat_input_t * input, va_list * args)
480{
481 u8 *r = va_arg (*args, u8 *);
482
483 if (unformat (input, "kbps"))
484 *r = SSE2_QOS_RATE_KBPS;
485 else if (unformat (input, "pps"))
486 *r = SSE2_QOS_RATE_PPS;
487 else
488 return 0;
489 return 1;
490}
491
492static uword
493unformat_policer_round_type (unformat_input_t * input, va_list * args)
494{
495 u8 *r = va_arg (*args, u8 *);
496
497 if (unformat (input, "closest"))
498 *r = SSE2_QOS_ROUND_TO_CLOSEST;
499 else if (unformat (input, "up"))
500 *r = SSE2_QOS_ROUND_TO_UP;
501 else if (unformat (input, "down"))
502 *r = SSE2_QOS_ROUND_TO_DOWN;
503 else
504 return 0;
505 return 1;
506}
507
508static uword
509unformat_policer_type (unformat_input_t * input, va_list * args)
510{
511 u8 *r = va_arg (*args, u8 *);
512
513 if (unformat (input, "1r2c"))
514 *r = SSE2_QOS_POLICER_TYPE_1R2C;
515 else if (unformat (input, "1r3c"))
516 *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
517 else if (unformat (input, "2r3c-2698"))
518 *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
519 else if (unformat (input, "2r3c-4115"))
520 *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
521 else if (unformat (input, "2r3c-mef5cf1"))
522 *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
523 else
524 return 0;
525 return 1;
526}
527
528static uword
529unformat_dscp (unformat_input_t * input, va_list * va)
530{
531 u8 *r = va_arg (*va, u8 *);
532
533 if (0);
534#define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
535 foreach_vnet_dscp
536#undef _
537 else
538 return 0;
539 return 1;
540}
541
542static uword
543unformat_policer_action_type (unformat_input_t * input, va_list * va)
544{
545 sse2_qos_pol_action_params_st *a
546 = va_arg (*va, sse2_qos_pol_action_params_st *);
547
548 if (unformat (input, "drop"))
549 a->action_type = SSE2_QOS_ACTION_DROP;
550 else if (unformat (input, "transmit"))
551 a->action_type = SSE2_QOS_ACTION_TRANSMIT;
552 else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
553 a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
554 else
555 return 0;
556 return 1;
557}
558
559static uword
560unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
561{
562 u32 *r = va_arg (*va, u32 *);
563 u32 tid;
564
565 if (unformat (input, "ip4"))
566 tid = POLICER_CLASSIFY_TABLE_IP4;
567 else if (unformat (input, "ip6"))
568 tid = POLICER_CLASSIFY_TABLE_IP6;
569 else if (unformat (input, "l2"))
570 tid = POLICER_CLASSIFY_TABLE_L2;
571 else
572 return 0;
573
574 *r = tid;
575 return 1;
576}
577
578static uword
579unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
580{
581 u32 *r = va_arg (*va, u32 *);
582 u32 tid;
583
584 if (unformat (input, "ip4"))
585 tid = FLOW_CLASSIFY_TABLE_IP4;
586 else if (unformat (input, "ip6"))
587 tid = FLOW_CLASSIFY_TABLE_IP6;
588 else
589 return 0;
590
591 *r = tid;
592 return 1;
593}
594
Benoît Ganne49ee6842019-04-30 11:50:46 +0200595#if (VPP_API_TEST_BUILTIN==0)
596
Neale Ranns32e1c012016-11-22 17:07:28 +0000597static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
598static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
599static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
600static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
601
602uword
603unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
604{
605 mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
606 mfib_itf_attribute_t attr;
607
608 old = *iflags;
609 FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
610 {
611 if (unformat (input, mfib_itf_flag_long_names[attr]))
612 *iflags |= (1 << attr);
613 }
614 FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
615 {
616 if (unformat (input, mfib_itf_flag_names[attr]))
617 *iflags |= (1 << attr);
618 }
619
620 return (old == *iflags ? 0 : 1);
621}
622
623uword
624unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
625{
626 mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
627 mfib_entry_attribute_t attr;
628
629 old = *eflags;
630 FOR_EACH_MFIB_ATTRIBUTE (attr)
631 {
632 if (unformat (input, mfib_flag_long_names[attr]))
633 *eflags |= (1 << attr);
634 }
635 FOR_EACH_MFIB_ATTRIBUTE (attr)
636 {
637 if (unformat (input, mfib_flag_names[attr]))
638 *eflags |= (1 << attr);
639 }
640
641 return (old == *eflags ? 0 : 1);
642}
643
Damjan Marion7cd468a2016-12-19 23:05:39 +0100644u8 *
645format_ip4_address (u8 * s, va_list * args)
646{
647 u8 *a = va_arg (*args, u8 *);
648 return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
649}
650
651u8 *
652format_ip6_address (u8 * s, va_list * args)
653{
654 ip6_address_t *a = va_arg (*args, ip6_address_t *);
655 u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
656
657 i_max_n_zero = ARRAY_LEN (a->as_u16);
658 max_n_zeros = 0;
659 i_first_zero = i_max_n_zero;
660 n_zeros = 0;
661 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
662 {
663 u32 is_zero = a->as_u16[i] == 0;
664 if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
665 {
666 i_first_zero = i;
667 n_zeros = 0;
668 }
669 n_zeros += is_zero;
670 if ((!is_zero && n_zeros > max_n_zeros)
671 || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
672 {
673 i_max_n_zero = i_first_zero;
674 max_n_zeros = n_zeros;
675 i_first_zero = ARRAY_LEN (a->as_u16);
676 n_zeros = 0;
677 }
678 }
679
680 last_double_colon = 0;
681 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
682 {
683 if (i == i_max_n_zero && max_n_zeros > 1)
684 {
685 s = format (s, "::");
686 i += max_n_zeros - 1;
687 last_double_colon = 1;
688 }
689 else
690 {
691 s = format (s, "%s%x",
692 (last_double_colon || i == 0) ? "" : ":",
693 clib_net_to_host_u16 (a->as_u16[i]));
694 last_double_colon = 0;
695 }
696 }
697
698 return s;
699}
700
701/* Format an IP46 address. */
702u8 *
703format_ip46_address (u8 * s, va_list * args)
704{
705 ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
706 ip46_type_t type = va_arg (*args, ip46_type_t);
707 int is_ip4 = 1;
708
709 switch (type)
710 {
711 case IP46_TYPE_ANY:
712 is_ip4 = ip46_address_is_ip4 (ip46);
713 break;
714 case IP46_TYPE_IP4:
715 is_ip4 = 1;
716 break;
717 case IP46_TYPE_IP6:
718 is_ip4 = 0;
719 break;
720 }
721
722 return is_ip4 ?
723 format (s, "%U", format_ip4_address, &ip46->ip4) :
724 format (s, "%U", format_ip6_address, &ip46->ip6);
725}
726
727u8 *
728format_ethernet_address (u8 * s, va_list * args)
729{
730 u8 *a = va_arg (*args, u8 *);
731
732 return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
733 a[0], a[1], a[2], a[3], a[4], a[5]);
734}
735#endif
736
737static void
Neale Ranns097fa662018-05-01 05:17:55 -0700738increment_v4_address (vl_api_ip4_address_t * i)
Damjan Marion7cd468a2016-12-19 23:05:39 +0100739{
Neale Ranns097fa662018-05-01 05:17:55 -0700740 ip4_address_t *a = (ip4_address_t *) i;
Damjan Marion7cd468a2016-12-19 23:05:39 +0100741 u32 v;
742
743 v = ntohl (a->as_u32) + 1;
744 a->as_u32 = ntohl (v);
745}
746
747static void
Neale Ranns097fa662018-05-01 05:17:55 -0700748increment_v6_address (vl_api_ip6_address_t * i)
Neale Ranns2b5ba952019-04-02 10:15:40 +0000749{
Neale Ranns097fa662018-05-01 05:17:55 -0700750 ip6_address_t *a = (ip6_address_t *) i;
Damjan Marion7cd468a2016-12-19 23:05:39 +0100751 u64 v0, v1;
752
753 v0 = clib_net_to_host_u64 (a->as_u64[0]);
754 v1 = clib_net_to_host_u64 (a->as_u64[1]);
755
756 v1 += 1;
757 if (v1 == 0)
758 v0 += 1;
759 a->as_u64[0] = clib_net_to_host_u64 (v0);
760 a->as_u64[1] = clib_net_to_host_u64 (v1);
761}
762
763static void
Neale Ranns097fa662018-05-01 05:17:55 -0700764increment_address (vl_api_address_t * a)
765{
Dave Barach54582662020-04-21 08:01:16 -0400766 if (a->af == ADDRESS_IP4)
Neale Ranns097fa662018-05-01 05:17:55 -0700767 increment_v4_address (&a->un.ip4);
Dave Barach54582662020-04-21 08:01:16 -0400768 else if (a->af == ADDRESS_IP6)
Neale Ranns097fa662018-05-01 05:17:55 -0700769 increment_v6_address (&a->un.ip6);
770}
771
772static void
773set_ip4_address (vl_api_address_t * a, u32 v)
774{
775 if (a->af == ADDRESS_IP4)
776 {
777 ip4_address_t *i = (ip4_address_t *) & a->un.ip4;
778 i->as_u32 = v;
779 }
780}
781
Jakub Grajciar23a386b2020-02-26 11:01:43 +0100782void
783ip_set (ip46_address_t * dst, void *src, u8 is_ip4)
784{
785 if (is_ip4)
786 dst->ip4.as_u32 = ((ip4_address_t *) src)->as_u32;
787 else
788 clib_memcpy_fast (&dst->ip6, (ip6_address_t *) src,
789 sizeof (ip6_address_t));
790}
791
Neale Ranns097fa662018-05-01 05:17:55 -0700792static void
Mohsin Kazmi57938f62017-10-27 21:28:07 +0200793increment_mac_address (u8 * mac)
Damjan Marion7cd468a2016-12-19 23:05:39 +0100794{
Mohsin Kazmi57938f62017-10-27 21:28:07 +0200795 u64 tmp = *((u64 *) mac);
Damjan Marion7cd468a2016-12-19 23:05:39 +0100796 tmp = clib_net_to_host_u64 (tmp);
797 tmp += 1 << 16; /* skip unused (least significant) octets */
798 tmp = clib_host_to_net_u64 (tmp);
Mohsin Kazmi57938f62017-10-27 21:28:07 +0200799
800 clib_memcpy (mac, &tmp, 6);
Damjan Marion7cd468a2016-12-19 23:05:39 +0100801}
802
Neale Ranns097fa662018-05-01 05:17:55 -0700803static void
804vat_json_object_add_address (vat_json_node_t * node,
805 const char *str, const vl_api_address_t * addr)
806{
807 if (ADDRESS_IP6 == addr->af)
808 {
809 struct in6_addr ip6;
810
811 clib_memcpy (&ip6, &addr->un.ip6, sizeof (ip6));
812 vat_json_object_add_ip6 (node, str, ip6);
813 }
814 else
815 {
816 struct in_addr ip4;
817
818 clib_memcpy (&ip4, &addr->un.ip4, sizeof (ip4));
819 vat_json_object_add_ip4 (node, str, ip4);
820 }
821}
822
823static void
824vat_json_object_add_prefix (vat_json_node_t * node,
825 const vl_api_prefix_t * prefix)
826{
Paul Vinciguerraab055082019-06-06 14:07:55 -0400827 vat_json_object_add_uint (node, "len", prefix->len);
828 vat_json_object_add_address (node, "address", &prefix->address);
Neale Ranns097fa662018-05-01 05:17:55 -0700829}
830
Damjan Marion7cd468a2016-12-19 23:05:39 +0100831static void vl_api_create_loopback_reply_t_handler
832 (vl_api_create_loopback_reply_t * mp)
833{
834 vat_main_t *vam = &vat_main;
835 i32 retval = ntohl (mp->retval);
836
837 vam->retval = retval;
838 vam->regenerate_interface_table = 1;
839 vam->sw_if_index = ntohl (mp->sw_if_index);
840 vam->result_ready = 1;
841}
842
843static void vl_api_create_loopback_reply_t_handler_json
844 (vl_api_create_loopback_reply_t * mp)
845{
846 vat_main_t *vam = &vat_main;
847 vat_json_node_t node;
848
849 vat_json_init_object (&node);
850 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
851 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
852
853 vat_json_print (vam->ofp, &node);
854 vat_json_free (&node);
855 vam->retval = ntohl (mp->retval);
856 vam->result_ready = 1;
857}
858
Jon Loeligerc83c3b72017-02-23 13:57:35 -0600859static void vl_api_create_loopback_instance_reply_t_handler
860 (vl_api_create_loopback_instance_reply_t * mp)
861{
862 vat_main_t *vam = &vat_main;
863 i32 retval = ntohl (mp->retval);
864
865 vam->retval = retval;
866 vam->regenerate_interface_table = 1;
867 vam->sw_if_index = ntohl (mp->sw_if_index);
868 vam->result_ready = 1;
869}
870
871static void vl_api_create_loopback_instance_reply_t_handler_json
872 (vl_api_create_loopback_instance_reply_t * mp)
873{
874 vat_main_t *vam = &vat_main;
875 vat_json_node_t node;
876
877 vat_json_init_object (&node);
878 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
879 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
880
881 vat_json_print (vam->ofp, &node);
882 vat_json_free (&node);
883 vam->retval = ntohl (mp->retval);
884 vam->result_ready = 1;
885}
886
Damjan Marion7cd468a2016-12-19 23:05:39 +0100887static void vl_api_af_packet_create_reply_t_handler
888 (vl_api_af_packet_create_reply_t * mp)
889{
890 vat_main_t *vam = &vat_main;
891 i32 retval = ntohl (mp->retval);
892
893 vam->retval = retval;
894 vam->regenerate_interface_table = 1;
895 vam->sw_if_index = ntohl (mp->sw_if_index);
896 vam->result_ready = 1;
897}
898
899static void vl_api_af_packet_create_reply_t_handler_json
900 (vl_api_af_packet_create_reply_t * mp)
901{
902 vat_main_t *vam = &vat_main;
903 vat_json_node_t node;
904
905 vat_json_init_object (&node);
906 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
907 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
908
909 vat_json_print (vam->ofp, &node);
910 vat_json_free (&node);
911
912 vam->retval = ntohl (mp->retval);
913 vam->result_ready = 1;
914}
915
916static void vl_api_create_vlan_subif_reply_t_handler
917 (vl_api_create_vlan_subif_reply_t * mp)
918{
919 vat_main_t *vam = &vat_main;
920 i32 retval = ntohl (mp->retval);
921
922 vam->retval = retval;
923 vam->regenerate_interface_table = 1;
924 vam->sw_if_index = ntohl (mp->sw_if_index);
925 vam->result_ready = 1;
926}
927
928static void vl_api_create_vlan_subif_reply_t_handler_json
929 (vl_api_create_vlan_subif_reply_t * mp)
930{
931 vat_main_t *vam = &vat_main;
932 vat_json_node_t node;
933
934 vat_json_init_object (&node);
935 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
936 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
937
938 vat_json_print (vam->ofp, &node);
939 vat_json_free (&node);
940
941 vam->retval = ntohl (mp->retval);
942 vam->result_ready = 1;
943}
944
945static void vl_api_create_subif_reply_t_handler
946 (vl_api_create_subif_reply_t * mp)
947{
948 vat_main_t *vam = &vat_main;
949 i32 retval = ntohl (mp->retval);
950
951 vam->retval = retval;
952 vam->regenerate_interface_table = 1;
953 vam->sw_if_index = ntohl (mp->sw_if_index);
954 vam->result_ready = 1;
955}
956
957static void vl_api_create_subif_reply_t_handler_json
958 (vl_api_create_subif_reply_t * mp)
959{
960 vat_main_t *vam = &vat_main;
961 vat_json_node_t node;
962
963 vat_json_init_object (&node);
964 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
965 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
966
967 vat_json_print (vam->ofp, &node);
968 vat_json_free (&node);
969
970 vam->retval = ntohl (mp->retval);
971 vam->result_ready = 1;
972}
973
974static void vl_api_interface_name_renumber_reply_t_handler
975 (vl_api_interface_name_renumber_reply_t * mp)
976{
977 vat_main_t *vam = &vat_main;
978 i32 retval = ntohl (mp->retval);
979
980 vam->retval = retval;
981 vam->regenerate_interface_table = 1;
982 vam->result_ready = 1;
983}
984
985static void vl_api_interface_name_renumber_reply_t_handler_json
986 (vl_api_interface_name_renumber_reply_t * mp)
987{
988 vat_main_t *vam = &vat_main;
989 vat_json_node_t node;
990
991 vat_json_init_object (&node);
992 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
993
994 vat_json_print (vam->ofp, &node);
995 vat_json_free (&node);
996
997 vam->retval = ntohl (mp->retval);
998 vam->result_ready = 1;
999}
1000
1001/*
1002 * Special-case: build the interface table, maintain
1003 * the next loopback sw_if_index vbl.
1004 */
1005static void vl_api_sw_interface_details_t_handler
1006 (vl_api_sw_interface_details_t * mp)
1007{
1008 vat_main_t *vam = &vat_main;
Ole Troane5ff5a32019-08-23 22:55:18 +02001009 u8 *s = format (0, "%s%c", mp->interface_name, 0);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001010
1011 hash_set_mem (vam->sw_if_index_by_interface_name, s,
1012 ntohl (mp->sw_if_index));
1013
1014 /* In sub interface case, fill the sub interface table entry */
1015 if (mp->sw_if_index != mp->sup_sw_if_index)
1016 {
1017 sw_interface_subif_t *sub = NULL;
1018
1019 vec_add2 (vam->sw_if_subif_table, sub, 1);
1020
1021 vec_validate (sub->interface_name, strlen ((char *) s) + 1);
1022 strncpy ((char *) sub->interface_name, (char *) s,
1023 vec_len (sub->interface_name));
1024 sub->sw_if_index = ntohl (mp->sw_if_index);
1025 sub->sub_id = ntohl (mp->sub_id);
1026
Jakub Grajciar053204a2019-03-18 13:17:53 +01001027 sub->raw_flags = ntohl (mp->sub_if_flags & SUB_IF_API_FLAG_MASK_VNET);
1028
Damjan Marion7cd468a2016-12-19 23:05:39 +01001029 sub->sub_number_of_tags = mp->sub_number_of_tags;
1030 sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
1031 sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001032
1033 /* vlan tag rewrite */
1034 sub->vtr_op = ntohl (mp->vtr_op);
1035 sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
1036 sub->vtr_tag1 = ntohl (mp->vtr_tag1);
1037 sub->vtr_tag2 = ntohl (mp->vtr_tag2);
1038 }
1039}
1040
1041static void vl_api_sw_interface_details_t_handler_json
1042 (vl_api_sw_interface_details_t * mp)
1043{
1044 vat_main_t *vam = &vat_main;
1045 vat_json_node_t *node = NULL;
1046
1047 if (VAT_JSON_ARRAY != vam->json_tree.type)
1048 {
1049 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1050 vat_json_init_array (&vam->json_tree);
1051 }
1052 node = vat_json_array_add (&vam->json_tree);
1053
1054 vat_json_init_object (node);
1055 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1056 vat_json_object_add_uint (node, "sup_sw_if_index",
1057 ntohl (mp->sup_sw_if_index));
Damjan Marion7cd468a2016-12-19 23:05:39 +01001058 vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
1059 sizeof (mp->l2_address));
1060 vat_json_object_add_string_copy (node, "interface_name",
Ole Troane5ff5a32019-08-23 22:55:18 +02001061 mp->interface_name);
Mohsin Kazmide312c22019-09-27 13:44:28 +02001062 vat_json_object_add_string_copy (node, "interface_dev_type",
1063 mp->interface_dev_type);
Jakub Grajciar053204a2019-03-18 13:17:53 +01001064 vat_json_object_add_uint (node, "flags", mp->flags);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001065 vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
1066 vat_json_object_add_uint (node, "link_speed", mp->link_speed);
Damjan Marionfe7d4a22018-04-13 19:43:39 +02001067 vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
Damjan Marion7cd468a2016-12-19 23:05:39 +01001068 vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
Damjan Marion7cd468a2016-12-19 23:05:39 +01001069 vat_json_object_add_uint (node, "sub_number_of_tags",
1070 mp->sub_number_of_tags);
1071 vat_json_object_add_uint (node, "sub_outer_vlan_id",
1072 ntohs (mp->sub_outer_vlan_id));
1073 vat_json_object_add_uint (node, "sub_inner_vlan_id",
1074 ntohs (mp->sub_inner_vlan_id));
Jakub Grajciar053204a2019-03-18 13:17:53 +01001075 vat_json_object_add_uint (node, "sub_if_flags", ntohl (mp->sub_if_flags));
Damjan Marion7cd468a2016-12-19 23:05:39 +01001076 vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1077 vat_json_object_add_uint (node, "vtr_push_dot1q",
1078 ntohl (mp->vtr_push_dot1q));
1079 vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1080 vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
Jakub Grajciar053204a2019-03-18 13:17:53 +01001081 if (ntohl (mp->sub_if_flags) & SUB_IF_API_FLAG_DOT1AH)
Pavel Kotucek65e84572017-01-16 17:01:56 +01001082 {
1083 vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1084 format (0, "%U",
1085 format_ethernet_address,
1086 &mp->b_dmac));
1087 vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1088 format (0, "%U",
1089 format_ethernet_address,
1090 &mp->b_smac));
1091 vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1092 vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1093 }
Damjan Marion7cd468a2016-12-19 23:05:39 +01001094}
1095
Dave Baracha1a093d2017-03-02 13:13:23 -05001096#if VPP_API_TEST_BUILTIN == 0
Neale Rannsa07bd702017-08-07 07:53:49 -07001097static void vl_api_sw_interface_event_t_handler
1098 (vl_api_sw_interface_event_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01001099{
1100 vat_main_t *vam = &vat_main;
1101 if (vam->interface_event_display)
1102 errmsg ("interface flags: sw_if_index %d %s %s",
1103 ntohl (mp->sw_if_index),
Jakub Grajciar053204a2019-03-18 13:17:53 +01001104 ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_ADMIN_UP) ?
1105 "admin-up" : "admin-down",
1106 ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_LINK_UP) ?
1107 "link-up" : "link-down");
Damjan Marion7cd468a2016-12-19 23:05:39 +01001108}
Dave Baracha1a093d2017-03-02 13:13:23 -05001109#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +01001110
Benoît Ganne49ee6842019-04-30 11:50:46 +02001111__clib_unused static void
1112vl_api_sw_interface_event_t_handler_json (vl_api_sw_interface_event_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01001113{
1114 /* JSON output not supported */
1115}
1116
1117static void
1118vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1119{
1120 vat_main_t *vam = &vat_main;
1121 i32 retval = ntohl (mp->retval);
1122
1123 vam->retval = retval;
Damjan Marion7bee80c2017-04-26 15:32:12 +02001124 vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001125 vam->result_ready = 1;
1126}
1127
1128static void
1129vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1130{
1131 vat_main_t *vam = &vat_main;
1132 vat_json_node_t node;
Damjan Marion7cd468a2016-12-19 23:05:39 +01001133 void *oldheap;
1134 u8 *reply;
1135
1136 vat_json_init_object (&node);
1137 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1138 vat_json_object_add_uint (&node, "reply_in_shmem",
1139 ntohl (mp->reply_in_shmem));
1140 /* Toss the shared-memory original... */
Nathan Skrzypczak0aa40132019-11-25 16:29:38 +01001141 oldheap = vl_msg_push_heap ();
Damjan Marion7cd468a2016-12-19 23:05:39 +01001142
Damjan Marion7bee80c2017-04-26 15:32:12 +02001143 reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001144 vec_free (reply);
1145
Nathan Skrzypczak0aa40132019-11-25 16:29:38 +01001146 vl_msg_pop_heap (oldheap);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001147
1148 vat_json_print (vam->ofp, &node);
1149 vat_json_free (&node);
1150
1151 vam->retval = ntohl (mp->retval);
1152 vam->result_ready = 1;
1153}
1154
1155static void
1156vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1157{
1158 vat_main_t *vam = &vat_main;
1159 i32 retval = ntohl (mp->retval);
Dave Barach59b25652017-09-10 15:04:27 -04001160
1161 vec_reset_length (vam->cmd_reply);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001162
1163 vam->retval = retval;
Dave Barach59b25652017-09-10 15:04:27 -04001164 if (retval == 0)
Dave Barach77841402020-04-29 17:04:10 -04001165 vam->cmd_reply = vl_api_from_api_to_new_vec (mp, &mp->reply);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001166 vam->result_ready = 1;
1167}
1168
1169static void
1170vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1171{
1172 vat_main_t *vam = &vat_main;
1173 vat_json_node_t node;
Jakub Grajciar2dbee932020-02-07 11:30:26 +01001174 u8 *reply = 0; /* reply vector */
Damjan Marion7cd468a2016-12-19 23:05:39 +01001175
Dave Barach77841402020-04-29 17:04:10 -04001176 reply = vl_api_from_api_to_new_vec (mp, &mp->reply);
Dave Barach59b25652017-09-10 15:04:27 -04001177 vec_reset_length (vam->cmd_reply);
1178
Damjan Marion7cd468a2016-12-19 23:05:39 +01001179 vat_json_init_object (&node);
1180 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
Jakub Grajciar2dbee932020-02-07 11:30:26 +01001181 vat_json_object_add_string_copy (&node, "reply", reply);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001182
1183 vat_json_print (vam->ofp, &node);
1184 vat_json_free (&node);
Jakub Grajciar2dbee932020-02-07 11:30:26 +01001185 vec_free (reply);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001186
1187 vam->retval = ntohl (mp->retval);
1188 vam->result_ready = 1;
1189}
1190
1191static void vl_api_classify_add_del_table_reply_t_handler
1192 (vl_api_classify_add_del_table_reply_t * mp)
1193{
1194 vat_main_t *vam = &vat_main;
1195 i32 retval = ntohl (mp->retval);
1196 if (vam->async_mode)
1197 {
1198 vam->async_errors += (retval < 0);
1199 }
1200 else
1201 {
1202 vam->retval = retval;
1203 if (retval == 0 &&
1204 ((mp->new_table_index != 0xFFFFFFFF) ||
1205 (mp->skip_n_vectors != 0xFFFFFFFF) ||
1206 (mp->match_n_vectors != 0xFFFFFFFF)))
1207 /*
1208 * Note: this is just barely thread-safe, depends on
1209 * the main thread spinning waiting for an answer...
1210 */
1211 errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1212 ntohl (mp->new_table_index),
1213 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1214 vam->result_ready = 1;
1215 }
1216}
1217
1218static void vl_api_classify_add_del_table_reply_t_handler_json
1219 (vl_api_classify_add_del_table_reply_t * mp)
1220{
1221 vat_main_t *vam = &vat_main;
1222 vat_json_node_t node;
1223
1224 vat_json_init_object (&node);
1225 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1226 vat_json_object_add_uint (&node, "new_table_index",
1227 ntohl (mp->new_table_index));
1228 vat_json_object_add_uint (&node, "skip_n_vectors",
1229 ntohl (mp->skip_n_vectors));
1230 vat_json_object_add_uint (&node, "match_n_vectors",
1231 ntohl (mp->match_n_vectors));
1232
1233 vat_json_print (vam->ofp, &node);
1234 vat_json_free (&node);
1235
1236 vam->retval = ntohl (mp->retval);
1237 vam->result_ready = 1;
1238}
1239
1240static void vl_api_get_node_index_reply_t_handler
1241 (vl_api_get_node_index_reply_t * mp)
1242{
1243 vat_main_t *vam = &vat_main;
1244 i32 retval = ntohl (mp->retval);
1245 if (vam->async_mode)
1246 {
1247 vam->async_errors += (retval < 0);
1248 }
1249 else
1250 {
1251 vam->retval = retval;
1252 if (retval == 0)
1253 errmsg ("node index %d", ntohl (mp->node_index));
1254 vam->result_ready = 1;
1255 }
1256}
1257
1258static void vl_api_get_node_index_reply_t_handler_json
1259 (vl_api_get_node_index_reply_t * mp)
1260{
1261 vat_main_t *vam = &vat_main;
1262 vat_json_node_t node;
1263
1264 vat_json_init_object (&node);
1265 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1266 vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1267
1268 vat_json_print (vam->ofp, &node);
1269 vat_json_free (&node);
1270
1271 vam->retval = ntohl (mp->retval);
1272 vam->result_ready = 1;
1273}
1274
1275static void vl_api_get_next_index_reply_t_handler
1276 (vl_api_get_next_index_reply_t * mp)
1277{
1278 vat_main_t *vam = &vat_main;
1279 i32 retval = ntohl (mp->retval);
1280 if (vam->async_mode)
1281 {
1282 vam->async_errors += (retval < 0);
1283 }
1284 else
1285 {
1286 vam->retval = retval;
1287 if (retval == 0)
1288 errmsg ("next node index %d", ntohl (mp->next_index));
1289 vam->result_ready = 1;
1290 }
1291}
1292
1293static void vl_api_get_next_index_reply_t_handler_json
1294 (vl_api_get_next_index_reply_t * mp)
1295{
1296 vat_main_t *vam = &vat_main;
1297 vat_json_node_t node;
1298
1299 vat_json_init_object (&node);
1300 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1301 vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1302
1303 vat_json_print (vam->ofp, &node);
1304 vat_json_free (&node);
1305
1306 vam->retval = ntohl (mp->retval);
1307 vam->result_ready = 1;
1308}
1309
1310static void vl_api_add_node_next_reply_t_handler
1311 (vl_api_add_node_next_reply_t * mp)
1312{
1313 vat_main_t *vam = &vat_main;
1314 i32 retval = ntohl (mp->retval);
1315 if (vam->async_mode)
1316 {
1317 vam->async_errors += (retval < 0);
1318 }
1319 else
1320 {
1321 vam->retval = retval;
1322 if (retval == 0)
1323 errmsg ("next index %d", ntohl (mp->next_index));
1324 vam->result_ready = 1;
1325 }
1326}
1327
1328static void vl_api_add_node_next_reply_t_handler_json
1329 (vl_api_add_node_next_reply_t * mp)
1330{
1331 vat_main_t *vam = &vat_main;
1332 vat_json_node_t node;
1333
1334 vat_json_init_object (&node);
1335 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1336 vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1337
1338 vat_json_print (vam->ofp, &node);
1339 vat_json_free (&node);
1340
1341 vam->retval = ntohl (mp->retval);
1342 vam->result_ready = 1;
1343}
1344
1345static void vl_api_show_version_reply_t_handler
1346 (vl_api_show_version_reply_t * mp)
1347{
1348 vat_main_t *vam = &vat_main;
1349 i32 retval = ntohl (mp->retval);
1350
1351 if (retval >= 0)
1352 {
Ole Troane5ff5a32019-08-23 22:55:18 +02001353 errmsg (" program: %s", mp->program);
1354 errmsg (" version: %s", mp->version);
1355 errmsg (" build date: %s", mp->build_date);
1356 errmsg ("build directory: %s", mp->build_directory);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001357 }
1358 vam->retval = retval;
1359 vam->result_ready = 1;
1360}
1361
1362static void vl_api_show_version_reply_t_handler_json
1363 (vl_api_show_version_reply_t * mp)
1364{
1365 vat_main_t *vam = &vat_main;
1366 vat_json_node_t node;
1367
1368 vat_json_init_object (&node);
1369 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
Ole Troane5ff5a32019-08-23 22:55:18 +02001370 vat_json_object_add_string_copy (&node, "program", mp->program);
1371 vat_json_object_add_string_copy (&node, "version", mp->version);
1372 vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001373 vat_json_object_add_string_copy (&node, "build_directory",
Ole Troane5ff5a32019-08-23 22:55:18 +02001374 mp->build_directory);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001375
1376 vat_json_print (vam->ofp, &node);
1377 vat_json_free (&node);
1378
1379 vam->retval = ntohl (mp->retval);
1380 vam->result_ready = 1;
1381}
1382
Mohsin Kazmi5d64c782018-09-11 20:27:09 +02001383static void vl_api_show_threads_reply_t_handler
1384 (vl_api_show_threads_reply_t * mp)
1385{
1386 vat_main_t *vam = &vat_main;
1387 i32 retval = ntohl (mp->retval);
1388 int i, count = 0;
1389
1390 if (retval >= 0)
1391 count = ntohl (mp->count);
1392
1393 for (i = 0; i < count; i++)
1394 print (vam->ofp,
1395 "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1396 ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1397 mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1398 ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1399 ntohl (mp->thread_data[i].cpu_socket));
1400
1401 vam->retval = retval;
1402 vam->result_ready = 1;
1403}
1404
1405static void vl_api_show_threads_reply_t_handler_json
1406 (vl_api_show_threads_reply_t * mp)
1407{
1408 vat_main_t *vam = &vat_main;
1409 vat_json_node_t node;
1410 vl_api_thread_data_t *td;
Mohsin Kazmi5df628b2018-10-01 17:41:08 +02001411 i32 retval = ntohl (mp->retval);
1412 int i, count = 0;
1413
1414 if (retval >= 0)
1415 count = ntohl (mp->count);
Mohsin Kazmi5d64c782018-09-11 20:27:09 +02001416
1417 vat_json_init_object (&node);
Mohsin Kazmi5df628b2018-10-01 17:41:08 +02001418 vat_json_object_add_int (&node, "retval", retval);
Mohsin Kazmi5d64c782018-09-11 20:27:09 +02001419 vat_json_object_add_uint (&node, "count", count);
1420
1421 for (i = 0; i < count; i++)
1422 {
1423 td = &mp->thread_data[i];
1424 vat_json_object_add_uint (&node, "id", ntohl (td->id));
1425 vat_json_object_add_string_copy (&node, "name", td->name);
1426 vat_json_object_add_string_copy (&node, "type", td->type);
1427 vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1428 vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1429 vat_json_object_add_int (&node, "core", ntohl (td->id));
1430 vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1431 }
1432
1433 vat_json_print (vam->ofp, &node);
1434 vat_json_free (&node);
1435
Mohsin Kazmi5df628b2018-10-01 17:41:08 +02001436 vam->retval = retval;
Mohsin Kazmi5d64c782018-09-11 20:27:09 +02001437 vam->result_ready = 1;
1438}
1439
1440static int
1441api_show_threads (vat_main_t * vam)
1442{
1443 vl_api_show_threads_t *mp;
1444 int ret;
1445
1446 print (vam->ofp,
1447 "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1448 "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1449
1450 M (SHOW_THREADS, mp);
1451
1452 S (mp);
1453 W (ret);
1454 return ret;
1455}
1456
Damjan Marion7cd468a2016-12-19 23:05:39 +01001457static void
John Lo8d00fff2017-08-03 00:35:36 -04001458vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1459{
1460 u32 n_macs = ntohl (mp->n_macs);
Paul Vinciguerraec11b132018-09-24 05:25:00 -07001461 errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
John Lo8d00fff2017-08-03 00:35:36 -04001462 ntohl (mp->pid), mp->client_index, n_macs);
1463 int i;
1464 for (i = 0; i < n_macs; i++)
1465 {
1466 vl_api_mac_entry_t *mac = &mp->mac[i];
John Loe23c99e2018-03-13 21:53:18 -04001467 errmsg (" [%d] sw_if_index %d mac_addr %U action %d \n",
John Lo8d00fff2017-08-03 00:35:36 -04001468 i + 1, ntohl (mac->sw_if_index),
John Loe23c99e2018-03-13 21:53:18 -04001469 format_ethernet_address, mac->mac_addr, mac->action);
John Lo8d00fff2017-08-03 00:35:36 -04001470 if (i == 1000)
1471 break;
1472 }
1473}
1474
1475static void
1476vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1477{
1478 /* JSON output not supported */
1479}
1480
Ole Troan01384fe2017-05-12 11:55:35 +02001481#define vl_api_bridge_domain_details_t_endian vl_noop_handler
1482#define vl_api_bridge_domain_details_t_print vl_noop_handler
1483
Damjan Marion7cd468a2016-12-19 23:05:39 +01001484/*
1485 * Special-case: build the bridge domain table, maintain
1486 * the next bd id vbl.
1487 */
1488static void vl_api_bridge_domain_details_t_handler
1489 (vl_api_bridge_domain_details_t * mp)
1490{
1491 vat_main_t *vam = &vat_main;
1492 u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
Ole Troan01384fe2017-05-12 11:55:35 +02001493 int i;
Damjan Marion7cd468a2016-12-19 23:05:39 +01001494
Mohsin Kazmi762d83c2018-09-27 15:00:32 +02001495 print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1496 " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
Damjan Marion7cd468a2016-12-19 23:05:39 +01001497
Mohsin Kazmi762d83c2018-09-27 15:00:32 +02001498 print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
Damjan Marion7cd468a2016-12-19 23:05:39 +01001499 ntohl (mp->bd_id), mp->learn, mp->forward,
Mohsin Kazmi762d83c2018-09-27 15:00:32 +02001500 mp->flood, ntohl (mp->bvi_sw_if_index),
1501 ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001502
1503 if (n_sw_ifs)
Ole Troan01384fe2017-05-12 11:55:35 +02001504 {
1505 vl_api_bridge_domain_sw_if_t *sw_ifs;
1506 print (vam->ofp, "\n\n%s %s %s", "sw_if_index", "SHG",
1507 "Interface Name");
1508
1509 sw_ifs = mp->sw_if_details;
1510 for (i = 0; i < n_sw_ifs; i++)
1511 {
1512 u8 *sw_if_name = 0;
1513 u32 sw_if_index;
1514 hash_pair_t *p;
1515
1516 sw_if_index = ntohl (sw_ifs->sw_if_index);
1517
1518 /* *INDENT-OFF* */
1519 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1520 ({
1521 if ((u32) p->value[0] == sw_if_index)
1522 {
1523 sw_if_name = (u8 *)(p->key);
1524 break;
1525 }
1526 }));
1527 /* *INDENT-ON* */
1528 print (vam->ofp, "%7d %3d %s", sw_if_index,
1529 sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1530 "sw_if_index not found!");
1531
1532 sw_ifs++;
1533 }
1534 }
Damjan Marion7cd468a2016-12-19 23:05:39 +01001535}
1536
1537static void vl_api_bridge_domain_details_t_handler_json
1538 (vl_api_bridge_domain_details_t * mp)
1539{
1540 vat_main_t *vam = &vat_main;
1541 vat_json_node_t *node, *array = NULL;
Ole Troan01384fe2017-05-12 11:55:35 +02001542 u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001543
1544 if (VAT_JSON_ARRAY != vam->json_tree.type)
1545 {
1546 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1547 vat_json_init_array (&vam->json_tree);
1548 }
1549 node = vat_json_array_add (&vam->json_tree);
1550
1551 vat_json_init_object (node);
1552 vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1553 vat_json_object_add_uint (node, "flood", mp->flood);
1554 vat_json_object_add_uint (node, "forward", mp->forward);
1555 vat_json_object_add_uint (node, "learn", mp->learn);
1556 vat_json_object_add_uint (node, "bvi_sw_if_index",
1557 ntohl (mp->bvi_sw_if_index));
Ole Troan01384fe2017-05-12 11:55:35 +02001558 vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001559 array = vat_json_object_add (node, "sw_if");
1560 vat_json_init_array (array);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001561
Damjan Marion7cd468a2016-12-19 23:05:39 +01001562
Damjan Marion7cd468a2016-12-19 23:05:39 +01001563
Ole Troan01384fe2017-05-12 11:55:35 +02001564 if (n_sw_ifs)
1565 {
1566 vl_api_bridge_domain_sw_if_t *sw_ifs;
1567 int i;
Damjan Marion7cd468a2016-12-19 23:05:39 +01001568
Ole Troan01384fe2017-05-12 11:55:35 +02001569 sw_ifs = mp->sw_if_details;
1570 for (i = 0; i < n_sw_ifs; i++)
1571 {
1572 node = vat_json_array_add (array);
1573 vat_json_init_object (node);
1574 vat_json_object_add_uint (node, "sw_if_index",
1575 ntohl (sw_ifs->sw_if_index));
1576 vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1577 sw_ifs++;
1578 }
1579 }
Damjan Marion7cd468a2016-12-19 23:05:39 +01001580}
1581
1582static void vl_api_control_ping_reply_t_handler
1583 (vl_api_control_ping_reply_t * mp)
1584{
1585 vat_main_t *vam = &vat_main;
1586 i32 retval = ntohl (mp->retval);
1587 if (vam->async_mode)
1588 {
1589 vam->async_errors += (retval < 0);
1590 }
1591 else
1592 {
1593 vam->retval = retval;
1594 vam->result_ready = 1;
1595 }
Florin Coras90a63982017-12-19 04:50:01 -08001596 if (vam->socket_client_main)
1597 vam->socket_client_main->control_pings_outstanding--;
Damjan Marion7cd468a2016-12-19 23:05:39 +01001598}
1599
1600static void vl_api_control_ping_reply_t_handler_json
1601 (vl_api_control_ping_reply_t * mp)
1602{
1603 vat_main_t *vam = &vat_main;
1604 i32 retval = ntohl (mp->retval);
1605
1606 if (VAT_JSON_NONE != vam->json_tree.type)
1607 {
1608 vat_json_print (vam->ofp, &vam->json_tree);
1609 vat_json_free (&vam->json_tree);
1610 vam->json_tree.type = VAT_JSON_NONE;
1611 }
1612 else
1613 {
1614 /* just print [] */
1615 vat_json_init_array (&vam->json_tree);
1616 vat_json_print (vam->ofp, &vam->json_tree);
1617 vam->json_tree.type = VAT_JSON_NONE;
1618 }
1619
1620 vam->retval = retval;
1621 vam->result_ready = 1;
1622}
1623
1624static void
Eyal Barifead6702017-04-04 04:46:32 +03001625 vl_api_bridge_domain_set_mac_age_reply_t_handler
1626 (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1627{
1628 vat_main_t *vam = &vat_main;
1629 i32 retval = ntohl (mp->retval);
1630 if (vam->async_mode)
1631 {
1632 vam->async_errors += (retval < 0);
1633 }
1634 else
1635 {
1636 vam->retval = retval;
1637 vam->result_ready = 1;
1638 }
1639}
1640
1641static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1642 (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1643{
1644 vat_main_t *vam = &vat_main;
1645 vat_json_node_t node;
1646
1647 vat_json_init_object (&node);
1648 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1649
1650 vat_json_print (vam->ofp, &node);
1651 vat_json_free (&node);
1652
1653 vam->retval = ntohl (mp->retval);
1654 vam->result_ready = 1;
1655}
1656
1657static void
Damjan Marion7cd468a2016-12-19 23:05:39 +01001658vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1659{
1660 vat_main_t *vam = &vat_main;
1661 i32 retval = ntohl (mp->retval);
1662 if (vam->async_mode)
1663 {
1664 vam->async_errors += (retval < 0);
1665 }
1666 else
1667 {
1668 vam->retval = retval;
1669 vam->result_ready = 1;
1670 }
1671}
1672
1673static void vl_api_l2_flags_reply_t_handler_json
1674 (vl_api_l2_flags_reply_t * mp)
1675{
1676 vat_main_t *vam = &vat_main;
1677 vat_json_node_t node;
1678
1679 vat_json_init_object (&node);
1680 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1681 vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1682 ntohl (mp->resulting_feature_bitmap));
1683
1684 vat_json_print (vam->ofp, &node);
1685 vat_json_free (&node);
1686
1687 vam->retval = ntohl (mp->retval);
1688 vam->result_ready = 1;
1689}
1690
1691static void vl_api_bridge_flags_reply_t_handler
1692 (vl_api_bridge_flags_reply_t * mp)
1693{
1694 vat_main_t *vam = &vat_main;
1695 i32 retval = ntohl (mp->retval);
1696 if (vam->async_mode)
1697 {
1698 vam->async_errors += (retval < 0);
1699 }
1700 else
1701 {
1702 vam->retval = retval;
1703 vam->result_ready = 1;
1704 }
1705}
1706
1707static void vl_api_bridge_flags_reply_t_handler_json
1708 (vl_api_bridge_flags_reply_t * mp)
1709{
1710 vat_main_t *vam = &vat_main;
1711 vat_json_node_t node;
1712
1713 vat_json_init_object (&node);
1714 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1715 vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1716 ntohl (mp->resulting_feature_bitmap));
1717
1718 vat_json_print (vam->ofp, &node);
1719 vat_json_free (&node);
1720
1721 vam->retval = ntohl (mp->retval);
1722 vam->result_ready = 1;
1723}
1724
Damjan Marion8389fb92017-10-13 18:29:53 +02001725static void
1726vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1727{
1728 vat_main_t *vam = &vat_main;
1729 i32 retval = ntohl (mp->retval);
1730 if (vam->async_mode)
1731 {
1732 vam->async_errors += (retval < 0);
1733 }
1734 else
1735 {
1736 vam->retval = retval;
1737 vam->sw_if_index = ntohl (mp->sw_if_index);
1738 vam->result_ready = 1;
1739 }
1740
1741}
1742
1743static void vl_api_tap_create_v2_reply_t_handler_json
1744 (vl_api_tap_create_v2_reply_t * mp)
1745{
1746 vat_main_t *vam = &vat_main;
1747 vat_json_node_t node;
1748
1749 vat_json_init_object (&node);
1750 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1751 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1752
1753 vat_json_print (vam->ofp, &node);
1754 vat_json_free (&node);
1755
1756 vam->retval = ntohl (mp->retval);
1757 vam->result_ready = 1;
1758
1759}
1760
1761static void
1762vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1763{
1764 vat_main_t *vam = &vat_main;
1765 i32 retval = ntohl (mp->retval);
1766 if (vam->async_mode)
1767 {
1768 vam->async_errors += (retval < 0);
1769 }
1770 else
1771 {
1772 vam->retval = retval;
1773 vam->result_ready = 1;
1774 }
1775}
1776
1777static void vl_api_tap_delete_v2_reply_t_handler_json
1778 (vl_api_tap_delete_v2_reply_t * mp)
1779{
1780 vat_main_t *vam = &vat_main;
1781 vat_json_node_t node;
1782
1783 vat_json_init_object (&node);
1784 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1785
1786 vat_json_print (vam->ofp, &node);
1787 vat_json_free (&node);
1788
1789 vam->retval = ntohl (mp->retval);
1790 vam->result_ready = 1;
1791}
1792
Steven9cd2d7a2017-12-20 12:43:01 -08001793static void
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01001794vl_api_virtio_pci_create_reply_t_handler (vl_api_virtio_pci_create_reply_t *
1795 mp)
1796{
1797 vat_main_t *vam = &vat_main;
1798 i32 retval = ntohl (mp->retval);
1799 if (vam->async_mode)
1800 {
1801 vam->async_errors += (retval < 0);
1802 }
1803 else
1804 {
1805 vam->retval = retval;
1806 vam->sw_if_index = ntohl (mp->sw_if_index);
1807 vam->result_ready = 1;
1808 }
1809}
1810
1811static void vl_api_virtio_pci_create_reply_t_handler_json
1812 (vl_api_virtio_pci_create_reply_t * mp)
1813{
1814 vat_main_t *vam = &vat_main;
1815 vat_json_node_t node;
1816
1817 vat_json_init_object (&node);
1818 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1819 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1820
1821 vat_json_print (vam->ofp, &node);
1822 vat_json_free (&node);
1823
1824 vam->retval = ntohl (mp->retval);
1825 vam->result_ready = 1;
1826
1827}
1828
1829static void
Mohsin Kazmi518251b2020-09-01 17:17:44 +00001830 vl_api_virtio_pci_create_v2_reply_t_handler
1831 (vl_api_virtio_pci_create_v2_reply_t * mp)
1832{
1833 vat_main_t *vam = &vat_main;
1834 i32 retval = ntohl (mp->retval);
1835 if (vam->async_mode)
1836 {
1837 vam->async_errors += (retval < 0);
1838 }
1839 else
1840 {
1841 vam->retval = retval;
1842 vam->sw_if_index = ntohl (mp->sw_if_index);
1843 vam->result_ready = 1;
1844 }
1845}
1846
1847static void vl_api_virtio_pci_create_v2_reply_t_handler_json
1848 (vl_api_virtio_pci_create_v2_reply_t * mp)
1849{
1850 vat_main_t *vam = &vat_main;
1851 vat_json_node_t node;
1852
1853 vat_json_init_object (&node);
1854 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1855 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1856
1857 vat_json_print (vam->ofp, &node);
1858 vat_json_free (&node);
1859
1860 vam->retval = ntohl (mp->retval);
1861 vam->result_ready = 1;
1862}
1863
1864static void
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01001865vl_api_virtio_pci_delete_reply_t_handler (vl_api_virtio_pci_delete_reply_t *
1866 mp)
1867{
1868 vat_main_t *vam = &vat_main;
1869 i32 retval = ntohl (mp->retval);
1870 if (vam->async_mode)
1871 {
1872 vam->async_errors += (retval < 0);
1873 }
1874 else
1875 {
1876 vam->retval = retval;
1877 vam->result_ready = 1;
1878 }
1879}
1880
1881static void vl_api_virtio_pci_delete_reply_t_handler_json
1882 (vl_api_virtio_pci_delete_reply_t * mp)
1883{
1884 vat_main_t *vam = &vat_main;
1885 vat_json_node_t node;
1886
1887 vat_json_init_object (&node);
1888 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1889
1890 vat_json_print (vam->ofp, &node);
1891 vat_json_free (&node);
1892
1893 vam->retval = ntohl (mp->retval);
1894 vam->result_ready = 1;
1895}
1896
1897static void
Steven9cd2d7a2017-12-20 12:43:01 -08001898vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1899{
1900 vat_main_t *vam = &vat_main;
1901 i32 retval = ntohl (mp->retval);
1902
1903 if (vam->async_mode)
1904 {
1905 vam->async_errors += (retval < 0);
1906 }
1907 else
1908 {
1909 vam->retval = retval;
1910 vam->sw_if_index = ntohl (mp->sw_if_index);
1911 vam->result_ready = 1;
1912 }
1913}
1914
1915static void vl_api_bond_create_reply_t_handler_json
1916 (vl_api_bond_create_reply_t * mp)
1917{
1918 vat_main_t *vam = &vat_main;
1919 vat_json_node_t node;
1920
1921 vat_json_init_object (&node);
1922 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1923 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1924
1925 vat_json_print (vam->ofp, &node);
1926 vat_json_free (&node);
1927
1928 vam->retval = ntohl (mp->retval);
1929 vam->result_ready = 1;
1930}
1931
1932static void
Steven Luongea717862020-07-30 07:31:40 -07001933vl_api_bond_create2_reply_t_handler (vl_api_bond_create2_reply_t * mp)
1934{
1935 vat_main_t *vam = &vat_main;
1936 i32 retval = ntohl (mp->retval);
1937
1938 if (vam->async_mode)
1939 {
1940 vam->async_errors += (retval < 0);
1941 }
1942 else
1943 {
1944 vam->retval = retval;
1945 vam->sw_if_index = ntohl (mp->sw_if_index);
1946 vam->result_ready = 1;
1947 }
1948}
1949
1950static void vl_api_bond_create2_reply_t_handler_json
1951 (vl_api_bond_create2_reply_t * mp)
1952{
1953 vat_main_t *vam = &vat_main;
1954 vat_json_node_t node;
1955
1956 vat_json_init_object (&node);
1957 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1958 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1959
1960 vat_json_print (vam->ofp, &node);
1961 vat_json_free (&node);
1962
1963 vam->retval = ntohl (mp->retval);
1964 vam->result_ready = 1;
1965}
1966
1967static void
Steven9cd2d7a2017-12-20 12:43:01 -08001968vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1969{
1970 vat_main_t *vam = &vat_main;
1971 i32 retval = ntohl (mp->retval);
1972
1973 if (vam->async_mode)
1974 {
1975 vam->async_errors += (retval < 0);
1976 }
1977 else
1978 {
1979 vam->retval = retval;
1980 vam->result_ready = 1;
1981 }
1982}
1983
1984static void vl_api_bond_delete_reply_t_handler_json
1985 (vl_api_bond_delete_reply_t * mp)
1986{
1987 vat_main_t *vam = &vat_main;
1988 vat_json_node_t node;
1989
1990 vat_json_init_object (&node);
1991 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1992
1993 vat_json_print (vam->ofp, &node);
1994 vat_json_free (&node);
1995
1996 vam->retval = ntohl (mp->retval);
1997 vam->result_ready = 1;
1998}
1999
2000static void
Steven Luong4c4223e2020-07-15 08:44:54 -07002001vl_api_bond_add_member_reply_t_handler (vl_api_bond_add_member_reply_t * mp)
Steven9cd2d7a2017-12-20 12:43:01 -08002002{
2003 vat_main_t *vam = &vat_main;
2004 i32 retval = ntohl (mp->retval);
2005
2006 if (vam->async_mode)
2007 {
2008 vam->async_errors += (retval < 0);
2009 }
2010 else
2011 {
2012 vam->retval = retval;
2013 vam->result_ready = 1;
2014 }
2015}
2016
Steven Luong4c4223e2020-07-15 08:44:54 -07002017static void vl_api_bond_add_member_reply_t_handler_json
2018 (vl_api_bond_add_member_reply_t * mp)
Steven9cd2d7a2017-12-20 12:43:01 -08002019{
2020 vat_main_t *vam = &vat_main;
2021 vat_json_node_t node;
2022
2023 vat_json_init_object (&node);
2024 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2025
2026 vat_json_print (vam->ofp, &node);
2027 vat_json_free (&node);
2028
2029 vam->retval = ntohl (mp->retval);
2030 vam->result_ready = 1;
2031}
2032
2033static void
Steven Luong4c4223e2020-07-15 08:44:54 -07002034vl_api_bond_detach_member_reply_t_handler (vl_api_bond_detach_member_reply_t *
2035 mp)
Steven9cd2d7a2017-12-20 12:43:01 -08002036{
2037 vat_main_t *vam = &vat_main;
2038 i32 retval = ntohl (mp->retval);
2039
2040 if (vam->async_mode)
2041 {
2042 vam->async_errors += (retval < 0);
2043 }
2044 else
2045 {
2046 vam->retval = retval;
2047 vam->result_ready = 1;
2048 }
2049}
2050
Steven Luong4c4223e2020-07-15 08:44:54 -07002051static void vl_api_bond_detach_member_reply_t_handler_json
2052 (vl_api_bond_detach_member_reply_t * mp)
Steven9cd2d7a2017-12-20 12:43:01 -08002053{
2054 vat_main_t *vam = &vat_main;
2055 vat_json_node_t node;
2056
2057 vat_json_init_object (&node);
2058 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2059
2060 vat_json_print (vam->ofp, &node);
2061 vat_json_free (&node);
2062
2063 vam->retval = ntohl (mp->retval);
2064 vam->result_ready = 1;
2065}
2066
Steven Luonga1876b82019-08-20 16:58:00 -07002067static int
2068api_sw_interface_set_bond_weight (vat_main_t * vam)
2069{
2070 unformat_input_t *i = vam->input;
2071 vl_api_sw_interface_set_bond_weight_t *mp;
2072 u32 sw_if_index = ~0;
2073 u32 weight = 0;
2074 u8 weight_enter = 0;
2075 int ret;
2076
2077 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2078 {
2079 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2080 ;
2081 else if (unformat (i, "sw_if_index %d", &sw_if_index))
2082 ;
2083 else if (unformat (i, "weight %u", &weight))
2084 weight_enter = 1;
2085 else
2086 break;
2087 }
2088
2089 if (sw_if_index == ~0)
2090 {
2091 errmsg ("missing interface name or sw_if_index");
2092 return -99;
2093 }
2094 if (weight_enter == 0)
2095 {
2096 errmsg ("missing valid weight");
2097 return -99;
2098 }
2099
2100 /* Construct the API message */
2101 M (SW_INTERFACE_SET_BOND_WEIGHT, mp);
2102 mp->sw_if_index = ntohl (sw_if_index);
2103 mp->weight = ntohl (weight);
2104
2105 S (mp);
2106 W (ret);
2107 return ret;
2108}
2109
Steven Luong4c4223e2020-07-15 08:44:54 -07002110static void vl_api_sw_bond_interface_details_t_handler
2111 (vl_api_sw_bond_interface_details_t * mp)
Steven9cd2d7a2017-12-20 12:43:01 -08002112{
2113 vat_main_t *vam = &vat_main;
2114
2115 print (vam->ofp,
2116 "%-16s %-12d %-12U %-13U %-14u %-14u",
2117 mp->interface_name, ntohl (mp->sw_if_index),
Jakub Grajciar3d1ef872019-08-26 12:55:15 +02002118 format_bond_mode, ntohl (mp->mode), format_bond_load_balance,
Steven Luong4c4223e2020-07-15 08:44:54 -07002119 ntohl (mp->lb), ntohl (mp->active_members), ntohl (mp->members));
Steven9cd2d7a2017-12-20 12:43:01 -08002120}
2121
Steven Luong4c4223e2020-07-15 08:44:54 -07002122static void vl_api_sw_bond_interface_details_t_handler_json
2123 (vl_api_sw_bond_interface_details_t * mp)
Steven9cd2d7a2017-12-20 12:43:01 -08002124{
2125 vat_main_t *vam = &vat_main;
2126 vat_json_node_t *node = NULL;
2127
2128 if (VAT_JSON_ARRAY != vam->json_tree.type)
2129 {
2130 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2131 vat_json_init_array (&vam->json_tree);
2132 }
2133 node = vat_json_array_add (&vam->json_tree);
2134
2135 vat_json_init_object (node);
2136 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2137 vat_json_object_add_string_copy (node, "interface_name",
2138 mp->interface_name);
Jakub Grajciar3d1ef872019-08-26 12:55:15 +02002139 vat_json_object_add_uint (node, "mode", ntohl (mp->mode));
2140 vat_json_object_add_uint (node, "load_balance", ntohl (mp->lb));
Steven Luong4c4223e2020-07-15 08:44:54 -07002141 vat_json_object_add_uint (node, "active_members",
2142 ntohl (mp->active_members));
2143 vat_json_object_add_uint (node, "members", ntohl (mp->members));
Steven9cd2d7a2017-12-20 12:43:01 -08002144}
2145
2146static int
Steven Luong4c4223e2020-07-15 08:44:54 -07002147api_sw_bond_interface_dump (vat_main_t * vam)
Steven9cd2d7a2017-12-20 12:43:01 -08002148{
Steven Luong4c4223e2020-07-15 08:44:54 -07002149 unformat_input_t *i = vam->input;
2150 vl_api_sw_bond_interface_dump_t *mp;
Steven9cd2d7a2017-12-20 12:43:01 -08002151 vl_api_control_ping_t *mp_ping;
2152 int ret;
Steven Luong4c4223e2020-07-15 08:44:54 -07002153 u32 sw_if_index = ~0;
2154
2155 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2156 {
2157 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2158 ;
2159 else if (unformat (i, "sw_if_index %d", &sw_if_index))
2160 ;
2161 else
2162 break;
2163 }
Steven9cd2d7a2017-12-20 12:43:01 -08002164
2165 print (vam->ofp,
2166 "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2167 "interface name", "sw_if_index", "mode", "load balance",
Steven Luong4c4223e2020-07-15 08:44:54 -07002168 "active members", "members");
Steven9cd2d7a2017-12-20 12:43:01 -08002169
2170 /* Get list of bond interfaces */
Steven Luong4c4223e2020-07-15 08:44:54 -07002171 M (SW_BOND_INTERFACE_DUMP, mp);
2172 mp->sw_if_index = ntohl (sw_if_index);
Steven9cd2d7a2017-12-20 12:43:01 -08002173 S (mp);
2174
2175 /* Use a control ping for synchronization */
2176 MPING (CONTROL_PING, mp_ping);
2177 S (mp_ping);
2178
2179 W (ret);
2180 return ret;
2181}
2182
Steven Luong4c4223e2020-07-15 08:44:54 -07002183static void vl_api_sw_member_interface_details_t_handler
2184 (vl_api_sw_member_interface_details_t * mp)
Steven9cd2d7a2017-12-20 12:43:01 -08002185{
2186 vat_main_t *vam = &vat_main;
2187
2188 print (vam->ofp,
Steven Luonga1876b82019-08-20 16:58:00 -07002189 "%-25s %-12d %-7d %-12d %-10d %-10d", mp->interface_name,
2190 ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout,
2191 ntohl (mp->weight), mp->is_local_numa);
Steven9cd2d7a2017-12-20 12:43:01 -08002192}
2193
Steven Luong4c4223e2020-07-15 08:44:54 -07002194static void vl_api_sw_member_interface_details_t_handler_json
2195 (vl_api_sw_member_interface_details_t * mp)
Steven9cd2d7a2017-12-20 12:43:01 -08002196{
2197 vat_main_t *vam = &vat_main;
2198 vat_json_node_t *node = NULL;
2199
2200 if (VAT_JSON_ARRAY != vam->json_tree.type)
2201 {
2202 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2203 vat_json_init_array (&vam->json_tree);
2204 }
2205 node = vat_json_array_add (&vam->json_tree);
2206
2207 vat_json_init_object (node);
2208 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2209 vat_json_object_add_string_copy (node, "interface_name",
2210 mp->interface_name);
2211 vat_json_object_add_uint (node, "passive", mp->is_passive);
2212 vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
Steven Luonga1876b82019-08-20 16:58:00 -07002213 vat_json_object_add_uint (node, "weight", ntohl (mp->weight));
2214 vat_json_object_add_uint (node, "is_local_numa", mp->is_local_numa);
Steven9cd2d7a2017-12-20 12:43:01 -08002215}
2216
2217static int
Steven Luong4c4223e2020-07-15 08:44:54 -07002218api_sw_member_interface_dump (vat_main_t * vam)
Steven9cd2d7a2017-12-20 12:43:01 -08002219{
2220 unformat_input_t *i = vam->input;
Steven Luong4c4223e2020-07-15 08:44:54 -07002221 vl_api_sw_member_interface_dump_t *mp;
Steven9cd2d7a2017-12-20 12:43:01 -08002222 vl_api_control_ping_t *mp_ping;
2223 u32 sw_if_index = ~0;
2224 u8 sw_if_index_set = 0;
2225 int ret;
2226
2227 /* Parse args required to build the message */
2228 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2229 {
2230 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2231 sw_if_index_set = 1;
2232 else if (unformat (i, "sw_if_index %d", &sw_if_index))
2233 sw_if_index_set = 1;
2234 else
2235 break;
2236 }
2237
2238 if (sw_if_index_set == 0)
2239 {
2240 errmsg ("missing vpp interface name. ");
2241 return -99;
2242 }
2243
2244 print (vam->ofp,
Steven Luonga1876b82019-08-20 16:58:00 -07002245 "\n%-25s %-12s %-7s %-12s %-10s %-10s",
Steven Luong4c4223e2020-07-15 08:44:54 -07002246 "member interface name", "sw_if_index", "passive", "long_timeout",
Steven Luonga1876b82019-08-20 16:58:00 -07002247 "weight", "local numa");
Steven9cd2d7a2017-12-20 12:43:01 -08002248
2249 /* Get list of bond interfaces */
Steven Luong4c4223e2020-07-15 08:44:54 -07002250 M (SW_MEMBER_INTERFACE_DUMP, mp);
Steven9cd2d7a2017-12-20 12:43:01 -08002251 mp->sw_if_index = ntohl (sw_if_index);
2252 S (mp);
2253
2254 /* Use a control ping for synchronization */
2255 MPING (CONTROL_PING, mp_ping);
2256 S (mp_ping);
2257
2258 W (ret);
2259 return ret;
2260}
2261
Damjan Marion7cd468a2016-12-19 23:05:39 +01002262static void vl_api_mpls_tunnel_add_del_reply_t_handler
2263 (vl_api_mpls_tunnel_add_del_reply_t * mp)
2264{
2265 vat_main_t *vam = &vat_main;
2266 i32 retval = ntohl (mp->retval);
2267 if (vam->async_mode)
2268 {
2269 vam->async_errors += (retval < 0);
2270 }
2271 else
2272 {
2273 vam->retval = retval;
John Lo06fda9c2018-10-03 16:32:44 -04002274 vam->sw_if_index = ntohl (mp->sw_if_index);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002275 vam->result_ready = 1;
2276 }
John Lo06fda9c2018-10-03 16:32:44 -04002277 vam->regenerate_interface_table = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002278}
2279
2280static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2281 (vl_api_mpls_tunnel_add_del_reply_t * mp)
2282{
2283 vat_main_t *vam = &vat_main;
2284 vat_json_node_t node;
2285
2286 vat_json_init_object (&node);
2287 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2288 vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2289 ntohl (mp->sw_if_index));
2290
2291 vat_json_print (vam->ofp, &node);
2292 vat_json_free (&node);
2293
2294 vam->retval = ntohl (mp->retval);
2295 vam->result_ready = 1;
2296}
2297
Damjan Marion7cd468a2016-12-19 23:05:39 +01002298static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2299 (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2300{
2301 vat_main_t *vam = &vat_main;
2302 i32 retval = ntohl (mp->retval);
2303 if (vam->async_mode)
2304 {
2305 vam->async_errors += (retval < 0);
2306 }
2307 else
2308 {
2309 vam->retval = retval;
2310 vam->sw_if_index = ntohl (mp->sw_if_index);
2311 vam->result_ready = 1;
2312 }
Dave Barachf72212e2018-01-11 10:25:07 -05002313 vam->regenerate_interface_table = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002314}
2315
2316static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2317 (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2318{
2319 vat_main_t *vam = &vat_main;
2320 vat_json_node_t node;
2321
2322 vat_json_init_object (&node);
2323 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2324 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2325
2326 vat_json_print (vam->ofp, &node);
2327 vat_json_free (&node);
2328
2329 vam->retval = ntohl (mp->retval);
2330 vam->result_ready = 1;
2331}
2332
eyal bariaf86a482018-04-17 11:20:27 +03002333static void vl_api_vxlan_offload_rx_reply_t_handler
2334 (vl_api_vxlan_offload_rx_reply_t * mp)
2335{
2336 vat_main_t *vam = &vat_main;
2337 i32 retval = ntohl (mp->retval);
2338 if (vam->async_mode)
2339 {
2340 vam->async_errors += (retval < 0);
2341 }
2342 else
2343 {
2344 vam->retval = retval;
2345 vam->result_ready = 1;
2346 }
2347}
2348
2349static void vl_api_vxlan_offload_rx_reply_t_handler_json
2350 (vl_api_vxlan_offload_rx_reply_t * mp)
2351{
2352 vat_main_t *vam = &vat_main;
2353 vat_json_node_t node;
2354
2355 vat_json_init_object (&node);
2356 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2357
2358 vat_json_print (vam->ofp, &node);
2359 vat_json_free (&node);
2360
2361 vam->retval = ntohl (mp->retval);
2362 vam->result_ready = 1;
2363}
2364
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +08002365static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2366 (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2367{
2368 vat_main_t *vam = &vat_main;
2369 i32 retval = ntohl (mp->retval);
2370 if (vam->async_mode)
2371 {
2372 vam->async_errors += (retval < 0);
2373 }
2374 else
2375 {
2376 vam->retval = retval;
2377 vam->sw_if_index = ntohl (mp->sw_if_index);
2378 vam->result_ready = 1;
2379 }
Dave Barachf72212e2018-01-11 10:25:07 -05002380 vam->regenerate_interface_table = 1;
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +08002381}
2382
2383static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2384 (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2385{
2386 vat_main_t *vam = &vat_main;
2387 vat_json_node_t node;
2388
2389 vat_json_init_object (&node);
2390 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2391 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2392
2393 vat_json_print (vam->ofp, &node);
2394 vat_json_free (&node);
2395
2396 vam->retval = ntohl (mp->retval);
2397 vam->result_ready = 1;
2398}
2399
Neale Ranns5a8844b2019-04-16 07:15:35 +00002400static void vl_api_gre_tunnel_add_del_reply_t_handler
2401 (vl_api_gre_tunnel_add_del_reply_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002402{
2403 vat_main_t *vam = &vat_main;
2404 i32 retval = ntohl (mp->retval);
2405 if (vam->async_mode)
2406 {
2407 vam->async_errors += (retval < 0);
2408 }
2409 else
2410 {
2411 vam->retval = retval;
2412 vam->sw_if_index = ntohl (mp->sw_if_index);
2413 vam->result_ready = 1;
2414 }
2415}
2416
Neale Ranns5a8844b2019-04-16 07:15:35 +00002417static void vl_api_gre_tunnel_add_del_reply_t_handler_json
2418 (vl_api_gre_tunnel_add_del_reply_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002419{
2420 vat_main_t *vam = &vat_main;
2421 vat_json_node_t node;
2422
2423 vat_json_init_object (&node);
2424 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2425 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2426
2427 vat_json_print (vam->ofp, &node);
2428 vat_json_free (&node);
2429
2430 vam->retval = ntohl (mp->retval);
2431 vam->result_ready = 1;
2432}
2433
2434static void vl_api_create_vhost_user_if_reply_t_handler
2435 (vl_api_create_vhost_user_if_reply_t * mp)
2436{
2437 vat_main_t *vam = &vat_main;
2438 i32 retval = ntohl (mp->retval);
2439 if (vam->async_mode)
2440 {
2441 vam->async_errors += (retval < 0);
2442 }
2443 else
2444 {
2445 vam->retval = retval;
2446 vam->sw_if_index = ntohl (mp->sw_if_index);
2447 vam->result_ready = 1;
2448 }
Dave Barachf72212e2018-01-11 10:25:07 -05002449 vam->regenerate_interface_table = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002450}
2451
2452static void vl_api_create_vhost_user_if_reply_t_handler_json
2453 (vl_api_create_vhost_user_if_reply_t * mp)
2454{
2455 vat_main_t *vam = &vat_main;
2456 vat_json_node_t node;
2457
2458 vat_json_init_object (&node);
2459 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2460 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2461
2462 vat_json_print (vam->ofp, &node);
2463 vat_json_free (&node);
2464
2465 vam->retval = ntohl (mp->retval);
2466 vam->result_ready = 1;
2467}
2468
2469static void vl_api_ip_address_details_t_handler
2470 (vl_api_ip_address_details_t * mp)
2471{
2472 vat_main_t *vam = &vat_main;
2473 static ip_address_details_t empty_ip_address_details = { {0} };
2474 ip_address_details_t *address = NULL;
2475 ip_details_t *current_ip_details = NULL;
2476 ip_details_t *details = NULL;
2477
2478 details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2479
2480 if (!details || vam->current_sw_if_index >= vec_len (details)
2481 || !details[vam->current_sw_if_index].present)
2482 {
2483 errmsg ("ip address details arrived but not stored");
2484 errmsg ("ip_dump should be called first");
2485 return;
2486 }
2487
2488 current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2489
2490#define addresses (current_ip_details->addr)
2491
2492 vec_validate_init_empty (addresses, vec_len (addresses),
2493 empty_ip_address_details);
2494
2495 address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2496
Neale Ranns097fa662018-05-01 05:17:55 -07002497 clib_memcpy (&address->ip, &mp->prefix.address.un, sizeof (address->ip));
Paul Vinciguerraab055082019-06-06 14:07:55 -04002498 address->prefix_length = mp->prefix.len;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002499#undef addresses
2500}
2501
2502static void vl_api_ip_address_details_t_handler_json
2503 (vl_api_ip_address_details_t * mp)
2504{
2505 vat_main_t *vam = &vat_main;
2506 vat_json_node_t *node = NULL;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002507
2508 if (VAT_JSON_ARRAY != vam->json_tree.type)
2509 {
2510 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2511 vat_json_init_array (&vam->json_tree);
2512 }
2513 node = vat_json_array_add (&vam->json_tree);
2514
2515 vat_json_init_object (node);
Neale Ranns097fa662018-05-01 05:17:55 -07002516 vat_json_object_add_prefix (node, &mp->prefix);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002517}
2518
2519static void
2520vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2521{
2522 vat_main_t *vam = &vat_main;
2523 static ip_details_t empty_ip_details = { 0 };
2524 ip_details_t *ip = NULL;
2525 u32 sw_if_index = ~0;
2526
2527 sw_if_index = ntohl (mp->sw_if_index);
2528
2529 vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2530 sw_if_index, empty_ip_details);
2531
2532 ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2533 sw_if_index);
2534
2535 ip->present = 1;
2536}
2537
2538static void
2539vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2540{
2541 vat_main_t *vam = &vat_main;
2542
2543 if (VAT_JSON_ARRAY != vam->json_tree.type)
2544 {
2545 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2546 vat_json_init_array (&vam->json_tree);
2547 }
2548 vat_json_array_add_uint (&vam->json_tree,
2549 clib_net_to_host_u32 (mp->sw_if_index));
2550}
2551
Damjan Marion7cd468a2016-12-19 23:05:39 +01002552static void vl_api_get_first_msg_id_reply_t_handler
2553 (vl_api_get_first_msg_id_reply_t * mp)
2554{
2555 vat_main_t *vam = &vat_main;
2556 i32 retval = ntohl (mp->retval);
2557
2558 if (vam->async_mode)
2559 {
2560 vam->async_errors += (retval < 0);
2561 }
2562 else
2563 {
2564 vam->retval = retval;
2565 vam->result_ready = 1;
2566 }
2567 if (retval >= 0)
2568 {
2569 errmsg ("first message id %d", ntohs (mp->first_msg_id));
2570 }
2571}
2572
2573static void vl_api_get_first_msg_id_reply_t_handler_json
2574 (vl_api_get_first_msg_id_reply_t * mp)
2575{
2576 vat_main_t *vam = &vat_main;
2577 vat_json_node_t node;
2578
2579 vat_json_init_object (&node);
2580 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2581 vat_json_object_add_uint (&node, "first_msg_id",
2582 (uint) ntohs (mp->first_msg_id));
2583
2584 vat_json_print (vam->ofp, &node);
2585 vat_json_free (&node);
2586
2587 vam->retval = ntohl (mp->retval);
2588 vam->result_ready = 1;
2589}
2590
2591static void vl_api_get_node_graph_reply_t_handler
2592 (vl_api_get_node_graph_reply_t * mp)
2593{
2594 vat_main_t *vam = &vat_main;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002595 i32 retval = ntohl (mp->retval);
2596 u8 *pvt_copy, *reply;
2597 void *oldheap;
2598 vlib_node_t *node;
2599 int i;
2600
2601 if (vam->async_mode)
2602 {
2603 vam->async_errors += (retval < 0);
2604 }
2605 else
2606 {
2607 vam->retval = retval;
2608 vam->result_ready = 1;
2609 }
2610
2611 /* "Should never happen..." */
2612 if (retval != 0)
2613 return;
2614
Damjan Marion7bee80c2017-04-26 15:32:12 +02002615 reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002616 pvt_copy = vec_dup (reply);
2617
2618 /* Toss the shared-memory original... */
Nathan Skrzypczak0aa40132019-11-25 16:29:38 +01002619 oldheap = vl_msg_push_heap ();
Damjan Marion7cd468a2016-12-19 23:05:39 +01002620
2621 vec_free (reply);
2622
Nathan Skrzypczak0aa40132019-11-25 16:29:38 +01002623 vl_msg_pop_heap (oldheap);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002624
2625 if (vam->graph_nodes)
2626 {
2627 hash_free (vam->graph_node_index_by_name);
2628
Dave Barach1ddbc012018-06-13 09:26:05 -04002629 for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002630 {
Dave Barach1ddbc012018-06-13 09:26:05 -04002631 node = vam->graph_nodes[0][i];
Damjan Marion7cd468a2016-12-19 23:05:39 +01002632 vec_free (node->name);
2633 vec_free (node->next_nodes);
2634 vec_free (node);
2635 }
Dave Barach1ddbc012018-06-13 09:26:05 -04002636 vec_free (vam->graph_nodes[0]);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002637 vec_free (vam->graph_nodes);
2638 }
2639
2640 vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2641 vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2642 vec_free (pvt_copy);
2643
Dave Barach1ddbc012018-06-13 09:26:05 -04002644 for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002645 {
Dave Barach1ddbc012018-06-13 09:26:05 -04002646 node = vam->graph_nodes[0][i];
Damjan Marion7cd468a2016-12-19 23:05:39 +01002647 hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2648 }
2649}
2650
2651static void vl_api_get_node_graph_reply_t_handler_json
2652 (vl_api_get_node_graph_reply_t * mp)
2653{
2654 vat_main_t *vam = &vat_main;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002655 void *oldheap;
2656 vat_json_node_t node;
2657 u8 *reply;
2658
2659 /* $$$$ make this real? */
2660 vat_json_init_object (&node);
2661 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2662 vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2663
Damjan Marion7bee80c2017-04-26 15:32:12 +02002664 reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002665
2666 /* Toss the shared-memory original... */
Nathan Skrzypczak0aa40132019-11-25 16:29:38 +01002667 oldheap = vl_msg_push_heap ();
Damjan Marion7cd468a2016-12-19 23:05:39 +01002668
2669 vec_free (reply);
2670
Nathan Skrzypczak0aa40132019-11-25 16:29:38 +01002671 vl_msg_pop_heap (oldheap);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002672
2673 vat_json_print (vam->ofp, &node);
2674 vat_json_free (&node);
2675
2676 vam->retval = ntohl (mp->retval);
2677 vam->result_ready = 1;
2678}
2679
Damjan Marion7cd468a2016-12-19 23:05:39 +01002680static u8 *
2681format_policer_type (u8 * s, va_list * va)
2682{
2683 u32 i = va_arg (*va, u32);
2684
2685 if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2686 s = format (s, "1r2c");
2687 else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2688 s = format (s, "1r3c");
2689 else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2690 s = format (s, "2r3c-2698");
2691 else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2692 s = format (s, "2r3c-4115");
2693 else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2694 s = format (s, "2r3c-mef5cf1");
2695 else
2696 s = format (s, "ILLEGAL");
2697 return s;
2698}
2699
2700static u8 *
2701format_policer_rate_type (u8 * s, va_list * va)
2702{
2703 u32 i = va_arg (*va, u32);
2704
2705 if (i == SSE2_QOS_RATE_KBPS)
2706 s = format (s, "kbps");
2707 else if (i == SSE2_QOS_RATE_PPS)
2708 s = format (s, "pps");
2709 else
2710 s = format (s, "ILLEGAL");
2711 return s;
2712}
2713
2714static u8 *
2715format_policer_round_type (u8 * s, va_list * va)
2716{
2717 u32 i = va_arg (*va, u32);
2718
2719 if (i == SSE2_QOS_ROUND_TO_CLOSEST)
2720 s = format (s, "closest");
2721 else if (i == SSE2_QOS_ROUND_TO_UP)
2722 s = format (s, "up");
2723 else if (i == SSE2_QOS_ROUND_TO_DOWN)
2724 s = format (s, "down");
2725 else
2726 s = format (s, "ILLEGAL");
2727 return s;
2728}
2729
2730static u8 *
2731format_policer_action_type (u8 * s, va_list * va)
2732{
2733 u32 i = va_arg (*va, u32);
2734
2735 if (i == SSE2_QOS_ACTION_DROP)
2736 s = format (s, "drop");
2737 else if (i == SSE2_QOS_ACTION_TRANSMIT)
2738 s = format (s, "transmit");
2739 else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2740 s = format (s, "mark-and-transmit");
2741 else
2742 s = format (s, "ILLEGAL");
2743 return s;
2744}
2745
2746static u8 *
2747format_dscp (u8 * s, va_list * va)
2748{
2749 u32 i = va_arg (*va, u32);
2750 char *t = 0;
2751
2752 switch (i)
2753 {
2754#define _(v,f,str) case VNET_DSCP_##f: t = str; break;
2755 foreach_vnet_dscp
2756#undef _
2757 default:
2758 return format (s, "ILLEGAL");
2759 }
2760 s = format (s, "%s", t);
2761 return s;
2762}
2763
2764static void
2765vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
2766{
2767 vat_main_t *vam = &vat_main;
2768 u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
2769
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002770 if (mp->conform_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
2771 conform_dscp_str = format (0, "%U", format_dscp, mp->conform_action.dscp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002772 else
2773 conform_dscp_str = format (0, "");
2774
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002775 if (mp->exceed_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
2776 exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_action.dscp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002777 else
2778 exceed_dscp_str = format (0, "");
2779
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002780 if (mp->violate_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
2781 violate_dscp_str = format (0, "%U", format_dscp, mp->violate_action.dscp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002782 else
2783 violate_dscp_str = format (0, "");
2784
2785 print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
2786 "rate type %U, round type %U, %s rate, %s color-aware, "
2787 "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
2788 "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
2789 "conform action %U%s, exceed action %U%s, violate action %U%s",
2790 mp->name,
2791 format_policer_type, mp->type,
2792 ntohl (mp->cir),
2793 ntohl (mp->eir),
2794 clib_net_to_host_u64 (mp->cb),
2795 clib_net_to_host_u64 (mp->eb),
2796 format_policer_rate_type, mp->rate_type,
2797 format_policer_round_type, mp->round_type,
2798 mp->single_rate ? "single" : "dual",
2799 mp->color_aware ? "is" : "not",
2800 ntohl (mp->cir_tokens_per_period),
2801 ntohl (mp->pir_tokens_per_period),
2802 ntohl (mp->scale),
2803 ntohl (mp->current_limit),
2804 ntohl (mp->current_bucket),
2805 ntohl (mp->extended_limit),
2806 ntohl (mp->extended_bucket),
2807 clib_net_to_host_u64 (mp->last_update_time),
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002808 format_policer_action_type, mp->conform_action.type,
Damjan Marion7cd468a2016-12-19 23:05:39 +01002809 conform_dscp_str,
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002810 format_policer_action_type, mp->exceed_action.type,
Damjan Marion7cd468a2016-12-19 23:05:39 +01002811 exceed_dscp_str,
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002812 format_policer_action_type, mp->violate_action.type,
Damjan Marion7cd468a2016-12-19 23:05:39 +01002813 violate_dscp_str);
2814
2815 vec_free (conform_dscp_str);
2816 vec_free (exceed_dscp_str);
2817 vec_free (violate_dscp_str);
2818}
2819
2820static void vl_api_policer_details_t_handler_json
2821 (vl_api_policer_details_t * mp)
2822{
2823 vat_main_t *vam = &vat_main;
2824 vat_json_node_t *node;
2825 u8 *rate_type_str, *round_type_str, *type_str;
2826 u8 *conform_action_str, *exceed_action_str, *violate_action_str;
2827
2828 rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
2829 round_type_str =
2830 format (0, "%U", format_policer_round_type, mp->round_type);
2831 type_str = format (0, "%U", format_policer_type, mp->type);
2832 conform_action_str = format (0, "%U", format_policer_action_type,
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002833 mp->conform_action.type);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002834 exceed_action_str = format (0, "%U", format_policer_action_type,
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002835 mp->exceed_action.type);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002836 violate_action_str = format (0, "%U", format_policer_action_type,
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002837 mp->violate_action.type);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002838
2839 if (VAT_JSON_ARRAY != vam->json_tree.type)
2840 {
2841 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2842 vat_json_init_array (&vam->json_tree);
2843 }
2844 node = vat_json_array_add (&vam->json_tree);
2845
2846 vat_json_init_object (node);
2847 vat_json_object_add_string_copy (node, "name", mp->name);
2848 vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
2849 vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
Marek Gradzki59ed4902017-03-21 11:51:54 +01002850 vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
2851 vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
Damjan Marion7cd468a2016-12-19 23:05:39 +01002852 vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
2853 vat_json_object_add_string_copy (node, "round_type", round_type_str);
2854 vat_json_object_add_string_copy (node, "type", type_str);
2855 vat_json_object_add_uint (node, "single_rate", mp->single_rate);
2856 vat_json_object_add_uint (node, "color_aware", mp->color_aware);
2857 vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
2858 vat_json_object_add_uint (node, "cir_tokens_per_period",
2859 ntohl (mp->cir_tokens_per_period));
2860 vat_json_object_add_uint (node, "eir_tokens_per_period",
2861 ntohl (mp->pir_tokens_per_period));
2862 vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
2863 vat_json_object_add_uint (node, "current_bucket",
2864 ntohl (mp->current_bucket));
2865 vat_json_object_add_uint (node, "extended_limit",
2866 ntohl (mp->extended_limit));
2867 vat_json_object_add_uint (node, "extended_bucket",
2868 ntohl (mp->extended_bucket));
2869 vat_json_object_add_uint (node, "last_update_time",
2870 ntohl (mp->last_update_time));
2871 vat_json_object_add_string_copy (node, "conform_action",
2872 conform_action_str);
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002873 if (mp->conform_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002874 {
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002875 u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_action.dscp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002876 vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
2877 vec_free (dscp_str);
2878 }
2879 vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002880 if (mp->exceed_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002881 {
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002882 u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_action.dscp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002883 vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
2884 vec_free (dscp_str);
2885 }
2886 vat_json_object_add_string_copy (node, "violate_action",
2887 violate_action_str);
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002888 if (mp->violate_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002889 {
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002890 u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_action.dscp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002891 vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
2892 vec_free (dscp_str);
2893 }
2894
2895 vec_free (rate_type_str);
2896 vec_free (round_type_str);
2897 vec_free (type_str);
2898 vec_free (conform_action_str);
2899 vec_free (exceed_action_str);
2900 vec_free (violate_action_str);
2901}
2902
2903static void
2904vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
2905 mp)
2906{
2907 vat_main_t *vam = &vat_main;
2908 int i, count = ntohl (mp->count);
2909
2910 if (count > 0)
2911 print (vam->ofp, "classify table ids (%d) : ", count);
2912 for (i = 0; i < count; i++)
2913 {
2914 print (vam->ofp, "%d", ntohl (mp->ids[i]));
2915 print (vam->ofp, (i < count - 1) ? "," : "");
2916 }
2917 vam->retval = ntohl (mp->retval);
2918 vam->result_ready = 1;
2919}
2920
2921static void
2922 vl_api_classify_table_ids_reply_t_handler_json
2923 (vl_api_classify_table_ids_reply_t * mp)
2924{
2925 vat_main_t *vam = &vat_main;
2926 int i, count = ntohl (mp->count);
2927
2928 if (count > 0)
2929 {
2930 vat_json_node_t node;
2931
2932 vat_json_init_object (&node);
2933 for (i = 0; i < count; i++)
2934 {
2935 vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
2936 }
2937 vat_json_print (vam->ofp, &node);
2938 vat_json_free (&node);
2939 }
2940 vam->retval = ntohl (mp->retval);
2941 vam->result_ready = 1;
2942}
2943
2944static void
2945 vl_api_classify_table_by_interface_reply_t_handler
2946 (vl_api_classify_table_by_interface_reply_t * mp)
2947{
2948 vat_main_t *vam = &vat_main;
2949 u32 table_id;
2950
2951 table_id = ntohl (mp->l2_table_id);
2952 if (table_id != ~0)
2953 print (vam->ofp, "l2 table id : %d", table_id);
2954 else
2955 print (vam->ofp, "l2 table id : No input ACL tables configured");
2956 table_id = ntohl (mp->ip4_table_id);
2957 if (table_id != ~0)
2958 print (vam->ofp, "ip4 table id : %d", table_id);
2959 else
2960 print (vam->ofp, "ip4 table id : No input ACL tables configured");
2961 table_id = ntohl (mp->ip6_table_id);
2962 if (table_id != ~0)
2963 print (vam->ofp, "ip6 table id : %d", table_id);
2964 else
2965 print (vam->ofp, "ip6 table id : No input ACL tables configured");
2966 vam->retval = ntohl (mp->retval);
2967 vam->result_ready = 1;
2968}
2969
2970static void
2971 vl_api_classify_table_by_interface_reply_t_handler_json
2972 (vl_api_classify_table_by_interface_reply_t * mp)
2973{
2974 vat_main_t *vam = &vat_main;
2975 vat_json_node_t node;
2976
2977 vat_json_init_object (&node);
2978
2979 vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
2980 vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
2981 vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
2982
2983 vat_json_print (vam->ofp, &node);
2984 vat_json_free (&node);
2985
2986 vam->retval = ntohl (mp->retval);
2987 vam->result_ready = 1;
2988}
2989
2990static void vl_api_policer_add_del_reply_t_handler
2991 (vl_api_policer_add_del_reply_t * mp)
2992{
2993 vat_main_t *vam = &vat_main;
2994 i32 retval = ntohl (mp->retval);
2995 if (vam->async_mode)
2996 {
2997 vam->async_errors += (retval < 0);
2998 }
2999 else
3000 {
3001 vam->retval = retval;
3002 vam->result_ready = 1;
3003 if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3004 /*
3005 * Note: this is just barely thread-safe, depends on
3006 * the main thread spinning waiting for an answer...
3007 */
3008 errmsg ("policer index %d", ntohl (mp->policer_index));
3009 }
3010}
3011
3012static void vl_api_policer_add_del_reply_t_handler_json
3013 (vl_api_policer_add_del_reply_t * mp)
3014{
3015 vat_main_t *vam = &vat_main;
3016 vat_json_node_t node;
3017
3018 vat_json_init_object (&node);
3019 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3020 vat_json_object_add_uint (&node, "policer_index",
3021 ntohl (mp->policer_index));
3022
3023 vat_json_print (vam->ofp, &node);
3024 vat_json_free (&node);
3025
3026 vam->retval = ntohl (mp->retval);
3027 vam->result_ready = 1;
3028}
3029
3030/* Format hex dump. */
3031u8 *
3032format_hex_bytes (u8 * s, va_list * va)
3033{
3034 u8 *bytes = va_arg (*va, u8 *);
3035 int n_bytes = va_arg (*va, int);
3036 uword i;
3037
3038 /* Print short or long form depending on byte count. */
3039 uword short_form = n_bytes <= 32;
Christophe Fontained3c008d2017-10-02 18:10:54 +02003040 u32 indent = format_get_indent (s);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003041
3042 if (n_bytes == 0)
3043 return s;
3044
3045 for (i = 0; i < n_bytes; i++)
3046 {
3047 if (!short_form && (i % 32) == 0)
3048 s = format (s, "%08x: ", i);
3049 s = format (s, "%02x", bytes[i]);
3050 if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3051 s = format (s, "\n%U", format_white_space, indent);
3052 }
3053
3054 return s;
3055}
3056
3057static void
3058vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3059 * mp)
3060{
3061 vat_main_t *vam = &vat_main;
3062 i32 retval = ntohl (mp->retval);
3063 if (retval == 0)
3064 {
3065 print (vam->ofp, "classify table info :");
3066 print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
3067 ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3068 ntohl (mp->miss_next_index));
3069 print (vam->ofp, "nbuckets: %d skip: %d match: %d",
3070 ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3071 ntohl (mp->match_n_vectors));
3072 print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
3073 ntohl (mp->mask_length));
3074 }
3075 vam->retval = retval;
3076 vam->result_ready = 1;
3077}
3078
3079static void
3080 vl_api_classify_table_info_reply_t_handler_json
3081 (vl_api_classify_table_info_reply_t * mp)
3082{
3083 vat_main_t *vam = &vat_main;
3084 vat_json_node_t node;
3085
3086 i32 retval = ntohl (mp->retval);
3087 if (retval == 0)
3088 {
3089 vat_json_init_object (&node);
3090
3091 vat_json_object_add_int (&node, "sessions",
3092 ntohl (mp->active_sessions));
3093 vat_json_object_add_int (&node, "nexttbl",
3094 ntohl (mp->next_table_index));
3095 vat_json_object_add_int (&node, "nextnode",
3096 ntohl (mp->miss_next_index));
3097 vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3098 vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3099 vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3100 u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3101 ntohl (mp->mask_length), 0);
3102 vat_json_object_add_string_copy (&node, "mask", s);
3103
3104 vat_json_print (vam->ofp, &node);
3105 vat_json_free (&node);
3106 }
3107 vam->retval = ntohl (mp->retval);
3108 vam->result_ready = 1;
3109}
3110
3111static void
3112vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3113 mp)
3114{
3115 vat_main_t *vam = &vat_main;
3116
3117 print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3118 ntohl (mp->hit_next_index), ntohl (mp->advance),
3119 ntohl (mp->opaque_index));
3120 print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
3121 ntohl (mp->match_length));
3122}
3123
3124static void
3125 vl_api_classify_session_details_t_handler_json
3126 (vl_api_classify_session_details_t * mp)
3127{
3128 vat_main_t *vam = &vat_main;
3129 vat_json_node_t *node = NULL;
3130
3131 if (VAT_JSON_ARRAY != vam->json_tree.type)
3132 {
3133 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3134 vat_json_init_array (&vam->json_tree);
3135 }
3136 node = vat_json_array_add (&vam->json_tree);
3137
3138 vat_json_init_object (node);
3139 vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3140 vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3141 vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3142 u8 *s =
3143 format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3144 0);
3145 vat_json_object_add_string_copy (node, "match", s);
3146}
3147
3148static void vl_api_pg_create_interface_reply_t_handler
3149 (vl_api_pg_create_interface_reply_t * mp)
3150{
3151 vat_main_t *vam = &vat_main;
3152
3153 vam->retval = ntohl (mp->retval);
3154 vam->result_ready = 1;
3155}
3156
3157static void vl_api_pg_create_interface_reply_t_handler_json
3158 (vl_api_pg_create_interface_reply_t * mp)
3159{
3160 vat_main_t *vam = &vat_main;
3161 vat_json_node_t node;
3162
3163 i32 retval = ntohl (mp->retval);
3164 if (retval == 0)
3165 {
3166 vat_json_init_object (&node);
3167
3168 vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3169
3170 vat_json_print (vam->ofp, &node);
3171 vat_json_free (&node);
3172 }
3173 vam->retval = ntohl (mp->retval);
3174 vam->result_ready = 1;
3175}
3176
3177static void vl_api_policer_classify_details_t_handler
3178 (vl_api_policer_classify_details_t * mp)
3179{
3180 vat_main_t *vam = &vat_main;
3181
3182 print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3183 ntohl (mp->table_index));
3184}
3185
3186static void vl_api_policer_classify_details_t_handler_json
3187 (vl_api_policer_classify_details_t * mp)
3188{
3189 vat_main_t *vam = &vat_main;
3190 vat_json_node_t *node;
3191
3192 if (VAT_JSON_ARRAY != vam->json_tree.type)
3193 {
3194 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3195 vat_json_init_array (&vam->json_tree);
3196 }
3197 node = vat_json_array_add (&vam->json_tree);
3198
3199 vat_json_init_object (node);
3200 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3201 vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3202}
3203
Damjan Marion7cd468a2016-12-19 23:05:39 +01003204static void vl_api_flow_classify_details_t_handler
3205 (vl_api_flow_classify_details_t * mp)
3206{
3207 vat_main_t *vam = &vat_main;
3208
3209 print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3210 ntohl (mp->table_index));
3211}
3212
3213static void vl_api_flow_classify_details_t_handler_json
3214 (vl_api_flow_classify_details_t * mp)
3215{
3216 vat_main_t *vam = &vat_main;
3217 vat_json_node_t *node;
3218
3219 if (VAT_JSON_ARRAY != vam->json_tree.type)
3220 {
3221 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3222 vat_json_init_array (&vam->json_tree);
3223 }
3224 node = vat_json_array_add (&vam->json_tree);
3225
3226 vat_json_init_object (node);
3227 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3228 vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3229}
3230
Damjan Marion7cd468a2016-12-19 23:05:39 +01003231/*
3232 * Generate boilerplate reply handlers, which
3233 * dig the return value out of the xxx_reply_t API message,
3234 * stick it into vam->retval, and set vam->result_ready
3235 *
3236 * Could also do this by pointing N message decode slots at
3237 * a single function, but that could break in subtle ways.
3238 */
3239
3240#define foreach_standard_reply_retval_handler \
3241_(sw_interface_set_flags_reply) \
3242_(sw_interface_add_del_address_reply) \
Stevenad8015b2017-10-29 22:10:46 -07003243_(sw_interface_set_rx_mode_reply) \
Mohsin Kazmi54f7c512018-08-23 18:28:11 +02003244_(sw_interface_set_rx_placement_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003245_(sw_interface_set_table_reply) \
3246_(sw_interface_set_mpls_enable_reply) \
3247_(sw_interface_set_vpath_reply) \
3248_(sw_interface_set_vxlan_bypass_reply) \
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +08003249_(sw_interface_set_vxlan_gpe_bypass_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003250_(sw_interface_set_l2_bridge_reply) \
Steven Luonga1876b82019-08-20 16:58:00 -07003251_(sw_interface_set_bond_weight_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003252_(bridge_domain_add_del_reply) \
3253_(sw_interface_set_l2_xconnect_reply) \
3254_(l2fib_add_del_reply) \
Eyal Barif24991c2017-04-05 05:33:21 +03003255_(l2fib_flush_int_reply) \
3256_(l2fib_flush_bd_reply) \
Neale Ranns097fa662018-05-01 05:17:55 -07003257_(ip_route_add_del_reply) \
Neale Ranns28ab9cc2017-08-14 07:18:42 -07003258_(ip_table_add_del_reply) \
Neale Ranns9db6ada2019-11-08 12:42:31 +00003259_(ip_table_replace_begin_reply) \
3260_(ip_table_flush_reply) \
3261_(ip_table_replace_end_reply) \
Neale Ranns32e1c012016-11-22 17:07:28 +00003262_(ip_mroute_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003263_(mpls_route_add_del_reply) \
Neale Ranns28ab9cc2017-08-14 07:18:42 -07003264_(mpls_table_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003265_(mpls_ip_bind_unbind_reply) \
Neale Rannsd792d9c2017-10-21 10:53:20 -07003266_(bier_route_add_del_reply) \
3267_(bier_table_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003268_(sw_interface_set_unnumbered_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003269_(set_ip_flow_hash_reply) \
3270_(sw_interface_ip6_enable_disable_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003271_(l2_patch_add_del_reply) \
John Loe166fd92018-09-13 14:08:59 -04003272_(sr_mpls_policy_add_reply) \
3273_(sr_mpls_policy_mod_reply) \
3274_(sr_mpls_policy_del_reply) \
Pablo Camarillofb380952016-12-07 18:34:18 +01003275_(sr_policy_add_reply) \
3276_(sr_policy_mod_reply) \
3277_(sr_policy_del_reply) \
3278_(sr_localsid_add_del_reply) \
3279_(sr_steering_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003280_(classify_add_del_session_reply) \
3281_(classify_set_interface_ip_table_reply) \
3282_(classify_set_interface_l2_tables_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003283_(l2_fib_clear_table_reply) \
3284_(l2_interface_efp_filter_reply) \
3285_(l2_interface_vlan_tag_rewrite_reply) \
3286_(modify_vhost_user_if_reply) \
3287_(delete_vhost_user_if_reply) \
John Lo8d00fff2017-08-03 00:35:36 -04003288_(want_l2_macs_events_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003289_(input_acl_set_interface_reply) \
3290_(ipsec_spd_add_del_reply) \
3291_(ipsec_interface_add_del_spd_reply) \
Neale Ranns17dcec02019-01-09 21:22:20 -08003292_(ipsec_spd_entry_add_del_reply) \
3293_(ipsec_sad_entry_add_del_reply) \
Matthew Smithb0972cb2017-05-02 16:20:41 -05003294_(ipsec_tunnel_if_add_del_reply) \
Matthew Smithca514fd2017-10-12 12:06:59 -05003295_(ipsec_tunnel_if_set_sa_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003296_(delete_loopback_reply) \
3297_(bd_ip_mac_add_del_reply) \
John Loe26c81f2019-01-07 15:16:33 -05003298_(bd_ip_mac_flush_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003299_(want_interface_events_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003300_(cop_interface_enable_disable_reply) \
3301_(cop_whitelist_enable_disable_reply) \
3302_(sw_interface_clear_stats_reply) \
Dave Barach65457162017-10-10 17:53:14 -04003303_(ioam_enable_reply) \
3304_(ioam_disable_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003305_(af_packet_delete_reply) \
3306_(policer_classify_set_interface_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003307_(set_ipfix_exporter_reply) \
3308_(set_ipfix_classify_stream_reply) \
3309_(ipfix_classify_table_add_del_reply) \
3310_(flow_classify_set_interface_reply) \
3311_(sw_interface_span_enable_disable_reply) \
3312_(pg_capture_reply) \
3313_(pg_enable_disable_reply) \
Mohsin Kazmif382b062020-08-11 15:00:44 +02003314_(pg_interface_enable_disable_coalesce_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003315_(ip_source_and_port_range_check_add_del_reply) \
3316_(ip_source_and_port_range_check_interface_add_del_reply)\
3317_(delete_subif_reply) \
3318_(l2_interface_pbb_tag_rewrite_reply) \
Pavel Kotuceke88865d2018-11-28 07:42:11 +01003319_(set_punt_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003320_(feature_enable_disable_reply) \
Mohsin Kazmi29467b52019-10-08 19:42:38 +02003321_(feature_gso_enable_disable_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003322_(sw_interface_tag_add_del_reply) \
Matthew Smithe0792fd2019-07-12 11:48:24 -05003323_(sw_interface_add_del_mac_address_reply) \
Ole Troand7231612018-06-07 10:17:57 +02003324_(hw_interface_set_mtu_reply) \
Pavel Kotucek6899a302017-06-08 08:46:10 +02003325_(p2p_ethernet_add_reply) \
Steve Shin99a0e602017-07-01 04:16:20 +00003326_(p2p_ethernet_del_reply) \
Florin Corascea194d2017-10-02 00:18:51 -07003327_(tcp_configure_src_addresses_reply) \
Florin Coras595992c2017-11-06 17:17:08 -08003328_(session_rule_add_del_reply) \
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +01003329_(ip_container_proxy_add_del_reply) \
Igor Mikhailov (imichail)582caa32018-04-26 21:33:02 -07003330_(output_acl_set_interface_reply) \
Chenmin Sund0236f72020-07-27 17:54:40 +08003331_(qos_record_enable_disable_reply) \
3332_(flow_add_reply)
Damjan Marion7cd468a2016-12-19 23:05:39 +01003333
3334#define _(n) \
3335 static void vl_api_##n##_t_handler \
3336 (vl_api_##n##_t * mp) \
3337 { \
3338 vat_main_t * vam = &vat_main; \
3339 i32 retval = ntohl(mp->retval); \
3340 if (vam->async_mode) { \
3341 vam->async_errors += (retval < 0); \
3342 } else { \
3343 vam->retval = retval; \
3344 vam->result_ready = 1; \
3345 } \
3346 }
3347foreach_standard_reply_retval_handler;
3348#undef _
3349
3350#define _(n) \
3351 static void vl_api_##n##_t_handler_json \
3352 (vl_api_##n##_t * mp) \
3353 { \
3354 vat_main_t * vam = &vat_main; \
3355 vat_json_node_t node; \
3356 vat_json_init_object(&node); \
3357 vat_json_object_add_int(&node, "retval", ntohl(mp->retval)); \
3358 vat_json_print(vam->ofp, &node); \
3359 vam->retval = ntohl(mp->retval); \
3360 vam->result_ready = 1; \
3361 }
3362foreach_standard_reply_retval_handler;
3363#undef _
3364
3365/*
3366 * Table of message reply handlers, must include boilerplate handlers
3367 * we just generated
3368 */
3369
3370#define foreach_vpe_api_reply_msg \
3371_(CREATE_LOOPBACK_REPLY, create_loopback_reply) \
Jon Loeligerc83c3b72017-02-23 13:57:35 -06003372_(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003373_(SW_INTERFACE_DETAILS, sw_interface_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003374_(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply) \
3375_(CONTROL_PING_REPLY, control_ping_reply) \
3376_(CLI_REPLY, cli_reply) \
3377_(CLI_INBAND_REPLY, cli_inband_reply) \
3378_(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY, \
3379 sw_interface_add_del_address_reply) \
Stevenad8015b2017-10-29 22:10:46 -07003380_(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply) \
Mohsin Kazmi54f7c512018-08-23 18:28:11 +02003381_(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply) \
Mohsin Kazmif0b42f42018-09-10 18:11:00 +02003382_(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003383_(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply) \
3384_(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
3385_(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply) \
3386_(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +08003387_(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003388_(SW_INTERFACE_SET_L2_XCONNECT_REPLY, \
3389 sw_interface_set_l2_xconnect_reply) \
3390_(SW_INTERFACE_SET_L2_BRIDGE_REPLY, \
3391 sw_interface_set_l2_bridge_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003392_(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply) \
3393_(BRIDGE_DOMAIN_DETAILS, bridge_domain_details) \
Eyal Barifead6702017-04-04 04:46:32 +03003394_(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003395_(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply) \
Eyal Barif24991c2017-04-05 05:33:21 +03003396_(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply) \
3397_(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003398_(L2_FLAGS_REPLY, l2_flags_reply) \
3399_(BRIDGE_FLAGS_REPLY, bridge_flags_reply) \
Damjan Marion8389fb92017-10-13 18:29:53 +02003400_(TAP_CREATE_V2_REPLY, tap_create_v2_reply) \
3401_(TAP_DELETE_V2_REPLY, tap_delete_v2_reply) \
3402_(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details) \
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01003403_(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply) \
Mohsin Kazmi518251b2020-09-01 17:17:44 +00003404_(VIRTIO_PCI_CREATE_V2_REPLY, virtio_pci_create_v2_reply) \
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01003405_(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply) \
3406_(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details) \
Steven9cd2d7a2017-12-20 12:43:01 -08003407_(BOND_CREATE_REPLY, bond_create_reply) \
Steven Luongea717862020-07-30 07:31:40 -07003408_(BOND_CREATE2_REPLY, bond_create2_reply) \
Steven9cd2d7a2017-12-20 12:43:01 -08003409_(BOND_DELETE_REPLY, bond_delete_reply) \
Steven Luong4c4223e2020-07-15 08:44:54 -07003410_(BOND_ADD_MEMBER_REPLY, bond_add_member_reply) \
3411_(BOND_DETACH_MEMBER_REPLY, bond_detach_member_reply) \
Steven Luonga1876b82019-08-20 16:58:00 -07003412_(SW_INTERFACE_SET_BOND_WEIGHT_REPLY, sw_interface_set_bond_weight_reply) \
Steven Luong4c4223e2020-07-15 08:44:54 -07003413_(SW_BOND_INTERFACE_DETAILS, sw_bond_interface_details) \
3414_(SW_MEMBER_INTERFACE_DETAILS, sw_member_interface_details) \
Neale Ranns097fa662018-05-01 05:17:55 -07003415_(IP_ROUTE_ADD_DEL_REPLY, ip_route_add_del_reply) \
Neale Ranns28ab9cc2017-08-14 07:18:42 -07003416_(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply) \
Neale Ranns9db6ada2019-11-08 12:42:31 +00003417_(IP_TABLE_REPLACE_BEGIN_REPLY, ip_table_replace_begin_reply) \
3418_(IP_TABLE_FLUSH_REPLY, ip_table_flush_reply) \
3419_(IP_TABLE_REPLACE_END_REPLY, ip_table_replace_end_reply) \
Neale Ranns32e1c012016-11-22 17:07:28 +00003420_(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply) \
Neale Ranns28ab9cc2017-08-14 07:18:42 -07003421_(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003422_(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply) \
3423_(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply) \
Neale Rannsd792d9c2017-10-21 10:53:20 -07003424_(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply) \
3425_(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003426_(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply) \
3427_(SW_INTERFACE_SET_UNNUMBERED_REPLY, \
3428 sw_interface_set_unnumbered_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003429_(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply) \
3430_(CREATE_SUBIF_REPLY, create_subif_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003431_(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply) \
3432_(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY, \
3433 sw_interface_ip6_enable_disable_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003434_(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply) \
John Loe166fd92018-09-13 14:08:59 -04003435_(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply) \
3436_(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply) \
3437_(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply) \
Pablo Camarillofb380952016-12-07 18:34:18 +01003438_(SR_POLICY_ADD_REPLY, sr_policy_add_reply) \
3439_(SR_POLICY_MOD_REPLY, sr_policy_mod_reply) \
3440_(SR_POLICY_DEL_REPLY, sr_policy_del_reply) \
3441_(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply) \
3442_(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003443_(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply) \
3444_(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply) \
3445_(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY, \
3446classify_set_interface_ip_table_reply) \
3447_(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY, \
3448 classify_set_interface_l2_tables_reply) \
3449_(GET_NODE_INDEX_REPLY, get_node_index_reply) \
3450_(ADD_NODE_NEXT_REPLY, add_node_next_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003451_(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply) \
eyal bariaf86a482018-04-17 11:20:27 +03003452_(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003453_(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details) \
Neale Ranns5a8844b2019-04-16 07:15:35 +00003454_(GRE_TUNNEL_ADD_DEL_REPLY, gre_tunnel_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003455_(GRE_TUNNEL_DETAILS, gre_tunnel_details) \
3456_(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply) \
3457_(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply) \
3458_(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3459_(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details) \
3460_(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply) \
3461_(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply) \
3462_(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply) \
3463_(SHOW_VERSION_REPLY, show_version_reply) \
Mohsin Kazmi5d64c782018-09-11 20:27:09 +02003464_(SHOW_THREADS_REPLY, show_threads_reply) \
Ole Troan01384fe2017-05-12 11:55:35 +02003465_(L2_FIB_TABLE_DETAILS, l2_fib_table_details) \
John Loc7b43042018-04-13 16:46:22 -04003466_(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003467_(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details) \
3468_(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply) \
John Lo8d00fff2017-08-03 00:35:36 -04003469_(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply) \
3470_(L2_MACS_EVENT, l2_macs_event) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003471_(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply) \
3472_(IP_ADDRESS_DETAILS, ip_address_details) \
3473_(IP_DETAILS, ip_details) \
3474_(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply) \
3475_(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
Neale Ranns17dcec02019-01-09 21:22:20 -08003476_(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply) \
3477_(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply) \
Matthew Smith28029532017-09-26 13:33:44 -05003478_(IPSEC_SA_DETAILS, ipsec_sa_details) \
Matthew Smithb0972cb2017-05-02 16:20:41 -05003479_(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply) \
Matthew Smithca514fd2017-10-12 12:06:59 -05003480_(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003481_(DELETE_LOOPBACK_REPLY, delete_loopback_reply) \
3482_(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply) \
John Loe26c81f2019-01-07 15:16:33 -05003483_(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply) \
Mohsin Kazmi5d82d2f2018-08-13 19:17:54 +02003484_(BD_IP_MAC_DETAILS, bd_ip_mac_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003485_(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003486_(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply) \
3487_(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
3488_(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
3489_(GET_NODE_GRAPH_REPLY, get_node_graph_reply) \
3490_(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply) \
3491_(IOAM_ENABLE_REPLY, ioam_enable_reply) \
3492_(IOAM_DISABLE_REPLY, ioam_disable_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003493_(AF_PACKET_CREATE_REPLY, af_packet_create_reply) \
3494_(AF_PACKET_DELETE_REPLY, af_packet_delete_reply) \
Mohsin Kazmi04e0bb22018-05-28 18:55:37 +02003495_(AF_PACKET_DETAILS, af_packet_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003496_(POLICER_ADD_DEL_REPLY, policer_add_del_reply) \
3497_(POLICER_DETAILS, policer_details) \
3498_(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3499_(POLICER_CLASSIFY_DETAILS, policer_classify_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003500_(MPLS_TUNNEL_DETAILS, mpls_tunnel_details) \
Neale Ranns097fa662018-05-01 05:17:55 -07003501_(MPLS_TABLE_DETAILS, mpls_table_details) \
3502_(MPLS_ROUTE_DETAILS, mpls_route_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003503_(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply) \
3504_(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3505_(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply) \
3506_(CLASSIFY_SESSION_DETAILS, classify_session_details) \
3507_(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply) \
3508_(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details) \
3509_(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply) \
3510_(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details) \
3511_(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
3512_(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details) \
3513_(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
3514_(FLOW_CLASSIFY_DETAILS, flow_classify_details) \
3515_(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
3516_(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details) \
3517_(GET_NEXT_INDEX_REPLY, get_next_index_reply) \
3518_(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply) \
3519_(PG_CAPTURE_REPLY, pg_capture_reply) \
3520_(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply) \
Mohsin Kazmif382b062020-08-11 15:00:44 +02003521_(PG_INTERFACE_ENABLE_DISABLE_COALESCE_REPLY, pg_interface_enable_disable_coalesce_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003522_(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY, \
3523 ip_source_and_port_range_check_add_del_reply) \
3524_(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY, \
3525 ip_source_and_port_range_check_interface_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003526_(DELETE_SUBIF_REPLY, delete_subif_reply) \
3527_(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
Pavel Kotuceke88865d2018-11-28 07:42:11 +01003528_(SET_PUNT_REPLY, set_punt_reply) \
Neale Ranns097fa662018-05-01 05:17:55 -07003529_(IP_TABLE_DETAILS, ip_table_details) \
3530_(IP_ROUTE_DETAILS, ip_route_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003531_(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply) \
Mohsin Kazmi29467b52019-10-08 19:42:38 +02003532_(FEATURE_GSO_ENABLE_DISABLE_REPLY, feature_gso_enable_disable_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003533_(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply) \
Matthew Smithe0792fd2019-07-12 11:48:24 -05003534_(SW_INTERFACE_ADD_DEL_MAC_ADDRESS_REPLY, sw_interface_add_del_mac_address_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003535_(L2_XCONNECT_DETAILS, l2_xconnect_details) \
Ole Troand7231612018-06-07 10:17:57 +02003536_(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply) \
Pavel Kotucek6899a302017-06-08 08:46:10 +02003537_(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply) \
3538_(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply) \
Steve Shin99a0e602017-07-01 04:16:20 +00003539_(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply) \
Florin Corascea194d2017-10-02 00:18:51 -07003540_(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
Dave Barach65457162017-10-10 17:53:14 -04003541_(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply) \
Florin Coras6c36f532017-11-03 18:32:34 -07003542_(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply) \
Florin Coras595992c2017-11-06 17:17:08 -08003543_(SESSION_RULES_DETAILS, session_rules_details) \
3544_(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply) \
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +01003545_(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply) \
Chenmin Sund0236f72020-07-27 17:54:40 +08003546_(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply) \
3547_(FLOW_ADD_REPLY, flow_add_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003548
Dave Baracha1a093d2017-03-02 13:13:23 -05003549#define foreach_standalone_reply_msg \
Ole Troanf49ba0e2018-11-13 14:04:50 +01003550_(SW_INTERFACE_EVENT, sw_interface_event)
Dave Baracha1a093d2017-03-02 13:13:23 -05003551
Damjan Marion7cd468a2016-12-19 23:05:39 +01003552typedef struct
3553{
3554 u8 *name;
3555 u32 value;
3556} name_sort_t;
3557
Damjan Marion7cd468a2016-12-19 23:05:39 +01003558#define STR_VTR_OP_CASE(op) \
3559 case L2_VTR_ ## op: \
3560 return "" # op;
3561
3562static const char *
3563str_vtr_op (u32 vtr_op)
3564{
3565 switch (vtr_op)
3566 {
3567 STR_VTR_OP_CASE (DISABLED);
3568 STR_VTR_OP_CASE (PUSH_1);
3569 STR_VTR_OP_CASE (PUSH_2);
3570 STR_VTR_OP_CASE (POP_1);
3571 STR_VTR_OP_CASE (POP_2);
3572 STR_VTR_OP_CASE (TRANSLATE_1_1);
3573 STR_VTR_OP_CASE (TRANSLATE_1_2);
3574 STR_VTR_OP_CASE (TRANSLATE_2_1);
3575 STR_VTR_OP_CASE (TRANSLATE_2_2);
3576 }
3577
3578 return "UNKNOWN";
3579}
3580
3581static int
3582dump_sub_interface_table (vat_main_t * vam)
3583{
3584 const sw_interface_subif_t *sub = NULL;
3585
3586 if (vam->json_output)
3587 {
3588 clib_warning
3589 ("JSON output supported only for VPE API calls and dump_stats_table");
3590 return -99;
3591 }
3592
3593 print (vam->ofp,
3594 "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
3595 "Interface", "sw_if_index",
3596 "sub id", "dot1ad", "tags", "outer id",
3597 "inner id", "exact", "default", "outer any", "inner any");
3598
3599 vec_foreach (sub, vam->sw_if_subif_table)
3600 {
3601 print (vam->ofp,
3602 "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
3603 sub->interface_name,
3604 sub->sw_if_index,
3605 sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
3606 sub->sub_number_of_tags, sub->sub_outer_vlan_id,
3607 sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
3608 sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
3609 if (sub->vtr_op != L2_VTR_DISABLED)
3610 {
3611 print (vam->ofp,
3612 " vlan-tag-rewrite - op: %-14s [ dot1q: %d "
3613 "tag1: %d tag2: %d ]",
3614 str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
3615 sub->vtr_tag1, sub->vtr_tag2);
3616 }
3617 }
3618
3619 return 0;
3620}
3621
3622static int
3623name_sort_cmp (void *a1, void *a2)
3624{
3625 name_sort_t *n1 = a1;
3626 name_sort_t *n2 = a2;
3627
3628 return strcmp ((char *) n1->name, (char *) n2->name);
3629}
3630
3631static int
3632dump_interface_table (vat_main_t * vam)
3633{
3634 hash_pair_t *p;
3635 name_sort_t *nses = 0, *ns;
3636
3637 if (vam->json_output)
3638 {
3639 clib_warning
3640 ("JSON output supported only for VPE API calls and dump_stats_table");
3641 return -99;
3642 }
3643
3644 /* *INDENT-OFF* */
3645 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3646 ({
3647 vec_add2 (nses, ns, 1);
3648 ns->name = (u8 *)(p->key);
3649 ns->value = (u32) p->value[0];
3650 }));
3651 /* *INDENT-ON* */
3652
3653 vec_sort_with_function (nses, name_sort_cmp);
3654
3655 print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
3656 vec_foreach (ns, nses)
3657 {
3658 print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
3659 }
3660 vec_free (nses);
3661 return 0;
3662}
3663
3664static int
3665dump_ip_table (vat_main_t * vam, int is_ipv6)
3666{
3667 const ip_details_t *det = NULL;
3668 const ip_address_details_t *address = NULL;
3669 u32 i = ~0;
3670
3671 print (vam->ofp, "%-12s", "sw_if_index");
3672
3673 vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
3674 {
3675 i++;
3676 if (!det->present)
3677 {
3678 continue;
3679 }
3680 print (vam->ofp, "%-12d", i);
3681 print (vam->ofp, " %-30s%-13s", "Address", "Prefix length");
3682 if (!det->addr)
3683 {
3684 continue;
3685 }
3686 vec_foreach (address, det->addr)
3687 {
3688 print (vam->ofp,
3689 " %-30U%-13d",
3690 is_ipv6 ? format_ip6_address : format_ip4_address,
3691 address->ip, address->prefix_length);
3692 }
3693 }
3694
3695 return 0;
3696}
3697
3698static int
3699dump_ipv4_table (vat_main_t * vam)
3700{
3701 if (vam->json_output)
3702 {
3703 clib_warning
3704 ("JSON output supported only for VPE API calls and dump_stats_table");
3705 return -99;
3706 }
3707
3708 return dump_ip_table (vam, 0);
3709}
3710
3711static int
3712dump_ipv6_table (vat_main_t * vam)
3713{
3714 if (vam->json_output)
3715 {
3716 clib_warning
3717 ("JSON output supported only for VPE API calls and dump_stats_table");
3718 return -99;
3719 }
3720
3721 return dump_ip_table (vam, 1);
3722}
3723
Damjan Marion7cd468a2016-12-19 23:05:39 +01003724/*
Dave Barach59b25652017-09-10 15:04:27 -04003725 * Pass CLI buffers directly in the CLI_INBAND API message,
3726 * instead of an additional shared memory area.
Damjan Marion7cd468a2016-12-19 23:05:39 +01003727 */
3728static int
3729exec_inband (vat_main_t * vam)
3730{
3731 vl_api_cli_inband_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003732 unformat_input_t *i = vam->input;
Jon Loeliger56c7b012017-02-01 12:31:41 -06003733 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003734
3735 if (vec_len (i->buffer) == 0)
3736 return -1;
3737
3738 if (vam->exec_mode == 0 && unformat (i, "mode"))
3739 {
3740 vam->exec_mode = 1;
3741 return 0;
3742 }
3743 if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
3744 {
3745 vam->exec_mode = 0;
3746 return 0;
3747 }
3748
3749 /*
3750 * In order for the CLI command to work, it
3751 * must be a vector ending in \n, not a C-string ending
3752 * in \n\0.
3753 */
Jakub Grajciar2dbee932020-02-07 11:30:26 +01003754 M2 (CLI_INBAND, mp, vec_len (vam->input->buffer));
3755 vl_api_vec_to_api_string (vam->input->buffer, &mp->cmd);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003756
Jon Loeliger7bc770c2017-01-31 14:03:33 -06003757 S (mp);
Dave Barach59b25652017-09-10 15:04:27 -04003758 W (ret);
3759 /* json responses may or may not include a useful reply... */
3760 if (vec_len (vam->cmd_reply))
Dave Barachcf5e8482017-10-17 11:48:29 -04003761 print (vam->ofp, "%v", (char *) (vam->cmd_reply));
Jon Loeliger56c7b012017-02-01 12:31:41 -06003762 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003763}
3764
Dave Barach59b25652017-09-10 15:04:27 -04003765int
3766exec (vat_main_t * vam)
3767{
3768 return exec_inband (vam);
3769}
3770
Damjan Marion7cd468a2016-12-19 23:05:39 +01003771static int
3772api_create_loopback (vat_main_t * vam)
3773{
3774 unformat_input_t *i = vam->input;
3775 vl_api_create_loopback_t *mp;
Jon Loeligerc83c3b72017-02-23 13:57:35 -06003776 vl_api_create_loopback_instance_t *mp_lbi;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003777 u8 mac_address[6];
3778 u8 mac_set = 0;
Jon Loeligerc83c3b72017-02-23 13:57:35 -06003779 u8 is_specified = 0;
3780 u32 user_instance = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06003781 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003782
Dave Barachb7b92992018-10-17 10:38:51 -04003783 clib_memset (mac_address, 0, sizeof (mac_address));
Damjan Marion7cd468a2016-12-19 23:05:39 +01003784
3785 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3786 {
3787 if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
3788 mac_set = 1;
Jon Loeligerc83c3b72017-02-23 13:57:35 -06003789 if (unformat (i, "instance %d", &user_instance))
3790 is_specified = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003791 else
3792 break;
3793 }
3794
Jon Loeligerc83c3b72017-02-23 13:57:35 -06003795 if (is_specified)
3796 {
3797 M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
3798 mp_lbi->is_specified = is_specified;
3799 if (is_specified)
3800 mp_lbi->user_instance = htonl (user_instance);
3801 if (mac_set)
3802 clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
3803 S (mp_lbi);
3804 }
3805 else
3806 {
3807 /* Construct the API message */
3808 M (CREATE_LOOPBACK, mp);
3809 if (mac_set)
3810 clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
3811 S (mp);
3812 }
Damjan Marion7cd468a2016-12-19 23:05:39 +01003813
Jon Loeliger56c7b012017-02-01 12:31:41 -06003814 W (ret);
3815 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003816}
3817
3818static int
3819api_delete_loopback (vat_main_t * vam)
3820{
3821 unformat_input_t *i = vam->input;
3822 vl_api_delete_loopback_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003823 u32 sw_if_index = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06003824 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003825
3826 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3827 {
3828 if (unformat (i, "sw_if_index %d", &sw_if_index))
3829 ;
3830 else
3831 break;
3832 }
3833
3834 if (sw_if_index == ~0)
3835 {
3836 errmsg ("missing sw_if_index");
3837 return -99;
3838 }
3839
3840 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06003841 M (DELETE_LOOPBACK, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003842 mp->sw_if_index = ntohl (sw_if_index);
3843
Jon Loeliger7bc770c2017-01-31 14:03:33 -06003844 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06003845 W (ret);
3846 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003847}
3848
3849static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01003850api_want_interface_events (vat_main_t * vam)
3851{
3852 unformat_input_t *i = vam->input;
3853 vl_api_want_interface_events_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003854 int enable = -1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06003855 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003856
3857 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3858 {
3859 if (unformat (i, "enable"))
3860 enable = 1;
3861 else if (unformat (i, "disable"))
3862 enable = 0;
3863 else
3864 break;
3865 }
3866
3867 if (enable == -1)
3868 {
3869 errmsg ("missing enable|disable");
3870 return -99;
3871 }
3872
Jon Loeliger8a2aea32017-01-31 13:19:40 -06003873 M (WANT_INTERFACE_EVENTS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003874 mp->enable_disable = enable;
3875
3876 vam->interface_event_display = enable;
3877
Jon Loeliger7bc770c2017-01-31 14:03:33 -06003878 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06003879 W (ret);
3880 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003881}
3882
3883
3884/* Note: non-static, called once to set up the initial intfc table */
3885int
3886api_sw_interface_dump (vat_main_t * vam)
3887{
3888 vl_api_sw_interface_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -06003889 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003890 hash_pair_t *p;
3891 name_sort_t *nses = 0, *ns;
3892 sw_interface_subif_t *sub = NULL;
Jon Loeliger56c7b012017-02-01 12:31:41 -06003893 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003894
3895 /* Toss the old name table */
3896 /* *INDENT-OFF* */
3897 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3898 ({
3899 vec_add2 (nses, ns, 1);
3900 ns->name = (u8 *)(p->key);
3901 ns->value = (u32) p->value[0];
3902 }));
3903 /* *INDENT-ON* */
3904
3905 hash_free (vam->sw_if_index_by_interface_name);
3906
3907 vec_foreach (ns, nses) vec_free (ns->name);
3908
3909 vec_free (nses);
3910
3911 vec_foreach (sub, vam->sw_if_subif_table)
3912 {
3913 vec_free (sub->interface_name);
3914 }
3915 vec_free (vam->sw_if_subif_table);
3916
3917 /* recreate the interface name hash table */
3918 vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
3919
Dave Barachf72212e2018-01-11 10:25:07 -05003920 /*
3921 * Ask for all interface names. Otherwise, the epic catalog of
3922 * name filters becomes ridiculously long, and vat ends up needing
3923 * to be taught about new interface types.
3924 */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06003925 M (SW_INTERFACE_DUMP, mp);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06003926 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003927
3928 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -04003929 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06003930 S (mp_ping);
3931
Jon Loeliger56c7b012017-02-01 12:31:41 -06003932 W (ret);
3933 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003934}
3935
3936static int
3937api_sw_interface_set_flags (vat_main_t * vam)
3938{
3939 unformat_input_t *i = vam->input;
3940 vl_api_sw_interface_set_flags_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003941 u32 sw_if_index;
3942 u8 sw_if_index_set = 0;
Neale Rannsa07bd702017-08-07 07:53:49 -07003943 u8 admin_up = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06003944 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003945
3946 /* Parse args required to build the message */
3947 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3948 {
3949 if (unformat (i, "admin-up"))
3950 admin_up = 1;
3951 else if (unformat (i, "admin-down"))
3952 admin_up = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003953 else
3954 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
3955 sw_if_index_set = 1;
3956 else if (unformat (i, "sw_if_index %d", &sw_if_index))
3957 sw_if_index_set = 1;
3958 else
3959 break;
3960 }
3961
3962 if (sw_if_index_set == 0)
3963 {
3964 errmsg ("missing interface name or sw_if_index");
3965 return -99;
3966 }
3967
3968 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06003969 M (SW_INTERFACE_SET_FLAGS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003970 mp->sw_if_index = ntohl (sw_if_index);
Jakub Grajciar053204a2019-03-18 13:17:53 +01003971 mp->flags = ntohl ((admin_up) ? IF_STATUS_API_FLAG_ADMIN_UP : 0);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003972
3973 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06003974 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003975
3976 /* Wait for a reply, return the good/bad news... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06003977 W (ret);
3978 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003979}
3980
3981static int
Stevenad8015b2017-10-29 22:10:46 -07003982api_sw_interface_set_rx_mode (vat_main_t * vam)
3983{
3984 unformat_input_t *i = vam->input;
3985 vl_api_sw_interface_set_rx_mode_t *mp;
3986 u32 sw_if_index;
3987 u8 sw_if_index_set = 0;
3988 int ret;
3989 u8 queue_id_valid = 0;
3990 u32 queue_id;
Damjan Marioneabd4242020-10-07 20:59:07 +02003991 vnet_hw_if_rx_mode mode = VNET_HW_IF_RX_MODE_UNKNOWN;
Stevenad8015b2017-10-29 22:10:46 -07003992
3993 /* Parse args required to build the message */
3994 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3995 {
3996 if (unformat (i, "queue %d", &queue_id))
3997 queue_id_valid = 1;
3998 else if (unformat (i, "polling"))
Damjan Marioneabd4242020-10-07 20:59:07 +02003999 mode = VNET_HW_IF_RX_MODE_POLLING;
Stevenad8015b2017-10-29 22:10:46 -07004000 else if (unformat (i, "interrupt"))
Damjan Marioneabd4242020-10-07 20:59:07 +02004001 mode = VNET_HW_IF_RX_MODE_INTERRUPT;
Stevenad8015b2017-10-29 22:10:46 -07004002 else if (unformat (i, "adaptive"))
Damjan Marioneabd4242020-10-07 20:59:07 +02004003 mode = VNET_HW_IF_RX_MODE_ADAPTIVE;
Stevenad8015b2017-10-29 22:10:46 -07004004 else
4005 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4006 sw_if_index_set = 1;
4007 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4008 sw_if_index_set = 1;
4009 else
4010 break;
4011 }
4012
4013 if (sw_if_index_set == 0)
4014 {
4015 errmsg ("missing interface name or sw_if_index");
4016 return -99;
4017 }
Damjan Marioneabd4242020-10-07 20:59:07 +02004018 if (mode == VNET_HW_IF_RX_MODE_UNKNOWN)
Stevenad8015b2017-10-29 22:10:46 -07004019 {
4020 errmsg ("missing rx-mode");
4021 return -99;
4022 }
4023
4024 /* Construct the API message */
4025 M (SW_INTERFACE_SET_RX_MODE, mp);
4026 mp->sw_if_index = ntohl (sw_if_index);
Jakub Grajciar053204a2019-03-18 13:17:53 +01004027 mp->mode = (vl_api_rx_mode_t) mode;
Stevenad8015b2017-10-29 22:10:46 -07004028 mp->queue_id_valid = queue_id_valid;
4029 mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
4030
4031 /* send it... */
4032 S (mp);
4033
4034 /* Wait for a reply, return the good/bad news... */
4035 W (ret);
4036 return ret;
4037}
4038
4039static int
Mohsin Kazmi54f7c512018-08-23 18:28:11 +02004040api_sw_interface_set_rx_placement (vat_main_t * vam)
4041{
4042 unformat_input_t *i = vam->input;
4043 vl_api_sw_interface_set_rx_placement_t *mp;
4044 u32 sw_if_index;
4045 u8 sw_if_index_set = 0;
4046 int ret;
4047 u8 is_main = 0;
4048 u32 queue_id, thread_index;
4049
4050 /* Parse args required to build the message */
4051 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4052 {
4053 if (unformat (i, "queue %d", &queue_id))
4054 ;
4055 else if (unformat (i, "main"))
4056 is_main = 1;
4057 else if (unformat (i, "worker %d", &thread_index))
4058 ;
4059 else
4060 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4061 sw_if_index_set = 1;
4062 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4063 sw_if_index_set = 1;
4064 else
4065 break;
4066 }
4067
4068 if (sw_if_index_set == 0)
4069 {
4070 errmsg ("missing interface name or sw_if_index");
4071 return -99;
4072 }
4073
4074 if (is_main)
4075 thread_index = 0;
4076 /* Construct the API message */
4077 M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
4078 mp->sw_if_index = ntohl (sw_if_index);
4079 mp->worker_id = ntohl (thread_index);
4080 mp->queue_id = ntohl (queue_id);
4081 mp->is_main = is_main;
4082
4083 /* send it... */
4084 S (mp);
4085 /* Wait for a reply, return the good/bad news... */
4086 W (ret);
4087 return ret;
4088}
4089
Mohsin Kazmif0b42f42018-09-10 18:11:00 +02004090static void vl_api_sw_interface_rx_placement_details_t_handler
4091 (vl_api_sw_interface_rx_placement_details_t * mp)
4092{
4093 vat_main_t *vam = &vat_main;
4094 u32 worker_id = ntohl (mp->worker_id);
4095
4096 print (vam->ofp,
4097 "\n%-11d %-11s %-6d %-5d %-9s",
4098 ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
4099 worker_id, ntohl (mp->queue_id),
4100 (mp->mode ==
4101 1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
4102}
4103
4104static void vl_api_sw_interface_rx_placement_details_t_handler_json
4105 (vl_api_sw_interface_rx_placement_details_t * mp)
4106{
4107 vat_main_t *vam = &vat_main;
4108 vat_json_node_t *node = NULL;
4109
4110 if (VAT_JSON_ARRAY != vam->json_tree.type)
4111 {
4112 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4113 vat_json_init_array (&vam->json_tree);
4114 }
4115 node = vat_json_array_add (&vam->json_tree);
4116
4117 vat_json_init_object (node);
4118 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4119 vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
4120 vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
4121 vat_json_object_add_uint (node, "mode", mp->mode);
4122}
4123
4124static int
4125api_sw_interface_rx_placement_dump (vat_main_t * vam)
4126{
4127 unformat_input_t *i = vam->input;
4128 vl_api_sw_interface_rx_placement_dump_t *mp;
4129 vl_api_control_ping_t *mp_ping;
4130 int ret;
4131 u32 sw_if_index;
4132 u8 sw_if_index_set = 0;
4133
4134 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4135 {
4136 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4137 sw_if_index_set++;
4138 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4139 sw_if_index_set++;
4140 else
4141 break;
4142 }
4143
4144 print (vam->ofp,
4145 "\n%-11s %-11s %-6s %-5s %-4s",
4146 "sw_if_index", "main/worker", "thread", "queue", "mode");
4147
4148 /* Dump Interface rx placement */
4149 M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
4150
4151 if (sw_if_index_set)
4152 mp->sw_if_index = htonl (sw_if_index);
4153 else
4154 mp->sw_if_index = ~0;
4155
4156 S (mp);
4157
4158 /* Use a control ping for synchronization */
4159 MPING (CONTROL_PING, mp_ping);
4160 S (mp_ping);
4161
4162 W (ret);
4163 return ret;
4164}
4165
Mohsin Kazmi54f7c512018-08-23 18:28:11 +02004166static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01004167api_sw_interface_clear_stats (vat_main_t * vam)
4168{
4169 unformat_input_t *i = vam->input;
4170 vl_api_sw_interface_clear_stats_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004171 u32 sw_if_index;
4172 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004173 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004174
4175 /* Parse args required to build the message */
4176 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4177 {
4178 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4179 sw_if_index_set = 1;
4180 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4181 sw_if_index_set = 1;
4182 else
4183 break;
4184 }
4185
4186 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004187 M (SW_INTERFACE_CLEAR_STATS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004188
4189 if (sw_if_index_set == 1)
4190 mp->sw_if_index = ntohl (sw_if_index);
4191 else
4192 mp->sw_if_index = ~0;
4193
4194 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004195 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004196
4197 /* Wait for a reply, return the good/bad news... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06004198 W (ret);
4199 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004200}
4201
Damjan Marion7cd468a2016-12-19 23:05:39 +01004202static int
4203api_sw_interface_add_del_address (vat_main_t * vam)
4204{
4205 unformat_input_t *i = vam->input;
4206 vl_api_sw_interface_add_del_address_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004207 u32 sw_if_index;
4208 u8 sw_if_index_set = 0;
4209 u8 is_add = 1, del_all = 0;
4210 u32 address_length = 0;
4211 u8 v4_address_set = 0;
4212 u8 v6_address_set = 0;
4213 ip4_address_t v4address;
4214 ip6_address_t v6address;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004215 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004216
4217 /* Parse args required to build the message */
4218 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4219 {
4220 if (unformat (i, "del-all"))
4221 del_all = 1;
4222 else if (unformat (i, "del"))
4223 is_add = 0;
4224 else
4225 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4226 sw_if_index_set = 1;
4227 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4228 sw_if_index_set = 1;
4229 else if (unformat (i, "%U/%d",
4230 unformat_ip4_address, &v4address, &address_length))
4231 v4_address_set = 1;
4232 else if (unformat (i, "%U/%d",
4233 unformat_ip6_address, &v6address, &address_length))
4234 v6_address_set = 1;
4235 else
4236 break;
4237 }
4238
4239 if (sw_if_index_set == 0)
4240 {
4241 errmsg ("missing interface name or sw_if_index");
4242 return -99;
4243 }
4244 if (v4_address_set && v6_address_set)
4245 {
4246 errmsg ("both v4 and v6 addresses set");
4247 return -99;
4248 }
4249 if (!v4_address_set && !v6_address_set && !del_all)
4250 {
4251 errmsg ("no addresses set");
4252 return -99;
4253 }
4254
4255 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004256 M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004257
4258 mp->sw_if_index = ntohl (sw_if_index);
4259 mp->is_add = is_add;
4260 mp->del_all = del_all;
4261 if (v6_address_set)
4262 {
Jakub Grajciar053204a2019-03-18 13:17:53 +01004263 mp->prefix.address.af = ADDRESS_IP6;
4264 clib_memcpy (mp->prefix.address.un.ip6, &v6address, sizeof (v6address));
Damjan Marion7cd468a2016-12-19 23:05:39 +01004265 }
4266 else
4267 {
Jakub Grajciar053204a2019-03-18 13:17:53 +01004268 mp->prefix.address.af = ADDRESS_IP4;
4269 clib_memcpy (mp->prefix.address.un.ip4, &v4address, sizeof (v4address));
Damjan Marion7cd468a2016-12-19 23:05:39 +01004270 }
Jakub Grajciar053204a2019-03-18 13:17:53 +01004271 mp->prefix.len = address_length;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004272
4273 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004274 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004275
4276 /* Wait for a reply, return good/bad news */
Jon Loeliger56c7b012017-02-01 12:31:41 -06004277 W (ret);
4278 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004279}
4280
4281static int
4282api_sw_interface_set_mpls_enable (vat_main_t * vam)
4283{
4284 unformat_input_t *i = vam->input;
4285 vl_api_sw_interface_set_mpls_enable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004286 u32 sw_if_index;
4287 u8 sw_if_index_set = 0;
4288 u8 enable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004289 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004290
4291 /* Parse args required to build the message */
4292 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4293 {
4294 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4295 sw_if_index_set = 1;
4296 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4297 sw_if_index_set = 1;
4298 else if (unformat (i, "disable"))
4299 enable = 0;
4300 else if (unformat (i, "dis"))
4301 enable = 0;
4302 else
4303 break;
4304 }
4305
4306 if (sw_if_index_set == 0)
4307 {
4308 errmsg ("missing interface name or sw_if_index");
4309 return -99;
4310 }
4311
4312 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004313 M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004314
4315 mp->sw_if_index = ntohl (sw_if_index);
4316 mp->enable = enable;
4317
4318 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004319 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004320
4321 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06004322 W (ret);
4323 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004324}
4325
4326static int
4327api_sw_interface_set_table (vat_main_t * vam)
4328{
4329 unformat_input_t *i = vam->input;
4330 vl_api_sw_interface_set_table_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004331 u32 sw_if_index, vrf_id = 0;
4332 u8 sw_if_index_set = 0;
4333 u8 is_ipv6 = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004334 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004335
4336 /* Parse args required to build the message */
4337 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4338 {
4339 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4340 sw_if_index_set = 1;
4341 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4342 sw_if_index_set = 1;
4343 else if (unformat (i, "vrf %d", &vrf_id))
4344 ;
4345 else if (unformat (i, "ipv6"))
4346 is_ipv6 = 1;
4347 else
4348 break;
4349 }
4350
4351 if (sw_if_index_set == 0)
4352 {
4353 errmsg ("missing interface name or sw_if_index");
4354 return -99;
4355 }
4356
4357 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004358 M (SW_INTERFACE_SET_TABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004359
4360 mp->sw_if_index = ntohl (sw_if_index);
4361 mp->is_ipv6 = is_ipv6;
4362 mp->vrf_id = ntohl (vrf_id);
4363
4364 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004365 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004366
4367 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06004368 W (ret);
4369 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004370}
4371
4372static void vl_api_sw_interface_get_table_reply_t_handler
4373 (vl_api_sw_interface_get_table_reply_t * mp)
4374{
4375 vat_main_t *vam = &vat_main;
4376
4377 print (vam->ofp, "%d", ntohl (mp->vrf_id));
4378
4379 vam->retval = ntohl (mp->retval);
4380 vam->result_ready = 1;
4381
4382}
4383
4384static void vl_api_sw_interface_get_table_reply_t_handler_json
4385 (vl_api_sw_interface_get_table_reply_t * mp)
4386{
4387 vat_main_t *vam = &vat_main;
4388 vat_json_node_t node;
4389
4390 vat_json_init_object (&node);
4391 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4392 vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
4393
4394 vat_json_print (vam->ofp, &node);
4395 vat_json_free (&node);
4396
4397 vam->retval = ntohl (mp->retval);
4398 vam->result_ready = 1;
4399}
4400
4401static int
4402api_sw_interface_get_table (vat_main_t * vam)
4403{
4404 unformat_input_t *i = vam->input;
4405 vl_api_sw_interface_get_table_t *mp;
4406 u32 sw_if_index;
4407 u8 sw_if_index_set = 0;
4408 u8 is_ipv6 = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004409 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004410
4411 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4412 {
4413 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4414 sw_if_index_set = 1;
4415 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4416 sw_if_index_set = 1;
4417 else if (unformat (i, "ipv6"))
4418 is_ipv6 = 1;
4419 else
4420 break;
4421 }
4422
4423 if (sw_if_index_set == 0)
4424 {
4425 errmsg ("missing interface name or sw_if_index");
4426 return -99;
4427 }
4428
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004429 M (SW_INTERFACE_GET_TABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004430 mp->sw_if_index = htonl (sw_if_index);
4431 mp->is_ipv6 = is_ipv6;
4432
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004433 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06004434 W (ret);
4435 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004436}
4437
4438static int
4439api_sw_interface_set_vpath (vat_main_t * vam)
4440{
4441 unformat_input_t *i = vam->input;
4442 vl_api_sw_interface_set_vpath_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004443 u32 sw_if_index = 0;
4444 u8 sw_if_index_set = 0;
4445 u8 is_enable = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004446 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004447
4448 /* Parse args required to build the message */
4449 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4450 {
4451 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4452 sw_if_index_set = 1;
4453 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4454 sw_if_index_set = 1;
4455 else if (unformat (i, "enable"))
4456 is_enable = 1;
4457 else if (unformat (i, "disable"))
4458 is_enable = 0;
4459 else
4460 break;
4461 }
4462
4463 if (sw_if_index_set == 0)
4464 {
4465 errmsg ("missing interface name or sw_if_index");
4466 return -99;
4467 }
4468
4469 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004470 M (SW_INTERFACE_SET_VPATH, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004471
4472 mp->sw_if_index = ntohl (sw_if_index);
4473 mp->enable = is_enable;
4474
4475 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004476 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004477
4478 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06004479 W (ret);
4480 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004481}
4482
4483static int
4484api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
4485{
4486 unformat_input_t *i = vam->input;
4487 vl_api_sw_interface_set_vxlan_bypass_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004488 u32 sw_if_index = 0;
4489 u8 sw_if_index_set = 0;
John Lo2b81eb82017-01-30 13:12:10 -05004490 u8 is_enable = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004491 u8 is_ipv6 = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004492 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004493
4494 /* Parse args required to build the message */
4495 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4496 {
4497 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4498 sw_if_index_set = 1;
4499 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4500 sw_if_index_set = 1;
4501 else if (unformat (i, "enable"))
4502 is_enable = 1;
4503 else if (unformat (i, "disable"))
4504 is_enable = 0;
4505 else if (unformat (i, "ip4"))
4506 is_ipv6 = 0;
4507 else if (unformat (i, "ip6"))
4508 is_ipv6 = 1;
4509 else
4510 break;
4511 }
4512
4513 if (sw_if_index_set == 0)
4514 {
4515 errmsg ("missing interface name or sw_if_index");
4516 return -99;
4517 }
4518
4519 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004520 M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004521
4522 mp->sw_if_index = ntohl (sw_if_index);
4523 mp->enable = is_enable;
4524 mp->is_ipv6 = is_ipv6;
4525
4526 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004527 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004528
4529 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06004530 W (ret);
4531 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004532}
4533
Marco Varleseb598f1d2017-09-19 14:25:28 +02004534static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01004535api_sw_interface_set_l2_xconnect (vat_main_t * vam)
4536{
4537 unformat_input_t *i = vam->input;
4538 vl_api_sw_interface_set_l2_xconnect_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004539 u32 rx_sw_if_index;
4540 u8 rx_sw_if_index_set = 0;
4541 u32 tx_sw_if_index;
4542 u8 tx_sw_if_index_set = 0;
4543 u8 enable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004544 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004545
4546 /* Parse args required to build the message */
4547 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4548 {
4549 if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
4550 rx_sw_if_index_set = 1;
4551 else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
4552 tx_sw_if_index_set = 1;
4553 else if (unformat (i, "rx"))
4554 {
4555 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4556 {
4557 if (unformat (i, "%U", api_unformat_sw_if_index, vam,
4558 &rx_sw_if_index))
4559 rx_sw_if_index_set = 1;
4560 }
4561 else
4562 break;
4563 }
4564 else if (unformat (i, "tx"))
4565 {
4566 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4567 {
4568 if (unformat (i, "%U", api_unformat_sw_if_index, vam,
4569 &tx_sw_if_index))
4570 tx_sw_if_index_set = 1;
4571 }
4572 else
4573 break;
4574 }
4575 else if (unformat (i, "enable"))
4576 enable = 1;
4577 else if (unformat (i, "disable"))
4578 enable = 0;
4579 else
4580 break;
4581 }
4582
4583 if (rx_sw_if_index_set == 0)
4584 {
4585 errmsg ("missing rx interface name or rx_sw_if_index");
4586 return -99;
4587 }
4588
4589 if (enable && (tx_sw_if_index_set == 0))
4590 {
4591 errmsg ("missing tx interface name or tx_sw_if_index");
4592 return -99;
4593 }
4594
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004595 M (SW_INTERFACE_SET_L2_XCONNECT, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004596
4597 mp->rx_sw_if_index = ntohl (rx_sw_if_index);
4598 mp->tx_sw_if_index = ntohl (tx_sw_if_index);
4599 mp->enable = enable;
4600
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004601 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06004602 W (ret);
4603 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004604}
4605
4606static int
4607api_sw_interface_set_l2_bridge (vat_main_t * vam)
4608{
4609 unformat_input_t *i = vam->input;
4610 vl_api_sw_interface_set_l2_bridge_t *mp;
Neale Rannsb4743802018-09-05 09:13:57 -07004611 vl_api_l2_port_type_t port_type;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004612 u32 rx_sw_if_index;
4613 u8 rx_sw_if_index_set = 0;
4614 u32 bd_id;
4615 u8 bd_id_set = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004616 u32 shg = 0;
4617 u8 enable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004618 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004619
Neale Rannsb4743802018-09-05 09:13:57 -07004620 port_type = L2_API_PORT_TYPE_NORMAL;
4621
Damjan Marion7cd468a2016-12-19 23:05:39 +01004622 /* Parse args required to build the message */
4623 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4624 {
4625 if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
4626 rx_sw_if_index_set = 1;
4627 else if (unformat (i, "bd_id %d", &bd_id))
4628 bd_id_set = 1;
4629 else
4630 if (unformat
4631 (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
4632 rx_sw_if_index_set = 1;
4633 else if (unformat (i, "shg %d", &shg))
4634 ;
4635 else if (unformat (i, "bvi"))
Neale Rannsb4743802018-09-05 09:13:57 -07004636 port_type = L2_API_PORT_TYPE_BVI;
4637 else if (unformat (i, "uu-fwd"))
4638 port_type = L2_API_PORT_TYPE_UU_FWD;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004639 else if (unformat (i, "enable"))
4640 enable = 1;
4641 else if (unformat (i, "disable"))
4642 enable = 0;
4643 else
4644 break;
4645 }
4646
4647 if (rx_sw_if_index_set == 0)
4648 {
4649 errmsg ("missing rx interface name or sw_if_index");
4650 return -99;
4651 }
4652
4653 if (enable && (bd_id_set == 0))
4654 {
4655 errmsg ("missing bridge domain");
4656 return -99;
4657 }
4658
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004659 M (SW_INTERFACE_SET_L2_BRIDGE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004660
4661 mp->rx_sw_if_index = ntohl (rx_sw_if_index);
4662 mp->bd_id = ntohl (bd_id);
4663 mp->shg = (u8) shg;
Neale Rannsb4743802018-09-05 09:13:57 -07004664 mp->port_type = ntohl (port_type);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004665 mp->enable = enable;
4666
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004667 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06004668 W (ret);
4669 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004670}
4671
4672static int
4673api_bridge_domain_dump (vat_main_t * vam)
4674{
4675 unformat_input_t *i = vam->input;
4676 vl_api_bridge_domain_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -06004677 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004678 u32 bd_id = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004679 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004680
4681 /* Parse args required to build the message */
4682 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4683 {
4684 if (unformat (i, "bd_id %d", &bd_id))
4685 ;
4686 else
4687 break;
4688 }
4689
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004690 M (BRIDGE_DOMAIN_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004691 mp->bd_id = ntohl (bd_id);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004692 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004693
4694 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -04004695 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06004696 S (mp_ping);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004697
Jon Loeliger56c7b012017-02-01 12:31:41 -06004698 W (ret);
4699 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004700}
4701
4702static int
4703api_bridge_domain_add_del (vat_main_t * vam)
4704{
4705 unformat_input_t *i = vam->input;
4706 vl_api_bridge_domain_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004707 u32 bd_id = ~0;
4708 u8 is_add = 1;
4709 u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
Jerome Tollet50570ec2017-09-14 12:53:56 +01004710 u8 *bd_tag = NULL;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004711 u32 mac_age = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004712 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004713
4714 /* Parse args required to build the message */
4715 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4716 {
4717 if (unformat (i, "bd_id %d", &bd_id))
4718 ;
4719 else if (unformat (i, "flood %d", &flood))
4720 ;
4721 else if (unformat (i, "uu-flood %d", &uu_flood))
4722 ;
4723 else if (unformat (i, "forward %d", &forward))
4724 ;
4725 else if (unformat (i, "learn %d", &learn))
4726 ;
4727 else if (unformat (i, "arp-term %d", &arp_term))
4728 ;
4729 else if (unformat (i, "mac-age %d", &mac_age))
4730 ;
Jerome Tollet50570ec2017-09-14 12:53:56 +01004731 else if (unformat (i, "bd-tag %s", &bd_tag))
4732 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004733 else if (unformat (i, "del"))
4734 {
4735 is_add = 0;
4736 flood = uu_flood = forward = learn = 0;
4737 }
4738 else
4739 break;
4740 }
4741
4742 if (bd_id == ~0)
4743 {
4744 errmsg ("missing bridge domain");
Jerome Tollet50570ec2017-09-14 12:53:56 +01004745 ret = -99;
4746 goto done;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004747 }
4748
4749 if (mac_age > 255)
4750 {
4751 errmsg ("mac age must be less than 256 ");
Jerome Tollet50570ec2017-09-14 12:53:56 +01004752 ret = -99;
4753 goto done;
4754 }
4755
John Lo70bfcaf2017-11-14 13:19:26 -05004756 if ((bd_tag) && (vec_len (bd_tag) > 63))
Jerome Tollet50570ec2017-09-14 12:53:56 +01004757 {
4758 errmsg ("bd-tag cannot be longer than 63");
4759 ret = -99;
4760 goto done;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004761 }
4762
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004763 M (BRIDGE_DOMAIN_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004764
4765 mp->bd_id = ntohl (bd_id);
4766 mp->flood = flood;
4767 mp->uu_flood = uu_flood;
4768 mp->forward = forward;
4769 mp->learn = learn;
4770 mp->arp_term = arp_term;
4771 mp->is_add = is_add;
4772 mp->mac_age = (u8) mac_age;
Jerome Tollet50570ec2017-09-14 12:53:56 +01004773 if (bd_tag)
John Lo70bfcaf2017-11-14 13:19:26 -05004774 {
4775 clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
4776 mp->bd_tag[vec_len (bd_tag)] = 0;
4777 }
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004778 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06004779 W (ret);
Jerome Tollet50570ec2017-09-14 12:53:56 +01004780
4781done:
4782 vec_free (bd_tag);
Jon Loeliger56c7b012017-02-01 12:31:41 -06004783 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004784}
4785
4786static int
Eyal Barif24991c2017-04-05 05:33:21 +03004787api_l2fib_flush_bd (vat_main_t * vam)
4788{
4789 unformat_input_t *i = vam->input;
4790 vl_api_l2fib_flush_bd_t *mp;
4791 u32 bd_id = ~0;
4792 int ret;
4793
4794 /* Parse args required to build the message */
4795 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4796 {
4797 if (unformat (i, "bd_id %d", &bd_id));
4798 else
4799 break;
4800 }
4801
4802 if (bd_id == ~0)
4803 {
4804 errmsg ("missing bridge domain");
4805 return -99;
4806 }
4807
4808 M (L2FIB_FLUSH_BD, mp);
4809
4810 mp->bd_id = htonl (bd_id);
4811
4812 S (mp);
4813 W (ret);
4814 return ret;
4815}
4816
4817static int
4818api_l2fib_flush_int (vat_main_t * vam)
4819{
4820 unformat_input_t *i = vam->input;
4821 vl_api_l2fib_flush_int_t *mp;
4822 u32 sw_if_index = ~0;
4823 int ret;
4824
4825 /* Parse args required to build the message */
4826 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4827 {
4828 if (unformat (i, "sw_if_index %d", &sw_if_index));
4829 else
4830 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
4831 else
4832 break;
4833 }
4834
4835 if (sw_if_index == ~0)
4836 {
4837 errmsg ("missing interface name or sw_if_index");
4838 return -99;
4839 }
4840
4841 M (L2FIB_FLUSH_INT, mp);
4842
4843 mp->sw_if_index = ntohl (sw_if_index);
4844
4845 S (mp);
4846 W (ret);
4847 return ret;
4848}
4849
4850static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01004851api_l2fib_add_del (vat_main_t * vam)
4852{
4853 unformat_input_t *i = vam->input;
4854 vl_api_l2fib_add_del_t *mp;
4855 f64 timeout;
Mohsin Kazmi57938f62017-10-27 21:28:07 +02004856 u8 mac[6] = { 0 };
Damjan Marion7cd468a2016-12-19 23:05:39 +01004857 u8 mac_set = 0;
4858 u32 bd_id;
4859 u8 bd_id_set = 0;
John Lo7dbd7262018-05-31 10:25:18 -04004860 u32 sw_if_index = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004861 u8 sw_if_index_set = 0;
4862 u8 is_add = 1;
4863 u8 static_mac = 0;
4864 u8 filter_mac = 0;
4865 u8 bvi_mac = 0;
4866 int count = 1;
4867 f64 before = 0;
4868 int j;
4869
4870 /* Parse args required to build the message */
4871 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4872 {
Mohsin Kazmi57938f62017-10-27 21:28:07 +02004873 if (unformat (i, "mac %U", unformat_ethernet_address, mac))
Damjan Marion7cd468a2016-12-19 23:05:39 +01004874 mac_set = 1;
4875 else if (unformat (i, "bd_id %d", &bd_id))
4876 bd_id_set = 1;
4877 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4878 sw_if_index_set = 1;
4879 else if (unformat (i, "sw_if"))
4880 {
4881 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4882 {
4883 if (unformat
4884 (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4885 sw_if_index_set = 1;
4886 }
4887 else
4888 break;
4889 }
4890 else if (unformat (i, "static"))
4891 static_mac = 1;
4892 else if (unformat (i, "filter"))
4893 {
4894 filter_mac = 1;
4895 static_mac = 1;
4896 }
4897 else if (unformat (i, "bvi"))
4898 {
4899 bvi_mac = 1;
4900 static_mac = 1;
4901 }
4902 else if (unformat (i, "del"))
4903 is_add = 0;
4904 else if (unformat (i, "count %d", &count))
4905 ;
4906 else
4907 break;
4908 }
4909
4910 if (mac_set == 0)
4911 {
4912 errmsg ("missing mac address");
4913 return -99;
4914 }
4915
4916 if (bd_id_set == 0)
4917 {
4918 errmsg ("missing bridge domain");
4919 return -99;
4920 }
4921
4922 if (is_add && sw_if_index_set == 0 && filter_mac == 0)
4923 {
4924 errmsg ("missing interface name or sw_if_index");
4925 return -99;
4926 }
4927
4928 if (count > 1)
4929 {
4930 /* Turn on async mode */
4931 vam->async_mode = 1;
4932 vam->async_errors = 0;
4933 before = vat_time_now (vam);
4934 }
4935
4936 for (j = 0; j < count; j++)
4937 {
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004938 M (L2FIB_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004939
Mohsin Kazmi57938f62017-10-27 21:28:07 +02004940 clib_memcpy (mp->mac, mac, 6);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004941 mp->bd_id = ntohl (bd_id);
4942 mp->is_add = is_add;
John Lo7dbd7262018-05-31 10:25:18 -04004943 mp->sw_if_index = ntohl (sw_if_index);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004944
4945 if (is_add)
4946 {
Damjan Marion7cd468a2016-12-19 23:05:39 +01004947 mp->static_mac = static_mac;
4948 mp->filter_mac = filter_mac;
4949 mp->bvi_mac = bvi_mac;
4950 }
Mohsin Kazmi57938f62017-10-27 21:28:07 +02004951 increment_mac_address (mac);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004952 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004953 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004954 }
4955
4956 if (count > 1)
4957 {
Jon Loeliger2d23eca2017-02-01 13:09:58 -06004958 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004959 f64 after;
4960
4961 /* Shut off async mode */
4962 vam->async_mode = 0;
4963
Dave Barach59b25652017-09-10 15:04:27 -04004964 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06004965 S (mp_ping);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004966
4967 timeout = vat_time_now (vam) + 1.0;
4968 while (vat_time_now (vam) < timeout)
4969 if (vam->result_ready == 1)
4970 goto out;
4971 vam->retval = -99;
4972
4973 out:
4974 if (vam->retval == -99)
4975 errmsg ("timeout");
4976
4977 if (vam->async_errors > 0)
4978 {
4979 errmsg ("%d asynchronous errors", vam->async_errors);
4980 vam->retval = -98;
4981 }
4982 vam->async_errors = 0;
4983 after = vat_time_now (vam);
4984
4985 print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
4986 count, after - before, count / (after - before));
4987 }
4988 else
4989 {
Jon Loeliger56c7b012017-02-01 12:31:41 -06004990 int ret;
4991
Damjan Marion7cd468a2016-12-19 23:05:39 +01004992 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06004993 W (ret);
4994 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004995 }
4996 /* Return the good/bad news */
4997 return (vam->retval);
4998}
4999
5000static int
Eyal Barifead6702017-04-04 04:46:32 +03005001api_bridge_domain_set_mac_age (vat_main_t * vam)
5002{
5003 unformat_input_t *i = vam->input;
5004 vl_api_bridge_domain_set_mac_age_t *mp;
5005 u32 bd_id = ~0;
5006 u32 mac_age = 0;
5007 int ret;
5008
5009 /* Parse args required to build the message */
5010 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5011 {
5012 if (unformat (i, "bd_id %d", &bd_id));
5013 else if (unformat (i, "mac-age %d", &mac_age));
5014 else
5015 break;
5016 }
5017
5018 if (bd_id == ~0)
5019 {
5020 errmsg ("missing bridge domain");
5021 return -99;
5022 }
5023
5024 if (mac_age > 255)
5025 {
5026 errmsg ("mac age must be less than 256 ");
5027 return -99;
5028 }
5029
5030 M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
5031
5032 mp->bd_id = htonl (bd_id);
5033 mp->mac_age = (u8) mac_age;
5034
5035 S (mp);
5036 W (ret);
5037 return ret;
5038}
5039
5040static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01005041api_l2_flags (vat_main_t * vam)
5042{
5043 unformat_input_t *i = vam->input;
5044 vl_api_l2_flags_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005045 u32 sw_if_index;
John Lo8d00fff2017-08-03 00:35:36 -04005046 u32 flags = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005047 u8 sw_if_index_set = 0;
John Lo8d00fff2017-08-03 00:35:36 -04005048 u8 is_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005049 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005050
5051 /* Parse args required to build the message */
5052 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5053 {
5054 if (unformat (i, "sw_if_index %d", &sw_if_index))
5055 sw_if_index_set = 1;
5056 else if (unformat (i, "sw_if"))
5057 {
5058 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5059 {
5060 if (unformat
5061 (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5062 sw_if_index_set = 1;
5063 }
5064 else
5065 break;
5066 }
5067 else if (unformat (i, "learn"))
John Lo8d00fff2017-08-03 00:35:36 -04005068 flags |= L2_LEARN;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005069 else if (unformat (i, "forward"))
John Lo8d00fff2017-08-03 00:35:36 -04005070 flags |= L2_FWD;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005071 else if (unformat (i, "flood"))
John Lo8d00fff2017-08-03 00:35:36 -04005072 flags |= L2_FLOOD;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005073 else if (unformat (i, "uu-flood"))
John Lo8d00fff2017-08-03 00:35:36 -04005074 flags |= L2_UU_FLOOD;
5075 else if (unformat (i, "arp-term"))
5076 flags |= L2_ARP_TERM;
5077 else if (unformat (i, "off"))
5078 is_set = 0;
5079 else if (unformat (i, "disable"))
5080 is_set = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005081 else
5082 break;
5083 }
5084
5085 if (sw_if_index_set == 0)
5086 {
5087 errmsg ("missing interface name or sw_if_index");
5088 return -99;
5089 }
5090
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005091 M (L2_FLAGS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005092
5093 mp->sw_if_index = ntohl (sw_if_index);
John Lo8d00fff2017-08-03 00:35:36 -04005094 mp->feature_bitmap = ntohl (flags);
5095 mp->is_set = is_set;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005096
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005097 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06005098 W (ret);
5099 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005100}
5101
5102static int
5103api_bridge_flags (vat_main_t * vam)
5104{
5105 unformat_input_t *i = vam->input;
5106 vl_api_bridge_flags_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005107 u32 bd_id;
5108 u8 bd_id_set = 0;
5109 u8 is_set = 1;
Neale Rannsb4743802018-09-05 09:13:57 -07005110 bd_flags_t flags = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005111 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005112
5113 /* Parse args required to build the message */
5114 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5115 {
5116 if (unformat (i, "bd_id %d", &bd_id))
5117 bd_id_set = 1;
5118 else if (unformat (i, "learn"))
Neale Rannsb4743802018-09-05 09:13:57 -07005119 flags |= BRIDGE_API_FLAG_LEARN;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005120 else if (unformat (i, "forward"))
Neale Rannsb4743802018-09-05 09:13:57 -07005121 flags |= BRIDGE_API_FLAG_FWD;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005122 else if (unformat (i, "flood"))
Neale Rannsb4743802018-09-05 09:13:57 -07005123 flags |= BRIDGE_API_FLAG_FLOOD;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005124 else if (unformat (i, "uu-flood"))
Neale Rannsb4743802018-09-05 09:13:57 -07005125 flags |= BRIDGE_API_FLAG_UU_FLOOD;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005126 else if (unformat (i, "arp-term"))
Neale Rannsb4743802018-09-05 09:13:57 -07005127 flags |= BRIDGE_API_FLAG_ARP_TERM;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005128 else if (unformat (i, "off"))
5129 is_set = 0;
5130 else if (unformat (i, "disable"))
5131 is_set = 0;
5132 else
5133 break;
5134 }
5135
5136 if (bd_id_set == 0)
5137 {
5138 errmsg ("missing bridge domain");
5139 return -99;
5140 }
5141
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005142 M (BRIDGE_FLAGS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005143
5144 mp->bd_id = ntohl (bd_id);
Neale Rannsb4743802018-09-05 09:13:57 -07005145 mp->flags = ntohl (flags);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005146 mp->is_set = is_set;
5147
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005148 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06005149 W (ret);
5150 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005151}
5152
5153static int
5154api_bd_ip_mac_add_del (vat_main_t * vam)
5155{
Neale Ranns4d5b9172018-10-24 02:57:49 -07005156 vl_api_address_t ip = VL_API_ZERO_ADDRESS;
Ole Troan8006c6a2018-12-17 12:02:26 +01005157 vl_api_mac_address_t mac = { 0 };
Damjan Marion7cd468a2016-12-19 23:05:39 +01005158 unformat_input_t *i = vam->input;
5159 vl_api_bd_ip_mac_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005160 u32 bd_id;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005161 u8 is_add = 1;
5162 u8 bd_id_set = 0;
5163 u8 ip_set = 0;
5164 u8 mac_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005165 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005166
5167
5168 /* Parse args required to build the message */
5169 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5170 {
5171 if (unformat (i, "bd_id %d", &bd_id))
5172 {
5173 bd_id_set++;
5174 }
Neale Ranns4d5b9172018-10-24 02:57:49 -07005175 else if (unformat (i, "%U", unformat_vl_api_address, &ip))
Damjan Marion7cd468a2016-12-19 23:05:39 +01005176 {
5177 ip_set++;
5178 }
Neale Ranns4d5b9172018-10-24 02:57:49 -07005179 else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
Damjan Marion7cd468a2016-12-19 23:05:39 +01005180 {
5181 mac_set++;
5182 }
5183 else if (unformat (i, "del"))
5184 is_add = 0;
5185 else
5186 break;
5187 }
5188
5189 if (bd_id_set == 0)
5190 {
5191 errmsg ("missing bridge domain");
5192 return -99;
5193 }
5194 else if (ip_set == 0)
5195 {
5196 errmsg ("missing IP address");
5197 return -99;
5198 }
5199 else if (mac_set == 0)
5200 {
5201 errmsg ("missing MAC address");
5202 return -99;
5203 }
5204
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005205 M (BD_IP_MAC_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005206
Neale Rannsbc764c82019-06-19 07:07:13 -07005207 mp->entry.bd_id = ntohl (bd_id);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005208 mp->is_add = is_add;
Neale Ranns4d5b9172018-10-24 02:57:49 -07005209
Neale Rannsbc764c82019-06-19 07:07:13 -07005210 clib_memcpy (&mp->entry.ip, &ip, sizeof (ip));
5211 clib_memcpy (&mp->entry.mac, &mac, sizeof (mac));
Neale Ranns4d5b9172018-10-24 02:57:49 -07005212
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005213 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06005214 W (ret);
5215 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005216}
5217
John Loe26c81f2019-01-07 15:16:33 -05005218static int
5219api_bd_ip_mac_flush (vat_main_t * vam)
5220{
5221 unformat_input_t *i = vam->input;
5222 vl_api_bd_ip_mac_flush_t *mp;
5223 u32 bd_id;
5224 u8 bd_id_set = 0;
5225 int ret;
5226
5227 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5228 {
5229 if (unformat (i, "bd_id %d", &bd_id))
5230 {
5231 bd_id_set++;
5232 }
5233 else
5234 break;
5235 }
5236
5237 if (bd_id_set == 0)
5238 {
5239 errmsg ("missing bridge domain");
5240 return -99;
5241 }
5242
5243 M (BD_IP_MAC_FLUSH, mp);
5244
5245 mp->bd_id = ntohl (bd_id);
5246
5247 S (mp);
5248 W (ret);
5249 return ret;
5250}
5251
Mohsin Kazmi5d82d2f2018-08-13 19:17:54 +02005252static void vl_api_bd_ip_mac_details_t_handler
5253 (vl_api_bd_ip_mac_details_t * mp)
5254{
5255 vat_main_t *vam = &vat_main;
Mohsin Kazmi5d82d2f2018-08-13 19:17:54 +02005256
5257 print (vam->ofp,
Neale Rannsbc764c82019-06-19 07:07:13 -07005258 "\n%-5d %U %U",
5259 ntohl (mp->entry.bd_id),
5260 format_vl_api_mac_address, mp->entry.mac,
5261 format_vl_api_address, &mp->entry.ip);
Mohsin Kazmi5d82d2f2018-08-13 19:17:54 +02005262}
5263
5264static void vl_api_bd_ip_mac_details_t_handler_json
5265 (vl_api_bd_ip_mac_details_t * mp)
5266{
5267 vat_main_t *vam = &vat_main;
5268 vat_json_node_t *node = NULL;
5269
5270 if (VAT_JSON_ARRAY != vam->json_tree.type)
5271 {
5272 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5273 vat_json_init_array (&vam->json_tree);
5274 }
5275 node = vat_json_array_add (&vam->json_tree);
5276
5277 vat_json_init_object (node);
Neale Rannsbc764c82019-06-19 07:07:13 -07005278 vat_json_object_add_uint (node, "bd_id", ntohl (mp->entry.bd_id));
Mohsin Kazmi5d82d2f2018-08-13 19:17:54 +02005279 vat_json_object_add_string_copy (node, "mac_address",
Neale Rannsbc764c82019-06-19 07:07:13 -07005280 format (0, "%U", format_vl_api_mac_address,
5281 &mp->entry.mac));
Mohsin Kazmi5d82d2f2018-08-13 19:17:54 +02005282 u8 *ip = 0;
5283
Neale Rannsbc764c82019-06-19 07:07:13 -07005284 ip = format (0, "%U", format_vl_api_address, &mp->entry.ip);
Mohsin Kazmi5d82d2f2018-08-13 19:17:54 +02005285 vat_json_object_add_string_copy (node, "ip_address", ip);
5286 vec_free (ip);
5287}
5288
5289static int
5290api_bd_ip_mac_dump (vat_main_t * vam)
5291{
5292 unformat_input_t *i = vam->input;
5293 vl_api_bd_ip_mac_dump_t *mp;
5294 vl_api_control_ping_t *mp_ping;
5295 int ret;
5296 u32 bd_id;
5297 u8 bd_id_set = 0;
5298
5299 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5300 {
5301 if (unformat (i, "bd_id %d", &bd_id))
5302 {
5303 bd_id_set++;
5304 }
5305 else
5306 break;
5307 }
5308
5309 print (vam->ofp,
5310 "\n%-5s %-7s %-20s %-30s",
5311 "bd_id", "is_ipv6", "mac_address", "ip_address");
5312
5313 /* Dump Bridge Domain Ip to Mac entries */
5314 M (BD_IP_MAC_DUMP, mp);
5315
5316 if (bd_id_set)
5317 mp->bd_id = htonl (bd_id);
5318 else
5319 mp->bd_id = ~0;
5320
5321 S (mp);
5322
5323 /* Use a control ping for synchronization */
5324 MPING (CONTROL_PING, mp_ping);
5325 S (mp_ping);
5326
5327 W (ret);
5328 return ret;
5329}
5330
Damjan Marion7cd468a2016-12-19 23:05:39 +01005331static int
Damjan Marion8389fb92017-10-13 18:29:53 +02005332api_tap_create_v2 (vat_main_t * vam)
5333{
5334 unformat_input_t *i = vam->input;
5335 vl_api_tap_create_v2_t *mp;
5336 u8 mac_address[6];
5337 u8 random_mac = 1;
Damjan Marion2df39092017-12-04 20:03:37 +01005338 u32 id = ~0;
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005339 u32 num_rx_queues = 0;
Damjan Marion2df39092017-12-04 20:03:37 +01005340 u8 *host_if_name = 0;
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005341 u8 host_if_name_set = 0;
Damjan Marion2df39092017-12-04 20:03:37 +01005342 u8 *host_ns = 0;
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005343 u8 host_ns_set = 0;
Damjan Marion2df39092017-12-04 20:03:37 +01005344 u8 host_mac_addr[6];
5345 u8 host_mac_addr_set = 0;
Damjan Marion91c6ef72017-12-01 13:34:24 +01005346 u8 *host_bridge = 0;
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005347 u8 host_bridge_set = 0;
5348 u8 host_ip4_prefix_set = 0;
5349 u8 host_ip6_prefix_set = 0;
Damjan Marion91c6ef72017-12-01 13:34:24 +01005350 ip4_address_t host_ip4_addr;
Damjan Marion7866c452018-01-18 13:35:11 +01005351 ip4_address_t host_ip4_gw;
5352 u8 host_ip4_gw_set = 0;
Damjan Marion91c6ef72017-12-01 13:34:24 +01005353 u32 host_ip4_prefix_len = 0;
5354 ip6_address_t host_ip6_addr;
Damjan Marion7866c452018-01-18 13:35:11 +01005355 ip6_address_t host_ip6_gw;
5356 u8 host_ip6_gw_set = 0;
Damjan Marion91c6ef72017-12-01 13:34:24 +01005357 u32 host_ip6_prefix_len = 0;
Mohsin Kazmi97d54ed2019-06-10 11:20:15 +02005358 u32 host_mtu_size = 0;
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005359 u8 host_mtu_set = 0;
Mohsin Kazmi97d54ed2019-06-10 11:20:15 +02005360 u32 tap_flags = 0;
Damjan Marion8389fb92017-10-13 18:29:53 +02005361 int ret;
Steven9e635692018-03-01 09:36:01 -08005362 u32 rx_ring_sz = 0, tx_ring_sz = 0;
Damjan Marion8389fb92017-10-13 18:29:53 +02005363
Dave Barachb7b92992018-10-17 10:38:51 -04005364 clib_memset (mac_address, 0, sizeof (mac_address));
Damjan Marion8389fb92017-10-13 18:29:53 +02005365
5366 /* Parse args required to build the message */
5367 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5368 {
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005369 if (unformat (i, "id %u", &id))
Damjan Marion91c6ef72017-12-01 13:34:24 +01005370 ;
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005371 else
5372 if (unformat
5373 (i, "hw-addr %U", unformat_ethernet_address, mac_address))
5374 random_mac = 0;
Damjan Marion2df39092017-12-04 20:03:37 +01005375 else if (unformat (i, "host-if-name %s", &host_if_name))
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005376 host_if_name_set = 1;
5377 else if (unformat (i, "num-rx-queues %u", &num_rx_queues))
Damjan Marion91c6ef72017-12-01 13:34:24 +01005378 ;
Damjan Marion2df39092017-12-04 20:03:37 +01005379 else if (unformat (i, "host-ns %s", &host_ns))
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005380 host_ns_set = 1;
Damjan Marion2df39092017-12-04 20:03:37 +01005381 else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
5382 host_mac_addr))
5383 host_mac_addr_set = 1;
Damjan Marion91c6ef72017-12-01 13:34:24 +01005384 else if (unformat (i, "host-bridge %s", &host_bridge))
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005385 host_bridge_set = 1;
5386 else if (unformat (i, "host-ip4-addr %U/%u", unformat_ip4_address,
Damjan Marion91c6ef72017-12-01 13:34:24 +01005387 &host_ip4_addr, &host_ip4_prefix_len))
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005388 host_ip4_prefix_set = 1;
5389 else if (unformat (i, "host-ip6-addr %U/%u", unformat_ip6_address,
Damjan Marion91c6ef72017-12-01 13:34:24 +01005390 &host_ip6_addr, &host_ip6_prefix_len))
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005391 host_ip6_prefix_set = 1;
Damjan Marion7866c452018-01-18 13:35:11 +01005392 else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
5393 &host_ip4_gw))
5394 host_ip4_gw_set = 1;
5395 else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
5396 &host_ip6_gw))
5397 host_ip6_gw_set = 1;
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005398 else if (unformat (i, "rx-ring-size %u", &rx_ring_sz))
Damjan Marion8389fb92017-10-13 18:29:53 +02005399 ;
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005400 else if (unformat (i, "tx-ring-size %u", &tx_ring_sz))
Damjan Marion8389fb92017-10-13 18:29:53 +02005401 ;
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005402 else if (unformat (i, "host-mtu-size %u", &host_mtu_size))
Mohsin Kazmi97d54ed2019-06-10 11:20:15 +02005403 host_mtu_set = 1;
5404 else if (unformat (i, "no-gso"))
Mohsin Kazmid88fc0f2020-04-30 19:05:56 +02005405 tap_flags &= ~TAP_API_FLAG_GSO;
Mohsin Kazmi97d54ed2019-06-10 11:20:15 +02005406 else if (unformat (i, "gso"))
Mohsin Kazmid88fc0f2020-04-30 19:05:56 +02005407 tap_flags |= TAP_API_FLAG_GSO;
Mohsin Kazmiba0061f2019-12-18 17:08:54 +01005408 else if (unformat (i, "csum-offload"))
Mohsin Kazmid88fc0f2020-04-30 19:05:56 +02005409 tap_flags |= TAP_API_FLAG_CSUM_OFFLOAD;
Mohsin Kazmib49bc1a2020-02-14 17:51:04 +00005410 else if (unformat (i, "persist"))
Mohsin Kazmid88fc0f2020-04-30 19:05:56 +02005411 tap_flags |= TAP_API_FLAG_PERSIST;
Mohsin Kazmib49bc1a2020-02-14 17:51:04 +00005412 else if (unformat (i, "attach"))
Mohsin Kazmid88fc0f2020-04-30 19:05:56 +02005413 tap_flags |= TAP_API_FLAG_ATTACH;
5414 else if (unformat (i, "tun"))
5415 tap_flags |= TAP_API_FLAG_TUN;
5416 else if (unformat (i, "gro-coalesce"))
5417 tap_flags |= TAP_API_FLAG_GRO_COALESCE;
Mohsin Kazmi50bd1652020-08-26 11:07:48 +02005418 else if (unformat (i, "packed"))
5419 tap_flags |= TAP_API_FLAG_PACKED;
5420 else if (unformat (i, "in-order"))
5421 tap_flags |= TAP_API_FLAG_IN_ORDER;
Damjan Marion8389fb92017-10-13 18:29:53 +02005422 else
5423 break;
5424 }
5425
Damjan Marion2df39092017-12-04 20:03:37 +01005426 if (vec_len (host_if_name) > 63)
Damjan Marion8389fb92017-10-13 18:29:53 +02005427 {
5428 errmsg ("tap name too long. ");
5429 return -99;
5430 }
Damjan Marion2df39092017-12-04 20:03:37 +01005431 if (vec_len (host_ns) > 63)
Damjan Marion8389fb92017-10-13 18:29:53 +02005432 {
5433 errmsg ("host name space too long. ");
5434 return -99;
5435 }
Damjan Marion91c6ef72017-12-01 13:34:24 +01005436 if (vec_len (host_bridge) > 63)
5437 {
5438 errmsg ("host bridge name too long. ");
5439 return -99;
5440 }
5441 if (host_ip4_prefix_len > 32)
5442 {
5443 errmsg ("host ip4 prefix length not valid. ");
5444 return -99;
5445 }
5446 if (host_ip6_prefix_len > 128)
5447 {
5448 errmsg ("host ip6 prefix length not valid. ");
5449 return -99;
5450 }
Damjan Marion8389fb92017-10-13 18:29:53 +02005451 if (!is_pow2 (rx_ring_sz))
5452 {
5453 errmsg ("rx ring size must be power of 2. ");
5454 return -99;
5455 }
5456 if (rx_ring_sz > 32768)
5457 {
5458 errmsg ("rx ring size must be 32768 or lower. ");
5459 return -99;
5460 }
5461 if (!is_pow2 (tx_ring_sz))
5462 {
5463 errmsg ("tx ring size must be power of 2. ");
5464 return -99;
5465 }
5466 if (tx_ring_sz > 32768)
5467 {
5468 errmsg ("tx ring size must be 32768 or lower. ");
5469 return -99;
5470 }
Mohsin Kazmi97d54ed2019-06-10 11:20:15 +02005471 if (host_mtu_set && (host_mtu_size < 64 || host_mtu_size > 65355))
5472 {
5473 errmsg ("host MTU size must be in between 64 and 65355. ");
5474 return -99;
5475 }
Damjan Marion8389fb92017-10-13 18:29:53 +02005476
Damjan Marion8389fb92017-10-13 18:29:53 +02005477 /* Construct the API message */
5478 M (TAP_CREATE_V2, mp);
5479
Steven9e635692018-03-01 09:36:01 -08005480 mp->id = ntohl (id);
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005481 mp->use_random_mac = random_mac;
5482 mp->num_rx_queues = (u8) num_rx_queues;
Steven9e635692018-03-01 09:36:01 -08005483 mp->tx_ring_sz = ntohs (tx_ring_sz);
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005484 mp->rx_ring_sz = ntohs (rx_ring_sz);
Mohsin Kazmi97d54ed2019-06-10 11:20:15 +02005485 mp->host_mtu_set = host_mtu_set;
5486 mp->host_mtu_size = ntohl (host_mtu_size);
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005487 mp->host_mac_addr_set = host_mac_addr_set;
5488 mp->host_ip4_prefix_set = host_ip4_prefix_set;
5489 mp->host_ip6_prefix_set = host_ip6_prefix_set;
5490 mp->host_ip4_gw_set = host_ip4_gw_set;
5491 mp->host_ip6_gw_set = host_ip6_gw_set;
Mohsin Kazmi97d54ed2019-06-10 11:20:15 +02005492 mp->tap_flags = ntohl (tap_flags);
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005493 mp->host_namespace_set = host_ns_set;
5494 mp->host_if_name_set = host_if_name_set;
5495 mp->host_bridge_set = host_bridge_set;
Damjan Marion2df39092017-12-04 20:03:37 +01005496
Steven9e635692018-03-01 09:36:01 -08005497 if (random_mac == 0)
Damjan Marion2df39092017-12-04 20:03:37 +01005498 clib_memcpy (mp->mac_address, mac_address, 6);
5499 if (host_mac_addr_set)
5500 clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005501 if (host_if_name_set)
Damjan Marion2df39092017-12-04 20:03:37 +01005502 clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005503 if (host_ns_set)
Damjan Marion2df39092017-12-04 20:03:37 +01005504 clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005505 if (host_bridge_set)
Damjan Marion91c6ef72017-12-01 13:34:24 +01005506 clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005507 if (host_ip4_prefix_set)
5508 {
5509 clib_memcpy (mp->host_ip4_prefix.address, &host_ip4_addr, 4);
5510 mp->host_ip4_prefix.len = (u8) host_ip4_prefix_len;
5511 }
5512 if (host_ip6_prefix_set)
5513 {
5514 clib_memcpy (mp->host_ip6_prefix.address, &host_ip6_addr, 16);
5515 mp->host_ip6_prefix.len = (u8) host_ip6_prefix_len;
5516 }
Damjan Marion7866c452018-01-18 13:35:11 +01005517 if (host_ip4_gw_set)
5518 clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
5519 if (host_ip6_gw_set)
5520 clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
Damjan Marion8389fb92017-10-13 18:29:53 +02005521
Damjan Marion2df39092017-12-04 20:03:37 +01005522 vec_free (host_ns);
5523 vec_free (host_if_name);
5524 vec_free (host_bridge);
Damjan Marion8389fb92017-10-13 18:29:53 +02005525
5526 /* send it... */
5527 S (mp);
5528
5529 /* Wait for a reply... */
5530 W (ret);
5531 return ret;
5532}
5533
5534static int
5535api_tap_delete_v2 (vat_main_t * vam)
5536{
5537 unformat_input_t *i = vam->input;
5538 vl_api_tap_delete_v2_t *mp;
5539 u32 sw_if_index = ~0;
5540 u8 sw_if_index_set = 0;
5541 int ret;
5542
5543 /* Parse args required to build the message */
5544 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5545 {
5546 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5547 sw_if_index_set = 1;
5548 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5549 sw_if_index_set = 1;
5550 else
5551 break;
5552 }
5553
5554 if (sw_if_index_set == 0)
5555 {
5556 errmsg ("missing vpp interface name. ");
5557 return -99;
5558 }
5559
5560 /* Construct the API message */
5561 M (TAP_DELETE_V2, mp);
5562
5563 mp->sw_if_index = ntohl (sw_if_index);
5564
5565 /* send it... */
5566 S (mp);
5567
5568 /* Wait for a reply... */
5569 W (ret);
5570 return ret;
5571}
5572
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005573uword
jialv01082ebeb2019-09-10 00:23:55 +08005574unformat_vlib_pci_addr (unformat_input_t * input, va_list * args)
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005575{
jialv01082ebeb2019-09-10 00:23:55 +08005576 vlib_pci_addr_t *addr = va_arg (*args, vlib_pci_addr_t *);
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005577 u32 x[4];
5578
5579 if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
5580 return 0;
5581
5582 addr->domain = x[0];
5583 addr->bus = x[1];
5584 addr->slot = x[2];
5585 addr->function = x[3];
5586
5587 return 1;
5588}
5589
5590static int
Mohsin Kazmi518251b2020-09-01 17:17:44 +00005591api_virtio_pci_create_v2 (vat_main_t * vam)
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005592{
5593 unformat_input_t *i = vam->input;
Mohsin Kazmi518251b2020-09-01 17:17:44 +00005594 vl_api_virtio_pci_create_v2_t *mp;
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005595 u8 mac_address[6];
5596 u8 random_mac = 1;
5597 u32 pci_addr = 0;
5598 u64 features = (u64) ~ (0ULL);
Mohsin Kazmi518251b2020-09-01 17:17:44 +00005599 u32 virtio_flags = 0;
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005600 int ret;
5601
5602 clib_memset (mac_address, 0, sizeof (mac_address));
5603
5604 /* Parse args required to build the message */
5605 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5606 {
5607 if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
5608 {
5609 random_mac = 0;
5610 }
jialv01082ebeb2019-09-10 00:23:55 +08005611 else if (unformat (i, "pci-addr %U", unformat_vlib_pci_addr, &pci_addr))
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005612 ;
5613 else if (unformat (i, "features 0x%llx", &features))
5614 ;
Mohsin Kazmibbd6b742019-05-02 13:54:59 +02005615 else if (unformat (i, "gso-enabled"))
Mohsin Kazmi518251b2020-09-01 17:17:44 +00005616 virtio_flags |= VIRTIO_API_FLAG_GSO;
Mohsin Kazmi6d4af892020-01-03 15:11:53 +00005617 else if (unformat (i, "csum-offload-enabled"))
Mohsin Kazmi518251b2020-09-01 17:17:44 +00005618 virtio_flags |= VIRTIO_API_FLAG_CSUM_OFFLOAD;
5619 else if (unformat (i, "gro-coalesce"))
5620 virtio_flags |= VIRTIO_API_FLAG_GRO_COALESCE;
5621 else if (unformat (i, "packed"))
5622 virtio_flags |= VIRTIO_API_FLAG_PACKED;
5623 else if (unformat (i, "in-order"))
5624 virtio_flags |= VIRTIO_API_FLAG_IN_ORDER;
Mohsin Kazmie347acb2020-09-28 10:26:33 +00005625 else if (unformat (i, "buffering"))
5626 virtio_flags |= VIRTIO_API_FLAG_BUFFERING;
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005627 else
5628 break;
5629 }
5630
5631 if (pci_addr == 0)
5632 {
5633 errmsg ("pci address must be non zero. ");
5634 return -99;
5635 }
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005636
5637 /* Construct the API message */
Mohsin Kazmi518251b2020-09-01 17:17:44 +00005638 M (VIRTIO_PCI_CREATE_V2, mp);
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005639
5640 mp->use_random_mac = random_mac;
5641
Jakub Grajciar2c504f82019-09-26 10:34:41 +02005642 mp->pci_addr.domain = htons (((vlib_pci_addr_t) pci_addr).domain);
5643 mp->pci_addr.bus = ((vlib_pci_addr_t) pci_addr).bus;
5644 mp->pci_addr.slot = ((vlib_pci_addr_t) pci_addr).slot;
5645 mp->pci_addr.function = ((vlib_pci_addr_t) pci_addr).function;
5646
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005647 mp->features = clib_host_to_net_u64 (features);
Mohsin Kazmi518251b2020-09-01 17:17:44 +00005648 mp->virtio_flags = clib_host_to_net_u32 (virtio_flags);
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005649
5650 if (random_mac == 0)
5651 clib_memcpy (mp->mac_address, mac_address, 6);
5652
5653 /* send it... */
5654 S (mp);
5655
5656 /* Wait for a reply... */
5657 W (ret);
5658 return ret;
5659}
5660
5661static int
5662api_virtio_pci_delete (vat_main_t * vam)
5663{
5664 unformat_input_t *i = vam->input;
5665 vl_api_virtio_pci_delete_t *mp;
5666 u32 sw_if_index = ~0;
5667 u8 sw_if_index_set = 0;
5668 int ret;
5669
5670 /* Parse args required to build the message */
5671 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5672 {
5673 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5674 sw_if_index_set = 1;
5675 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5676 sw_if_index_set = 1;
5677 else
5678 break;
5679 }
5680
5681 if (sw_if_index_set == 0)
5682 {
5683 errmsg ("missing vpp interface name. ");
5684 return -99;
5685 }
5686
5687 /* Construct the API message */
5688 M (VIRTIO_PCI_DELETE, mp);
5689
5690 mp->sw_if_index = htonl (sw_if_index);
5691
5692 /* send it... */
5693 S (mp);
5694
5695 /* Wait for a reply... */
5696 W (ret);
5697 return ret;
5698}
5699
Damjan Marion8389fb92017-10-13 18:29:53 +02005700static int
Steven9cd2d7a2017-12-20 12:43:01 -08005701api_bond_create (vat_main_t * vam)
5702{
5703 unformat_input_t *i = vam->input;
5704 vl_api_bond_create_t *mp;
5705 u8 mac_address[6];
5706 u8 custom_mac = 0;
5707 int ret;
5708 u8 mode;
5709 u8 lb;
5710 u8 mode_is_set = 0;
Alexander Chernavinad9d5282018-12-13 09:08:09 -05005711 u32 id = ~0;
Zhiyong Yang751e3f32019-06-26 05:49:14 -04005712 u8 numa_only = 0;
Steven9cd2d7a2017-12-20 12:43:01 -08005713
Dave Barachb7b92992018-10-17 10:38:51 -04005714 clib_memset (mac_address, 0, sizeof (mac_address));
Steven9cd2d7a2017-12-20 12:43:01 -08005715 lb = BOND_LB_L2;
5716
5717 /* Parse args required to build the message */
5718 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5719 {
5720 if (unformat (i, "mode %U", unformat_bond_mode, &mode))
5721 mode_is_set = 1;
5722 else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
5723 && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
5724 ;
5725 else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
5726 mac_address))
5727 custom_mac = 1;
Zhiyong Yang751e3f32019-06-26 05:49:14 -04005728 else if (unformat (i, "numa-only"))
5729 numa_only = 1;
Alexander Chernavinad9d5282018-12-13 09:08:09 -05005730 else if (unformat (i, "id %u", &id))
5731 ;
Steven9cd2d7a2017-12-20 12:43:01 -08005732 else
5733 break;
5734 }
5735
5736 if (mode_is_set == 0)
5737 {
5738 errmsg ("Missing bond mode. ");
5739 return -99;
5740 }
5741
5742 /* Construct the API message */
5743 M (BOND_CREATE, mp);
5744
5745 mp->use_custom_mac = custom_mac;
5746
Jakub Grajciar3d1ef872019-08-26 12:55:15 +02005747 mp->mode = htonl (mode);
5748 mp->lb = htonl (lb);
Alexander Chernavinad9d5282018-12-13 09:08:09 -05005749 mp->id = htonl (id);
Zhiyong Yang751e3f32019-06-26 05:49:14 -04005750 mp->numa_only = numa_only;
Steven9cd2d7a2017-12-20 12:43:01 -08005751
5752 if (custom_mac)
5753 clib_memcpy (mp->mac_address, mac_address, 6);
5754
5755 /* send it... */
5756 S (mp);
5757
5758 /* Wait for a reply... */
5759 W (ret);
5760 return ret;
5761}
5762
5763static int
Steven Luongea717862020-07-30 07:31:40 -07005764api_bond_create2 (vat_main_t * vam)
5765{
5766 unformat_input_t *i = vam->input;
5767 vl_api_bond_create2_t *mp;
5768 u8 mac_address[6];
5769 u8 custom_mac = 0;
5770 int ret;
5771 u8 mode;
5772 u8 lb;
5773 u8 mode_is_set = 0;
5774 u32 id = ~0;
5775 u8 numa_only = 0;
5776 u8 gso = 0;
5777
5778 clib_memset (mac_address, 0, sizeof (mac_address));
5779 lb = BOND_LB_L2;
5780
5781 /* Parse args required to build the message */
5782 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5783 {
5784 if (unformat (i, "mode %U", unformat_bond_mode, &mode))
5785 mode_is_set = 1;
5786 else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
5787 && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
5788 ;
5789 else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
5790 mac_address))
5791 custom_mac = 1;
5792 else if (unformat (i, "numa-only"))
5793 numa_only = 1;
5794 else if (unformat (i, "gso"))
5795 gso = 1;
5796 else if (unformat (i, "id %u", &id))
5797 ;
5798 else
5799 break;
5800 }
5801
5802 if (mode_is_set == 0)
5803 {
5804 errmsg ("Missing bond mode. ");
5805 return -99;
5806 }
5807
5808 /* Construct the API message */
5809 M (BOND_CREATE2, mp);
5810
5811 mp->use_custom_mac = custom_mac;
5812
5813 mp->mode = htonl (mode);
5814 mp->lb = htonl (lb);
5815 mp->id = htonl (id);
5816 mp->numa_only = numa_only;
5817 mp->enable_gso = gso;
5818
5819 if (custom_mac)
5820 clib_memcpy (mp->mac_address, mac_address, 6);
5821
5822 /* send it... */
5823 S (mp);
5824
5825 /* Wait for a reply... */
5826 W (ret);
5827 return ret;
5828}
5829
5830static int
Steven9cd2d7a2017-12-20 12:43:01 -08005831api_bond_delete (vat_main_t * vam)
5832{
5833 unformat_input_t *i = vam->input;
5834 vl_api_bond_delete_t *mp;
5835 u32 sw_if_index = ~0;
5836 u8 sw_if_index_set = 0;
5837 int ret;
5838
5839 /* Parse args required to build the message */
5840 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5841 {
5842 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5843 sw_if_index_set = 1;
5844 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5845 sw_if_index_set = 1;
5846 else
5847 break;
5848 }
5849
5850 if (sw_if_index_set == 0)
5851 {
5852 errmsg ("missing vpp interface name. ");
5853 return -99;
5854 }
5855
5856 /* Construct the API message */
5857 M (BOND_DELETE, mp);
5858
5859 mp->sw_if_index = ntohl (sw_if_index);
5860
5861 /* send it... */
5862 S (mp);
5863
5864 /* Wait for a reply... */
5865 W (ret);
5866 return ret;
5867}
5868
5869static int
Steven Luong4c4223e2020-07-15 08:44:54 -07005870api_bond_add_member (vat_main_t * vam)
Steven9cd2d7a2017-12-20 12:43:01 -08005871{
5872 unformat_input_t *i = vam->input;
Steven Luong4c4223e2020-07-15 08:44:54 -07005873 vl_api_bond_add_member_t *mp;
Steven9cd2d7a2017-12-20 12:43:01 -08005874 u32 bond_sw_if_index;
5875 int ret;
5876 u8 is_passive;
5877 u8 is_long_timeout;
5878 u32 bond_sw_if_index_is_set = 0;
5879 u32 sw_if_index;
5880 u8 sw_if_index_is_set = 0;
5881
5882 /* Parse args required to build the message */
5883 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5884 {
5885 if (unformat (i, "sw_if_index %d", &sw_if_index))
5886 sw_if_index_is_set = 1;
5887 else if (unformat (i, "bond %u", &bond_sw_if_index))
5888 bond_sw_if_index_is_set = 1;
5889 else if (unformat (i, "passive %d", &is_passive))
5890 ;
5891 else if (unformat (i, "long-timeout %d", &is_long_timeout))
5892 ;
5893 else
5894 break;
5895 }
5896
5897 if (bond_sw_if_index_is_set == 0)
5898 {
5899 errmsg ("Missing bond sw_if_index. ");
5900 return -99;
5901 }
5902 if (sw_if_index_is_set == 0)
5903 {
Steven Luong4c4223e2020-07-15 08:44:54 -07005904 errmsg ("Missing member sw_if_index. ");
Steven9cd2d7a2017-12-20 12:43:01 -08005905 return -99;
5906 }
5907
5908 /* Construct the API message */
Steven Luong4c4223e2020-07-15 08:44:54 -07005909 M (BOND_ADD_MEMBER, mp);
Steven9cd2d7a2017-12-20 12:43:01 -08005910
5911 mp->bond_sw_if_index = ntohl (bond_sw_if_index);
5912 mp->sw_if_index = ntohl (sw_if_index);
5913 mp->is_long_timeout = is_long_timeout;
5914 mp->is_passive = is_passive;
5915
5916 /* send it... */
5917 S (mp);
5918
5919 /* Wait for a reply... */
5920 W (ret);
5921 return ret;
5922}
5923
5924static int
Steven Luong4c4223e2020-07-15 08:44:54 -07005925api_bond_detach_member (vat_main_t * vam)
Steven9cd2d7a2017-12-20 12:43:01 -08005926{
5927 unformat_input_t *i = vam->input;
Steven Luong4c4223e2020-07-15 08:44:54 -07005928 vl_api_bond_detach_member_t *mp;
Steven9cd2d7a2017-12-20 12:43:01 -08005929 u32 sw_if_index = ~0;
5930 u8 sw_if_index_set = 0;
5931 int ret;
5932
5933 /* Parse args required to build the message */
5934 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5935 {
5936 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5937 sw_if_index_set = 1;
5938 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5939 sw_if_index_set = 1;
5940 else
5941 break;
5942 }
5943
5944 if (sw_if_index_set == 0)
5945 {
5946 errmsg ("missing vpp interface name. ");
5947 return -99;
5948 }
5949
5950 /* Construct the API message */
Steven Luong4c4223e2020-07-15 08:44:54 -07005951 M (BOND_DETACH_MEMBER, mp);
Steven9cd2d7a2017-12-20 12:43:01 -08005952
5953 mp->sw_if_index = ntohl (sw_if_index);
5954
5955 /* send it... */
5956 S (mp);
5957
5958 /* Wait for a reply... */
5959 W (ret);
5960 return ret;
5961}
5962
5963static int
Neale Ranns28ab9cc2017-08-14 07:18:42 -07005964api_ip_table_add_del (vat_main_t * vam)
5965{
5966 unformat_input_t *i = vam->input;
5967 vl_api_ip_table_add_del_t *mp;
5968 u32 table_id = ~0;
5969 u8 is_ipv6 = 0;
5970 u8 is_add = 1;
5971 int ret = 0;
5972
5973 /* Parse args required to build the message */
5974 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5975 {
5976 if (unformat (i, "ipv6"))
5977 is_ipv6 = 1;
5978 else if (unformat (i, "del"))
5979 is_add = 0;
5980 else if (unformat (i, "add"))
5981 is_add = 1;
5982 else if (unformat (i, "table %d", &table_id))
5983 ;
5984 else
5985 {
5986 clib_warning ("parse error '%U'", format_unformat_error, i);
5987 return -99;
5988 }
5989 }
5990
5991 if (~0 == table_id)
5992 {
5993 errmsg ("missing table-ID");
5994 return -99;
5995 }
5996
5997 /* Construct the API message */
5998 M (IP_TABLE_ADD_DEL, mp);
5999
Neale Ranns097fa662018-05-01 05:17:55 -07006000 mp->table.table_id = ntohl (table_id);
6001 mp->table.is_ip6 = is_ipv6;
Neale Ranns28ab9cc2017-08-14 07:18:42 -07006002 mp->is_add = is_add;
6003
6004 /* send it... */
6005 S (mp);
6006
6007 /* Wait for a reply... */
6008 W (ret);
6009
6010 return ret;
6011}
6012
Neale Ranns097fa662018-05-01 05:17:55 -07006013uword
6014unformat_fib_path (unformat_input_t * input, va_list * args)
6015{
6016 vat_main_t *vam = va_arg (*args, vat_main_t *);
6017 vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
6018 u32 weight, preference;
6019 mpls_label_t out_label;
6020
6021 clib_memset (path, 0, sizeof (*path));
6022 path->weight = 1;
6023 path->sw_if_index = ~0;
6024 path->rpf_id = ~0;
6025 path->n_labels = 0;
6026
6027 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
6028 {
6029 if (unformat (input, "%U %U",
6030 unformat_vl_api_ip4_address,
6031 &path->nh.address.ip4,
6032 api_unformat_sw_if_index, vam, &path->sw_if_index))
6033 {
6034 path->proto = FIB_API_PATH_NH_PROTO_IP4;
6035 }
6036 else if (unformat (input, "%U %U",
6037 unformat_vl_api_ip6_address,
6038 &path->nh.address.ip6,
6039 api_unformat_sw_if_index, vam, &path->sw_if_index))
6040 {
6041 path->proto = FIB_API_PATH_NH_PROTO_IP6;
6042 }
6043 else if (unformat (input, "weight %u", &weight))
6044 {
6045 path->weight = weight;
6046 }
6047 else if (unformat (input, "preference %u", &preference))
6048 {
6049 path->preference = preference;
6050 }
6051 else if (unformat (input, "%U next-hop-table %d",
6052 unformat_vl_api_ip4_address,
6053 &path->nh.address.ip4, &path->table_id))
6054 {
6055 path->proto = FIB_API_PATH_NH_PROTO_IP4;
6056 }
6057 else if (unformat (input, "%U next-hop-table %d",
6058 unformat_vl_api_ip6_address,
6059 &path->nh.address.ip6, &path->table_id))
6060 {
6061 path->proto = FIB_API_PATH_NH_PROTO_IP6;
6062 }
6063 else if (unformat (input, "%U",
6064 unformat_vl_api_ip4_address, &path->nh.address.ip4))
6065 {
6066 /*
6067 * the recursive next-hops are by default in the default table
6068 */
6069 path->table_id = 0;
6070 path->sw_if_index = ~0;
6071 path->proto = FIB_API_PATH_NH_PROTO_IP4;
6072 }
6073 else if (unformat (input, "%U",
6074 unformat_vl_api_ip6_address, &path->nh.address.ip6))
6075 {
6076 /*
6077 * the recursive next-hops are by default in the default table
6078 */
6079 path->table_id = 0;
6080 path->sw_if_index = ~0;
6081 path->proto = FIB_API_PATH_NH_PROTO_IP6;
6082 }
6083 else if (unformat (input, "resolve-via-host"))
6084 {
6085 path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
6086 }
6087 else if (unformat (input, "resolve-via-attached"))
6088 {
6089 path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
6090 }
6091 else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
6092 {
6093 path->type = FIB_API_PATH_TYPE_LOCAL;
6094 path->sw_if_index = ~0;
6095 path->proto = FIB_API_PATH_NH_PROTO_IP4;
6096 }
6097 else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
6098 {
6099 path->type = FIB_API_PATH_TYPE_LOCAL;
6100 path->sw_if_index = ~0;
6101 path->proto = FIB_API_PATH_NH_PROTO_IP6;
6102 }
6103 else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
6104 ;
6105 else if (unformat (input, "via-label %d", &path->nh.via_label))
6106 {
6107 path->proto = FIB_API_PATH_NH_PROTO_MPLS;
6108 path->sw_if_index = ~0;
6109 }
6110 else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
6111 {
6112 path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
6113 path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
6114 }
6115 else if (unformat (input, "local"))
6116 {
6117 path->type = FIB_API_PATH_TYPE_LOCAL;
6118 }
6119 else if (unformat (input, "out-labels"))
6120 {
6121 while (unformat (input, "%d", &out_label))
6122 {
6123 path->label_stack[path->n_labels].label = out_label;
6124 path->label_stack[path->n_labels].is_uniform = 0;
6125 path->label_stack[path->n_labels].ttl = 64;
6126 path->n_labels++;
6127 }
6128 }
6129 else if (unformat (input, "via"))
6130 {
6131 /* new path, back up and return */
6132 unformat_put_input (input);
6133 unformat_put_input (input);
6134 unformat_put_input (input);
6135 unformat_put_input (input);
6136 break;
6137 }
6138 else
6139 {
6140 return (0);
6141 }
6142 }
6143
6144 path->proto = ntohl (path->proto);
6145 path->type = ntohl (path->type);
6146 path->flags = ntohl (path->flags);
6147 path->table_id = ntohl (path->table_id);
6148 path->sw_if_index = ntohl (path->sw_if_index);
6149
6150 return (1);
6151}
6152
Neale Ranns28ab9cc2017-08-14 07:18:42 -07006153static int
Neale Ranns097fa662018-05-01 05:17:55 -07006154api_ip_route_add_del (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +01006155{
6156 unformat_input_t *i = vam->input;
Neale Ranns097fa662018-05-01 05:17:55 -07006157 vl_api_ip_route_add_del_t *mp;
6158 u32 vrf_id = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006159 u8 is_add = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006160 u8 is_multipath = 0;
Neale Ranns097fa662018-05-01 05:17:55 -07006161 u8 prefix_set = 0;
6162 u8 path_count = 0;
6163 vl_api_prefix_t pfx = { };
6164 vl_api_fib_path_t paths[8];
Damjan Marion7cd468a2016-12-19 23:05:39 +01006165 int count = 1;
6166 int j;
6167 f64 before = 0;
6168 u32 random_add_del = 0;
6169 u32 *random_vector = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006170 u32 random_seed = 0xdeaddabe;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006171
6172 /* Parse args required to build the message */
6173 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6174 {
Neale Ranns097fa662018-05-01 05:17:55 -07006175 if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
6176 prefix_set = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006177 else if (unformat (i, "del"))
6178 is_add = 0;
6179 else if (unformat (i, "add"))
6180 is_add = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006181 else if (unformat (i, "vrf %d", &vrf_id))
6182 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006183 else if (unformat (i, "count %d", &count))
6184 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006185 else if (unformat (i, "random"))
6186 random_add_del = 1;
Neale Ranns097fa662018-05-01 05:17:55 -07006187 else if (unformat (i, "multipath"))
6188 is_multipath = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006189 else if (unformat (i, "seed %d", &random_seed))
6190 ;
6191 else
Neale Ranns097fa662018-05-01 05:17:55 -07006192 if (unformat
6193 (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
6194 {
6195 path_count++;
6196 if (8 == path_count)
6197 {
6198 errmsg ("max 8 paths");
6199 return -99;
6200 }
6201 }
6202 else
Damjan Marion7cd468a2016-12-19 23:05:39 +01006203 {
6204 clib_warning ("parse error '%U'", format_unformat_error, i);
6205 return -99;
6206 }
6207 }
6208
Neale Ranns097fa662018-05-01 05:17:55 -07006209 if (!path_count)
Damjan Marion7cd468a2016-12-19 23:05:39 +01006210 {
Neale Ranns097fa662018-05-01 05:17:55 -07006211 errmsg ("specify a path; via ...");
Damjan Marion7cd468a2016-12-19 23:05:39 +01006212 return -99;
6213 }
Neale Ranns097fa662018-05-01 05:17:55 -07006214 if (prefix_set == 0)
Damjan Marion7cd468a2016-12-19 23:05:39 +01006215 {
Neale Ranns097fa662018-05-01 05:17:55 -07006216 errmsg ("missing prefix");
Damjan Marion7cd468a2016-12-19 23:05:39 +01006217 return -99;
6218 }
6219
6220 /* Generate a pile of unique, random routes */
6221 if (random_add_del)
6222 {
Neale Ranns097fa662018-05-01 05:17:55 -07006223 ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006224 u32 this_random_address;
Neale Ranns097fa662018-05-01 05:17:55 -07006225 uword *random_hash;
6226
Damjan Marion7cd468a2016-12-19 23:05:39 +01006227 random_hash = hash_create (count, sizeof (uword));
6228
Neale Ranns097fa662018-05-01 05:17:55 -07006229 hash_set (random_hash, i->as_u32, 1);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006230 for (j = 0; j <= count; j++)
6231 {
6232 do
6233 {
6234 this_random_address = random_u32 (&random_seed);
6235 this_random_address =
6236 clib_host_to_net_u32 (this_random_address);
6237 }
6238 while (hash_get (random_hash, this_random_address));
6239 vec_add1 (random_vector, this_random_address);
6240 hash_set (random_hash, this_random_address, 1);
6241 }
6242 hash_free (random_hash);
Neale Ranns097fa662018-05-01 05:17:55 -07006243 set_ip4_address (&pfx.address, random_vector[0]);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006244 }
6245
6246 if (count > 1)
6247 {
6248 /* Turn on async mode */
6249 vam->async_mode = 1;
6250 vam->async_errors = 0;
6251 before = vat_time_now (vam);
6252 }
6253
6254 for (j = 0; j < count; j++)
6255 {
6256 /* Construct the API message */
Neale Ranns097fa662018-05-01 05:17:55 -07006257 M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006258
6259 mp->is_add = is_add;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006260 mp->is_multipath = is_multipath;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006261
Neale Ranns097fa662018-05-01 05:17:55 -07006262 clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
6263 mp->route.table_id = ntohl (vrf_id);
6264 mp->route.n_paths = path_count;
6265
6266 clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
6267
6268 if (random_add_del)
6269 set_ip4_address (&pfx.address, random_vector[j + 1]);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006270 else
Neale Ranns097fa662018-05-01 05:17:55 -07006271 increment_address (&pfx.address);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006272 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006273 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006274 /* If we receive SIGTERM, stop now... */
6275 if (vam->do_exit)
6276 break;
6277 }
6278
6279 /* When testing multiple add/del ops, use a control-ping to sync */
6280 if (count > 1)
6281 {
Jon Loeliger2d23eca2017-02-01 13:09:58 -06006282 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006283 f64 after;
Jon Loeliger1f9191f2017-01-31 15:27:19 -06006284 f64 timeout;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006285
6286 /* Shut off async mode */
6287 vam->async_mode = 0;
6288
Dave Barach59b25652017-09-10 15:04:27 -04006289 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06006290 S (mp_ping);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006291
6292 timeout = vat_time_now (vam) + 1.0;
6293 while (vat_time_now (vam) < timeout)
6294 if (vam->result_ready == 1)
6295 goto out;
6296 vam->retval = -99;
6297
6298 out:
6299 if (vam->retval == -99)
6300 errmsg ("timeout");
6301
6302 if (vam->async_errors > 0)
6303 {
6304 errmsg ("%d asynchronous errors", vam->async_errors);
6305 vam->retval = -98;
6306 }
6307 vam->async_errors = 0;
6308 after = vat_time_now (vam);
6309
6310 /* slim chance, but we might have eaten SIGTERM on the first iteration */
6311 if (j > 0)
6312 count = j;
6313
6314 print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6315 count, after - before, count / (after - before));
6316 }
6317 else
6318 {
Jon Loeliger56c7b012017-02-01 12:31:41 -06006319 int ret;
6320
Damjan Marion7cd468a2016-12-19 23:05:39 +01006321 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06006322 W (ret);
6323 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006324 }
6325
6326 /* Return the good/bad news */
6327 return (vam->retval);
6328}
6329
6330static int
Neale Ranns32e1c012016-11-22 17:07:28 +00006331api_ip_mroute_add_del (vat_main_t * vam)
6332{
6333 unformat_input_t *i = vam->input;
Neale Ranns097fa662018-05-01 05:17:55 -07006334 u8 path_set = 0, prefix_set = 0, is_add = 1;
Neale Ranns32e1c012016-11-22 17:07:28 +00006335 vl_api_ip_mroute_add_del_t *mp;
Neale Ranns32e1c012016-11-22 17:07:28 +00006336 mfib_entry_flags_t eflags = 0;
Neale Ranns097fa662018-05-01 05:17:55 -07006337 vl_api_mfib_path_t path;
6338 vl_api_mprefix_t pfx = { };
6339 u32 vrf_id = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006340 int ret;
Neale Ranns32e1c012016-11-22 17:07:28 +00006341
6342 /* Parse args required to build the message */
6343 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6344 {
Neale Ranns097fa662018-05-01 05:17:55 -07006345 if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
Neale Ranns32e1c012016-11-22 17:07:28 +00006346 {
Neale Ranns097fa662018-05-01 05:17:55 -07006347 prefix_set = 1;
6348 pfx.grp_address_length = htons (pfx.grp_address_length);
Neale Ranns32e1c012016-11-22 17:07:28 +00006349 }
6350 else if (unformat (i, "del"))
6351 is_add = 0;
6352 else if (unformat (i, "add"))
6353 is_add = 1;
6354 else if (unformat (i, "vrf %d", &vrf_id))
6355 ;
Neale Ranns097fa662018-05-01 05:17:55 -07006356 else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
6357 path.itf_flags = htonl (path.itf_flags);
Neale Ranns32e1c012016-11-22 17:07:28 +00006358 else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
6359 ;
Neale Ranns097fa662018-05-01 05:17:55 -07006360 else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
6361 path_set = 1;
Neale Ranns32e1c012016-11-22 17:07:28 +00006362 else
6363 {
6364 clib_warning ("parse error '%U'", format_unformat_error, i);
6365 return -99;
6366 }
6367 }
6368
Neale Ranns097fa662018-05-01 05:17:55 -07006369 if (prefix_set == 0)
Neale Ranns32e1c012016-11-22 17:07:28 +00006370 {
6371 errmsg ("missing addresses\n");
6372 return -99;
6373 }
Neale Ranns097fa662018-05-01 05:17:55 -07006374 if (path_set == 0)
6375 {
6376 errmsg ("missing path\n");
6377 return -99;
6378 }
Neale Ranns32e1c012016-11-22 17:07:28 +00006379
6380 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006381 M (IP_MROUTE_ADD_DEL, mp);
Neale Ranns32e1c012016-11-22 17:07:28 +00006382
Neale Ranns32e1c012016-11-22 17:07:28 +00006383 mp->is_add = is_add;
Neale Ranns097fa662018-05-01 05:17:55 -07006384 mp->is_multipath = 1;
Neale Ranns32e1c012016-11-22 17:07:28 +00006385
Neale Ranns097fa662018-05-01 05:17:55 -07006386 clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
6387 mp->route.table_id = htonl (vrf_id);
6388 mp->route.n_paths = 1;
6389 mp->route.entry_flags = htonl (eflags);
Neale Ranns32e1c012016-11-22 17:07:28 +00006390
Neale Ranns097fa662018-05-01 05:17:55 -07006391 clib_memcpy (&mp->route.paths, &path, sizeof (path));
Neale Ranns32e1c012016-11-22 17:07:28 +00006392
6393 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006394 S (mp);
Neale Ranns32e1c012016-11-22 17:07:28 +00006395 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06006396 W (ret);
6397 return ret;
Neale Ranns32e1c012016-11-22 17:07:28 +00006398}
6399
6400static int
Neale Ranns28ab9cc2017-08-14 07:18:42 -07006401api_mpls_table_add_del (vat_main_t * vam)
6402{
6403 unformat_input_t *i = vam->input;
6404 vl_api_mpls_table_add_del_t *mp;
6405 u32 table_id = ~0;
6406 u8 is_add = 1;
6407 int ret = 0;
6408
6409 /* Parse args required to build the message */
6410 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6411 {
Florin Corasd0a59722017-10-15 17:41:21 +00006412 if (unformat (i, "table %d", &table_id))
6413 ;
6414 else if (unformat (i, "del"))
Neale Ranns28ab9cc2017-08-14 07:18:42 -07006415 is_add = 0;
6416 else if (unformat (i, "add"))
6417 is_add = 1;
6418 else
6419 {
6420 clib_warning ("parse error '%U'", format_unformat_error, i);
6421 return -99;
6422 }
6423 }
6424
6425 if (~0 == table_id)
6426 {
6427 errmsg ("missing table-ID");
6428 return -99;
6429 }
6430
6431 /* Construct the API message */
6432 M (MPLS_TABLE_ADD_DEL, mp);
6433
Neale Ranns097fa662018-05-01 05:17:55 -07006434 mp->mt_table.mt_table_id = ntohl (table_id);
Neale Ranns28ab9cc2017-08-14 07:18:42 -07006435 mp->mt_is_add = is_add;
6436
6437 /* send it... */
6438 S (mp);
6439
6440 /* Wait for a reply... */
6441 W (ret);
6442
6443 return ret;
6444}
6445
6446static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01006447api_mpls_route_add_del (vat_main_t * vam)
6448{
Neale Ranns097fa662018-05-01 05:17:55 -07006449 u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
6450 mpls_label_t local_label = MPLS_LABEL_INVALID;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006451 unformat_input_t *i = vam->input;
6452 vl_api_mpls_route_add_del_t *mp;
Neale Ranns097fa662018-05-01 05:17:55 -07006453 vl_api_fib_path_t paths[8];
6454 int count = 1, j;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006455 f64 before = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006456
6457 /* Parse args required to build the message */
6458 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6459 {
Neale Ranns097fa662018-05-01 05:17:55 -07006460 if (unformat (i, "%d", &local_label))
Damjan Marion7cd468a2016-12-19 23:05:39 +01006461 ;
6462 else if (unformat (i, "eos"))
6463 is_eos = 1;
6464 else if (unformat (i, "non-eos"))
6465 is_eos = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006466 else if (unformat (i, "del"))
6467 is_add = 0;
6468 else if (unformat (i, "add"))
6469 is_add = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006470 else if (unformat (i, "multipath"))
6471 is_multipath = 1;
6472 else if (unformat (i, "count %d", &count))
6473 ;
John Loe166fd92018-09-13 14:08:59 -04006474 else
6475 if (unformat
Neale Ranns097fa662018-05-01 05:17:55 -07006476 (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
John Loe166fd92018-09-13 14:08:59 -04006477 {
Neale Ranns097fa662018-05-01 05:17:55 -07006478 path_count++;
6479 if (8 == path_count)
6480 {
6481 errmsg ("max 8 paths");
6482 return -99;
6483 }
John Loe166fd92018-09-13 14:08:59 -04006484 }
Damjan Marion7cd468a2016-12-19 23:05:39 +01006485 else
6486 {
6487 clib_warning ("parse error '%U'", format_unformat_error, i);
6488 return -99;
6489 }
6490 }
6491
Neale Ranns097fa662018-05-01 05:17:55 -07006492 if (!path_count)
Damjan Marion7cd468a2016-12-19 23:05:39 +01006493 {
Neale Ranns097fa662018-05-01 05:17:55 -07006494 errmsg ("specify a path; via ...");
Damjan Marion7cd468a2016-12-19 23:05:39 +01006495 return -99;
6496 }
6497
6498 if (MPLS_LABEL_INVALID == local_label)
6499 {
6500 errmsg ("missing label");
6501 return -99;
6502 }
6503
6504 if (count > 1)
6505 {
6506 /* Turn on async mode */
6507 vam->async_mode = 1;
6508 vam->async_errors = 0;
6509 before = vat_time_now (vam);
6510 }
6511
6512 for (j = 0; j < count; j++)
6513 {
6514 /* Construct the API message */
Neale Ranns097fa662018-05-01 05:17:55 -07006515 M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006516
6517 mp->mr_is_add = is_add;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006518 mp->mr_is_multipath = is_multipath;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006519
Neale Ranns097fa662018-05-01 05:17:55 -07006520 mp->mr_route.mr_label = local_label;
6521 mp->mr_route.mr_eos = is_eos;
6522 mp->mr_route.mr_table_id = 0;
6523 mp->mr_route.mr_n_paths = path_count;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006524
Neale Ranns097fa662018-05-01 05:17:55 -07006525 clib_memcpy (&mp->mr_route.mr_paths, paths,
6526 sizeof (paths[0]) * path_count);
Neale Rannsda78f952017-05-24 09:15:43 -07006527
Damjan Marion7cd468a2016-12-19 23:05:39 +01006528 local_label++;
6529
6530 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006531 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006532 /* If we receive SIGTERM, stop now... */
6533 if (vam->do_exit)
6534 break;
6535 }
6536
6537 /* When testing multiple add/del ops, use a control-ping to sync */
6538 if (count > 1)
6539 {
Jon Loeliger2d23eca2017-02-01 13:09:58 -06006540 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006541 f64 after;
Jon Loeliger1f9191f2017-01-31 15:27:19 -06006542 f64 timeout;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006543
6544 /* Shut off async mode */
6545 vam->async_mode = 0;
6546
Dave Barach59b25652017-09-10 15:04:27 -04006547 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06006548 S (mp_ping);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006549
6550 timeout = vat_time_now (vam) + 1.0;
6551 while (vat_time_now (vam) < timeout)
6552 if (vam->result_ready == 1)
6553 goto out;
6554 vam->retval = -99;
6555
6556 out:
6557 if (vam->retval == -99)
6558 errmsg ("timeout");
6559
6560 if (vam->async_errors > 0)
6561 {
6562 errmsg ("%d asynchronous errors", vam->async_errors);
6563 vam->retval = -98;
6564 }
6565 vam->async_errors = 0;
6566 after = vat_time_now (vam);
6567
6568 /* slim chance, but we might have eaten SIGTERM on the first iteration */
6569 if (j > 0)
6570 count = j;
6571
6572 print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6573 count, after - before, count / (after - before));
6574 }
6575 else
6576 {
Jon Loeliger56c7b012017-02-01 12:31:41 -06006577 int ret;
6578
Damjan Marion7cd468a2016-12-19 23:05:39 +01006579 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06006580 W (ret);
6581 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006582 }
6583
6584 /* Return the good/bad news */
6585 return (vam->retval);
Neale Ranns097fa662018-05-01 05:17:55 -07006586 return (0);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006587}
6588
6589static int
6590api_mpls_ip_bind_unbind (vat_main_t * vam)
6591{
6592 unformat_input_t *i = vam->input;
6593 vl_api_mpls_ip_bind_unbind_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006594 u32 ip_table_id = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006595 u8 is_bind = 1;
Neale Ranns097fa662018-05-01 05:17:55 -07006596 vl_api_prefix_t pfx;
6597 u8 prefix_set = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006598 mpls_label_t local_label = MPLS_LABEL_INVALID;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006599 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006600
6601 /* Parse args required to build the message */
6602 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6603 {
Neale Ranns097fa662018-05-01 05:17:55 -07006604 if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
6605 prefix_set = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006606 else if (unformat (i, "%d", &local_label))
6607 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006608 else if (unformat (i, "table-id %d", &ip_table_id))
6609 ;
6610 else if (unformat (i, "unbind"))
6611 is_bind = 0;
6612 else if (unformat (i, "bind"))
6613 is_bind = 1;
6614 else
6615 {
6616 clib_warning ("parse error '%U'", format_unformat_error, i);
6617 return -99;
6618 }
6619 }
6620
Neale Ranns097fa662018-05-01 05:17:55 -07006621 if (!prefix_set)
Damjan Marion7cd468a2016-12-19 23:05:39 +01006622 {
Neale Ranns097fa662018-05-01 05:17:55 -07006623 errmsg ("IP prefix not set");
Damjan Marion7cd468a2016-12-19 23:05:39 +01006624 return -99;
6625 }
6626
6627 if (MPLS_LABEL_INVALID == local_label)
6628 {
6629 errmsg ("missing label");
6630 return -99;
6631 }
6632
6633 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006634 M (MPLS_IP_BIND_UNBIND, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006635
Damjan Marion7cd468a2016-12-19 23:05:39 +01006636 mp->mb_is_bind = is_bind;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006637 mp->mb_ip_table_id = ntohl (ip_table_id);
6638 mp->mb_mpls_table_id = 0;
6639 mp->mb_label = ntohl (local_label);
Neale Ranns097fa662018-05-01 05:17:55 -07006640 clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
Damjan Marion7cd468a2016-12-19 23:05:39 +01006641
6642 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006643 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006644
6645 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06006646 W (ret);
6647 return ret;
Neale Ranns097fa662018-05-01 05:17:55 -07006648 return (0);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006649}
6650
6651static int
John Loe166fd92018-09-13 14:08:59 -04006652api_sr_mpls_policy_add (vat_main_t * vam)
6653{
6654 unformat_input_t *i = vam->input;
6655 vl_api_sr_mpls_policy_add_t *mp;
6656 u32 bsid = 0;
6657 u32 weight = 1;
6658 u8 type = 0;
6659 u8 n_segments = 0;
6660 u32 sid;
6661 u32 *segments = NULL;
6662 int ret;
6663
6664 /* Parse args required to build the message */
6665 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6666 {
6667 if (unformat (i, "bsid %d", &bsid))
6668 ;
6669 else if (unformat (i, "weight %d", &weight))
6670 ;
6671 else if (unformat (i, "spray"))
6672 type = 1;
6673 else if (unformat (i, "next %d", &sid))
6674 {
6675 n_segments += 1;
6676 vec_add1 (segments, htonl (sid));
6677 }
6678 else
6679 {
6680 clib_warning ("parse error '%U'", format_unformat_error, i);
6681 return -99;
6682 }
6683 }
6684
6685 if (bsid == 0)
6686 {
6687 errmsg ("bsid not set");
6688 return -99;
6689 }
6690
6691 if (n_segments == 0)
6692 {
6693 errmsg ("no sid in segment stack");
6694 return -99;
6695 }
6696
6697 /* Construct the API message */
6698 M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
6699
6700 mp->bsid = htonl (bsid);
6701 mp->weight = htonl (weight);
Jakub Grajciar00ec4012020-01-31 10:17:29 +01006702 mp->is_spray = type;
John Loe166fd92018-09-13 14:08:59 -04006703 mp->n_segments = n_segments;
6704 memcpy (mp->segments, segments, sizeof (u32) * n_segments);
6705 vec_free (segments);
6706
6707 /* send it... */
6708 S (mp);
6709
6710 /* Wait for a reply... */
6711 W (ret);
6712 return ret;
6713}
6714
6715static int
6716api_sr_mpls_policy_del (vat_main_t * vam)
6717{
6718 unformat_input_t *i = vam->input;
6719 vl_api_sr_mpls_policy_del_t *mp;
6720 u32 bsid = 0;
6721 int ret;
6722
6723 /* Parse args required to build the message */
6724 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6725 {
6726 if (unformat (i, "bsid %d", &bsid))
6727 ;
6728 else
6729 {
6730 clib_warning ("parse error '%U'", format_unformat_error, i);
6731 return -99;
6732 }
6733 }
6734
6735 if (bsid == 0)
6736 {
6737 errmsg ("bsid not set");
6738 return -99;
6739 }
6740
6741 /* Construct the API message */
6742 M (SR_MPLS_POLICY_DEL, mp);
6743
6744 mp->bsid = htonl (bsid);
6745
6746 /* send it... */
6747 S (mp);
6748
6749 /* Wait for a reply... */
6750 W (ret);
6751 return ret;
6752}
6753
6754static int
Neale Rannsd792d9c2017-10-21 10:53:20 -07006755api_bier_table_add_del (vat_main_t * vam)
6756{
6757 unformat_input_t *i = vam->input;
6758 vl_api_bier_table_add_del_t *mp;
6759 u8 is_add = 1;
6760 u32 set = 0, sub_domain = 0, hdr_len = 3;
6761 mpls_label_t local_label = MPLS_LABEL_INVALID;
6762 int ret;
6763
6764 /* Parse args required to build the message */
6765 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6766 {
6767 if (unformat (i, "sub-domain %d", &sub_domain))
6768 ;
6769 else if (unformat (i, "set %d", &set))
6770 ;
6771 else if (unformat (i, "label %d", &local_label))
6772 ;
6773 else if (unformat (i, "hdr-len %d", &hdr_len))
6774 ;
6775 else if (unformat (i, "add"))
6776 is_add = 1;
6777 else if (unformat (i, "del"))
6778 is_add = 0;
6779 else
6780 {
6781 clib_warning ("parse error '%U'", format_unformat_error, i);
6782 return -99;
6783 }
6784 }
6785
6786 if (MPLS_LABEL_INVALID == local_label)
6787 {
6788 errmsg ("missing label\n");
6789 return -99;
6790 }
6791
6792 /* Construct the API message */
6793 M (BIER_TABLE_ADD_DEL, mp);
6794
6795 mp->bt_is_add = is_add;
6796 mp->bt_label = ntohl (local_label);
6797 mp->bt_tbl_id.bt_set = set;
6798 mp->bt_tbl_id.bt_sub_domain = sub_domain;
6799 mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
6800
6801 /* send it... */
6802 S (mp);
6803
6804 /* Wait for a reply... */
6805 W (ret);
6806
6807 return (ret);
6808}
6809
6810static int
6811api_bier_route_add_del (vat_main_t * vam)
6812{
6813 unformat_input_t *i = vam->input;
6814 vl_api_bier_route_add_del_t *mp;
6815 u8 is_add = 1;
6816 u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
6817 ip4_address_t v4_next_hop_address;
6818 ip6_address_t v6_next_hop_address;
6819 u8 next_hop_set = 0;
6820 u8 next_hop_proto_is_ip4 = 1;
6821 mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6822 int ret;
6823
6824 /* Parse args required to build the message */
6825 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6826 {
6827 if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
6828 {
6829 next_hop_proto_is_ip4 = 1;
6830 next_hop_set = 1;
6831 }
6832 else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
6833 {
6834 next_hop_proto_is_ip4 = 0;
6835 next_hop_set = 1;
6836 }
6837 if (unformat (i, "sub-domain %d", &sub_domain))
6838 ;
6839 else if (unformat (i, "set %d", &set))
6840 ;
6841 else if (unformat (i, "hdr-len %d", &hdr_len))
6842 ;
6843 else if (unformat (i, "bp %d", &bp))
6844 ;
6845 else if (unformat (i, "add"))
6846 is_add = 1;
6847 else if (unformat (i, "del"))
6848 is_add = 0;
6849 else if (unformat (i, "out-label %d", &next_hop_out_label))
6850 ;
6851 else
6852 {
6853 clib_warning ("parse error '%U'", format_unformat_error, i);
6854 return -99;
6855 }
6856 }
6857
6858 if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
6859 {
6860 errmsg ("next hop / label set\n");
6861 return -99;
6862 }
6863 if (0 == bp)
6864 {
6865 errmsg ("bit=position not set\n");
6866 return -99;
6867 }
6868
6869 /* Construct the API message */
Neale Ranns31ed7442018-02-23 05:29:09 -08006870 M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
Neale Rannsd792d9c2017-10-21 10:53:20 -07006871
6872 mp->br_is_add = is_add;
Neale Ranns097fa662018-05-01 05:17:55 -07006873 mp->br_route.br_tbl_id.bt_set = set;
6874 mp->br_route.br_tbl_id.bt_sub_domain = sub_domain;
6875 mp->br_route.br_tbl_id.bt_hdr_len_id = hdr_len;
6876 mp->br_route.br_bp = ntohs (bp);
6877 mp->br_route.br_n_paths = 1;
6878 mp->br_route.br_paths[0].n_labels = 1;
6879 mp->br_route.br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
6880 mp->br_route.br_paths[0].proto = (next_hop_proto_is_ip4 ?
6881 FIB_API_PATH_NH_PROTO_IP4 :
6882 FIB_API_PATH_NH_PROTO_IP6);
Neale Rannsd792d9c2017-10-21 10:53:20 -07006883
6884 if (next_hop_proto_is_ip4)
6885 {
Neale Ranns097fa662018-05-01 05:17:55 -07006886 clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip4,
Neale Rannsd792d9c2017-10-21 10:53:20 -07006887 &v4_next_hop_address, sizeof (v4_next_hop_address));
6888 }
6889 else
6890 {
Neale Ranns097fa662018-05-01 05:17:55 -07006891 clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip6,
Neale Rannsd792d9c2017-10-21 10:53:20 -07006892 &v6_next_hop_address, sizeof (v6_next_hop_address));
6893 }
6894
6895 /* send it... */
6896 S (mp);
6897
6898 /* Wait for a reply... */
6899 W (ret);
6900
6901 return (ret);
6902}
6903
6904static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01006905api_mpls_tunnel_add_del (vat_main_t * vam)
6906{
6907 unformat_input_t *i = vam->input;
6908 vl_api_mpls_tunnel_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006909
Neale Ranns097fa662018-05-01 05:17:55 -07006910 vl_api_fib_path_t paths[8];
Damjan Marion7cd468a2016-12-19 23:05:39 +01006911 u32 sw_if_index = ~0;
Neale Ranns097fa662018-05-01 05:17:55 -07006912 u8 path_count = 0;
6913 u8 l2_only = 0;
6914 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006915 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006916
6917 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6918 {
6919 if (unformat (i, "add"))
6920 is_add = 1;
John Lo06fda9c2018-10-03 16:32:44 -04006921 else
6922 if (unformat
6923 (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
6924 is_add = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006925 else if (unformat (i, "del sw_if_index %d", &sw_if_index))
6926 is_add = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006927 else if (unformat (i, "l2-only"))
6928 l2_only = 1;
Neale Ranns097fa662018-05-01 05:17:55 -07006929 else
6930 if (unformat
6931 (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
John Lo06fda9c2018-10-03 16:32:44 -04006932 {
Neale Ranns097fa662018-05-01 05:17:55 -07006933 path_count++;
6934 if (8 == path_count)
6935 {
6936 errmsg ("max 8 paths");
6937 return -99;
6938 }
John Lo06fda9c2018-10-03 16:32:44 -04006939 }
Damjan Marion7cd468a2016-12-19 23:05:39 +01006940 else
6941 {
6942 clib_warning ("parse error '%U'", format_unformat_error, i);
6943 return -99;
6944 }
6945 }
6946
Neale Ranns097fa662018-05-01 05:17:55 -07006947 M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006948
Damjan Marion7cd468a2016-12-19 23:05:39 +01006949 mp->mt_is_add = is_add;
Neale Ranns097fa662018-05-01 05:17:55 -07006950 mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
6951 mp->mt_tunnel.mt_l2_only = l2_only;
6952 mp->mt_tunnel.mt_is_multicast = 0;
6953 mp->mt_tunnel.mt_n_paths = path_count;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006954
Neale Ranns097fa662018-05-01 05:17:55 -07006955 clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
6956 sizeof (paths[0]) * path_count);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006957
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006958 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06006959 W (ret);
6960 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006961}
6962
6963static int
6964api_sw_interface_set_unnumbered (vat_main_t * vam)
6965{
6966 unformat_input_t *i = vam->input;
6967 vl_api_sw_interface_set_unnumbered_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006968 u32 sw_if_index;
6969 u32 unnum_sw_index = ~0;
6970 u8 is_add = 1;
6971 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006972 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006973
6974 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6975 {
6976 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6977 sw_if_index_set = 1;
6978 else if (unformat (i, "sw_if_index %d", &sw_if_index))
6979 sw_if_index_set = 1;
6980 else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
6981 ;
6982 else if (unformat (i, "del"))
6983 is_add = 0;
6984 else
6985 {
6986 clib_warning ("parse error '%U'", format_unformat_error, i);
6987 return -99;
6988 }
6989 }
6990
6991 if (sw_if_index_set == 0)
6992 {
6993 errmsg ("missing interface name or sw_if_index");
6994 return -99;
6995 }
6996
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006997 M (SW_INTERFACE_SET_UNNUMBERED, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006998
6999 mp->sw_if_index = ntohl (sw_if_index);
7000 mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
7001 mp->is_add = is_add;
7002
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007003 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007004 W (ret);
7005 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007006}
7007
Damjan Marion7cd468a2016-12-19 23:05:39 +01007008
7009static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01007010api_create_vlan_subif (vat_main_t * vam)
7011{
7012 unformat_input_t *i = vam->input;
7013 vl_api_create_vlan_subif_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007014 u32 sw_if_index;
7015 u8 sw_if_index_set = 0;
7016 u32 vlan_id;
7017 u8 vlan_id_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007018 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007019
7020 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7021 {
7022 if (unformat (i, "sw_if_index %d", &sw_if_index))
7023 sw_if_index_set = 1;
7024 else
7025 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7026 sw_if_index_set = 1;
7027 else if (unformat (i, "vlan %d", &vlan_id))
7028 vlan_id_set = 1;
7029 else
7030 {
7031 clib_warning ("parse error '%U'", format_unformat_error, i);
7032 return -99;
7033 }
7034 }
7035
7036 if (sw_if_index_set == 0)
7037 {
7038 errmsg ("missing interface name or sw_if_index");
7039 return -99;
7040 }
7041
7042 if (vlan_id_set == 0)
7043 {
7044 errmsg ("missing vlan_id");
7045 return -99;
7046 }
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007047 M (CREATE_VLAN_SUBIF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007048
7049 mp->sw_if_index = ntohl (sw_if_index);
7050 mp->vlan_id = ntohl (vlan_id);
7051
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007052 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007053 W (ret);
7054 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007055}
7056
7057#define foreach_create_subif_bit \
7058_(no_tags) \
7059_(one_tag) \
7060_(two_tags) \
7061_(dot1ad) \
7062_(exact_match) \
7063_(default_sub) \
7064_(outer_vlan_id_any) \
7065_(inner_vlan_id_any)
7066
Jakub Grajciar053204a2019-03-18 13:17:53 +01007067#define foreach_create_subif_flag \
7068_(0, "no_tags") \
7069_(1, "one_tag") \
7070_(2, "two_tags") \
7071_(3, "dot1ad") \
7072_(4, "exact_match") \
7073_(5, "default_sub") \
7074_(6, "outer_vlan_id_any") \
7075_(7, "inner_vlan_id_any")
7076
Damjan Marion7cd468a2016-12-19 23:05:39 +01007077static int
7078api_create_subif (vat_main_t * vam)
7079{
7080 unformat_input_t *i = vam->input;
7081 vl_api_create_subif_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007082 u32 sw_if_index;
7083 u8 sw_if_index_set = 0;
7084 u32 sub_id;
7085 u8 sub_id_set = 0;
Jakub Grajciar053204a2019-03-18 13:17:53 +01007086 u32 __attribute__ ((unused)) no_tags = 0;
7087 u32 __attribute__ ((unused)) one_tag = 0;
7088 u32 __attribute__ ((unused)) two_tags = 0;
7089 u32 __attribute__ ((unused)) dot1ad = 0;
7090 u32 __attribute__ ((unused)) exact_match = 0;
7091 u32 __attribute__ ((unused)) default_sub = 0;
7092 u32 __attribute__ ((unused)) outer_vlan_id_any = 0;
7093 u32 __attribute__ ((unused)) inner_vlan_id_any = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007094 u32 tmp;
7095 u16 outer_vlan_id = 0;
7096 u16 inner_vlan_id = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007097 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007098
7099 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7100 {
7101 if (unformat (i, "sw_if_index %d", &sw_if_index))
7102 sw_if_index_set = 1;
7103 else
7104 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7105 sw_if_index_set = 1;
7106 else if (unformat (i, "sub_id %d", &sub_id))
7107 sub_id_set = 1;
7108 else if (unformat (i, "outer_vlan_id %d", &tmp))
7109 outer_vlan_id = tmp;
7110 else if (unformat (i, "inner_vlan_id %d", &tmp))
7111 inner_vlan_id = tmp;
7112
7113#define _(a) else if (unformat (i, #a)) a = 1 ;
7114 foreach_create_subif_bit
7115#undef _
7116 else
7117 {
7118 clib_warning ("parse error '%U'", format_unformat_error, i);
7119 return -99;
7120 }
7121 }
7122
7123 if (sw_if_index_set == 0)
7124 {
7125 errmsg ("missing interface name or sw_if_index");
7126 return -99;
7127 }
7128
7129 if (sub_id_set == 0)
7130 {
7131 errmsg ("missing sub_id");
7132 return -99;
7133 }
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007134 M (CREATE_SUBIF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007135
7136 mp->sw_if_index = ntohl (sw_if_index);
7137 mp->sub_id = ntohl (sub_id);
7138
Jakub Grajciar053204a2019-03-18 13:17:53 +01007139#define _(a,b) mp->sub_if_flags |= (1 << a);
7140 foreach_create_subif_flag;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007141#undef _
7142
7143 mp->outer_vlan_id = ntohs (outer_vlan_id);
7144 mp->inner_vlan_id = ntohs (inner_vlan_id);
7145
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007146 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007147 W (ret);
7148 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007149}
7150
7151static int
Neale Ranns9db6ada2019-11-08 12:42:31 +00007152api_ip_table_replace_begin (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +01007153{
7154 unformat_input_t *i = vam->input;
Neale Ranns9db6ada2019-11-08 12:42:31 +00007155 vl_api_ip_table_replace_begin_t *mp;
7156 u32 table_id = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007157 u8 is_ipv6 = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007158
Jon Loeliger56c7b012017-02-01 12:31:41 -06007159 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007160 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7161 {
Neale Ranns9db6ada2019-11-08 12:42:31 +00007162 if (unformat (i, "table %d", &table_id))
7163 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007164 else if (unformat (i, "ipv6"))
7165 is_ipv6 = 1;
7166 else
7167 {
7168 clib_warning ("parse error '%U'", format_unformat_error, i);
7169 return -99;
7170 }
7171 }
7172
Neale Ranns9db6ada2019-11-08 12:42:31 +00007173 M (IP_TABLE_REPLACE_BEGIN, mp);
7174
7175 mp->table.table_id = ntohl (table_id);
7176 mp->table.is_ip6 = is_ipv6;
7177
7178 S (mp);
7179 W (ret);
7180 return ret;
7181}
7182
7183static int
7184api_ip_table_flush (vat_main_t * vam)
7185{
7186 unformat_input_t *i = vam->input;
7187 vl_api_ip_table_flush_t *mp;
7188 u32 table_id = 0;
7189 u8 is_ipv6 = 0;
7190
7191 int ret;
7192 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
Damjan Marion7cd468a2016-12-19 23:05:39 +01007193 {
Neale Ranns9db6ada2019-11-08 12:42:31 +00007194 if (unformat (i, "table %d", &table_id))
7195 ;
7196 else if (unformat (i, "ipv6"))
7197 is_ipv6 = 1;
7198 else
7199 {
7200 clib_warning ("parse error '%U'", format_unformat_error, i);
7201 return -99;
7202 }
Damjan Marion7cd468a2016-12-19 23:05:39 +01007203 }
7204
Neale Ranns9db6ada2019-11-08 12:42:31 +00007205 M (IP_TABLE_FLUSH, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007206
Neale Ranns9db6ada2019-11-08 12:42:31 +00007207 mp->table.table_id = ntohl (table_id);
7208 mp->table.is_ip6 = is_ipv6;
7209
7210 S (mp);
7211 W (ret);
7212 return ret;
7213}
7214
7215static int
7216api_ip_table_replace_end (vat_main_t * vam)
7217{
7218 unformat_input_t *i = vam->input;
7219 vl_api_ip_table_replace_end_t *mp;
7220 u32 table_id = 0;
7221 u8 is_ipv6 = 0;
7222
7223 int ret;
7224 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7225 {
7226 if (unformat (i, "table %d", &table_id))
7227 ;
7228 else if (unformat (i, "ipv6"))
7229 is_ipv6 = 1;
7230 else
7231 {
7232 clib_warning ("parse error '%U'", format_unformat_error, i);
7233 return -99;
7234 }
7235 }
7236
7237 M (IP_TABLE_REPLACE_END, mp);
7238
7239 mp->table.table_id = ntohl (table_id);
7240 mp->table.is_ip6 = is_ipv6;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007241
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007242 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007243 W (ret);
7244 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007245}
7246
7247static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01007248api_set_ip_flow_hash (vat_main_t * vam)
7249{
7250 unformat_input_t *i = vam->input;
7251 vl_api_set_ip_flow_hash_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007252 u32 vrf_id = 0;
7253 u8 is_ipv6 = 0;
7254 u8 vrf_id_set = 0;
7255 u8 src = 0;
7256 u8 dst = 0;
7257 u8 sport = 0;
7258 u8 dport = 0;
7259 u8 proto = 0;
7260 u8 reverse = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007261 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007262
7263 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7264 {
7265 if (unformat (i, "vrf %d", &vrf_id))
7266 vrf_id_set = 1;
7267 else if (unformat (i, "ipv6"))
7268 is_ipv6 = 1;
7269 else if (unformat (i, "src"))
7270 src = 1;
7271 else if (unformat (i, "dst"))
7272 dst = 1;
7273 else if (unformat (i, "sport"))
7274 sport = 1;
7275 else if (unformat (i, "dport"))
7276 dport = 1;
7277 else if (unformat (i, "proto"))
7278 proto = 1;
7279 else if (unformat (i, "reverse"))
7280 reverse = 1;
7281
7282 else
7283 {
7284 clib_warning ("parse error '%U'", format_unformat_error, i);
7285 return -99;
7286 }
7287 }
7288
7289 if (vrf_id_set == 0)
7290 {
7291 errmsg ("missing vrf id");
7292 return -99;
7293 }
7294
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007295 M (SET_IP_FLOW_HASH, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007296 mp->src = src;
7297 mp->dst = dst;
7298 mp->sport = sport;
7299 mp->dport = dport;
7300 mp->proto = proto;
7301 mp->reverse = reverse;
7302 mp->vrf_id = ntohl (vrf_id);
7303 mp->is_ipv6 = is_ipv6;
7304
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007305 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007306 W (ret);
7307 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007308}
7309
7310static int
7311api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7312{
7313 unformat_input_t *i = vam->input;
7314 vl_api_sw_interface_ip6_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007315 u32 sw_if_index;
7316 u8 sw_if_index_set = 0;
7317 u8 enable = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007318 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007319
7320 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7321 {
7322 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7323 sw_if_index_set = 1;
7324 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7325 sw_if_index_set = 1;
7326 else if (unformat (i, "enable"))
7327 enable = 1;
7328 else if (unformat (i, "disable"))
7329 enable = 0;
7330 else
7331 {
7332 clib_warning ("parse error '%U'", format_unformat_error, i);
7333 return -99;
7334 }
7335 }
7336
7337 if (sw_if_index_set == 0)
7338 {
7339 errmsg ("missing interface name or sw_if_index");
7340 return -99;
7341 }
7342
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007343 M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007344
7345 mp->sw_if_index = ntohl (sw_if_index);
7346 mp->enable = enable;
7347
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007348 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007349 W (ret);
7350 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007351}
7352
Damjan Marion7cd468a2016-12-19 23:05:39 +01007353
7354static int
7355api_l2_patch_add_del (vat_main_t * vam)
7356{
7357 unformat_input_t *i = vam->input;
7358 vl_api_l2_patch_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007359 u32 rx_sw_if_index;
7360 u8 rx_sw_if_index_set = 0;
7361 u32 tx_sw_if_index;
7362 u8 tx_sw_if_index_set = 0;
7363 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007364 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007365
7366 /* Parse args required to build the message */
7367 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7368 {
7369 if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7370 rx_sw_if_index_set = 1;
7371 else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7372 tx_sw_if_index_set = 1;
7373 else if (unformat (i, "rx"))
7374 {
7375 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7376 {
7377 if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7378 &rx_sw_if_index))
7379 rx_sw_if_index_set = 1;
7380 }
7381 else
7382 break;
7383 }
7384 else if (unformat (i, "tx"))
7385 {
7386 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7387 {
7388 if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7389 &tx_sw_if_index))
7390 tx_sw_if_index_set = 1;
7391 }
7392 else
7393 break;
7394 }
7395 else if (unformat (i, "del"))
7396 is_add = 0;
7397 else
7398 break;
7399 }
7400
7401 if (rx_sw_if_index_set == 0)
7402 {
7403 errmsg ("missing rx interface name or rx_sw_if_index");
7404 return -99;
7405 }
7406
7407 if (tx_sw_if_index_set == 0)
7408 {
7409 errmsg ("missing tx interface name or tx_sw_if_index");
7410 return -99;
7411 }
7412
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007413 M (L2_PATCH_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007414
7415 mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7416 mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7417 mp->is_add = is_add;
7418
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007419 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007420 W (ret);
7421 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007422}
7423
Pablo Camarillofb380952016-12-07 18:34:18 +01007424u8 is_del;
7425u8 localsid_addr[16];
7426u8 end_psp;
7427u8 behavior;
7428u32 sw_if_index;
7429u32 vlan_index;
7430u32 fib_table;
7431u8 nh_addr[16];
7432
7433static int
7434api_sr_localsid_add_del (vat_main_t * vam)
7435{
7436 unformat_input_t *i = vam->input;
7437 vl_api_sr_localsid_add_del_t *mp;
7438
7439 u8 is_del;
7440 ip6_address_t localsid;
7441 u8 end_psp = 0;
7442 u8 behavior = ~0;
7443 u32 sw_if_index;
7444 u32 fib_table = ~(u32) 0;
Jakub Grajciar0938eba2020-03-04 13:08:27 +01007445 ip46_address_t nh_addr;
7446 clib_memset (&nh_addr, 0, sizeof (ip46_address_t));
Pablo Camarillofb380952016-12-07 18:34:18 +01007447
7448 bool nexthop_set = 0;
7449
7450 int ret;
7451
7452 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7453 {
7454 if (unformat (i, "del"))
7455 is_del = 1;
7456 else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
Jakub Grajciar0938eba2020-03-04 13:08:27 +01007457 else if (unformat (i, "next-hop %U", unformat_ip46_address, &nh_addr))
Pablo Camarillofb380952016-12-07 18:34:18 +01007458 nexthop_set = 1;
7459 else if (unformat (i, "behavior %u", &behavior));
7460 else if (unformat (i, "sw_if_index %u", &sw_if_index));
7461 else if (unformat (i, "fib-table %u", &fib_table));
7462 else if (unformat (i, "end.psp %u", &behavior));
7463 else
7464 break;
7465 }
7466
7467 M (SR_LOCALSID_ADD_DEL, mp);
7468
Jakub Grajciar0938eba2020-03-04 13:08:27 +01007469 clib_memcpy (mp->localsid, &localsid, sizeof (mp->localsid));
Tetsuya Murakami1b81e6e2019-11-06 11:05:51 -08007470
Pablo Camarillofb380952016-12-07 18:34:18 +01007471 if (nexthop_set)
Pablo Camarillo3337bd22018-06-19 15:49:02 +02007472 {
Jakub Grajciar0938eba2020-03-04 13:08:27 +01007473 clib_memcpy (&mp->nh_addr.un, &nh_addr, sizeof (mp->nh_addr.un));
Pablo Camarillo3337bd22018-06-19 15:49:02 +02007474 }
Pablo Camarillofb380952016-12-07 18:34:18 +01007475 mp->behavior = behavior;
7476 mp->sw_if_index = ntohl (sw_if_index);
7477 mp->fib_table = ntohl (fib_table);
7478 mp->end_psp = end_psp;
7479 mp->is_del = is_del;
7480
7481 S (mp);
7482 W (ret);
7483 return ret;
7484}
7485
Damjan Marion7cd468a2016-12-19 23:05:39 +01007486static int
7487api_ioam_enable (vat_main_t * vam)
7488{
7489 unformat_input_t *input = vam->input;
7490 vl_api_ioam_enable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007491 u32 id = 0;
7492 int has_trace_option = 0;
7493 int has_pot_option = 0;
7494 int has_seqno_option = 0;
7495 int has_analyse_option = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007496 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007497
7498 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7499 {
7500 if (unformat (input, "trace"))
7501 has_trace_option = 1;
7502 else if (unformat (input, "pot"))
7503 has_pot_option = 1;
7504 else if (unformat (input, "seqno"))
7505 has_seqno_option = 1;
7506 else if (unformat (input, "analyse"))
7507 has_analyse_option = 1;
7508 else
7509 break;
7510 }
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007511 M (IOAM_ENABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007512 mp->id = htons (id);
7513 mp->seqno = has_seqno_option;
7514 mp->analyse = has_analyse_option;
7515 mp->pot_enable = has_pot_option;
7516 mp->trace_enable = has_trace_option;
7517
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007518 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007519 W (ret);
7520 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007521}
7522
7523
7524static int
7525api_ioam_disable (vat_main_t * vam)
7526{
7527 vl_api_ioam_disable_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007528 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007529
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007530 M (IOAM_DISABLE, mp);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007531 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007532 W (ret);
7533 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007534}
7535
Damjan Marion7cd468a2016-12-19 23:05:39 +01007536#define foreach_tcp_proto_field \
7537_(src_port) \
7538_(dst_port)
7539
7540#define foreach_udp_proto_field \
7541_(src_port) \
7542_(dst_port)
7543
7544#define foreach_ip4_proto_field \
7545_(src_address) \
7546_(dst_address) \
7547_(tos) \
7548_(length) \
7549_(fragment_id) \
7550_(ttl) \
7551_(protocol) \
7552_(checksum)
7553
Dave Barach4a3f69c2017-02-22 12:44:56 -05007554typedef struct
7555{
7556 u16 src_port, dst_port;
7557} tcpudp_header_t;
7558
7559#if VPP_API_TEST_BUILTIN == 0
Damjan Marion7cd468a2016-12-19 23:05:39 +01007560uword
7561unformat_tcp_mask (unformat_input_t * input, va_list * args)
7562{
7563 u8 **maskp = va_arg (*args, u8 **);
7564 u8 *mask = 0;
7565 u8 found_something = 0;
7566 tcp_header_t *tcp;
7567
7568#define _(a) u8 a=0;
7569 foreach_tcp_proto_field;
7570#undef _
7571
7572 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7573 {
7574 if (0);
7575#define _(a) else if (unformat (input, #a)) a=1;
7576 foreach_tcp_proto_field
7577#undef _
7578 else
7579 break;
7580 }
7581
7582#define _(a) found_something += a;
7583 foreach_tcp_proto_field;
7584#undef _
7585
7586 if (found_something == 0)
7587 return 0;
7588
7589 vec_validate (mask, sizeof (*tcp) - 1);
7590
7591 tcp = (tcp_header_t *) mask;
7592
Dave Barachb7b92992018-10-17 10:38:51 -04007593#define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
Damjan Marion7cd468a2016-12-19 23:05:39 +01007594 foreach_tcp_proto_field;
7595#undef _
7596
7597 *maskp = mask;
7598 return 1;
7599}
7600
7601uword
7602unformat_udp_mask (unformat_input_t * input, va_list * args)
7603{
7604 u8 **maskp = va_arg (*args, u8 **);
7605 u8 *mask = 0;
7606 u8 found_something = 0;
7607 udp_header_t *udp;
7608
7609#define _(a) u8 a=0;
7610 foreach_udp_proto_field;
7611#undef _
7612
7613 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7614 {
7615 if (0);
7616#define _(a) else if (unformat (input, #a)) a=1;
7617 foreach_udp_proto_field
7618#undef _
7619 else
7620 break;
7621 }
7622
7623#define _(a) found_something += a;
7624 foreach_udp_proto_field;
7625#undef _
7626
7627 if (found_something == 0)
7628 return 0;
7629
7630 vec_validate (mask, sizeof (*udp) - 1);
7631
7632 udp = (udp_header_t *) mask;
7633
Dave Barachb7b92992018-10-17 10:38:51 -04007634#define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
Damjan Marion7cd468a2016-12-19 23:05:39 +01007635 foreach_udp_proto_field;
7636#undef _
7637
7638 *maskp = mask;
7639 return 1;
7640}
7641
Damjan Marion7cd468a2016-12-19 23:05:39 +01007642uword
7643unformat_l4_mask (unformat_input_t * input, va_list * args)
7644{
7645 u8 **maskp = va_arg (*args, u8 **);
7646 u16 src_port = 0, dst_port = 0;
7647 tcpudp_header_t *tcpudp;
7648
7649 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7650 {
7651 if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
7652 return 1;
7653 else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
7654 return 1;
7655 else if (unformat (input, "src_port"))
7656 src_port = 0xFFFF;
7657 else if (unformat (input, "dst_port"))
7658 dst_port = 0xFFFF;
7659 else
7660 return 0;
7661 }
7662
7663 if (!src_port && !dst_port)
7664 return 0;
7665
7666 u8 *mask = 0;
7667 vec_validate (mask, sizeof (tcpudp_header_t) - 1);
7668
7669 tcpudp = (tcpudp_header_t *) mask;
7670 tcpudp->src_port = src_port;
7671 tcpudp->dst_port = dst_port;
7672
7673 *maskp = mask;
7674
7675 return 1;
7676}
7677
7678uword
7679unformat_ip4_mask (unformat_input_t * input, va_list * args)
7680{
7681 u8 **maskp = va_arg (*args, u8 **);
7682 u8 *mask = 0;
7683 u8 found_something = 0;
7684 ip4_header_t *ip;
7685
7686#define _(a) u8 a=0;
7687 foreach_ip4_proto_field;
7688#undef _
7689 u8 version = 0;
7690 u8 hdr_length = 0;
7691
7692
7693 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7694 {
7695 if (unformat (input, "version"))
7696 version = 1;
7697 else if (unformat (input, "hdr_length"))
7698 hdr_length = 1;
7699 else if (unformat (input, "src"))
7700 src_address = 1;
7701 else if (unformat (input, "dst"))
7702 dst_address = 1;
7703 else if (unformat (input, "proto"))
7704 protocol = 1;
7705
7706#define _(a) else if (unformat (input, #a)) a=1;
7707 foreach_ip4_proto_field
7708#undef _
7709 else
7710 break;
7711 }
7712
7713#define _(a) found_something += a;
7714 foreach_ip4_proto_field;
7715#undef _
7716
7717 if (found_something == 0)
7718 return 0;
7719
7720 vec_validate (mask, sizeof (*ip) - 1);
7721
7722 ip = (ip4_header_t *) mask;
7723
Dave Barachb7b92992018-10-17 10:38:51 -04007724#define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
Damjan Marion7cd468a2016-12-19 23:05:39 +01007725 foreach_ip4_proto_field;
7726#undef _
7727
7728 ip->ip_version_and_header_length = 0;
7729
7730 if (version)
7731 ip->ip_version_and_header_length |= 0xF0;
7732
7733 if (hdr_length)
7734 ip->ip_version_and_header_length |= 0x0F;
7735
7736 *maskp = mask;
7737 return 1;
7738}
7739
7740#define foreach_ip6_proto_field \
7741_(src_address) \
7742_(dst_address) \
7743_(payload_length) \
7744_(hop_limit) \
7745_(protocol)
7746
7747uword
7748unformat_ip6_mask (unformat_input_t * input, va_list * args)
7749{
7750 u8 **maskp = va_arg (*args, u8 **);
7751 u8 *mask = 0;
7752 u8 found_something = 0;
7753 ip6_header_t *ip;
7754 u32 ip_version_traffic_class_and_flow_label;
7755
7756#define _(a) u8 a=0;
7757 foreach_ip6_proto_field;
7758#undef _
7759 u8 version = 0;
7760 u8 traffic_class = 0;
7761 u8 flow_label = 0;
7762
7763 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7764 {
7765 if (unformat (input, "version"))
7766 version = 1;
7767 else if (unformat (input, "traffic-class"))
7768 traffic_class = 1;
7769 else if (unformat (input, "flow-label"))
7770 flow_label = 1;
7771 else if (unformat (input, "src"))
7772 src_address = 1;
7773 else if (unformat (input, "dst"))
7774 dst_address = 1;
7775 else if (unformat (input, "proto"))
7776 protocol = 1;
7777
7778#define _(a) else if (unformat (input, #a)) a=1;
7779 foreach_ip6_proto_field
7780#undef _
7781 else
7782 break;
7783 }
7784
7785#define _(a) found_something += a;
7786 foreach_ip6_proto_field;
7787#undef _
7788
7789 if (found_something == 0)
7790 return 0;
7791
7792 vec_validate (mask, sizeof (*ip) - 1);
7793
7794 ip = (ip6_header_t *) mask;
7795
Dave Barachb7b92992018-10-17 10:38:51 -04007796#define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
Damjan Marion7cd468a2016-12-19 23:05:39 +01007797 foreach_ip6_proto_field;
7798#undef _
7799
7800 ip_version_traffic_class_and_flow_label = 0;
7801
7802 if (version)
7803 ip_version_traffic_class_and_flow_label |= 0xF0000000;
7804
7805 if (traffic_class)
7806 ip_version_traffic_class_and_flow_label |= 0x0FF00000;
7807
7808 if (flow_label)
7809 ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
7810
7811 ip->ip_version_traffic_class_and_flow_label =
7812 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
7813
7814 *maskp = mask;
7815 return 1;
7816}
7817
7818uword
7819unformat_l3_mask (unformat_input_t * input, va_list * args)
7820{
7821 u8 **maskp = va_arg (*args, u8 **);
7822
7823 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7824 {
7825 if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
7826 return 1;
7827 else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
7828 return 1;
7829 else
7830 break;
7831 }
7832 return 0;
7833}
7834
7835uword
7836unformat_l2_mask (unformat_input_t * input, va_list * args)
7837{
7838 u8 **maskp = va_arg (*args, u8 **);
7839 u8 *mask = 0;
7840 u8 src = 0;
7841 u8 dst = 0;
7842 u8 proto = 0;
7843 u8 tag1 = 0;
7844 u8 tag2 = 0;
7845 u8 ignore_tag1 = 0;
7846 u8 ignore_tag2 = 0;
7847 u8 cos1 = 0;
7848 u8 cos2 = 0;
7849 u8 dot1q = 0;
7850 u8 dot1ad = 0;
7851 int len = 14;
7852
7853 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7854 {
7855 if (unformat (input, "src"))
7856 src = 1;
7857 else if (unformat (input, "dst"))
7858 dst = 1;
7859 else if (unformat (input, "proto"))
7860 proto = 1;
7861 else if (unformat (input, "tag1"))
7862 tag1 = 1;
7863 else if (unformat (input, "tag2"))
7864 tag2 = 1;
7865 else if (unformat (input, "ignore-tag1"))
7866 ignore_tag1 = 1;
7867 else if (unformat (input, "ignore-tag2"))
7868 ignore_tag2 = 1;
7869 else if (unformat (input, "cos1"))
7870 cos1 = 1;
7871 else if (unformat (input, "cos2"))
7872 cos2 = 1;
7873 else if (unformat (input, "dot1q"))
7874 dot1q = 1;
7875 else if (unformat (input, "dot1ad"))
7876 dot1ad = 1;
7877 else
7878 break;
7879 }
7880 if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
7881 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
7882 return 0;
7883
7884 if (tag1 || ignore_tag1 || cos1 || dot1q)
7885 len = 18;
7886 if (tag2 || ignore_tag2 || cos2 || dot1ad)
7887 len = 22;
7888
7889 vec_validate (mask, len - 1);
7890
7891 if (dst)
Dave Barachb7b92992018-10-17 10:38:51 -04007892 clib_memset (mask, 0xff, 6);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007893
7894 if (src)
Dave Barachb7b92992018-10-17 10:38:51 -04007895 clib_memset (mask + 6, 0xff, 6);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007896
7897 if (tag2 || dot1ad)
7898 {
7899 /* inner vlan tag */
7900 if (tag2)
7901 {
7902 mask[19] = 0xff;
7903 mask[18] = 0x0f;
7904 }
7905 if (cos2)
7906 mask[18] |= 0xe0;
7907 if (proto)
7908 mask[21] = mask[20] = 0xff;
7909 if (tag1)
7910 {
7911 mask[15] = 0xff;
7912 mask[14] = 0x0f;
7913 }
7914 if (cos1)
7915 mask[14] |= 0xe0;
7916 *maskp = mask;
7917 return 1;
7918 }
7919 if (tag1 | dot1q)
7920 {
7921 if (tag1)
7922 {
7923 mask[15] = 0xff;
7924 mask[14] = 0x0f;
7925 }
7926 if (cos1)
7927 mask[14] |= 0xe0;
7928 if (proto)
7929 mask[16] = mask[17] = 0xff;
7930
7931 *maskp = mask;
7932 return 1;
7933 }
7934 if (cos2)
7935 mask[18] |= 0xe0;
7936 if (cos1)
7937 mask[14] |= 0xe0;
7938 if (proto)
7939 mask[12] = mask[13] = 0xff;
7940
7941 *maskp = mask;
7942 return 1;
7943}
7944
7945uword
7946unformat_classify_mask (unformat_input_t * input, va_list * args)
7947{
7948 u8 **maskp = va_arg (*args, u8 **);
7949 u32 *skipp = va_arg (*args, u32 *);
7950 u32 *matchp = va_arg (*args, u32 *);
7951 u32 match;
7952 u8 *mask = 0;
7953 u8 *l2 = 0;
7954 u8 *l3 = 0;
7955 u8 *l4 = 0;
7956 int i;
7957
7958 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7959 {
7960 if (unformat (input, "hex %U", unformat_hex_string, &mask))
7961 ;
7962 else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
7963 ;
7964 else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
7965 ;
7966 else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
7967 ;
7968 else
7969 break;
7970 }
7971
7972 if (l4 && !l3)
7973 {
7974 vec_free (mask);
7975 vec_free (l2);
7976 vec_free (l4);
7977 return 0;
7978 }
7979
7980 if (mask || l2 || l3 || l4)
7981 {
7982 if (l2 || l3 || l4)
7983 {
7984 /* "With a free Ethernet header in every package" */
7985 if (l2 == 0)
7986 vec_validate (l2, 13);
7987 mask = l2;
7988 if (vec_len (l3))
7989 {
7990 vec_append (mask, l3);
7991 vec_free (l3);
7992 }
7993 if (vec_len (l4))
7994 {
7995 vec_append (mask, l4);
7996 vec_free (l4);
7997 }
7998 }
7999
8000 /* Scan forward looking for the first significant mask octet */
8001 for (i = 0; i < vec_len (mask); i++)
8002 if (mask[i])
8003 break;
8004
8005 /* compute (skip, match) params */
8006 *skipp = i / sizeof (u32x4);
8007 vec_delete (mask, *skipp * sizeof (u32x4), 0);
8008
8009 /* Pad mask to an even multiple of the vector size */
8010 while (vec_len (mask) % sizeof (u32x4))
8011 vec_add1 (mask, 0);
8012
8013 match = vec_len (mask) / sizeof (u32x4);
8014
8015 for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
8016 {
8017 u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
8018 if (*tmp || *(tmp + 1))
8019 break;
8020 match--;
8021 }
8022 if (match == 0)
8023 clib_warning ("BUG: match 0");
8024
8025 _vec_len (mask) = match * sizeof (u32x4);
8026
8027 *matchp = match;
8028 *maskp = mask;
8029
8030 return 1;
8031 }
8032
8033 return 0;
8034}
Dave Barach4a3f69c2017-02-22 12:44:56 -05008035#endif /* VPP_API_TEST_BUILTIN */
Damjan Marion7cd468a2016-12-19 23:05:39 +01008036
8037#define foreach_l2_next \
8038_(drop, DROP) \
8039_(ethernet, ETHERNET_INPUT) \
8040_(ip4, IP4_INPUT) \
8041_(ip6, IP6_INPUT)
8042
8043uword
8044unformat_l2_next_index (unformat_input_t * input, va_list * args)
8045{
8046 u32 *miss_next_indexp = va_arg (*args, u32 *);
8047 u32 next_index = 0;
8048 u32 tmp;
8049
8050#define _(n,N) \
8051 if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
8052 foreach_l2_next;
8053#undef _
8054
8055 if (unformat (input, "%d", &tmp))
8056 {
8057 next_index = tmp;
8058 goto out;
8059 }
8060
8061 return 0;
8062
8063out:
8064 *miss_next_indexp = next_index;
8065 return 1;
8066}
8067
8068#define foreach_ip_next \
8069_(drop, DROP) \
8070_(local, LOCAL) \
8071_(rewrite, REWRITE)
8072
8073uword
Dave Barach4a3f69c2017-02-22 12:44:56 -05008074api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
Damjan Marion7cd468a2016-12-19 23:05:39 +01008075{
8076 u32 *miss_next_indexp = va_arg (*args, u32 *);
8077 u32 next_index = 0;
8078 u32 tmp;
8079
8080#define _(n,N) \
8081 if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
8082 foreach_ip_next;
8083#undef _
8084
8085 if (unformat (input, "%d", &tmp))
8086 {
8087 next_index = tmp;
8088 goto out;
8089 }
8090
8091 return 0;
8092
8093out:
8094 *miss_next_indexp = next_index;
8095 return 1;
8096}
8097
8098#define foreach_acl_next \
8099_(deny, DENY)
8100
8101uword
Dave Barach4a3f69c2017-02-22 12:44:56 -05008102api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
Damjan Marion7cd468a2016-12-19 23:05:39 +01008103{
8104 u32 *miss_next_indexp = va_arg (*args, u32 *);
8105 u32 next_index = 0;
8106 u32 tmp;
8107
8108#define _(n,N) \
8109 if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
8110 foreach_acl_next;
8111#undef _
8112
8113 if (unformat (input, "permit"))
8114 {
8115 next_index = ~0;
8116 goto out;
8117 }
8118 else if (unformat (input, "%d", &tmp))
8119 {
8120 next_index = tmp;
8121 goto out;
8122 }
8123
8124 return 0;
8125
8126out:
8127 *miss_next_indexp = next_index;
8128 return 1;
8129}
8130
8131uword
8132unformat_policer_precolor (unformat_input_t * input, va_list * args)
8133{
8134 u32 *r = va_arg (*args, u32 *);
8135
8136 if (unformat (input, "conform-color"))
8137 *r = POLICE_CONFORM;
8138 else if (unformat (input, "exceed-color"))
8139 *r = POLICE_EXCEED;
8140 else
8141 return 0;
8142
8143 return 1;
8144}
8145
8146static int
8147api_classify_add_del_table (vat_main_t * vam)
8148{
8149 unformat_input_t *i = vam->input;
8150 vl_api_classify_add_del_table_t *mp;
8151
8152 u32 nbuckets = 2;
8153 u32 skip = ~0;
8154 u32 match = ~0;
8155 int is_add = 1;
8156 int del_chain = 0;
8157 u32 table_index = ~0;
8158 u32 next_table_index = ~0;
8159 u32 miss_next_index = ~0;
8160 u32 memory_size = 32 << 20;
8161 u8 *mask = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008162 u32 current_data_flag = 0;
8163 int current_data_offset = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008164 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008165
8166 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8167 {
8168 if (unformat (i, "del"))
8169 is_add = 0;
8170 else if (unformat (i, "del-chain"))
8171 {
8172 is_add = 0;
8173 del_chain = 1;
8174 }
8175 else if (unformat (i, "buckets %d", &nbuckets))
8176 ;
8177 else if (unformat (i, "memory_size %d", &memory_size))
8178 ;
8179 else if (unformat (i, "skip %d", &skip))
8180 ;
8181 else if (unformat (i, "match %d", &match))
8182 ;
8183 else if (unformat (i, "table %d", &table_index))
8184 ;
8185 else if (unformat (i, "mask %U", unformat_classify_mask,
8186 &mask, &skip, &match))
8187 ;
8188 else if (unformat (i, "next-table %d", &next_table_index))
8189 ;
Dave Barach4a3f69c2017-02-22 12:44:56 -05008190 else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
Damjan Marion7cd468a2016-12-19 23:05:39 +01008191 &miss_next_index))
8192 ;
8193 else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
8194 &miss_next_index))
8195 ;
Dave Barach4a3f69c2017-02-22 12:44:56 -05008196 else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
Damjan Marion7cd468a2016-12-19 23:05:39 +01008197 &miss_next_index))
8198 ;
8199 else if (unformat (i, "current-data-flag %d", &current_data_flag))
8200 ;
8201 else if (unformat (i, "current-data-offset %d", &current_data_offset))
8202 ;
8203 else
8204 break;
8205 }
8206
8207 if (is_add && mask == 0)
8208 {
8209 errmsg ("Mask required");
8210 return -99;
8211 }
8212
8213 if (is_add && skip == ~0)
8214 {
8215 errmsg ("skip count required");
8216 return -99;
8217 }
8218
8219 if (is_add && match == ~0)
8220 {
8221 errmsg ("match count required");
8222 return -99;
8223 }
8224
8225 if (!is_add && table_index == ~0)
8226 {
8227 errmsg ("table index required for delete");
8228 return -99;
8229 }
8230
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008231 M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
Damjan Marion7cd468a2016-12-19 23:05:39 +01008232
8233 mp->is_add = is_add;
8234 mp->del_chain = del_chain;
8235 mp->table_index = ntohl (table_index);
8236 mp->nbuckets = ntohl (nbuckets);
8237 mp->memory_size = ntohl (memory_size);
8238 mp->skip_n_vectors = ntohl (skip);
8239 mp->match_n_vectors = ntohl (match);
8240 mp->next_table_index = ntohl (next_table_index);
8241 mp->miss_next_index = ntohl (miss_next_index);
8242 mp->current_data_flag = ntohl (current_data_flag);
8243 mp->current_data_offset = ntohl (current_data_offset);
Juraj Sloboda75282452018-06-12 14:20:49 +02008244 mp->mask_len = ntohl (vec_len (mask));
Damjan Marion7cd468a2016-12-19 23:05:39 +01008245 clib_memcpy (mp->mask, mask, vec_len (mask));
8246
8247 vec_free (mask);
8248
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008249 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008250 W (ret);
8251 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008252}
8253
Dave Barach4a3f69c2017-02-22 12:44:56 -05008254#if VPP_API_TEST_BUILTIN == 0
Damjan Marion7cd468a2016-12-19 23:05:39 +01008255uword
8256unformat_l4_match (unformat_input_t * input, va_list * args)
8257{
8258 u8 **matchp = va_arg (*args, u8 **);
8259
8260 u8 *proto_header = 0;
8261 int src_port = 0;
8262 int dst_port = 0;
8263
8264 tcpudp_header_t h;
8265
8266 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8267 {
8268 if (unformat (input, "src_port %d", &src_port))
8269 ;
8270 else if (unformat (input, "dst_port %d", &dst_port))
8271 ;
8272 else
8273 return 0;
8274 }
8275
8276 h.src_port = clib_host_to_net_u16 (src_port);
8277 h.dst_port = clib_host_to_net_u16 (dst_port);
8278 vec_validate (proto_header, sizeof (h) - 1);
8279 memcpy (proto_header, &h, sizeof (h));
8280
8281 *matchp = proto_header;
8282
8283 return 1;
8284}
8285
8286uword
8287unformat_ip4_match (unformat_input_t * input, va_list * args)
8288{
8289 u8 **matchp = va_arg (*args, u8 **);
8290 u8 *match = 0;
8291 ip4_header_t *ip;
8292 int version = 0;
8293 u32 version_val;
8294 int hdr_length = 0;
8295 u32 hdr_length_val;
8296 int src = 0, dst = 0;
8297 ip4_address_t src_val, dst_val;
8298 int proto = 0;
8299 u32 proto_val;
8300 int tos = 0;
8301 u32 tos_val;
8302 int length = 0;
8303 u32 length_val;
8304 int fragment_id = 0;
8305 u32 fragment_id_val;
8306 int ttl = 0;
8307 int ttl_val;
8308 int checksum = 0;
8309 u32 checksum_val;
8310
8311 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8312 {
8313 if (unformat (input, "version %d", &version_val))
8314 version = 1;
8315 else if (unformat (input, "hdr_length %d", &hdr_length_val))
8316 hdr_length = 1;
8317 else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
8318 src = 1;
8319 else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
8320 dst = 1;
8321 else if (unformat (input, "proto %d", &proto_val))
8322 proto = 1;
8323 else if (unformat (input, "tos %d", &tos_val))
8324 tos = 1;
8325 else if (unformat (input, "length %d", &length_val))
8326 length = 1;
8327 else if (unformat (input, "fragment_id %d", &fragment_id_val))
8328 fragment_id = 1;
8329 else if (unformat (input, "ttl %d", &ttl_val))
8330 ttl = 1;
8331 else if (unformat (input, "checksum %d", &checksum_val))
8332 checksum = 1;
8333 else
8334 break;
8335 }
8336
8337 if (version + hdr_length + src + dst + proto + tos + length + fragment_id
8338 + ttl + checksum == 0)
8339 return 0;
8340
8341 /*
8342 * Aligned because we use the real comparison functions
8343 */
8344 vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8345
8346 ip = (ip4_header_t *) match;
8347
8348 /* These are realistically matched in practice */
8349 if (src)
8350 ip->src_address.as_u32 = src_val.as_u32;
8351
8352 if (dst)
8353 ip->dst_address.as_u32 = dst_val.as_u32;
8354
8355 if (proto)
8356 ip->protocol = proto_val;
8357
8358
8359 /* These are not, but they're included for completeness */
8360 if (version)
8361 ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
8362
8363 if (hdr_length)
8364 ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
8365
8366 if (tos)
8367 ip->tos = tos_val;
8368
8369 if (length)
8370 ip->length = clib_host_to_net_u16 (length_val);
8371
8372 if (ttl)
8373 ip->ttl = ttl_val;
8374
8375 if (checksum)
8376 ip->checksum = clib_host_to_net_u16 (checksum_val);
8377
8378 *matchp = match;
8379 return 1;
8380}
8381
8382uword
8383unformat_ip6_match (unformat_input_t * input, va_list * args)
8384{
8385 u8 **matchp = va_arg (*args, u8 **);
8386 u8 *match = 0;
8387 ip6_header_t *ip;
8388 int version = 0;
8389 u32 version_val;
8390 u8 traffic_class = 0;
8391 u32 traffic_class_val = 0;
8392 u8 flow_label = 0;
8393 u8 flow_label_val;
8394 int src = 0, dst = 0;
8395 ip6_address_t src_val, dst_val;
8396 int proto = 0;
8397 u32 proto_val;
8398 int payload_length = 0;
8399 u32 payload_length_val;
8400 int hop_limit = 0;
8401 int hop_limit_val;
8402 u32 ip_version_traffic_class_and_flow_label;
8403
8404 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8405 {
8406 if (unformat (input, "version %d", &version_val))
8407 version = 1;
8408 else if (unformat (input, "traffic_class %d", &traffic_class_val))
8409 traffic_class = 1;
8410 else if (unformat (input, "flow_label %d", &flow_label_val))
8411 flow_label = 1;
8412 else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
8413 src = 1;
8414 else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
8415 dst = 1;
8416 else if (unformat (input, "proto %d", &proto_val))
8417 proto = 1;
8418 else if (unformat (input, "payload_length %d", &payload_length_val))
8419 payload_length = 1;
8420 else if (unformat (input, "hop_limit %d", &hop_limit_val))
8421 hop_limit = 1;
8422 else
8423 break;
8424 }
8425
8426 if (version + traffic_class + flow_label + src + dst + proto +
8427 payload_length + hop_limit == 0)
8428 return 0;
8429
8430 /*
8431 * Aligned because we use the real comparison functions
8432 */
8433 vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8434
8435 ip = (ip6_header_t *) match;
8436
8437 if (src)
8438 clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
8439
8440 if (dst)
8441 clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
8442
8443 if (proto)
8444 ip->protocol = proto_val;
8445
8446 ip_version_traffic_class_and_flow_label = 0;
8447
8448 if (version)
8449 ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
8450
8451 if (traffic_class)
8452 ip_version_traffic_class_and_flow_label |=
8453 (traffic_class_val & 0xFF) << 20;
8454
8455 if (flow_label)
8456 ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
8457
8458 ip->ip_version_traffic_class_and_flow_label =
8459 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8460
8461 if (payload_length)
8462 ip->payload_length = clib_host_to_net_u16 (payload_length_val);
8463
8464 if (hop_limit)
8465 ip->hop_limit = hop_limit_val;
8466
8467 *matchp = match;
8468 return 1;
8469}
8470
8471uword
8472unformat_l3_match (unformat_input_t * input, va_list * args)
8473{
8474 u8 **matchp = va_arg (*args, u8 **);
8475
8476 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8477 {
8478 if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
8479 return 1;
8480 else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
8481 return 1;
8482 else
8483 break;
8484 }
8485 return 0;
8486}
8487
8488uword
8489unformat_vlan_tag (unformat_input_t * input, va_list * args)
8490{
8491 u8 *tagp = va_arg (*args, u8 *);
8492 u32 tag;
8493
8494 if (unformat (input, "%d", &tag))
8495 {
8496 tagp[0] = (tag >> 8) & 0x0F;
8497 tagp[1] = tag & 0xFF;
8498 return 1;
8499 }
8500
8501 return 0;
8502}
8503
8504uword
8505unformat_l2_match (unformat_input_t * input, va_list * args)
8506{
8507 u8 **matchp = va_arg (*args, u8 **);
8508 u8 *match = 0;
8509 u8 src = 0;
8510 u8 src_val[6];
8511 u8 dst = 0;
8512 u8 dst_val[6];
8513 u8 proto = 0;
8514 u16 proto_val;
8515 u8 tag1 = 0;
8516 u8 tag1_val[2];
8517 u8 tag2 = 0;
8518 u8 tag2_val[2];
8519 int len = 14;
8520 u8 ignore_tag1 = 0;
8521 u8 ignore_tag2 = 0;
8522 u8 cos1 = 0;
8523 u8 cos2 = 0;
8524 u32 cos1_val = 0;
8525 u32 cos2_val = 0;
8526
8527 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8528 {
8529 if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
8530 src = 1;
8531 else
8532 if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
8533 dst = 1;
8534 else if (unformat (input, "proto %U",
8535 unformat_ethernet_type_host_byte_order, &proto_val))
8536 proto = 1;
8537 else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
8538 tag1 = 1;
8539 else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
8540 tag2 = 1;
8541 else if (unformat (input, "ignore-tag1"))
8542 ignore_tag1 = 1;
8543 else if (unformat (input, "ignore-tag2"))
8544 ignore_tag2 = 1;
8545 else if (unformat (input, "cos1 %d", &cos1_val))
8546 cos1 = 1;
8547 else if (unformat (input, "cos2 %d", &cos2_val))
8548 cos2 = 1;
8549 else
8550 break;
8551 }
8552 if ((src + dst + proto + tag1 + tag2 +
8553 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8554 return 0;
8555
8556 if (tag1 || ignore_tag1 || cos1)
8557 len = 18;
8558 if (tag2 || ignore_tag2 || cos2)
8559 len = 22;
8560
8561 vec_validate_aligned (match, len - 1, sizeof (u32x4));
8562
8563 if (dst)
8564 clib_memcpy (match, dst_val, 6);
8565
8566 if (src)
8567 clib_memcpy (match + 6, src_val, 6);
8568
8569 if (tag2)
8570 {
8571 /* inner vlan tag */
8572 match[19] = tag2_val[1];
8573 match[18] = tag2_val[0];
8574 if (cos2)
8575 match[18] |= (cos2_val & 0x7) << 5;
8576 if (proto)
8577 {
8578 match[21] = proto_val & 0xff;
8579 match[20] = proto_val >> 8;
8580 }
8581 if (tag1)
8582 {
8583 match[15] = tag1_val[1];
8584 match[14] = tag1_val[0];
8585 }
8586 if (cos1)
8587 match[14] |= (cos1_val & 0x7) << 5;
8588 *matchp = match;
8589 return 1;
8590 }
8591 if (tag1)
8592 {
8593 match[15] = tag1_val[1];
8594 match[14] = tag1_val[0];
8595 if (proto)
8596 {
8597 match[17] = proto_val & 0xff;
8598 match[16] = proto_val >> 8;
8599 }
8600 if (cos1)
8601 match[14] |= (cos1_val & 0x7) << 5;
8602
8603 *matchp = match;
8604 return 1;
8605 }
8606 if (cos2)
8607 match[18] |= (cos2_val & 0x7) << 5;
8608 if (cos1)
8609 match[14] |= (cos1_val & 0x7) << 5;
8610 if (proto)
8611 {
8612 match[13] = proto_val & 0xff;
8613 match[12] = proto_val >> 8;
8614 }
8615
8616 *matchp = match;
8617 return 1;
8618}
Igor Mikhailov (imichail)582caa32018-04-26 21:33:02 -07008619
8620uword
8621unformat_qos_source (unformat_input_t * input, va_list * args)
8622{
8623 int *qs = va_arg (*args, int *);
8624
8625 if (unformat (input, "ip"))
8626 *qs = QOS_SOURCE_IP;
8627 else if (unformat (input, "mpls"))
8628 *qs = QOS_SOURCE_MPLS;
8629 else if (unformat (input, "ext"))
8630 *qs = QOS_SOURCE_EXT;
8631 else if (unformat (input, "vlan"))
8632 *qs = QOS_SOURCE_VLAN;
8633 else
8634 return 0;
8635
8636 return 1;
8637}
Dave Barach4a3f69c2017-02-22 12:44:56 -05008638#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +01008639
8640uword
Dave Barach4a3f69c2017-02-22 12:44:56 -05008641api_unformat_classify_match (unformat_input_t * input, va_list * args)
Damjan Marion7cd468a2016-12-19 23:05:39 +01008642{
8643 u8 **matchp = va_arg (*args, u8 **);
8644 u32 skip_n_vectors = va_arg (*args, u32);
8645 u32 match_n_vectors = va_arg (*args, u32);
8646
8647 u8 *match = 0;
8648 u8 *l2 = 0;
8649 u8 *l3 = 0;
8650 u8 *l4 = 0;
8651
8652 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8653 {
8654 if (unformat (input, "hex %U", unformat_hex_string, &match))
8655 ;
8656 else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
8657 ;
8658 else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
8659 ;
8660 else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
8661 ;
8662 else
8663 break;
8664 }
8665
8666 if (l4 && !l3)
8667 {
8668 vec_free (match);
8669 vec_free (l2);
8670 vec_free (l4);
8671 return 0;
8672 }
8673
8674 if (match || l2 || l3 || l4)
8675 {
8676 if (l2 || l3 || l4)
8677 {
8678 /* "Win a free Ethernet header in every packet" */
8679 if (l2 == 0)
8680 vec_validate_aligned (l2, 13, sizeof (u32x4));
8681 match = l2;
8682 if (vec_len (l3))
8683 {
8684 vec_append_aligned (match, l3, sizeof (u32x4));
8685 vec_free (l3);
8686 }
8687 if (vec_len (l4))
8688 {
8689 vec_append_aligned (match, l4, sizeof (u32x4));
8690 vec_free (l4);
8691 }
8692 }
8693
8694 /* Make sure the vector is big enough even if key is all 0's */
8695 vec_validate_aligned
8696 (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
8697 sizeof (u32x4));
8698
8699 /* Set size, include skipped vectors */
8700 _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
8701
8702 *matchp = match;
8703
8704 return 1;
8705 }
8706
8707 return 0;
8708}
8709
8710static int
8711api_classify_add_del_session (vat_main_t * vam)
8712{
8713 unformat_input_t *i = vam->input;
8714 vl_api_classify_add_del_session_t *mp;
8715 int is_add = 1;
8716 u32 table_index = ~0;
8717 u32 hit_next_index = ~0;
8718 u32 opaque_index = ~0;
8719 u8 *match = 0;
8720 i32 advance = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008721 u32 skip_n_vectors = 0;
8722 u32 match_n_vectors = 0;
8723 u32 action = 0;
8724 u32 metadata = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008725 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008726
8727 /*
8728 * Warning: you have to supply skip_n and match_n
8729 * because the API client cant simply look at the classify
8730 * table object.
8731 */
8732
8733 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8734 {
8735 if (unformat (i, "del"))
8736 is_add = 0;
Dave Barach4a3f69c2017-02-22 12:44:56 -05008737 else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
Damjan Marion7cd468a2016-12-19 23:05:39 +01008738 &hit_next_index))
8739 ;
8740 else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
8741 &hit_next_index))
8742 ;
Dave Barach4a3f69c2017-02-22 12:44:56 -05008743 else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
Damjan Marion7cd468a2016-12-19 23:05:39 +01008744 &hit_next_index))
8745 ;
8746 else if (unformat (i, "policer-hit-next %d", &hit_next_index))
8747 ;
8748 else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
8749 ;
8750 else if (unformat (i, "opaque-index %d", &opaque_index))
8751 ;
8752 else if (unformat (i, "skip_n %d", &skip_n_vectors))
8753 ;
8754 else if (unformat (i, "match_n %d", &match_n_vectors))
8755 ;
Dave Barach4a3f69c2017-02-22 12:44:56 -05008756 else if (unformat (i, "match %U", api_unformat_classify_match,
Damjan Marion7cd468a2016-12-19 23:05:39 +01008757 &match, skip_n_vectors, match_n_vectors))
8758 ;
8759 else if (unformat (i, "advance %d", &advance))
8760 ;
8761 else if (unformat (i, "table-index %d", &table_index))
8762 ;
8763 else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
8764 action = 1;
8765 else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
8766 action = 2;
8767 else if (unformat (i, "action %d", &action))
8768 ;
8769 else if (unformat (i, "metadata %d", &metadata))
8770 ;
8771 else
8772 break;
8773 }
8774
8775 if (table_index == ~0)
8776 {
8777 errmsg ("Table index required");
8778 return -99;
8779 }
8780
8781 if (is_add && match == 0)
8782 {
8783 errmsg ("Match value required");
8784 return -99;
8785 }
8786
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008787 M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
Damjan Marion7cd468a2016-12-19 23:05:39 +01008788
8789 mp->is_add = is_add;
8790 mp->table_index = ntohl (table_index);
8791 mp->hit_next_index = ntohl (hit_next_index);
8792 mp->opaque_index = ntohl (opaque_index);
8793 mp->advance = ntohl (advance);
8794 mp->action = action;
8795 mp->metadata = ntohl (metadata);
Juraj Sloboda75282452018-06-12 14:20:49 +02008796 mp->match_len = ntohl (vec_len (match));
Damjan Marion7cd468a2016-12-19 23:05:39 +01008797 clib_memcpy (mp->match, match, vec_len (match));
8798 vec_free (match);
8799
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008800 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008801 W (ret);
8802 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008803}
8804
8805static int
8806api_classify_set_interface_ip_table (vat_main_t * vam)
8807{
8808 unformat_input_t *i = vam->input;
8809 vl_api_classify_set_interface_ip_table_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008810 u32 sw_if_index;
8811 int sw_if_index_set;
8812 u32 table_index = ~0;
8813 u8 is_ipv6 = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008814 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008815
8816 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8817 {
8818 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8819 sw_if_index_set = 1;
8820 else if (unformat (i, "sw_if_index %d", &sw_if_index))
8821 sw_if_index_set = 1;
8822 else if (unformat (i, "table %d", &table_index))
8823 ;
8824 else
8825 {
8826 clib_warning ("parse error '%U'", format_unformat_error, i);
8827 return -99;
8828 }
8829 }
8830
8831 if (sw_if_index_set == 0)
8832 {
8833 errmsg ("missing interface name or sw_if_index");
8834 return -99;
8835 }
8836
8837
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008838 M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008839
8840 mp->sw_if_index = ntohl (sw_if_index);
8841 mp->table_index = ntohl (table_index);
8842 mp->is_ipv6 = is_ipv6;
8843
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008844 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008845 W (ret);
8846 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008847}
8848
8849static int
8850api_classify_set_interface_l2_tables (vat_main_t * vam)
8851{
8852 unformat_input_t *i = vam->input;
8853 vl_api_classify_set_interface_l2_tables_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008854 u32 sw_if_index;
8855 int sw_if_index_set;
8856 u32 ip4_table_index = ~0;
8857 u32 ip6_table_index = ~0;
8858 u32 other_table_index = ~0;
8859 u32 is_input = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008860 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008861
8862 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8863 {
8864 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8865 sw_if_index_set = 1;
8866 else if (unformat (i, "sw_if_index %d", &sw_if_index))
8867 sw_if_index_set = 1;
8868 else if (unformat (i, "ip4-table %d", &ip4_table_index))
8869 ;
8870 else if (unformat (i, "ip6-table %d", &ip6_table_index))
8871 ;
8872 else if (unformat (i, "other-table %d", &other_table_index))
8873 ;
8874 else if (unformat (i, "is-input %d", &is_input))
8875 ;
8876 else
8877 {
8878 clib_warning ("parse error '%U'", format_unformat_error, i);
8879 return -99;
8880 }
8881 }
8882
8883 if (sw_if_index_set == 0)
8884 {
8885 errmsg ("missing interface name or sw_if_index");
8886 return -99;
8887 }
8888
8889
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008890 M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008891
8892 mp->sw_if_index = ntohl (sw_if_index);
8893 mp->ip4_table_index = ntohl (ip4_table_index);
8894 mp->ip6_table_index = ntohl (ip6_table_index);
8895 mp->other_table_index = ntohl (other_table_index);
8896 mp->is_input = (u8) is_input;
8897
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008898 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008899 W (ret);
8900 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008901}
8902
8903static int
8904api_set_ipfix_exporter (vat_main_t * vam)
8905{
8906 unformat_input_t *i = vam->input;
8907 vl_api_set_ipfix_exporter_t *mp;
8908 ip4_address_t collector_address;
8909 u8 collector_address_set = 0;
8910 u32 collector_port = ~0;
8911 ip4_address_t src_address;
8912 u8 src_address_set = 0;
8913 u32 vrf_id = ~0;
8914 u32 path_mtu = ~0;
8915 u32 template_interval = ~0;
8916 u8 udp_checksum = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008917 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008918
8919 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8920 {
8921 if (unformat (i, "collector_address %U", unformat_ip4_address,
8922 &collector_address))
8923 collector_address_set = 1;
8924 else if (unformat (i, "collector_port %d", &collector_port))
8925 ;
8926 else if (unformat (i, "src_address %U", unformat_ip4_address,
8927 &src_address))
8928 src_address_set = 1;
8929 else if (unformat (i, "vrf_id %d", &vrf_id))
8930 ;
8931 else if (unformat (i, "path_mtu %d", &path_mtu))
8932 ;
8933 else if (unformat (i, "template_interval %d", &template_interval))
8934 ;
8935 else if (unformat (i, "udp_checksum"))
8936 udp_checksum = 1;
8937 else
8938 break;
8939 }
8940
8941 if (collector_address_set == 0)
8942 {
8943 errmsg ("collector_address required");
8944 return -99;
8945 }
8946
8947 if (src_address_set == 0)
8948 {
8949 errmsg ("src_address required");
8950 return -99;
8951 }
8952
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008953 M (SET_IPFIX_EXPORTER, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008954
Jakub Grajciar2f71a882019-10-10 14:21:22 +02008955 memcpy (mp->collector_address.un.ip4, collector_address.data,
Damjan Marion7cd468a2016-12-19 23:05:39 +01008956 sizeof (collector_address.data));
8957 mp->collector_port = htons ((u16) collector_port);
Jakub Grajciar2f71a882019-10-10 14:21:22 +02008958 memcpy (mp->src_address.un.ip4, src_address.data,
8959 sizeof (src_address.data));
Damjan Marion7cd468a2016-12-19 23:05:39 +01008960 mp->vrf_id = htonl (vrf_id);
8961 mp->path_mtu = htonl (path_mtu);
8962 mp->template_interval = htonl (template_interval);
8963 mp->udp_checksum = udp_checksum;
8964
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008965 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008966 W (ret);
8967 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008968}
8969
8970static int
8971api_set_ipfix_classify_stream (vat_main_t * vam)
8972{
8973 unformat_input_t *i = vam->input;
8974 vl_api_set_ipfix_classify_stream_t *mp;
8975 u32 domain_id = 0;
8976 u32 src_port = UDP_DST_PORT_ipfix;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008977 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008978
8979 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8980 {
8981 if (unformat (i, "domain %d", &domain_id))
8982 ;
8983 else if (unformat (i, "src_port %d", &src_port))
8984 ;
8985 else
8986 {
8987 errmsg ("unknown input `%U'", format_unformat_error, i);
8988 return -99;
8989 }
8990 }
8991
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008992 M (SET_IPFIX_CLASSIFY_STREAM, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008993
8994 mp->domain_id = htonl (domain_id);
8995 mp->src_port = htons ((u16) src_port);
8996
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008997 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008998 W (ret);
8999 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009000}
9001
9002static int
9003api_ipfix_classify_table_add_del (vat_main_t * vam)
9004{
9005 unformat_input_t *i = vam->input;
9006 vl_api_ipfix_classify_table_add_del_t *mp;
9007 int is_add = -1;
9008 u32 classify_table_index = ~0;
9009 u8 ip_version = 0;
9010 u8 transport_protocol = 255;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009011 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009012
9013 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9014 {
9015 if (unformat (i, "add"))
9016 is_add = 1;
9017 else if (unformat (i, "del"))
9018 is_add = 0;
9019 else if (unformat (i, "table %d", &classify_table_index))
9020 ;
9021 else if (unformat (i, "ip4"))
9022 ip_version = 4;
9023 else if (unformat (i, "ip6"))
9024 ip_version = 6;
9025 else if (unformat (i, "tcp"))
9026 transport_protocol = 6;
9027 else if (unformat (i, "udp"))
9028 transport_protocol = 17;
9029 else
9030 {
9031 errmsg ("unknown input `%U'", format_unformat_error, i);
9032 return -99;
9033 }
9034 }
9035
9036 if (is_add == -1)
9037 {
9038 errmsg ("expecting: add|del");
9039 return -99;
9040 }
9041 if (classify_table_index == ~0)
9042 {
9043 errmsg ("classifier table not specified");
9044 return -99;
9045 }
9046 if (ip_version == 0)
9047 {
9048 errmsg ("IP version not specified");
9049 return -99;
9050 }
9051
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009052 M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009053
9054 mp->is_add = is_add;
9055 mp->table_id = htonl (classify_table_index);
9056 mp->ip_version = ip_version;
9057 mp->transport_protocol = transport_protocol;
9058
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009059 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06009060 W (ret);
9061 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009062}
9063
9064static int
9065api_get_node_index (vat_main_t * vam)
9066{
9067 unformat_input_t *i = vam->input;
9068 vl_api_get_node_index_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009069 u8 *name = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009070 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009071
9072 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9073 {
9074 if (unformat (i, "node %s", &name))
9075 ;
9076 else
9077 break;
9078 }
9079 if (name == 0)
9080 {
9081 errmsg ("node name required");
9082 return -99;
9083 }
9084 if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9085 {
9086 errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9087 return -99;
9088 }
9089
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009090 M (GET_NODE_INDEX, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009091 clib_memcpy (mp->node_name, name, vec_len (name));
9092 vec_free (name);
9093
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009094 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06009095 W (ret);
9096 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009097}
9098
9099static int
9100api_get_next_index (vat_main_t * vam)
9101{
9102 unformat_input_t *i = vam->input;
9103 vl_api_get_next_index_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009104 u8 *node_name = 0, *next_node_name = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009105 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009106
9107 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9108 {
9109 if (unformat (i, "node-name %s", &node_name))
9110 ;
9111 else if (unformat (i, "next-node-name %s", &next_node_name))
9112 break;
9113 }
9114
9115 if (node_name == 0)
9116 {
9117 errmsg ("node name required");
9118 return -99;
9119 }
9120 if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
9121 {
9122 errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9123 return -99;
9124 }
9125
9126 if (next_node_name == 0)
9127 {
9128 errmsg ("next node name required");
9129 return -99;
9130 }
9131 if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
9132 {
9133 errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
9134 return -99;
9135 }
9136
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009137 M (GET_NEXT_INDEX, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009138 clib_memcpy (mp->node_name, node_name, vec_len (node_name));
9139 clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
9140 vec_free (node_name);
9141 vec_free (next_node_name);
9142
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009143 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06009144 W (ret);
9145 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009146}
9147
9148static int
9149api_add_node_next (vat_main_t * vam)
9150{
9151 unformat_input_t *i = vam->input;
9152 vl_api_add_node_next_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009153 u8 *name = 0;
9154 u8 *next = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009155 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009156
9157 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9158 {
9159 if (unformat (i, "node %s", &name))
9160 ;
9161 else if (unformat (i, "next %s", &next))
9162 ;
9163 else
9164 break;
9165 }
9166 if (name == 0)
9167 {
9168 errmsg ("node name required");
9169 return -99;
9170 }
9171 if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9172 {
9173 errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9174 return -99;
9175 }
9176 if (next == 0)
9177 {
9178 errmsg ("next node required");
9179 return -99;
9180 }
9181 if (vec_len (next) >= ARRAY_LEN (mp->next_name))
9182 {
9183 errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
9184 return -99;
9185 }
9186
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009187 M (ADD_NODE_NEXT, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009188 clib_memcpy (mp->node_name, name, vec_len (name));
9189 clib_memcpy (mp->next_name, next, vec_len (next));
9190 vec_free (name);
9191 vec_free (next);
9192
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009193 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06009194 W (ret);
9195 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009196}
9197
Damjan Marion8389fb92017-10-13 18:29:53 +02009198static void vl_api_sw_interface_tap_v2_details_t_handler
9199 (vl_api_sw_interface_tap_v2_details_t * mp)
9200{
9201 vat_main_t *vam = &vat_main;
9202
Jakub Grajciar5de4fb72019-09-03 10:40:01 +02009203 u8 *ip4 =
9204 format (0, "%U/%d", format_ip4_address, mp->host_ip4_prefix.address,
9205 mp->host_ip4_prefix.len);
9206 u8 *ip6 =
9207 format (0, "%U/%d", format_ip6_address, mp->host_ip6_prefix.address,
9208 mp->host_ip6_prefix.len);
Milan Lenco73e7f422017-12-14 10:04:25 +01009209
9210 print (vam->ofp,
Andrew Yourtchenko754f24b2019-01-07 20:56:46 +01009211 "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
Milan Lenco73e7f422017-12-14 10:04:25 +01009212 mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
9213 ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
9214 format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
Andrew Yourtchenko754f24b2019-01-07 20:56:46 +01009215 mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
Milan Lenco73e7f422017-12-14 10:04:25 +01009216
9217 vec_free (ip4);
9218 vec_free (ip6);
Damjan Marion8389fb92017-10-13 18:29:53 +02009219}
9220
9221static void vl_api_sw_interface_tap_v2_details_t_handler_json
9222 (vl_api_sw_interface_tap_v2_details_t * mp)
9223{
9224 vat_main_t *vam = &vat_main;
9225 vat_json_node_t *node = NULL;
9226
9227 if (VAT_JSON_ARRAY != vam->json_tree.type)
9228 {
9229 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9230 vat_json_init_array (&vam->json_tree);
9231 }
9232 node = vat_json_array_add (&vam->json_tree);
9233
9234 vat_json_init_object (node);
Milan Lenco73e7f422017-12-14 10:04:25 +01009235 vat_json_object_add_uint (node, "id", ntohl (mp->id));
Damjan Marion8389fb92017-10-13 18:29:53 +02009236 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
Andrew Yourtchenko754f24b2019-01-07 20:56:46 +01009237 vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
Damjan Marion8389fb92017-10-13 18:29:53 +02009238 vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
Milan Lenco73e7f422017-12-14 10:04:25 +01009239 vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
9240 vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
9241 vat_json_object_add_string_copy (node, "host_mac_addr",
9242 format (0, "%U", format_ethernet_address,
9243 &mp->host_mac_addr));
9244 vat_json_object_add_string_copy (node, "host_namespace",
9245 mp->host_namespace);
9246 vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
9247 vat_json_object_add_string_copy (node, "host_ip4_addr",
9248 format (0, "%U/%d", format_ip4_address,
Jakub Grajciar5de4fb72019-09-03 10:40:01 +02009249 mp->host_ip4_prefix.address,
9250 mp->host_ip4_prefix.len));
9251 vat_json_object_add_string_copy (node, "host_ip6_prefix",
Milan Lenco73e7f422017-12-14 10:04:25 +01009252 format (0, "%U/%d", format_ip6_address,
Jakub Grajciar5de4fb72019-09-03 10:40:01 +02009253 mp->host_ip6_prefix.address,
9254 mp->host_ip6_prefix.len));
Milan Lenco73e7f422017-12-14 10:04:25 +01009255
Damjan Marion8389fb92017-10-13 18:29:53 +02009256}
9257
9258static int
9259api_sw_interface_tap_v2_dump (vat_main_t * vam)
9260{
9261 vl_api_sw_interface_tap_v2_dump_t *mp;
9262 vl_api_control_ping_t *mp_ping;
9263 int ret;
9264
Milan Lenco73e7f422017-12-14 10:04:25 +01009265 print (vam->ofp,
9266 "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
9267 "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
9268 "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
9269 "host_ip6_addr");
9270
Damjan Marion8389fb92017-10-13 18:29:53 +02009271 /* Get list of tap interfaces */
9272 M (SW_INTERFACE_TAP_V2_DUMP, mp);
9273 S (mp);
9274
9275 /* Use a control ping for synchronization */
9276 MPING (CONTROL_PING, mp_ping);
9277 S (mp_ping);
9278
9279 W (ret);
9280 return ret;
9281}
9282
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01009283static void vl_api_sw_interface_virtio_pci_details_t_handler
9284 (vl_api_sw_interface_virtio_pci_details_t * mp)
9285{
9286 vat_main_t *vam = &vat_main;
9287
9288 typedef union
9289 {
9290 struct
9291 {
9292 u16 domain;
9293 u8 bus;
9294 u8 slot:5;
9295 u8 function:3;
9296 };
9297 u32 as_u32;
9298 } pci_addr_t;
9299 pci_addr_t addr;
Jakub Grajciar2c504f82019-09-26 10:34:41 +02009300
9301 addr.domain = ntohs (mp->pci_addr.domain);
9302 addr.bus = mp->pci_addr.bus;
9303 addr.slot = mp->pci_addr.slot;
9304 addr.function = mp->pci_addr.function;
9305
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01009306 u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
9307 addr.slot, addr.function);
9308
9309 print (vam->ofp,
9310 "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
9311 pci_addr, ntohl (mp->sw_if_index),
9312 ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
9313 format_ethernet_address, mp->mac_addr,
9314 clib_net_to_host_u64 (mp->features));
9315 vec_free (pci_addr);
9316}
9317
9318static void vl_api_sw_interface_virtio_pci_details_t_handler_json
9319 (vl_api_sw_interface_virtio_pci_details_t * mp)
9320{
9321 vat_main_t *vam = &vat_main;
9322 vat_json_node_t *node = NULL;
Jakub Grajciar2c504f82019-09-26 10:34:41 +02009323 vlib_pci_addr_t pci_addr;
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01009324
9325 if (VAT_JSON_ARRAY != vam->json_tree.type)
9326 {
9327 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9328 vat_json_init_array (&vam->json_tree);
9329 }
9330 node = vat_json_array_add (&vam->json_tree);
9331
Jakub Grajciar2c504f82019-09-26 10:34:41 +02009332 pci_addr.domain = ntohs (mp->pci_addr.domain);
9333 pci_addr.bus = mp->pci_addr.bus;
9334 pci_addr.slot = mp->pci_addr.slot;
9335 pci_addr.function = mp->pci_addr.function;
9336
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01009337 vat_json_init_object (node);
Jakub Grajciar2c504f82019-09-26 10:34:41 +02009338 vat_json_object_add_uint (node, "pci-addr", pci_addr.as_u32);
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01009339 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9340 vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
9341 vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
9342 vat_json_object_add_uint (node, "features",
9343 clib_net_to_host_u64 (mp->features));
9344 vat_json_object_add_string_copy (node, "mac_addr",
9345 format (0, "%U", format_ethernet_address,
9346 &mp->mac_addr));
9347}
9348
9349static int
9350api_sw_interface_virtio_pci_dump (vat_main_t * vam)
9351{
9352 vl_api_sw_interface_virtio_pci_dump_t *mp;
9353 vl_api_control_ping_t *mp_ping;
9354 int ret;
9355
9356 print (vam->ofp,
9357 "\n%-12s %-12s %-12s %-12s %-17s %-08s",
9358 "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
9359 "mac_addr", "features");
9360
9361 /* Get list of tap interfaces */
9362 M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
9363 S (mp);
9364
9365 /* Use a control ping for synchronization */
9366 MPING (CONTROL_PING, mp_ping);
9367 S (mp_ping);
9368
9369 W (ret);
9370 return ret;
9371}
9372
eyal bariaf86a482018-04-17 11:20:27 +03009373static int
9374api_vxlan_offload_rx (vat_main_t * vam)
9375{
9376 unformat_input_t *line_input = vam->input;
9377 vl_api_vxlan_offload_rx_t *mp;
9378 u32 hw_if_index = ~0, rx_if_index = ~0;
9379 u8 is_add = 1;
9380 int ret;
9381
9382 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9383 {
9384 if (unformat (line_input, "del"))
9385 is_add = 0;
9386 else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
9387 &hw_if_index))
9388 ;
9389 else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
9390 ;
9391 else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
9392 &rx_if_index))
9393 ;
9394 else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
9395 ;
9396 else
9397 {
9398 errmsg ("parse error '%U'", format_unformat_error, line_input);
9399 return -99;
9400 }
9401 }
9402
9403 if (hw_if_index == ~0)
9404 {
9405 errmsg ("no hw interface");
9406 return -99;
9407 }
9408
9409 if (rx_if_index == ~0)
9410 {
9411 errmsg ("no rx tunnel");
9412 return -99;
9413 }
9414
9415 M (VXLAN_OFFLOAD_RX, mp);
9416
9417 mp->hw_if_index = ntohl (hw_if_index);
9418 mp->sw_if_index = ntohl (rx_if_index);
9419 mp->enable = is_add;
9420
9421 S (mp);
9422 W (ret);
9423 return ret;
9424}
9425
Damjan Marion7cd468a2016-12-19 23:05:39 +01009426static uword unformat_vxlan_decap_next
9427 (unformat_input_t * input, va_list * args)
9428{
9429 u32 *result = va_arg (*args, u32 *);
9430 u32 tmp;
9431
9432 if (unformat (input, "l2"))
9433 *result = VXLAN_INPUT_NEXT_L2_INPUT;
9434 else if (unformat (input, "%d", &tmp))
9435 *result = tmp;
9436 else
9437 return 0;
9438 return 1;
9439}
9440
9441static int
9442api_vxlan_add_del_tunnel (vat_main_t * vam)
9443{
9444 unformat_input_t *line_input = vam->input;
9445 vl_api_vxlan_add_del_tunnel_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009446 ip46_address_t src, dst;
9447 u8 is_add = 1;
9448 u8 ipv4_set = 0, ipv6_set = 0;
9449 u8 src_set = 0;
9450 u8 dst_set = 0;
9451 u8 grp_set = 0;
Jon Loeliger3d460bd2018-02-01 16:36:12 -06009452 u32 instance = ~0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009453 u32 mcast_sw_if_index = ~0;
9454 u32 encap_vrf_id = 0;
9455 u32 decap_next_index = ~0;
9456 u32 vni = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009457 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009458
9459 /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
Dave Barachb7b92992018-10-17 10:38:51 -04009460 clib_memset (&src, 0, sizeof src);
9461 clib_memset (&dst, 0, sizeof dst);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009462
9463 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9464 {
9465 if (unformat (line_input, "del"))
9466 is_add = 0;
Jon Loeliger3d460bd2018-02-01 16:36:12 -06009467 else if (unformat (line_input, "instance %d", &instance))
9468 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009469 else
9470 if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
9471 {
9472 ipv4_set = 1;
9473 src_set = 1;
9474 }
9475 else
9476 if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
9477 {
9478 ipv4_set = 1;
9479 dst_set = 1;
9480 }
9481 else
9482 if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
9483 {
9484 ipv6_set = 1;
9485 src_set = 1;
9486 }
9487 else
9488 if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
9489 {
9490 ipv6_set = 1;
9491 dst_set = 1;
9492 }
9493 else if (unformat (line_input, "group %U %U",
9494 unformat_ip4_address, &dst.ip4,
9495 api_unformat_sw_if_index, vam, &mcast_sw_if_index))
9496 {
9497 grp_set = dst_set = 1;
9498 ipv4_set = 1;
9499 }
9500 else if (unformat (line_input, "group %U",
9501 unformat_ip4_address, &dst.ip4))
9502 {
9503 grp_set = dst_set = 1;
9504 ipv4_set = 1;
9505 }
9506 else if (unformat (line_input, "group %U %U",
9507 unformat_ip6_address, &dst.ip6,
9508 api_unformat_sw_if_index, vam, &mcast_sw_if_index))
9509 {
9510 grp_set = dst_set = 1;
9511 ipv6_set = 1;
9512 }
9513 else if (unformat (line_input, "group %U",
9514 unformat_ip6_address, &dst.ip6))
9515 {
9516 grp_set = dst_set = 1;
9517 ipv6_set = 1;
9518 }
9519 else
9520 if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
9521 ;
9522 else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
9523 ;
9524 else if (unformat (line_input, "decap-next %U",
9525 unformat_vxlan_decap_next, &decap_next_index))
9526 ;
9527 else if (unformat (line_input, "vni %d", &vni))
9528 ;
9529 else
9530 {
9531 errmsg ("parse error '%U'", format_unformat_error, line_input);
9532 return -99;
9533 }
9534 }
9535
9536 if (src_set == 0)
9537 {
9538 errmsg ("tunnel src address not specified");
9539 return -99;
9540 }
9541 if (dst_set == 0)
9542 {
9543 errmsg ("tunnel dst address not specified");
9544 return -99;
9545 }
9546
9547 if (grp_set && !ip46_address_is_multicast (&dst))
9548 {
9549 errmsg ("tunnel group address not multicast");
9550 return -99;
9551 }
9552 if (grp_set && mcast_sw_if_index == ~0)
9553 {
9554 errmsg ("tunnel nonexistent multicast device");
9555 return -99;
9556 }
9557 if (grp_set == 0 && ip46_address_is_multicast (&dst))
9558 {
9559 errmsg ("tunnel dst address must be unicast");
9560 return -99;
9561 }
9562
9563
9564 if (ipv4_set && ipv6_set)
9565 {
9566 errmsg ("both IPv4 and IPv6 addresses specified");
9567 return -99;
9568 }
9569
9570 if ((vni == 0) || (vni >> 24))
9571 {
9572 errmsg ("vni not specified or out of range");
9573 return -99;
9574 }
9575
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009576 M (VXLAN_ADD_DEL_TUNNEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009577
9578 if (ipv6_set)
9579 {
Jakub Grajciar7c0eb562020-03-02 13:55:31 +01009580 clib_memcpy (mp->src_address.un.ip6, &src.ip6, sizeof (src.ip6));
9581 clib_memcpy (mp->dst_address.un.ip6, &dst.ip6, sizeof (dst.ip6));
Damjan Marion7cd468a2016-12-19 23:05:39 +01009582 }
9583 else
9584 {
Jakub Grajciar7c0eb562020-03-02 13:55:31 +01009585 clib_memcpy (mp->src_address.un.ip4, &src.ip4, sizeof (src.ip4));
9586 clib_memcpy (mp->dst_address.un.ip4, &dst.ip4, sizeof (dst.ip4));
Damjan Marion7cd468a2016-12-19 23:05:39 +01009587 }
Jakub Grajciar7c0eb562020-03-02 13:55:31 +01009588 mp->src_address.af = ipv6_set;
9589 mp->dst_address.af = ipv6_set;
Jon Loeliger3d460bd2018-02-01 16:36:12 -06009590
9591 mp->instance = htonl (instance);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009592 mp->encap_vrf_id = ntohl (encap_vrf_id);
9593 mp->decap_next_index = ntohl (decap_next_index);
9594 mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
9595 mp->vni = ntohl (vni);
9596 mp->is_add = is_add;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009597
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009598 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06009599 W (ret);
9600 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009601}
9602
9603static void vl_api_vxlan_tunnel_details_t_handler
9604 (vl_api_vxlan_tunnel_details_t * mp)
9605{
9606 vat_main_t *vam = &vat_main;
Jakub Grajciar7c0eb562020-03-02 13:55:31 +01009607 ip46_address_t src =
9608 to_ip46 (mp->dst_address.af, (u8 *) & mp->dst_address.un);
9609 ip46_address_t dst =
9610 to_ip46 (mp->dst_address.af, (u8 *) & mp->src_address.un);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009611
Jon Loeliger3d460bd2018-02-01 16:36:12 -06009612 print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
Damjan Marion7cd468a2016-12-19 23:05:39 +01009613 ntohl (mp->sw_if_index),
Jon Loeliger3d460bd2018-02-01 16:36:12 -06009614 ntohl (mp->instance),
Damjan Marion7cd468a2016-12-19 23:05:39 +01009615 format_ip46_address, &src, IP46_TYPE_ANY,
9616 format_ip46_address, &dst, IP46_TYPE_ANY,
9617 ntohl (mp->encap_vrf_id),
9618 ntohl (mp->decap_next_index), ntohl (mp->vni),
9619 ntohl (mp->mcast_sw_if_index));
9620}
9621
9622static void vl_api_vxlan_tunnel_details_t_handler_json
9623 (vl_api_vxlan_tunnel_details_t * mp)
9624{
9625 vat_main_t *vam = &vat_main;
9626 vat_json_node_t *node = NULL;
9627
9628 if (VAT_JSON_ARRAY != vam->json_tree.type)
9629 {
9630 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9631 vat_json_init_array (&vam->json_tree);
9632 }
9633 node = vat_json_array_add (&vam->json_tree);
9634
9635 vat_json_init_object (node);
9636 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
Jon Loeliger3d460bd2018-02-01 16:36:12 -06009637
9638 vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
9639
Jakub Grajciar7c0eb562020-03-02 13:55:31 +01009640 if (mp->src_address.af)
Damjan Marion7cd468a2016-12-19 23:05:39 +01009641 {
9642 struct in6_addr ip6;
9643
Jakub Grajciar7c0eb562020-03-02 13:55:31 +01009644 clib_memcpy (&ip6, mp->src_address.un.ip6, sizeof (ip6));
Damjan Marion7cd468a2016-12-19 23:05:39 +01009645 vat_json_object_add_ip6 (node, "src_address", ip6);
Jakub Grajciar7c0eb562020-03-02 13:55:31 +01009646 clib_memcpy (&ip6, mp->dst_address.un.ip6, sizeof (ip6));
Damjan Marion7cd468a2016-12-19 23:05:39 +01009647 vat_json_object_add_ip6 (node, "dst_address", ip6);
9648 }
9649 else
9650 {
9651 struct in_addr ip4;
9652
Jakub Grajciar7c0eb562020-03-02 13:55:31 +01009653 clib_memcpy (&ip4, mp->src_address.un.ip4, sizeof (ip4));
Damjan Marion7cd468a2016-12-19 23:05:39 +01009654 vat_json_object_add_ip4 (node, "src_address", ip4);
Jakub Grajciar7c0eb562020-03-02 13:55:31 +01009655 clib_memcpy (&ip4, mp->dst_address.un.ip4, sizeof (ip4));
Damjan Marion7cd468a2016-12-19 23:05:39 +01009656 vat_json_object_add_ip4 (node, "dst_address", ip4);
9657 }
9658 vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
9659 vat_json_object_add_uint (node, "decap_next_index",
9660 ntohl (mp->decap_next_index));
9661 vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
Damjan Marion7cd468a2016-12-19 23:05:39 +01009662 vat_json_object_add_uint (node, "mcast_sw_if_index",
9663 ntohl (mp->mcast_sw_if_index));
9664}
9665
9666static int
9667api_vxlan_tunnel_dump (vat_main_t * vam)
9668{
9669 unformat_input_t *i = vam->input;
9670 vl_api_vxlan_tunnel_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -06009671 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009672 u32 sw_if_index;
9673 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009674 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009675
9676 /* Parse args required to build the message */
9677 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9678 {
9679 if (unformat (i, "sw_if_index %d", &sw_if_index))
9680 sw_if_index_set = 1;
9681 else
9682 break;
9683 }
9684
9685 if (sw_if_index_set == 0)
9686 {
9687 sw_if_index = ~0;
9688 }
9689
9690 if (!vam->json_output)
9691 {
Jon Loeliger3d460bd2018-02-01 16:36:12 -06009692 print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
9693 "sw_if_index", "instance", "src_address", "dst_address",
Damjan Marion7cd468a2016-12-19 23:05:39 +01009694 "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
9695 }
9696
9697 /* Get list of vxlan-tunnel interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009698 M (VXLAN_TUNNEL_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009699
9700 mp->sw_if_index = htonl (sw_if_index);
9701
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009702 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009703
9704 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -04009705 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06009706 S (mp_ping);
9707
Jon Loeliger56c7b012017-02-01 12:31:41 -06009708 W (ret);
9709 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009710}
9711
9712static int
Neale Ranns5a8844b2019-04-16 07:15:35 +00009713api_gre_tunnel_add_del (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +01009714{
9715 unformat_input_t *line_input = vam->input;
Neale Ranns5a8844b2019-04-16 07:15:35 +00009716 vl_api_address_t src = { }, dst =
9717 {
9718 };
9719 vl_api_gre_tunnel_add_del_t *mp;
9720 vl_api_gre_tunnel_type_t t_type;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009721 u8 is_add = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009722 u8 src_set = 0;
9723 u8 dst_set = 0;
Neale Ranns5f8f6172019-04-18 10:23:56 +00009724 u32 outer_table_id = 0;
John Loa43ccae2018-02-13 17:15:23 -05009725 u32 session_id = 0;
9726 u32 instance = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009727 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009728
Neale Ranns5a8844b2019-04-16 07:15:35 +00009729 t_type = GRE_API_TUNNEL_TYPE_L3;
Ciara Loftus7eac9162016-09-30 15:47:03 +01009730
Damjan Marion7cd468a2016-12-19 23:05:39 +01009731 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9732 {
9733 if (unformat (line_input, "del"))
9734 is_add = 0;
John Loa43ccae2018-02-13 17:15:23 -05009735 else if (unformat (line_input, "instance %d", &instance))
9736 ;
Neale Ranns5a8844b2019-04-16 07:15:35 +00009737 else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
Ciara Loftus7eac9162016-09-30 15:47:03 +01009738 {
9739 src_set = 1;
Ciara Loftus7eac9162016-09-30 15:47:03 +01009740 }
Neale Ranns5a8844b2019-04-16 07:15:35 +00009741 else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
Ciara Loftus7eac9162016-09-30 15:47:03 +01009742 {
9743 dst_set = 1;
Ciara Loftus7eac9162016-09-30 15:47:03 +01009744 }
Neale Ranns5f8f6172019-04-18 10:23:56 +00009745 else if (unformat (line_input, "outer-table-id %d", &outer_table_id))
Damjan Marion7cd468a2016-12-19 23:05:39 +01009746 ;
9747 else if (unformat (line_input, "teb"))
Neale Ranns5a8844b2019-04-16 07:15:35 +00009748 t_type = GRE_API_TUNNEL_TYPE_TEB;
John Loa43ccae2018-02-13 17:15:23 -05009749 else if (unformat (line_input, "erspan %d", &session_id))
Neale Ranns5a8844b2019-04-16 07:15:35 +00009750 t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009751 else
9752 {
9753 errmsg ("parse error '%U'", format_unformat_error, line_input);
9754 return -99;
9755 }
9756 }
9757
9758 if (src_set == 0)
9759 {
9760 errmsg ("tunnel src address not specified");
9761 return -99;
9762 }
9763 if (dst_set == 0)
9764 {
9765 errmsg ("tunnel dst address not specified");
9766 return -99;
9767 }
9768
Neale Ranns5a8844b2019-04-16 07:15:35 +00009769 M (GRE_TUNNEL_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009770
Neale Ranns5a8844b2019-04-16 07:15:35 +00009771 clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
9772 clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
Damjan Marion7cd468a2016-12-19 23:05:39 +01009773
Neale Ranns5a8844b2019-04-16 07:15:35 +00009774 mp->tunnel.instance = htonl (instance);
Neale Ranns5f8f6172019-04-18 10:23:56 +00009775 mp->tunnel.outer_table_id = htonl (outer_table_id);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009776 mp->is_add = is_add;
Neale Ranns5a8844b2019-04-16 07:15:35 +00009777 mp->tunnel.session_id = htons ((u16) session_id);
9778 mp->tunnel.type = htonl (t_type);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009779
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009780 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06009781 W (ret);
9782 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009783}
9784
9785static void vl_api_gre_tunnel_details_t_handler
9786 (vl_api_gre_tunnel_details_t * mp)
9787{
9788 vat_main_t *vam = &vat_main;
9789
John Loa43ccae2018-02-13 17:15:23 -05009790 print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
Neale Ranns5a8844b2019-04-16 07:15:35 +00009791 ntohl (mp->tunnel.sw_if_index),
9792 ntohl (mp->tunnel.instance),
9793 format_vl_api_address, &mp->tunnel.src,
9794 format_vl_api_address, &mp->tunnel.dst,
Neale Ranns5f8f6172019-04-18 10:23:56 +00009795 mp->tunnel.type, ntohl (mp->tunnel.outer_table_id),
Neale Ranns5a8844b2019-04-16 07:15:35 +00009796 ntohl (mp->tunnel.session_id));
9797}
9798
Damjan Marion7cd468a2016-12-19 23:05:39 +01009799static void vl_api_gre_tunnel_details_t_handler_json
9800 (vl_api_gre_tunnel_details_t * mp)
9801{
9802 vat_main_t *vam = &vat_main;
9803 vat_json_node_t *node = NULL;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009804
9805 if (VAT_JSON_ARRAY != vam->json_tree.type)
9806 {
9807 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9808 vat_json_init_array (&vam->json_tree);
9809 }
9810 node = vat_json_array_add (&vam->json_tree);
9811
9812 vat_json_init_object (node);
Neale Ranns5a8844b2019-04-16 07:15:35 +00009813 vat_json_object_add_uint (node, "sw_if_index",
9814 ntohl (mp->tunnel.sw_if_index));
9815 vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
9816
9817 vat_json_object_add_address (node, "src", &mp->tunnel.src);
9818 vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
9819 vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
Neale Ranns5f8f6172019-04-18 10:23:56 +00009820 vat_json_object_add_uint (node, "outer_table_id",
9821 ntohl (mp->tunnel.outer_table_id));
Neale Ranns5a8844b2019-04-16 07:15:35 +00009822 vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009823}
9824
9825static int
9826api_gre_tunnel_dump (vat_main_t * vam)
9827{
9828 unformat_input_t *i = vam->input;
9829 vl_api_gre_tunnel_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -06009830 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009831 u32 sw_if_index;
9832 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009833 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009834
9835 /* Parse args required to build the message */
9836 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9837 {
9838 if (unformat (i, "sw_if_index %d", &sw_if_index))
9839 sw_if_index_set = 1;
9840 else
9841 break;
9842 }
9843
9844 if (sw_if_index_set == 0)
9845 {
9846 sw_if_index = ~0;
9847 }
9848
9849 if (!vam->json_output)
9850 {
John Loa43ccae2018-02-13 17:15:23 -05009851 print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
9852 "sw_if_index", "instance", "src_address", "dst_address",
9853 "tunnel_type", "outer_fib_id", "session_id");
Damjan Marion7cd468a2016-12-19 23:05:39 +01009854 }
9855
9856 /* Get list of gre-tunnel interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009857 M (GRE_TUNNEL_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009858
9859 mp->sw_if_index = htonl (sw_if_index);
9860
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009861 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009862
9863 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -04009864 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06009865 S (mp_ping);
9866
Jon Loeliger56c7b012017-02-01 12:31:41 -06009867 W (ret);
9868 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009869}
9870
9871static int
9872api_l2_fib_clear_table (vat_main_t * vam)
9873{
9874// unformat_input_t * i = vam->input;
9875 vl_api_l2_fib_clear_table_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009876 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009877
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009878 M (L2_FIB_CLEAR_TABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009879
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009880 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06009881 W (ret);
9882 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009883}
9884
9885static int
9886api_l2_interface_efp_filter (vat_main_t * vam)
9887{
9888 unformat_input_t *i = vam->input;
9889 vl_api_l2_interface_efp_filter_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009890 u32 sw_if_index;
9891 u8 enable = 1;
9892 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009893 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009894
9895 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9896 {
9897 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9898 sw_if_index_set = 1;
9899 else if (unformat (i, "sw_if_index %d", &sw_if_index))
9900 sw_if_index_set = 1;
9901 else if (unformat (i, "enable"))
9902 enable = 1;
9903 else if (unformat (i, "disable"))
9904 enable = 0;
9905 else
9906 {
9907 clib_warning ("parse error '%U'", format_unformat_error, i);
9908 return -99;
9909 }
9910 }
9911
9912 if (sw_if_index_set == 0)
9913 {
9914 errmsg ("missing sw_if_index");
9915 return -99;
9916 }
9917
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009918 M (L2_INTERFACE_EFP_FILTER, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009919
9920 mp->sw_if_index = ntohl (sw_if_index);
9921 mp->enable_disable = enable;
9922
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009923 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06009924 W (ret);
9925 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009926}
9927
9928#define foreach_vtr_op \
9929_("disable", L2_VTR_DISABLED) \
9930_("push-1", L2_VTR_PUSH_1) \
9931_("push-2", L2_VTR_PUSH_2) \
9932_("pop-1", L2_VTR_POP_1) \
9933_("pop-2", L2_VTR_POP_2) \
9934_("translate-1-1", L2_VTR_TRANSLATE_1_1) \
9935_("translate-1-2", L2_VTR_TRANSLATE_1_2) \
9936_("translate-2-1", L2_VTR_TRANSLATE_2_1) \
9937_("translate-2-2", L2_VTR_TRANSLATE_2_2)
9938
9939static int
9940api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
9941{
9942 unformat_input_t *i = vam->input;
9943 vl_api_l2_interface_vlan_tag_rewrite_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009944 u32 sw_if_index;
9945 u8 sw_if_index_set = 0;
9946 u8 vtr_op_set = 0;
9947 u32 vtr_op = 0;
9948 u32 push_dot1q = 1;
9949 u32 tag1 = ~0;
9950 u32 tag2 = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009951 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009952
9953 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9954 {
9955 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9956 sw_if_index_set = 1;
9957 else if (unformat (i, "sw_if_index %d", &sw_if_index))
9958 sw_if_index_set = 1;
9959 else if (unformat (i, "vtr_op %d", &vtr_op))
9960 vtr_op_set = 1;
9961#define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
9962 foreach_vtr_op
9963#undef _
9964 else if (unformat (i, "push_dot1q %d", &push_dot1q))
9965 ;
9966 else if (unformat (i, "tag1 %d", &tag1))
9967 ;
9968 else if (unformat (i, "tag2 %d", &tag2))
9969 ;
9970 else
9971 {
9972 clib_warning ("parse error '%U'", format_unformat_error, i);
9973 return -99;
9974 }
9975 }
9976
9977 if ((sw_if_index_set == 0) || (vtr_op_set == 0))
9978 {
9979 errmsg ("missing vtr operation or sw_if_index");
9980 return -99;
9981 }
9982
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009983 M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
9984 mp->sw_if_index = ntohl (sw_if_index);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009985 mp->vtr_op = ntohl (vtr_op);
9986 mp->push_dot1q = ntohl (push_dot1q);
9987 mp->tag1 = ntohl (tag1);
9988 mp->tag2 = ntohl (tag2);
9989
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009990 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06009991 W (ret);
9992 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009993}
9994
9995static int
9996api_create_vhost_user_if (vat_main_t * vam)
9997{
9998 unformat_input_t *i = vam->input;
9999 vl_api_create_vhost_user_if_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010000 u8 *file_name;
10001 u8 is_server = 0;
10002 u8 file_name_set = 0;
10003 u32 custom_dev_instance = ~0;
10004 u8 hwaddr[6];
10005 u8 use_custom_mac = 0;
Mohsin Kazmiee2e58f2018-08-21 16:07:03 +020010006 u8 disable_mrg_rxbuf = 0;
10007 u8 disable_indirect_desc = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010008 u8 *tag = 0;
Steven Luong4208a4c2019-05-06 08:51:56 -070010009 u8 enable_gso = 0;
Steven Luongbc0d9ff2020-03-23 09:34:59 -070010010 u8 enable_packed = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010011 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010012
10013 /* Shut up coverity */
Dave Barachb7b92992018-10-17 10:38:51 -040010014 clib_memset (hwaddr, 0, sizeof (hwaddr));
Damjan Marion7cd468a2016-12-19 23:05:39 +010010015
10016 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10017 {
10018 if (unformat (i, "socket %s", &file_name))
10019 {
10020 file_name_set = 1;
10021 }
10022 else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10023 ;
10024 else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
10025 use_custom_mac = 1;
10026 else if (unformat (i, "server"))
10027 is_server = 1;
Mohsin Kazmiee2e58f2018-08-21 16:07:03 +020010028 else if (unformat (i, "disable_mrg_rxbuf"))
10029 disable_mrg_rxbuf = 1;
10030 else if (unformat (i, "disable_indirect_desc"))
10031 disable_indirect_desc = 1;
Steven Luong4208a4c2019-05-06 08:51:56 -070010032 else if (unformat (i, "gso"))
10033 enable_gso = 1;
Steven Luongbc0d9ff2020-03-23 09:34:59 -070010034 else if (unformat (i, "packed"))
10035 enable_packed = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010036 else if (unformat (i, "tag %s", &tag))
10037 ;
10038 else
10039 break;
10040 }
10041
10042 if (file_name_set == 0)
10043 {
10044 errmsg ("missing socket file name");
10045 return -99;
10046 }
10047
10048 if (vec_len (file_name) > 255)
10049 {
10050 errmsg ("socket file name too long");
10051 return -99;
10052 }
10053 vec_add1 (file_name, 0);
10054
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010055 M (CREATE_VHOST_USER_IF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010056
10057 mp->is_server = is_server;
Mohsin Kazmiee2e58f2018-08-21 16:07:03 +020010058 mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
10059 mp->disable_indirect_desc = disable_indirect_desc;
Steven Luong4208a4c2019-05-06 08:51:56 -070010060 mp->enable_gso = enable_gso;
Steven Luongbc0d9ff2020-03-23 09:34:59 -070010061 mp->enable_packed = enable_packed;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010062 clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10063 vec_free (file_name);
10064 if (custom_dev_instance != ~0)
10065 {
10066 mp->renumber = 1;
10067 mp->custom_dev_instance = ntohl (custom_dev_instance);
10068 }
Mohsin Kazmiee2e58f2018-08-21 16:07:03 +020010069
Damjan Marion7cd468a2016-12-19 23:05:39 +010010070 mp->use_custom_mac = use_custom_mac;
10071 clib_memcpy (mp->mac_address, hwaddr, 6);
10072 if (tag)
10073 strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
10074 vec_free (tag);
10075
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010076 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010077 W (ret);
10078 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010079}
10080
10081static int
10082api_modify_vhost_user_if (vat_main_t * vam)
10083{
10084 unformat_input_t *i = vam->input;
10085 vl_api_modify_vhost_user_if_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010086 u8 *file_name;
10087 u8 is_server = 0;
10088 u8 file_name_set = 0;
10089 u32 custom_dev_instance = ~0;
10090 u8 sw_if_index_set = 0;
10091 u32 sw_if_index = (u32) ~ 0;
Steven Luong4208a4c2019-05-06 08:51:56 -070010092 u8 enable_gso = 0;
Steven Luongbc0d9ff2020-03-23 09:34:59 -070010093 u8 enable_packed = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010094 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010095
10096 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10097 {
10098 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10099 sw_if_index_set = 1;
10100 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10101 sw_if_index_set = 1;
10102 else if (unformat (i, "socket %s", &file_name))
10103 {
10104 file_name_set = 1;
10105 }
10106 else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10107 ;
10108 else if (unformat (i, "server"))
10109 is_server = 1;
Steven Luong4208a4c2019-05-06 08:51:56 -070010110 else if (unformat (i, "gso"))
10111 enable_gso = 1;
Steven Luongbc0d9ff2020-03-23 09:34:59 -070010112 else if (unformat (i, "packed"))
10113 enable_packed = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010114 else
10115 break;
10116 }
10117
10118 if (sw_if_index_set == 0)
10119 {
10120 errmsg ("missing sw_if_index or interface name");
10121 return -99;
10122 }
10123
10124 if (file_name_set == 0)
10125 {
10126 errmsg ("missing socket file name");
10127 return -99;
10128 }
10129
10130 if (vec_len (file_name) > 255)
10131 {
10132 errmsg ("socket file name too long");
10133 return -99;
10134 }
10135 vec_add1 (file_name, 0);
10136
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010137 M (MODIFY_VHOST_USER_IF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010138
10139 mp->sw_if_index = ntohl (sw_if_index);
10140 mp->is_server = is_server;
Steven Luong4208a4c2019-05-06 08:51:56 -070010141 mp->enable_gso = enable_gso;
Steven Luongbc0d9ff2020-03-23 09:34:59 -070010142 mp->enable_packed = enable_packed;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010143 clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10144 vec_free (file_name);
10145 if (custom_dev_instance != ~0)
10146 {
10147 mp->renumber = 1;
10148 mp->custom_dev_instance = ntohl (custom_dev_instance);
10149 }
10150
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010151 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010152 W (ret);
10153 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010154}
10155
10156static int
10157api_delete_vhost_user_if (vat_main_t * vam)
10158{
10159 unformat_input_t *i = vam->input;
10160 vl_api_delete_vhost_user_if_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010161 u32 sw_if_index = ~0;
10162 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010163 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010164
10165 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10166 {
10167 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10168 sw_if_index_set = 1;
10169 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10170 sw_if_index_set = 1;
10171 else
10172 break;
10173 }
10174
10175 if (sw_if_index_set == 0)
10176 {
10177 errmsg ("missing sw_if_index or interface name");
10178 return -99;
10179 }
10180
10181
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010182 M (DELETE_VHOST_USER_IF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010183
10184 mp->sw_if_index = ntohl (sw_if_index);
10185
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010186 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010187 W (ret);
10188 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010189}
10190
10191static void vl_api_sw_interface_vhost_user_details_t_handler
10192 (vl_api_sw_interface_vhost_user_details_t * mp)
10193{
10194 vat_main_t *vam = &vat_main;
Jakub Grajciar5d4c99f2019-09-26 10:21:59 +020010195 u64 features;
10196
10197 features =
10198 clib_net_to_host_u32 (mp->features_first_32) | ((u64)
10199 clib_net_to_host_u32
10200 (mp->features_last_32) <<
10201 32);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010202
Stevenf3b53642017-05-01 14:03:02 -070010203 print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
Damjan Marion7cd468a2016-12-19 23:05:39 +010010204 (char *) mp->interface_name,
10205 ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
Jakub Grajciar5d4c99f2019-09-26 10:21:59 +020010206 features, mp->is_server,
Stevenf3b53642017-05-01 14:03:02 -070010207 ntohl (mp->num_regions), (char *) mp->sock_filename);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010208 print (vam->ofp, " Status: '%s'", strerror (ntohl (mp->sock_errno)));
10209}
10210
10211static void vl_api_sw_interface_vhost_user_details_t_handler_json
10212 (vl_api_sw_interface_vhost_user_details_t * mp)
10213{
10214 vat_main_t *vam = &vat_main;
10215 vat_json_node_t *node = NULL;
10216
10217 if (VAT_JSON_ARRAY != vam->json_tree.type)
10218 {
10219 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10220 vat_json_init_array (&vam->json_tree);
10221 }
10222 node = vat_json_array_add (&vam->json_tree);
10223
10224 vat_json_init_object (node);
10225 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10226 vat_json_object_add_string_copy (node, "interface_name",
10227 mp->interface_name);
10228 vat_json_object_add_uint (node, "virtio_net_hdr_sz",
10229 ntohl (mp->virtio_net_hdr_sz));
Jakub Grajciar5d4c99f2019-09-26 10:21:59 +020010230 vat_json_object_add_uint (node, "features_first_32",
10231 clib_net_to_host_u32 (mp->features_first_32));
10232 vat_json_object_add_uint (node, "features_last_32",
10233 clib_net_to_host_u32 (mp->features_last_32));
Damjan Marion7cd468a2016-12-19 23:05:39 +010010234 vat_json_object_add_uint (node, "is_server", mp->is_server);
10235 vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
10236 vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
10237 vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
10238}
10239
10240static int
10241api_sw_interface_vhost_user_dump (vat_main_t * vam)
10242{
Steven Luonga0e8d962020-05-18 17:12:56 -070010243 unformat_input_t *i = vam->input;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010244 vl_api_sw_interface_vhost_user_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010245 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010246 int ret;
Steven Luonga0e8d962020-05-18 17:12:56 -070010247 u32 sw_if_index = ~0;
10248
10249 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10250 {
10251 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10252 ;
10253 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10254 ;
10255 else
10256 break;
10257 }
10258
Damjan Marion7cd468a2016-12-19 23:05:39 +010010259 print (vam->ofp,
Stevenf3b53642017-05-01 14:03:02 -070010260 "Interface name idx hdr_sz features server regions filename");
Damjan Marion7cd468a2016-12-19 23:05:39 +010010261
10262 /* Get list of vhost-user interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010263 M (SW_INTERFACE_VHOST_USER_DUMP, mp);
Steven Luonga0e8d962020-05-18 17:12:56 -070010264 mp->sw_if_index = ntohl (sw_if_index);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010265 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010266
10267 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040010268 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010269 S (mp_ping);
10270
Jon Loeliger56c7b012017-02-01 12:31:41 -060010271 W (ret);
10272 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010273}
10274
10275static int
10276api_show_version (vat_main_t * vam)
10277{
10278 vl_api_show_version_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010279 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010280
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010281 M (SHOW_VERSION, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010282
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010283 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010284 W (ret);
10285 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010286}
10287
10288
10289static int
10290api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
10291{
10292 unformat_input_t *line_input = vam->input;
10293 vl_api_vxlan_gpe_add_del_tunnel_t *mp;
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010294 ip46_address_t local, remote;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010295 u8 is_add = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010296 u8 local_set = 0;
10297 u8 remote_set = 0;
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010298 u8 grp_set = 0;
10299 u32 mcast_sw_if_index = ~0;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010300 u32 encap_vrf_id = 0;
10301 u32 decap_vrf_id = 0;
10302 u8 protocol = ~0;
10303 u32 vni;
10304 u8 vni_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010305 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010306
10307 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10308 {
10309 if (unformat (line_input, "del"))
10310 is_add = 0;
10311 else if (unformat (line_input, "local %U",
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010312 unformat_ip46_address, &local))
Damjan Marion7cd468a2016-12-19 23:05:39 +010010313 {
10314 local_set = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010315 }
10316 else if (unformat (line_input, "remote %U",
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010317 unformat_ip46_address, &remote))
Damjan Marion7cd468a2016-12-19 23:05:39 +010010318 {
10319 remote_set = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010320 }
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010321 else if (unformat (line_input, "group %U %U",
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010322 unformat_ip46_address, &remote,
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010323 api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10324 {
10325 grp_set = remote_set = 1;
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010326 }
10327 else if (unformat (line_input, "group %U",
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010328 unformat_ip46_address, &remote))
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010329 {
10330 grp_set = remote_set = 1;
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010331 }
10332 else
10333 if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10334 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010335 else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10336 ;
10337 else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
10338 ;
10339 else if (unformat (line_input, "vni %d", &vni))
10340 vni_set = 1;
10341 else if (unformat (line_input, "next-ip4"))
10342 protocol = 1;
10343 else if (unformat (line_input, "next-ip6"))
10344 protocol = 2;
10345 else if (unformat (line_input, "next-ethernet"))
10346 protocol = 3;
10347 else if (unformat (line_input, "next-nsh"))
10348 protocol = 4;
10349 else
10350 {
10351 errmsg ("parse error '%U'", format_unformat_error, line_input);
10352 return -99;
10353 }
10354 }
10355
10356 if (local_set == 0)
10357 {
10358 errmsg ("tunnel local address not specified");
10359 return -99;
10360 }
10361 if (remote_set == 0)
10362 {
10363 errmsg ("tunnel remote address not specified");
10364 return -99;
10365 }
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010366 if (grp_set && mcast_sw_if_index == ~0)
10367 {
10368 errmsg ("tunnel nonexistent multicast device");
10369 return -99;
10370 }
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010371 if (ip46_address_is_ip4 (&local) != ip46_address_is_ip4 (&remote))
Damjan Marion7cd468a2016-12-19 23:05:39 +010010372 {
10373 errmsg ("both IPv4 and IPv6 addresses specified");
10374 return -99;
10375 }
10376
10377 if (vni_set == 0)
10378 {
10379 errmsg ("vni not specified");
10380 return -99;
10381 }
10382
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010383 M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010384
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010385 ip_address_encode (&local,
10386 ip46_address_is_ip4 (&local) ? IP46_TYPE_IP4 :
10387 IP46_TYPE_IP6, &mp->local);
10388 ip_address_encode (&remote,
10389 ip46_address_is_ip4 (&remote) ? IP46_TYPE_IP4 :
10390 IP46_TYPE_IP6, &mp->remote);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010391
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010392 mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010393 mp->encap_vrf_id = ntohl (encap_vrf_id);
10394 mp->decap_vrf_id = ntohl (decap_vrf_id);
10395 mp->protocol = protocol;
10396 mp->vni = ntohl (vni);
10397 mp->is_add = is_add;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010398
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010399 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010400 W (ret);
10401 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010402}
10403
10404static void vl_api_vxlan_gpe_tunnel_details_t_handler
10405 (vl_api_vxlan_gpe_tunnel_details_t * mp)
10406{
10407 vat_main_t *vam = &vat_main;
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010408 ip46_address_t local, remote;
10409
10410 ip_address_decode (&mp->local, &local);
10411 ip_address_decode (&mp->remote, &remote);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010412
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010413 print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
Damjan Marion7cd468a2016-12-19 23:05:39 +010010414 ntohl (mp->sw_if_index),
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010415 format_ip46_address, &local, IP46_TYPE_ANY,
10416 format_ip46_address, &remote, IP46_TYPE_ANY,
10417 ntohl (mp->vni), mp->protocol,
10418 ntohl (mp->mcast_sw_if_index),
Damjan Marion7cd468a2016-12-19 23:05:39 +010010419 ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
10420}
10421
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010422
Damjan Marion7cd468a2016-12-19 23:05:39 +010010423static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
10424 (vl_api_vxlan_gpe_tunnel_details_t * mp)
10425{
10426 vat_main_t *vam = &vat_main;
10427 vat_json_node_t *node = NULL;
10428 struct in_addr ip4;
10429 struct in6_addr ip6;
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010430 ip46_address_t local, remote;
10431
10432 ip_address_decode (&mp->local, &local);
10433 ip_address_decode (&mp->remote, &remote);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010434
10435 if (VAT_JSON_ARRAY != vam->json_tree.type)
10436 {
10437 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10438 vat_json_init_array (&vam->json_tree);
10439 }
10440 node = vat_json_array_add (&vam->json_tree);
10441
10442 vat_json_init_object (node);
10443 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010444 if (ip46_address_is_ip4 (&local))
Damjan Marion7cd468a2016-12-19 23:05:39 +010010445 {
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010446 clib_memcpy (&ip4, &local.ip4, sizeof (ip4));
10447 vat_json_object_add_ip4 (node, "local", ip4);
10448 clib_memcpy (&ip4, &remote.ip4, sizeof (ip4));
10449 vat_json_object_add_ip4 (node, "remote", ip4);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010450 }
10451 else
10452 {
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010453 clib_memcpy (&ip6, &local.ip6, sizeof (ip6));
10454 vat_json_object_add_ip6 (node, "local", ip6);
10455 clib_memcpy (&ip6, &remote.ip6, sizeof (ip6));
10456 vat_json_object_add_ip6 (node, "remote", ip6);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010457 }
10458 vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10459 vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010460 vat_json_object_add_uint (node, "mcast_sw_if_index",
10461 ntohl (mp->mcast_sw_if_index));
Damjan Marion7cd468a2016-12-19 23:05:39 +010010462 vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10463 vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
10464 vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10465}
10466
10467static int
10468api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
10469{
10470 unformat_input_t *i = vam->input;
10471 vl_api_vxlan_gpe_tunnel_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010472 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010473 u32 sw_if_index;
10474 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010475 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010476
10477 /* Parse args required to build the message */
10478 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10479 {
10480 if (unformat (i, "sw_if_index %d", &sw_if_index))
10481 sw_if_index_set = 1;
10482 else
10483 break;
10484 }
10485
10486 if (sw_if_index_set == 0)
10487 {
10488 sw_if_index = ~0;
10489 }
10490
10491 if (!vam->json_output)
10492 {
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010493 print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
Damjan Marion7cd468a2016-12-19 23:05:39 +010010494 "sw_if_index", "local", "remote", "vni",
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010495 "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
Damjan Marion7cd468a2016-12-19 23:05:39 +010010496 }
10497
10498 /* Get list of vxlan-tunnel interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010499 M (VXLAN_GPE_TUNNEL_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010500
10501 mp->sw_if_index = htonl (sw_if_index);
10502
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010503 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010504
10505 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040010506 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010507 S (mp_ping);
10508
Jon Loeliger56c7b012017-02-01 12:31:41 -060010509 W (ret);
10510 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010511}
10512
Ole Troan01384fe2017-05-12 11:55:35 +020010513static void vl_api_l2_fib_table_details_t_handler
10514 (vl_api_l2_fib_table_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010010515{
10516 vat_main_t *vam = &vat_main;
10517
10518 print (vam->ofp, "%3" PRIu32 " %U %3" PRIu32
10519 " %d %d %d",
Mohsin Kazmi57938f62017-10-27 21:28:07 +020010520 ntohl (mp->bd_id), format_ethernet_address, mp->mac,
Damjan Marion7cd468a2016-12-19 23:05:39 +010010521 ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
10522 mp->bvi_mac);
10523}
10524
Ole Troan01384fe2017-05-12 11:55:35 +020010525static void vl_api_l2_fib_table_details_t_handler_json
10526 (vl_api_l2_fib_table_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010010527{
10528 vat_main_t *vam = &vat_main;
10529 vat_json_node_t *node = NULL;
10530
10531 if (VAT_JSON_ARRAY != vam->json_tree.type)
10532 {
10533 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10534 vat_json_init_array (&vam->json_tree);
10535 }
10536 node = vat_json_array_add (&vam->json_tree);
10537
10538 vat_json_init_object (node);
10539 vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
Mohsin Kazmi57938f62017-10-27 21:28:07 +020010540 vat_json_object_add_bytes (node, "mac", mp->mac, 6);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010541 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10542 vat_json_object_add_uint (node, "static_mac", mp->static_mac);
10543 vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
10544 vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
10545}
10546
10547static int
10548api_l2_fib_table_dump (vat_main_t * vam)
10549{
10550 unformat_input_t *i = vam->input;
10551 vl_api_l2_fib_table_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010552 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010553 u32 bd_id;
10554 u8 bd_id_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010555 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010556
10557 /* Parse args required to build the message */
10558 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10559 {
10560 if (unformat (i, "bd_id %d", &bd_id))
10561 bd_id_set = 1;
10562 else
10563 break;
10564 }
10565
10566 if (bd_id_set == 0)
10567 {
10568 errmsg ("missing bridge domain");
10569 return -99;
10570 }
10571
10572 print (vam->ofp, "BD-ID Mac Address sw-ndx Static Filter BVI");
10573
10574 /* Get list of l2 fib entries */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010575 M (L2_FIB_TABLE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010576
10577 mp->bd_id = ntohl (bd_id);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010578 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010579
10580 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040010581 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010582 S (mp_ping);
10583
Jon Loeliger56c7b012017-02-01 12:31:41 -060010584 W (ret);
10585 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010586}
10587
10588
10589static int
10590api_interface_name_renumber (vat_main_t * vam)
10591{
10592 unformat_input_t *line_input = vam->input;
10593 vl_api_interface_name_renumber_t *mp;
10594 u32 sw_if_index = ~0;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010595 u32 new_show_dev_instance = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010596 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010597
10598 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10599 {
10600 if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
10601 &sw_if_index))
10602 ;
10603 else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
10604 ;
10605 else if (unformat (line_input, "new_show_dev_instance %d",
10606 &new_show_dev_instance))
10607 ;
10608 else
10609 break;
10610 }
10611
10612 if (sw_if_index == ~0)
10613 {
10614 errmsg ("missing interface name or sw_if_index");
10615 return -99;
10616 }
10617
10618 if (new_show_dev_instance == ~0)
10619 {
10620 errmsg ("missing new_show_dev_instance");
10621 return -99;
10622 }
10623
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010624 M (INTERFACE_NAME_RENUMBER, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010625
10626 mp->sw_if_index = ntohl (sw_if_index);
10627 mp->new_show_dev_instance = ntohl (new_show_dev_instance);
10628
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010629 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010630 W (ret);
10631 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010632}
10633
10634static int
John Lo8d00fff2017-08-03 00:35:36 -040010635api_want_l2_macs_events (vat_main_t * vam)
10636{
10637 unformat_input_t *line_input = vam->input;
10638 vl_api_want_l2_macs_events_t *mp;
10639 u8 enable_disable = 1;
10640 u32 scan_delay = 0;
10641 u32 max_macs_in_event = 0;
10642 u32 learn_limit = 0;
10643 int ret;
10644
10645 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10646 {
10647 if (unformat (line_input, "learn-limit %d", &learn_limit))
10648 ;
10649 else if (unformat (line_input, "scan-delay %d", &scan_delay))
10650 ;
10651 else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
10652 ;
10653 else if (unformat (line_input, "disable"))
10654 enable_disable = 0;
10655 else
10656 break;
10657 }
10658
10659 M (WANT_L2_MACS_EVENTS, mp);
10660 mp->enable_disable = enable_disable;
10661 mp->pid = htonl (getpid ());
10662 mp->learn_limit = htonl (learn_limit);
10663 mp->scan_delay = (u8) scan_delay;
10664 mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
10665 S (mp);
10666 W (ret);
10667 return ret;
10668}
10669
10670static int
Damjan Marion7cd468a2016-12-19 23:05:39 +010010671api_input_acl_set_interface (vat_main_t * vam)
10672{
10673 unformat_input_t *i = vam->input;
10674 vl_api_input_acl_set_interface_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010675 u32 sw_if_index;
10676 int sw_if_index_set;
10677 u32 ip4_table_index = ~0;
10678 u32 ip6_table_index = ~0;
10679 u32 l2_table_index = ~0;
10680 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010681 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010682
10683 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10684 {
10685 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10686 sw_if_index_set = 1;
10687 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10688 sw_if_index_set = 1;
10689 else if (unformat (i, "del"))
10690 is_add = 0;
10691 else if (unformat (i, "ip4-table %d", &ip4_table_index))
10692 ;
10693 else if (unformat (i, "ip6-table %d", &ip6_table_index))
10694 ;
10695 else if (unformat (i, "l2-table %d", &l2_table_index))
10696 ;
10697 else
10698 {
10699 clib_warning ("parse error '%U'", format_unformat_error, i);
10700 return -99;
10701 }
10702 }
10703
10704 if (sw_if_index_set == 0)
10705 {
10706 errmsg ("missing interface name or sw_if_index");
10707 return -99;
10708 }
10709
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010710 M (INPUT_ACL_SET_INTERFACE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010711
10712 mp->sw_if_index = ntohl (sw_if_index);
10713 mp->ip4_table_index = ntohl (ip4_table_index);
10714 mp->ip6_table_index = ntohl (ip6_table_index);
10715 mp->l2_table_index = ntohl (l2_table_index);
10716 mp->is_add = is_add;
10717
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010718 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010719 W (ret);
10720 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010721}
10722
10723static int
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +010010724api_output_acl_set_interface (vat_main_t * vam)
10725{
10726 unformat_input_t *i = vam->input;
10727 vl_api_output_acl_set_interface_t *mp;
10728 u32 sw_if_index;
10729 int sw_if_index_set;
10730 u32 ip4_table_index = ~0;
10731 u32 ip6_table_index = ~0;
10732 u32 l2_table_index = ~0;
10733 u8 is_add = 1;
10734 int ret;
10735
10736 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10737 {
10738 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10739 sw_if_index_set = 1;
10740 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10741 sw_if_index_set = 1;
10742 else if (unformat (i, "del"))
10743 is_add = 0;
10744 else if (unformat (i, "ip4-table %d", &ip4_table_index))
10745 ;
10746 else if (unformat (i, "ip6-table %d", &ip6_table_index))
10747 ;
10748 else if (unformat (i, "l2-table %d", &l2_table_index))
10749 ;
10750 else
10751 {
10752 clib_warning ("parse error '%U'", format_unformat_error, i);
10753 return -99;
10754 }
10755 }
10756
10757 if (sw_if_index_set == 0)
10758 {
10759 errmsg ("missing interface name or sw_if_index");
10760 return -99;
10761 }
10762
10763 M (OUTPUT_ACL_SET_INTERFACE, mp);
10764
10765 mp->sw_if_index = ntohl (sw_if_index);
10766 mp->ip4_table_index = ntohl (ip4_table_index);
10767 mp->ip6_table_index = ntohl (ip6_table_index);
10768 mp->l2_table_index = ntohl (l2_table_index);
10769 mp->is_add = is_add;
10770
10771 S (mp);
10772 W (ret);
10773 return ret;
10774}
10775
10776static int
Damjan Marion7cd468a2016-12-19 23:05:39 +010010777api_ip_address_dump (vat_main_t * vam)
10778{
10779 unformat_input_t *i = vam->input;
10780 vl_api_ip_address_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010781 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010782 u32 sw_if_index = ~0;
10783 u8 sw_if_index_set = 0;
10784 u8 ipv4_set = 0;
10785 u8 ipv6_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010786 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010787
10788 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10789 {
10790 if (unformat (i, "sw_if_index %d", &sw_if_index))
10791 sw_if_index_set = 1;
10792 else
10793 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10794 sw_if_index_set = 1;
10795 else if (unformat (i, "ipv4"))
10796 ipv4_set = 1;
10797 else if (unformat (i, "ipv6"))
10798 ipv6_set = 1;
10799 else
10800 break;
10801 }
10802
10803 if (ipv4_set && ipv6_set)
10804 {
10805 errmsg ("ipv4 and ipv6 flags cannot be both set");
10806 return -99;
10807 }
10808
10809 if ((!ipv4_set) && (!ipv6_set))
10810 {
10811 errmsg ("no ipv4 nor ipv6 flag set");
10812 return -99;
10813 }
10814
10815 if (sw_if_index_set == 0)
10816 {
10817 errmsg ("missing interface name or sw_if_index");
10818 return -99;
10819 }
10820
10821 vam->current_sw_if_index = sw_if_index;
10822 vam->is_ipv6 = ipv6_set;
10823
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010824 M (IP_ADDRESS_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010825 mp->sw_if_index = ntohl (sw_if_index);
10826 mp->is_ipv6 = ipv6_set;
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010827 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010828
10829 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040010830 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010831 S (mp_ping);
10832
Jon Loeliger56c7b012017-02-01 12:31:41 -060010833 W (ret);
10834 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010835}
10836
10837static int
10838api_ip_dump (vat_main_t * vam)
10839{
10840 vl_api_ip_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010841 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010842 unformat_input_t *in = vam->input;
10843 int ipv4_set = 0;
10844 int ipv6_set = 0;
10845 int is_ipv6;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010846 int i;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010847 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010848
10849 while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
10850 {
10851 if (unformat (in, "ipv4"))
10852 ipv4_set = 1;
10853 else if (unformat (in, "ipv6"))
10854 ipv6_set = 1;
10855 else
10856 break;
10857 }
10858
10859 if (ipv4_set && ipv6_set)
10860 {
10861 errmsg ("ipv4 and ipv6 flags cannot be both set");
10862 return -99;
10863 }
10864
10865 if ((!ipv4_set) && (!ipv6_set))
10866 {
10867 errmsg ("no ipv4 nor ipv6 flag set");
10868 return -99;
10869 }
10870
10871 is_ipv6 = ipv6_set;
10872 vam->is_ipv6 = is_ipv6;
10873
10874 /* free old data */
10875 for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
10876 {
10877 vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
10878 }
10879 vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
10880
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010881 M (IP_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010882 mp->is_ipv6 = ipv6_set;
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010883 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010884
10885 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040010886 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010887 S (mp_ping);
10888
Jon Loeliger56c7b012017-02-01 12:31:41 -060010889 W (ret);
10890 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010891}
10892
10893static int
10894api_ipsec_spd_add_del (vat_main_t * vam)
10895{
10896 unformat_input_t *i = vam->input;
10897 vl_api_ipsec_spd_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010898 u32 spd_id = ~0;
10899 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010900 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010901
10902 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10903 {
10904 if (unformat (i, "spd_id %d", &spd_id))
10905 ;
10906 else if (unformat (i, "del"))
10907 is_add = 0;
10908 else
10909 {
10910 clib_warning ("parse error '%U'", format_unformat_error, i);
10911 return -99;
10912 }
10913 }
10914 if (spd_id == ~0)
10915 {
10916 errmsg ("spd_id must be set");
10917 return -99;
10918 }
10919
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010920 M (IPSEC_SPD_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010921
10922 mp->spd_id = ntohl (spd_id);
10923 mp->is_add = is_add;
10924
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010925 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010926 W (ret);
10927 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010928}
10929
10930static int
10931api_ipsec_interface_add_del_spd (vat_main_t * vam)
10932{
10933 unformat_input_t *i = vam->input;
10934 vl_api_ipsec_interface_add_del_spd_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010935 u32 sw_if_index;
10936 u8 sw_if_index_set = 0;
10937 u32 spd_id = (u32) ~ 0;
10938 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010939 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010940
10941 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10942 {
10943 if (unformat (i, "del"))
10944 is_add = 0;
10945 else if (unformat (i, "spd_id %d", &spd_id))
10946 ;
10947 else
10948 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10949 sw_if_index_set = 1;
10950 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10951 sw_if_index_set = 1;
10952 else
10953 {
10954 clib_warning ("parse error '%U'", format_unformat_error, i);
10955 return -99;
10956 }
10957
10958 }
10959
10960 if (spd_id == (u32) ~ 0)
10961 {
10962 errmsg ("spd_id must be set");
10963 return -99;
10964 }
10965
10966 if (sw_if_index_set == 0)
10967 {
10968 errmsg ("missing interface name or sw_if_index");
10969 return -99;
10970 }
10971
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010972 M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010973
10974 mp->spd_id = ntohl (spd_id);
10975 mp->sw_if_index = ntohl (sw_if_index);
10976 mp->is_add = is_add;
10977
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010978 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010979 W (ret);
10980 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010981}
10982
10983static int
Neale Ranns17dcec02019-01-09 21:22:20 -080010984api_ipsec_spd_entry_add_del (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010010985{
10986 unformat_input_t *i = vam->input;
Neale Ranns17dcec02019-01-09 21:22:20 -080010987 vl_api_ipsec_spd_entry_add_del_t *mp;
Benoît Ganne49ee6842019-04-30 11:50:46 +020010988 u8 is_add = 1, is_outbound = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010989 u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
10990 i32 priority = 0;
10991 u32 rport_start = 0, rport_stop = (u32) ~ 0;
10992 u32 lport_start = 0, lport_stop = (u32) ~ 0;
Neale Ranns17dcec02019-01-09 21:22:20 -080010993 vl_api_address_t laddr_start = { }, laddr_stop =
10994 {
10995 }, raddr_start =
10996 {
10997 }, raddr_stop =
10998 {
10999 };
Jon Loeliger56c7b012017-02-01 12:31:41 -060011000 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011001
Damjan Marion7cd468a2016-12-19 23:05:39 +010011002 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11003 {
11004 if (unformat (i, "del"))
11005 is_add = 0;
11006 if (unformat (i, "outbound"))
11007 is_outbound = 1;
11008 if (unformat (i, "inbound"))
11009 is_outbound = 0;
11010 else if (unformat (i, "spd_id %d", &spd_id))
11011 ;
11012 else if (unformat (i, "sa_id %d", &sa_id))
11013 ;
11014 else if (unformat (i, "priority %d", &priority))
11015 ;
11016 else if (unformat (i, "protocol %d", &protocol))
11017 ;
11018 else if (unformat (i, "lport_start %d", &lport_start))
11019 ;
11020 else if (unformat (i, "lport_stop %d", &lport_stop))
11021 ;
11022 else if (unformat (i, "rport_start %d", &rport_start))
11023 ;
11024 else if (unformat (i, "rport_stop %d", &rport_stop))
11025 ;
Neale Ranns17dcec02019-01-09 21:22:20 -080011026 else if (unformat (i, "laddr_start %U",
11027 unformat_vl_api_address, &laddr_start))
Benoît Ganne49ee6842019-04-30 11:50:46 +020011028 ;
Neale Ranns17dcec02019-01-09 21:22:20 -080011029 else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
11030 &laddr_stop))
Benoît Ganne49ee6842019-04-30 11:50:46 +020011031 ;
Neale Ranns17dcec02019-01-09 21:22:20 -080011032 else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
11033 &raddr_start))
Benoît Ganne49ee6842019-04-30 11:50:46 +020011034 ;
Neale Ranns17dcec02019-01-09 21:22:20 -080011035 else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
11036 &raddr_stop))
Benoît Ganne49ee6842019-04-30 11:50:46 +020011037 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011038 else
11039 if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
11040 {
11041 if (policy == IPSEC_POLICY_ACTION_RESOLVE)
11042 {
11043 clib_warning ("unsupported action: 'resolve'");
11044 return -99;
11045 }
11046 }
11047 else
11048 {
11049 clib_warning ("parse error '%U'", format_unformat_error, i);
11050 return -99;
11051 }
11052
11053 }
11054
Neale Ranns17dcec02019-01-09 21:22:20 -080011055 M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011056
Damjan Marion7cd468a2016-12-19 23:05:39 +010011057 mp->is_add = is_add;
Neale Ranns17dcec02019-01-09 21:22:20 -080011058
11059 mp->entry.spd_id = ntohl (spd_id);
11060 mp->entry.priority = ntohl (priority);
11061 mp->entry.is_outbound = is_outbound;
11062
11063 clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
11064 sizeof (vl_api_address_t));
11065 clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
11066 sizeof (vl_api_address_t));
11067 clib_memcpy (&mp->entry.local_address_start, &laddr_start,
11068 sizeof (vl_api_address_t));
11069 clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
11070 sizeof (vl_api_address_t));
11071
11072 mp->entry.protocol = (u8) protocol;
11073 mp->entry.local_port_start = ntohs ((u16) lport_start);
11074 mp->entry.local_port_stop = ntohs ((u16) lport_stop);
11075 mp->entry.remote_port_start = ntohs ((u16) rport_start);
11076 mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
11077 mp->entry.policy = (u8) policy;
11078 mp->entry.sa_id = ntohl (sa_id);
Neale Ranns17dcec02019-01-09 21:22:20 -080011079
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011080 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011081 W (ret);
11082 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011083}
11084
11085static int
Neale Ranns17dcec02019-01-09 21:22:20 -080011086api_ipsec_sad_entry_add_del (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010011087{
11088 unformat_input_t *i = vam->input;
Neale Ranns17dcec02019-01-09 21:22:20 -080011089 vl_api_ipsec_sad_entry_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011090 u32 sad_id = 0, spi = 0;
11091 u8 *ck = 0, *ik = 0;
11092 u8 is_add = 1;
11093
Neale Ranns17dcec02019-01-09 21:22:20 -080011094 vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
11095 vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
11096 vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
11097 vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
11098 vl_api_address_t tun_src, tun_dst;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011099 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011100
11101 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11102 {
11103 if (unformat (i, "del"))
11104 is_add = 0;
11105 else if (unformat (i, "sad_id %d", &sad_id))
11106 ;
11107 else if (unformat (i, "spi %d", &spi))
11108 ;
11109 else if (unformat (i, "esp"))
Neale Ranns17dcec02019-01-09 21:22:20 -080011110 protocol = IPSEC_API_PROTO_ESP;
11111 else
11112 if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
Damjan Marion7cd468a2016-12-19 23:05:39 +010011113 {
Neale Ranns17dcec02019-01-09 21:22:20 -080011114 flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
11115 if (ADDRESS_IP6 == tun_src.af)
11116 flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011117 }
11118 else
Neale Ranns17dcec02019-01-09 21:22:20 -080011119 if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
Damjan Marion7cd468a2016-12-19 23:05:39 +010011120 {
Neale Ranns17dcec02019-01-09 21:22:20 -080011121 flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
11122 if (ADDRESS_IP6 == tun_src.af)
11123 flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011124 }
Neale Ranns17dcec02019-01-09 21:22:20 -080011125 else
11126 if (unformat (i, "crypto_alg %U",
11127 unformat_ipsec_api_crypto_alg, &crypto_alg))
11128 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011129 else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11130 ;
Neale Ranns17dcec02019-01-09 21:22:20 -080011131 else if (unformat (i, "integ_alg %U",
11132 unformat_ipsec_api_integ_alg, &integ_alg))
11133 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011134 else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11135 ;
11136 else
11137 {
11138 clib_warning ("parse error '%U'", format_unformat_error, i);
11139 return -99;
11140 }
11141
11142 }
11143
Neale Ranns17dcec02019-01-09 21:22:20 -080011144 M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011145
Damjan Marion7cd468a2016-12-19 23:05:39 +010011146 mp->is_add = is_add;
Neale Ranns17dcec02019-01-09 21:22:20 -080011147 mp->entry.sad_id = ntohl (sad_id);
11148 mp->entry.protocol = protocol;
11149 mp->entry.spi = ntohl (spi);
11150 mp->entry.flags = flags;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011151
Neale Ranns17dcec02019-01-09 21:22:20 -080011152 mp->entry.crypto_algorithm = crypto_alg;
11153 mp->entry.integrity_algorithm = integ_alg;
11154 mp->entry.crypto_key.length = vec_len (ck);
11155 mp->entry.integrity_key.length = vec_len (ik);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011156
Neale Ranns17dcec02019-01-09 21:22:20 -080011157 if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
11158 mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
11159
11160 if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
11161 mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011162
11163 if (ck)
Neale Ranns17dcec02019-01-09 21:22:20 -080011164 clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011165 if (ik)
Neale Ranns17dcec02019-01-09 21:22:20 -080011166 clib_memcpy (mp->entry.integrity_key.data, ik,
11167 mp->entry.integrity_key.length);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011168
Neale Ranns17dcec02019-01-09 21:22:20 -080011169 if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
Damjan Marion7cd468a2016-12-19 23:05:39 +010011170 {
Neale Ranns17dcec02019-01-09 21:22:20 -080011171 clib_memcpy (&mp->entry.tunnel_src, &tun_src,
11172 sizeof (mp->entry.tunnel_src));
11173 clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
11174 sizeof (mp->entry.tunnel_dst));
Damjan Marion7cd468a2016-12-19 23:05:39 +010011175 }
11176
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011177 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011178 W (ret);
11179 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011180}
11181
11182static int
Matthew Smithb0972cb2017-05-02 16:20:41 -050011183api_ipsec_tunnel_if_add_del (vat_main_t * vam)
11184{
11185 unformat_input_t *i = vam->input;
11186 vl_api_ipsec_tunnel_if_add_del_t *mp;
11187 u32 local_spi = 0, remote_spi = 0;
11188 u32 crypto_alg = 0, integ_alg = 0;
11189 u8 *lck = NULL, *rck = NULL;
11190 u8 *lik = NULL, *rik = NULL;
Kingwel Xie1ba5bc82019-03-20 07:21:58 -040011191 vl_api_address_t local_ip = { 0 };
11192 vl_api_address_t remote_ip = { 0 };
Neale Ranns2b5ba952019-04-02 10:15:40 +000011193 f64 before = 0;
Matthew Smithb0972cb2017-05-02 16:20:41 -050011194 u8 is_add = 1;
11195 u8 esn = 0;
11196 u8 anti_replay = 0;
Matthew Smith8e1039a2018-04-12 07:32:56 -050011197 u8 renumber = 0;
11198 u32 instance = ~0;
Neale Ranns2b5ba952019-04-02 10:15:40 +000011199 u32 count = 1, jj;
Benoît Ganne49ee6842019-04-30 11:50:46 +020011200 int ret = -1;
Matthew Smithb0972cb2017-05-02 16:20:41 -050011201
11202 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11203 {
11204 if (unformat (i, "del"))
11205 is_add = 0;
11206 else if (unformat (i, "esn"))
11207 esn = 1;
Neale Ranns2b5ba952019-04-02 10:15:40 +000011208 else if (unformat (i, "anti-replay"))
Matthew Smithb0972cb2017-05-02 16:20:41 -050011209 anti_replay = 1;
Neale Ranns2b5ba952019-04-02 10:15:40 +000011210 else if (unformat (i, "count %d", &count))
11211 ;
Matthew Smithb0972cb2017-05-02 16:20:41 -050011212 else if (unformat (i, "local_spi %d", &local_spi))
11213 ;
11214 else if (unformat (i, "remote_spi %d", &remote_spi))
11215 ;
Kingwel Xie1ba5bc82019-03-20 07:21:58 -040011216 else
11217 if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
Matthew Smithb0972cb2017-05-02 16:20:41 -050011218 ;
Kingwel Xie1ba5bc82019-03-20 07:21:58 -040011219 else
11220 if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
Matthew Smithb0972cb2017-05-02 16:20:41 -050011221 ;
11222 else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
11223 ;
11224 else
11225 if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
11226 ;
11227 else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
11228 ;
11229 else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
11230 ;
11231 else
11232 if (unformat
Neale Ranns17dcec02019-01-09 21:22:20 -080011233 (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
Matthew Smithb0972cb2017-05-02 16:20:41 -050011234 {
Dave Baracha8d47642018-07-13 11:22:23 -040011235 if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
Matthew Smithb0972cb2017-05-02 16:20:41 -050011236 {
11237 errmsg ("unsupported crypto-alg: '%U'\n",
11238 format_ipsec_crypto_alg, crypto_alg);
11239 return -99;
11240 }
11241 }
11242 else
11243 if (unformat
Neale Ranns17dcec02019-01-09 21:22:20 -080011244 (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
Matthew Smithb0972cb2017-05-02 16:20:41 -050011245 {
Dave Baracha8d47642018-07-13 11:22:23 -040011246 if (integ_alg >= IPSEC_INTEG_N_ALG)
Matthew Smithb0972cb2017-05-02 16:20:41 -050011247 {
11248 errmsg ("unsupported integ-alg: '%U'\n",
11249 format_ipsec_integ_alg, integ_alg);
11250 return -99;
11251 }
11252 }
Matthew Smith8e1039a2018-04-12 07:32:56 -050011253 else if (unformat (i, "instance %u", &instance))
11254 renumber = 1;
Matthew Smithb0972cb2017-05-02 16:20:41 -050011255 else
11256 {
11257 errmsg ("parse error '%U'\n", format_unformat_error, i);
11258 return -99;
11259 }
11260 }
11261
Neale Ranns2b5ba952019-04-02 10:15:40 +000011262 if (count > 1)
Matthew Smithb0972cb2017-05-02 16:20:41 -050011263 {
Neale Ranns2b5ba952019-04-02 10:15:40 +000011264 /* Turn on async mode */
11265 vam->async_mode = 1;
11266 vam->async_errors = 0;
11267 before = vat_time_now (vam);
Matthew Smithb0972cb2017-05-02 16:20:41 -050011268 }
11269
Neale Ranns2b5ba952019-04-02 10:15:40 +000011270 for (jj = 0; jj < count; jj++)
Matthew Smithb0972cb2017-05-02 16:20:41 -050011271 {
Neale Ranns2b5ba952019-04-02 10:15:40 +000011272 M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
11273
11274 mp->is_add = is_add;
11275 mp->esn = esn;
11276 mp->anti_replay = anti_replay;
11277
11278 if (jj > 0)
Neale Ranns097fa662018-05-01 05:17:55 -070011279 increment_address (&remote_ip);
Neale Ranns2b5ba952019-04-02 10:15:40 +000011280
11281 clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
11282 clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
11283
11284 mp->local_spi = htonl (local_spi + jj);
11285 mp->remote_spi = htonl (remote_spi + jj);
11286 mp->crypto_alg = (u8) crypto_alg;
11287
11288 mp->local_crypto_key_len = 0;
11289 if (lck)
11290 {
11291 mp->local_crypto_key_len = vec_len (lck);
11292 if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
11293 mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
11294 clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
11295 }
11296
11297 mp->remote_crypto_key_len = 0;
11298 if (rck)
11299 {
11300 mp->remote_crypto_key_len = vec_len (rck);
11301 if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
11302 mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
11303 clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
11304 }
11305
11306 mp->integ_alg = (u8) integ_alg;
11307
11308 mp->local_integ_key_len = 0;
11309 if (lik)
11310 {
11311 mp->local_integ_key_len = vec_len (lik);
11312 if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
11313 mp->local_integ_key_len = sizeof (mp->local_integ_key);
11314 clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
11315 }
11316
11317 mp->remote_integ_key_len = 0;
11318 if (rik)
11319 {
11320 mp->remote_integ_key_len = vec_len (rik);
11321 if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
11322 mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
11323 clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
11324 }
11325
11326 if (renumber)
11327 {
11328 mp->renumber = renumber;
11329 mp->show_instance = ntohl (instance);
11330 }
11331 S (mp);
Matthew Smithb0972cb2017-05-02 16:20:41 -050011332 }
11333
Neale Ranns2b5ba952019-04-02 10:15:40 +000011334 /* When testing multiple add/del ops, use a control-ping to sync */
11335 if (count > 1)
Matthew Smithb0972cb2017-05-02 16:20:41 -050011336 {
Neale Ranns2b5ba952019-04-02 10:15:40 +000011337 vl_api_control_ping_t *mp_ping;
11338 f64 after;
11339 f64 timeout;
11340
11341 /* Shut off async mode */
11342 vam->async_mode = 0;
11343
11344 MPING (CONTROL_PING, mp_ping);
11345 S (mp_ping);
11346
11347 timeout = vat_time_now (vam) + 1.0;
11348 while (vat_time_now (vam) < timeout)
11349 if (vam->result_ready == 1)
11350 goto out;
11351 vam->retval = -99;
11352
11353 out:
11354 if (vam->retval == -99)
11355 errmsg ("timeout");
11356
11357 if (vam->async_errors > 0)
11358 {
11359 errmsg ("%d asynchronous errors", vam->async_errors);
11360 vam->retval = -98;
11361 }
11362 vam->async_errors = 0;
11363 after = vat_time_now (vam);
11364
11365 /* slim chance, but we might have eaten SIGTERM on the first iteration */
11366 if (jj > 0)
11367 count = jj;
11368
11369 print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
11370 count, after - before, count / (after - before));
11371 }
11372 else
11373 {
11374 /* Wait for a reply... */
11375 W (ret);
11376 return ret;
Matthew Smithb0972cb2017-05-02 16:20:41 -050011377 }
11378
Matthew Smithb0972cb2017-05-02 16:20:41 -050011379 return ret;
11380}
11381
Matthew Smith28029532017-09-26 13:33:44 -050011382static void
11383vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
11384{
11385 vat_main_t *vam = &vat_main;
11386
11387 print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
Neale Ranns8d7c5022019-02-06 01:41:05 -080011388 "crypto_key %U integ_alg %u integ_key %U flags %x "
Matthew Smith28029532017-09-26 13:33:44 -050011389 "tunnel_src_addr %U tunnel_dst_addr %U "
11390 "salt %u seq_outbound %lu last_seq_inbound %lu "
Matthew Smith48d32b42020-04-02 07:45:49 -050011391 "replay_window %lu stat_index %u\n",
Neale Ranns8d7c5022019-02-06 01:41:05 -080011392 ntohl (mp->entry.sad_id),
11393 ntohl (mp->sw_if_index),
11394 ntohl (mp->entry.spi),
11395 ntohl (mp->entry.protocol),
11396 ntohl (mp->entry.crypto_algorithm),
11397 format_hex_bytes, mp->entry.crypto_key.data,
11398 mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
11399 format_hex_bytes, mp->entry.integrity_key.data,
11400 mp->entry.integrity_key.length, ntohl (mp->entry.flags),
11401 format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
11402 &mp->entry.tunnel_dst, ntohl (mp->salt),
Matthew Smith28029532017-09-26 13:33:44 -050011403 clib_net_to_host_u64 (mp->seq_outbound),
11404 clib_net_to_host_u64 (mp->last_seq_inbound),
Matthew Smith48d32b42020-04-02 07:45:49 -050011405 clib_net_to_host_u64 (mp->replay_window), ntohl (mp->stat_index));
Matthew Smith28029532017-09-26 13:33:44 -050011406}
11407
11408#define vl_api_ipsec_sa_details_t_endian vl_noop_handler
11409#define vl_api_ipsec_sa_details_t_print vl_noop_handler
11410
11411static void vl_api_ipsec_sa_details_t_handler_json
11412 (vl_api_ipsec_sa_details_t * mp)
11413{
11414 vat_main_t *vam = &vat_main;
11415 vat_json_node_t *node = NULL;
Neale Ranns8d7c5022019-02-06 01:41:05 -080011416 vl_api_ipsec_sad_flags_t flags;
Matthew Smith28029532017-09-26 13:33:44 -050011417
11418 if (VAT_JSON_ARRAY != vam->json_tree.type)
11419 {
11420 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11421 vat_json_init_array (&vam->json_tree);
11422 }
11423 node = vat_json_array_add (&vam->json_tree);
11424
11425 vat_json_init_object (node);
Neale Ranns8d7c5022019-02-06 01:41:05 -080011426 vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
Matthew Smith28029532017-09-26 13:33:44 -050011427 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
Neale Ranns8d7c5022019-02-06 01:41:05 -080011428 vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
11429 vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
11430 vat_json_object_add_uint (node, "crypto_alg",
11431 ntohl (mp->entry.crypto_algorithm));
11432 vat_json_object_add_uint (node, "integ_alg",
11433 ntohl (mp->entry.integrity_algorithm));
11434 flags = ntohl (mp->entry.flags);
11435 vat_json_object_add_uint (node, "use_esn",
Damjan Marion1e3aa5e2019-03-28 10:58:59 +010011436 ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
Neale Ranns8d7c5022019-02-06 01:41:05 -080011437 vat_json_object_add_uint (node, "use_anti_replay",
11438 ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
11439 vat_json_object_add_uint (node, "is_tunnel",
11440 ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
11441 vat_json_object_add_uint (node, "is_tunnel_ip6",
11442 ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
11443 vat_json_object_add_uint (node, "udp_encap",
11444 ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
11445 vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
11446 mp->entry.crypto_key.length);
11447 vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
11448 mp->entry.integrity_key.length);
Neale Ranns5a8844b2019-04-16 07:15:35 +000011449 vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
11450 vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
Matthew Smith28029532017-09-26 13:33:44 -050011451 vat_json_object_add_uint (node, "replay_window",
11452 clib_net_to_host_u64 (mp->replay_window));
Matthew Smith48d32b42020-04-02 07:45:49 -050011453 vat_json_object_add_uint (node, "stat_index", ntohl (mp->stat_index));
Matthew Smith28029532017-09-26 13:33:44 -050011454}
11455
11456static int
11457api_ipsec_sa_dump (vat_main_t * vam)
11458{
11459 unformat_input_t *i = vam->input;
11460 vl_api_ipsec_sa_dump_t *mp;
11461 vl_api_control_ping_t *mp_ping;
11462 u32 sa_id = ~0;
11463 int ret;
11464
11465 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11466 {
11467 if (unformat (i, "sa_id %d", &sa_id))
11468 ;
11469 else
11470 {
11471 clib_warning ("parse error '%U'", format_unformat_error, i);
11472 return -99;
11473 }
11474 }
11475
11476 M (IPSEC_SA_DUMP, mp);
11477
11478 mp->sa_id = ntohl (sa_id);
11479
11480 S (mp);
11481
11482 /* Use a control ping for synchronization */
11483 M (CONTROL_PING, mp_ping);
11484 S (mp_ping);
11485
11486 W (ret);
11487 return ret;
11488}
11489
Matthew Smithb0972cb2017-05-02 16:20:41 -050011490static int
Matthew Smithca514fd2017-10-12 12:06:59 -050011491api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
11492{
11493 unformat_input_t *i = vam->input;
11494 vl_api_ipsec_tunnel_if_set_sa_t *mp;
11495 u32 sw_if_index = ~0;
11496 u32 sa_id = ~0;
11497 u8 is_outbound = (u8) ~ 0;
11498 int ret;
11499
11500 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11501 {
11502 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11503 ;
11504 else if (unformat (i, "sa_id %d", &sa_id))
11505 ;
11506 else if (unformat (i, "outbound"))
11507 is_outbound = 1;
11508 else if (unformat (i, "inbound"))
11509 is_outbound = 0;
11510 else
11511 {
11512 clib_warning ("parse error '%U'", format_unformat_error, i);
11513 return -99;
11514 }
11515 }
11516
11517 if (sw_if_index == ~0)
11518 {
11519 errmsg ("interface must be specified");
11520 return -99;
11521 }
11522
11523 if (sa_id == ~0)
11524 {
11525 errmsg ("SA ID must be specified");
11526 return -99;
11527 }
11528
11529 M (IPSEC_TUNNEL_IF_SET_SA, mp);
11530
11531 mp->sw_if_index = htonl (sw_if_index);
11532 mp->sa_id = htonl (sa_id);
11533 mp->is_outbound = is_outbound;
11534
11535 S (mp);
11536 W (ret);
11537
11538 return ret;
11539}
11540
11541static int
Damjan Marion7cd468a2016-12-19 23:05:39 +010011542api_get_first_msg_id (vat_main_t * vam)
11543{
11544 vl_api_get_first_msg_id_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011545 unformat_input_t *i = vam->input;
11546 u8 *name;
11547 u8 name_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011548 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011549
11550 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11551 {
11552 if (unformat (i, "client %s", &name))
11553 name_set = 1;
11554 else
11555 break;
11556 }
11557
11558 if (name_set == 0)
11559 {
11560 errmsg ("missing client name");
11561 return -99;
11562 }
11563 vec_add1 (name, 0);
11564
11565 if (vec_len (name) > 63)
11566 {
11567 errmsg ("client name too long");
11568 return -99;
11569 }
11570
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011571 M (GET_FIRST_MSG_ID, mp);
Ole Troan7adaa222019-08-27 15:05:27 +020011572 clib_memcpy (mp->name, name, vec_len (name));
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011573 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011574 W (ret);
11575 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011576}
11577
11578static int
11579api_cop_interface_enable_disable (vat_main_t * vam)
11580{
11581 unformat_input_t *line_input = vam->input;
11582 vl_api_cop_interface_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011583 u32 sw_if_index = ~0;
11584 u8 enable_disable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011585 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011586
11587 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11588 {
11589 if (unformat (line_input, "disable"))
11590 enable_disable = 0;
11591 if (unformat (line_input, "enable"))
11592 enable_disable = 1;
11593 else if (unformat (line_input, "%U", api_unformat_sw_if_index,
11594 vam, &sw_if_index))
11595 ;
11596 else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11597 ;
11598 else
11599 break;
11600 }
11601
11602 if (sw_if_index == ~0)
11603 {
11604 errmsg ("missing interface name or sw_if_index");
11605 return -99;
11606 }
11607
11608 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011609 M (COP_INTERFACE_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011610 mp->sw_if_index = ntohl (sw_if_index);
11611 mp->enable_disable = enable_disable;
11612
11613 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011614 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011615 /* Wait for the reply */
Jon Loeliger56c7b012017-02-01 12:31:41 -060011616 W (ret);
11617 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011618}
11619
11620static int
11621api_cop_whitelist_enable_disable (vat_main_t * vam)
11622{
11623 unformat_input_t *line_input = vam->input;
11624 vl_api_cop_whitelist_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011625 u32 sw_if_index = ~0;
11626 u8 ip4 = 0, ip6 = 0, default_cop = 0;
11627 u32 fib_id = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011628 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011629
11630 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11631 {
11632 if (unformat (line_input, "ip4"))
11633 ip4 = 1;
11634 else if (unformat (line_input, "ip6"))
11635 ip6 = 1;
11636 else if (unformat (line_input, "default"))
11637 default_cop = 1;
11638 else if (unformat (line_input, "%U", api_unformat_sw_if_index,
11639 vam, &sw_if_index))
11640 ;
11641 else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11642 ;
11643 else if (unformat (line_input, "fib-id %d", &fib_id))
11644 ;
11645 else
11646 break;
11647 }
11648
11649 if (sw_if_index == ~0)
11650 {
11651 errmsg ("missing interface name or sw_if_index");
11652 return -99;
11653 }
11654
11655 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011656 M (COP_WHITELIST_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011657 mp->sw_if_index = ntohl (sw_if_index);
11658 mp->fib_id = ntohl (fib_id);
11659 mp->ip4 = ip4;
11660 mp->ip6 = ip6;
11661 mp->default_cop = default_cop;
11662
11663 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011664 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011665 /* Wait for the reply */
Jon Loeliger56c7b012017-02-01 12:31:41 -060011666 W (ret);
11667 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011668}
11669
11670static int
11671api_get_node_graph (vat_main_t * vam)
11672{
11673 vl_api_get_node_graph_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011674 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011675
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011676 M (GET_NODE_GRAPH, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011677
11678 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011679 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011680 /* Wait for the reply */
Jon Loeliger56c7b012017-02-01 12:31:41 -060011681 W (ret);
11682 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011683}
11684
Damjan Marion7cd468a2016-12-19 23:05:39 +010011685static int
11686api_af_packet_create (vat_main_t * vam)
11687{
11688 unformat_input_t *i = vam->input;
11689 vl_api_af_packet_create_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011690 u8 *host_if_name = 0;
11691 u8 hw_addr[6];
11692 u8 random_hw_addr = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011693 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011694
Dave Barachb7b92992018-10-17 10:38:51 -040011695 clib_memset (hw_addr, 0, sizeof (hw_addr));
Damjan Marion7cd468a2016-12-19 23:05:39 +010011696
11697 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11698 {
11699 if (unformat (i, "name %s", &host_if_name))
11700 vec_add1 (host_if_name, 0);
11701 else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
11702 random_hw_addr = 0;
11703 else
11704 break;
11705 }
11706
11707 if (!vec_len (host_if_name))
11708 {
11709 errmsg ("host-interface name must be specified");
11710 return -99;
11711 }
11712
11713 if (vec_len (host_if_name) > 64)
11714 {
11715 errmsg ("host-interface name too long");
11716 return -99;
11717 }
11718
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011719 M (AF_PACKET_CREATE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011720
11721 clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
11722 clib_memcpy (mp->hw_addr, hw_addr, 6);
11723 mp->use_random_hw_addr = random_hw_addr;
11724 vec_free (host_if_name);
11725
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011726 S (mp);
Dave Baracha1a093d2017-03-02 13:13:23 -050011727
11728 /* *INDENT-OFF* */
11729 W2 (ret,
11730 ({
11731 if (ret == 0)
11732 fprintf (vam->ofp ? vam->ofp : stderr,
11733 " new sw_if_index = %d\n", vam->sw_if_index);
11734 }));
11735 /* *INDENT-ON* */
Jon Loeliger56c7b012017-02-01 12:31:41 -060011736 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011737}
11738
11739static int
11740api_af_packet_delete (vat_main_t * vam)
11741{
11742 unformat_input_t *i = vam->input;
11743 vl_api_af_packet_delete_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011744 u8 *host_if_name = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011745 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011746
11747 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11748 {
11749 if (unformat (i, "name %s", &host_if_name))
11750 vec_add1 (host_if_name, 0);
11751 else
11752 break;
11753 }
11754
11755 if (!vec_len (host_if_name))
11756 {
11757 errmsg ("host-interface name must be specified");
11758 return -99;
11759 }
11760
11761 if (vec_len (host_if_name) > 64)
11762 {
11763 errmsg ("host-interface name too long");
11764 return -99;
11765 }
11766
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011767 M (AF_PACKET_DELETE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011768
11769 clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
11770 vec_free (host_if_name);
11771
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011772 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011773 W (ret);
11774 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011775}
11776
Mohsin Kazmi04e0bb22018-05-28 18:55:37 +020011777static void vl_api_af_packet_details_t_handler
11778 (vl_api_af_packet_details_t * mp)
11779{
11780 vat_main_t *vam = &vat_main;
11781
11782 print (vam->ofp, "%-16s %d",
11783 mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
11784}
11785
11786static void vl_api_af_packet_details_t_handler_json
11787 (vl_api_af_packet_details_t * mp)
11788{
11789 vat_main_t *vam = &vat_main;
11790 vat_json_node_t *node = NULL;
11791
11792 if (VAT_JSON_ARRAY != vam->json_tree.type)
11793 {
11794 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11795 vat_json_init_array (&vam->json_tree);
11796 }
11797 node = vat_json_array_add (&vam->json_tree);
11798
11799 vat_json_init_object (node);
11800 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11801 vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
11802}
11803
11804static int
11805api_af_packet_dump (vat_main_t * vam)
11806{
11807 vl_api_af_packet_dump_t *mp;
11808 vl_api_control_ping_t *mp_ping;
11809 int ret;
11810
11811 print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
11812 /* Get list of tap interfaces */
11813 M (AF_PACKET_DUMP, mp);
11814 S (mp);
11815
11816 /* Use a control ping for synchronization */
11817 MPING (CONTROL_PING, mp_ping);
11818 S (mp_ping);
11819
11820 W (ret);
11821 return ret;
11822}
11823
Damjan Marion7cd468a2016-12-19 23:05:39 +010011824static int
11825api_policer_add_del (vat_main_t * vam)
11826{
11827 unformat_input_t *i = vam->input;
11828 vl_api_policer_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011829 u8 is_add = 1;
11830 u8 *name = 0;
11831 u32 cir = 0;
11832 u32 eir = 0;
11833 u64 cb = 0;
11834 u64 eb = 0;
11835 u8 rate_type = 0;
11836 u8 round_type = 0;
11837 u8 type = 0;
11838 u8 color_aware = 0;
11839 sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011840 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011841
11842 conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
11843 conform_action.dscp = 0;
11844 exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
11845 exceed_action.dscp = 0;
11846 violate_action.action_type = SSE2_QOS_ACTION_DROP;
11847 violate_action.dscp = 0;
11848
11849 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11850 {
11851 if (unformat (i, "del"))
11852 is_add = 0;
11853 else if (unformat (i, "name %s", &name))
11854 vec_add1 (name, 0);
11855 else if (unformat (i, "cir %u", &cir))
11856 ;
11857 else if (unformat (i, "eir %u", &eir))
11858 ;
11859 else if (unformat (i, "cb %u", &cb))
11860 ;
11861 else if (unformat (i, "eb %u", &eb))
11862 ;
11863 else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
11864 &rate_type))
11865 ;
11866 else if (unformat (i, "round_type %U", unformat_policer_round_type,
11867 &round_type))
11868 ;
11869 else if (unformat (i, "type %U", unformat_policer_type, &type))
11870 ;
11871 else if (unformat (i, "conform_action %U", unformat_policer_action_type,
11872 &conform_action))
11873 ;
11874 else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
11875 &exceed_action))
11876 ;
11877 else if (unformat (i, "violate_action %U", unformat_policer_action_type,
11878 &violate_action))
11879 ;
11880 else if (unformat (i, "color-aware"))
11881 color_aware = 1;
11882 else
11883 break;
11884 }
11885
11886 if (!vec_len (name))
11887 {
11888 errmsg ("policer name must be specified");
11889 return -99;
11890 }
11891
11892 if (vec_len (name) > 64)
11893 {
11894 errmsg ("policer name too long");
11895 return -99;
11896 }
11897
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011898 M (POLICER_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011899
11900 clib_memcpy (mp->name, name, vec_len (name));
11901 vec_free (name);
11902 mp->is_add = is_add;
Neale Rannsd91c1db2017-07-31 02:30:50 -070011903 mp->cir = ntohl (cir);
11904 mp->eir = ntohl (eir);
11905 mp->cb = clib_net_to_host_u64 (cb);
11906 mp->eb = clib_net_to_host_u64 (eb);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011907 mp->rate_type = rate_type;
11908 mp->round_type = round_type;
11909 mp->type = type;
Jakub Grajciarcd01fb42020-03-02 13:16:53 +010011910 mp->conform_action.type = conform_action.action_type;
11911 mp->conform_action.dscp = conform_action.dscp;
11912 mp->exceed_action.type = exceed_action.action_type;
11913 mp->exceed_action.dscp = exceed_action.dscp;
11914 mp->violate_action.type = violate_action.action_type;
11915 mp->violate_action.dscp = violate_action.dscp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011916 mp->color_aware = color_aware;
11917
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011918 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011919 W (ret);
11920 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011921}
11922
11923static int
11924api_policer_dump (vat_main_t * vam)
11925{
11926 unformat_input_t *i = vam->input;
11927 vl_api_policer_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011928 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011929 u8 *match_name = 0;
11930 u8 match_name_valid = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011931 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011932
11933 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11934 {
11935 if (unformat (i, "name %s", &match_name))
11936 {
11937 vec_add1 (match_name, 0);
11938 match_name_valid = 1;
11939 }
11940 else
11941 break;
11942 }
11943
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011944 M (POLICER_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011945 mp->match_name_valid = match_name_valid;
11946 clib_memcpy (mp->match_name, match_name, vec_len (match_name));
11947 vec_free (match_name);
11948 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011949 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011950
11951 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040011952 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011953 S (mp_ping);
11954
Damjan Marion7cd468a2016-12-19 23:05:39 +010011955 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060011956 W (ret);
11957 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011958}
11959
11960static int
11961api_policer_classify_set_interface (vat_main_t * vam)
11962{
11963 unformat_input_t *i = vam->input;
11964 vl_api_policer_classify_set_interface_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011965 u32 sw_if_index;
11966 int sw_if_index_set;
11967 u32 ip4_table_index = ~0;
11968 u32 ip6_table_index = ~0;
11969 u32 l2_table_index = ~0;
11970 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011971 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011972
11973 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11974 {
11975 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11976 sw_if_index_set = 1;
11977 else if (unformat (i, "sw_if_index %d", &sw_if_index))
11978 sw_if_index_set = 1;
11979 else if (unformat (i, "del"))
11980 is_add = 0;
11981 else if (unformat (i, "ip4-table %d", &ip4_table_index))
11982 ;
11983 else if (unformat (i, "ip6-table %d", &ip6_table_index))
11984 ;
11985 else if (unformat (i, "l2-table %d", &l2_table_index))
11986 ;
11987 else
11988 {
11989 clib_warning ("parse error '%U'", format_unformat_error, i);
11990 return -99;
11991 }
11992 }
11993
11994 if (sw_if_index_set == 0)
11995 {
11996 errmsg ("missing interface name or sw_if_index");
11997 return -99;
11998 }
11999
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012000 M (POLICER_CLASSIFY_SET_INTERFACE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012001
12002 mp->sw_if_index = ntohl (sw_if_index);
12003 mp->ip4_table_index = ntohl (ip4_table_index);
12004 mp->ip6_table_index = ntohl (ip6_table_index);
12005 mp->l2_table_index = ntohl (l2_table_index);
12006 mp->is_add = is_add;
12007
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012008 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012009 W (ret);
12010 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012011}
12012
12013static int
12014api_policer_classify_dump (vat_main_t * vam)
12015{
12016 unformat_input_t *i = vam->input;
12017 vl_api_policer_classify_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012018 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012019 u8 type = POLICER_CLASSIFY_N_TABLES;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012020 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012021
12022 if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
12023 ;
12024 else
12025 {
12026 errmsg ("classify table type must be specified");
12027 return -99;
12028 }
12029
12030 if (!vam->json_output)
12031 {
12032 print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
12033 }
12034
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012035 M (POLICER_CLASSIFY_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012036 mp->type = type;
12037 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012038 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012039
12040 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040012041 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012042 S (mp_ping);
12043
Damjan Marion7cd468a2016-12-19 23:05:39 +010012044 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060012045 W (ret);
12046 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012047}
12048
Neale Ranns097fa662018-05-01 05:17:55 -070012049static u8 *
12050format_fib_api_path_nh_proto (u8 * s, va_list * args)
Neale Ranns0f26c5a2017-03-01 15:12:11 -080012051{
Neale Ranns097fa662018-05-01 05:17:55 -070012052 vl_api_fib_path_nh_proto_t proto =
12053 va_arg (*args, vl_api_fib_path_nh_proto_t);
12054
12055 switch (proto)
12056 {
12057 case FIB_API_PATH_NH_PROTO_IP4:
12058 s = format (s, "ip4");
12059 break;
12060 case FIB_API_PATH_NH_PROTO_IP6:
12061 s = format (s, "ip6");
12062 break;
12063 case FIB_API_PATH_NH_PROTO_MPLS:
12064 s = format (s, "mpls");
12065 break;
12066 case FIB_API_PATH_NH_PROTO_BIER:
12067 s = format (s, "bier");
12068 break;
12069 case FIB_API_PATH_NH_PROTO_ETHERNET:
12070 s = format (s, "ethernet");
12071 break;
12072 }
12073
12074 return (s);
12075}
12076
12077static u8 *
12078format_vl_api_ip_address_union (u8 * s, va_list * args)
12079{
Jakub Grajciar7dd63e52020-03-19 08:03:55 +010012080 vl_api_address_family_t af = va_arg (*args, int);
Neale Ranns097fa662018-05-01 05:17:55 -070012081 const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
12082
12083 switch (af)
12084 {
12085 case ADDRESS_IP4:
12086 s = format (s, "%U", format_ip4_address, u->ip4);
12087 break;
12088 case ADDRESS_IP6:
12089 s = format (s, "%U", format_ip6_address, u->ip6);
12090 break;
12091 }
12092 return (s);
12093}
12094
12095static u8 *
12096format_vl_api_fib_path_type (u8 * s, va_list * args)
12097{
12098 vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
12099
12100 switch (t)
12101 {
12102 case FIB_API_PATH_TYPE_NORMAL:
12103 s = format (s, "normal");
12104 break;
12105 case FIB_API_PATH_TYPE_LOCAL:
12106 s = format (s, "local");
12107 break;
12108 case FIB_API_PATH_TYPE_DROP:
12109 s = format (s, "drop");
12110 break;
12111 case FIB_API_PATH_TYPE_UDP_ENCAP:
12112 s = format (s, "udp-encap");
12113 break;
12114 case FIB_API_PATH_TYPE_BIER_IMP:
12115 s = format (s, "bier-imp");
12116 break;
12117 case FIB_API_PATH_TYPE_ICMP_UNREACH:
12118 s = format (s, "unreach");
12119 break;
12120 case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
12121 s = format (s, "prohibit");
12122 break;
12123 case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
12124 s = format (s, "src-lookup");
12125 break;
12126 case FIB_API_PATH_TYPE_DVR:
12127 s = format (s, "dvr");
12128 break;
12129 case FIB_API_PATH_TYPE_INTERFACE_RX:
12130 s = format (s, "interface-rx");
12131 break;
12132 case FIB_API_PATH_TYPE_CLASSIFY:
12133 s = format (s, "classify");
12134 break;
12135 }
12136
12137 return (s);
12138}
12139
12140static void
12141vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
12142{
12143 print (vam->ofp,
12144 " weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
12145 ntohl (fp->weight), ntohl (fp->sw_if_index),
12146 format_vl_api_fib_path_type, fp->type,
12147 format_fib_api_path_nh_proto, fp->proto,
12148 format_vl_api_ip_address_union, &fp->nh.address);
Neale Ranns0f26c5a2017-03-01 15:12:11 -080012149}
12150
12151static void
12152vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
Neale Ranns31ed7442018-02-23 05:29:09 -080012153 vl_api_fib_path_t * fp)
Neale Ranns0f26c5a2017-03-01 15:12:11 -080012154{
12155 struct in_addr ip4;
12156 struct in6_addr ip6;
12157
12158 vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
12159 vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
Neale Ranns097fa662018-05-01 05:17:55 -070012160 vat_json_object_add_uint (node, "type", fp->type);
12161 vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
12162 if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
Neale Ranns0f26c5a2017-03-01 15:12:11 -080012163 {
Neale Ranns097fa662018-05-01 05:17:55 -070012164 clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
Neale Ranns0f26c5a2017-03-01 15:12:11 -080012165 vat_json_object_add_ip4 (node, "next_hop", ip4);
12166 }
Dave Barachc35f3e82020-04-02 10:44:09 -040012167 else if (fp->proto == FIB_API_PATH_NH_PROTO_IP6)
Neale Ranns0f26c5a2017-03-01 15:12:11 -080012168 {
Neale Ranns097fa662018-05-01 05:17:55 -070012169 clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
Neale Ranns0f26c5a2017-03-01 15:12:11 -080012170 vat_json_object_add_ip6 (node, "next_hop", ip6);
12171 }
12172}
12173
12174static void
12175vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012176{
12177 vat_main_t *vam = &vat_main;
Neale Ranns097fa662018-05-01 05:17:55 -070012178 int count = ntohl (mp->mt_tunnel.mt_n_paths);
Neale Ranns31ed7442018-02-23 05:29:09 -080012179 vl_api_fib_path_t *fp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012180 i32 i;
12181
Neale Ranns097fa662018-05-01 05:17:55 -070012182 print (vam->ofp, "sw_if_index %d via:",
12183 ntohl (mp->mt_tunnel.mt_sw_if_index));
12184 fp = mp->mt_tunnel.mt_paths;
Neale Ranns0f26c5a2017-03-01 15:12:11 -080012185 for (i = 0; i < count; i++)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012186 {
Neale Ranns097fa662018-05-01 05:17:55 -070012187 vl_api_fib_path_print (vam, fp);
Neale Ranns0f26c5a2017-03-01 15:12:11 -080012188 fp++;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012189 }
Neale Ranns0f26c5a2017-03-01 15:12:11 -080012190
Damjan Marion7cd468a2016-12-19 23:05:39 +010012191 print (vam->ofp, "");
12192}
12193
Neale Ranns0f26c5a2017-03-01 15:12:11 -080012194#define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
12195#define vl_api_mpls_tunnel_details_t_print vl_noop_handler
12196
12197static void
12198vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012199{
12200 vat_main_t *vam = &vat_main;
12201 vat_json_node_t *node = NULL;
Neale Ranns097fa662018-05-01 05:17:55 -070012202 int count = ntohl (mp->mt_tunnel.mt_n_paths);
Neale Ranns31ed7442018-02-23 05:29:09 -080012203 vl_api_fib_path_t *fp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012204 i32 i;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012205
12206 if (VAT_JSON_ARRAY != vam->json_tree.type)
12207 {
12208 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12209 vat_json_init_array (&vam->json_tree);
12210 }
12211 node = vat_json_array_add (&vam->json_tree);
12212
12213 vat_json_init_object (node);
Neale Ranns097fa662018-05-01 05:17:55 -070012214 vat_json_object_add_uint (node, "sw_if_index",
12215 ntohl (mp->mt_tunnel.mt_sw_if_index));
Neale Ranns0f26c5a2017-03-01 15:12:11 -080012216
Neale Ranns097fa662018-05-01 05:17:55 -070012217 vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
Neale Ranns0f26c5a2017-03-01 15:12:11 -080012218
Neale Ranns097fa662018-05-01 05:17:55 -070012219 fp = mp->mt_tunnel.mt_paths;
Neale Ranns0f26c5a2017-03-01 15:12:11 -080012220 for (i = 0; i < count; i++)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012221 {
Neale Ranns0f26c5a2017-03-01 15:12:11 -080012222 vl_api_mpls_fib_path_json_print (node, fp);
12223 fp++;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012224 }
12225}
12226
12227static int
12228api_mpls_tunnel_dump (vat_main_t * vam)
12229{
12230 vl_api_mpls_tunnel_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012231 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012232 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012233
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012234 M (MPLS_TUNNEL_DUMP, mp);
Neale Ranns097fa662018-05-01 05:17:55 -070012235
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012236 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012237
12238 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040012239 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012240 S (mp_ping);
12241
Jon Loeliger56c7b012017-02-01 12:31:41 -060012242 W (ret);
12243 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012244}
12245
Neale Ranns097fa662018-05-01 05:17:55 -070012246#define vl_api_mpls_table_details_t_endian vl_noop_handler
12247#define vl_api_mpls_table_details_t_print vl_noop_handler
Damjan Marion7cd468a2016-12-19 23:05:39 +010012248
Neale Ranns0f26c5a2017-03-01 15:12:11 -080012249
Damjan Marion7cd468a2016-12-19 23:05:39 +010012250static void
Neale Ranns097fa662018-05-01 05:17:55 -070012251vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012252{
12253 vat_main_t *vam = &vat_main;
Neale Ranns097fa662018-05-01 05:17:55 -070012254
12255 print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
12256}
12257
12258static void vl_api_mpls_table_details_t_handler_json
12259 (vl_api_mpls_table_details_t * mp)
12260{
12261 vat_main_t *vam = &vat_main;
12262 vat_json_node_t *node = NULL;
12263
12264 if (VAT_JSON_ARRAY != vam->json_tree.type)
12265 {
12266 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12267 vat_json_init_array (&vam->json_tree);
12268 }
12269 node = vat_json_array_add (&vam->json_tree);
12270
12271 vat_json_init_object (node);
12272 vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
12273}
12274
12275static int
12276api_mpls_table_dump (vat_main_t * vam)
12277{
12278 vl_api_mpls_table_dump_t *mp;
12279 vl_api_control_ping_t *mp_ping;
12280 int ret;
12281
12282 M (MPLS_TABLE_DUMP, mp);
12283 S (mp);
12284
12285 /* Use a control ping for synchronization */
12286 MPING (CONTROL_PING, mp_ping);
12287 S (mp_ping);
12288
12289 W (ret);
12290 return ret;
12291}
12292
12293#define vl_api_mpls_route_details_t_endian vl_noop_handler
12294#define vl_api_mpls_route_details_t_print vl_noop_handler
12295
12296static void
12297vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
12298{
12299 vat_main_t *vam = &vat_main;
Dave Barach4bda2d92019-07-03 15:21:50 -040012300 int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
Neale Ranns31ed7442018-02-23 05:29:09 -080012301 vl_api_fib_path_t *fp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012302 int i;
12303
12304 print (vam->ofp,
12305 "table-id %d, label %u, ess_bit %u",
Neale Ranns097fa662018-05-01 05:17:55 -070012306 ntohl (mp->mr_route.mr_table_id),
12307 ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
12308 fp = mp->mr_route.mr_paths;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012309 for (i = 0; i < count; i++)
12310 {
Neale Ranns097fa662018-05-01 05:17:55 -070012311 vl_api_fib_path_print (vam, fp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012312 fp++;
12313 }
12314}
12315
Neale Ranns097fa662018-05-01 05:17:55 -070012316static void vl_api_mpls_route_details_t_handler_json
12317 (vl_api_mpls_route_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012318{
12319 vat_main_t *vam = &vat_main;
Dave Barach4bda2d92019-07-03 15:21:50 -040012320 int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012321 vat_json_node_t *node = NULL;
Neale Ranns31ed7442018-02-23 05:29:09 -080012322 vl_api_fib_path_t *fp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012323 int i;
12324
12325 if (VAT_JSON_ARRAY != vam->json_tree.type)
12326 {
12327 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12328 vat_json_init_array (&vam->json_tree);
12329 }
12330 node = vat_json_array_add (&vam->json_tree);
12331
12332 vat_json_init_object (node);
Neale Ranns097fa662018-05-01 05:17:55 -070012333 vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
12334 vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
12335 vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
Damjan Marion7cd468a2016-12-19 23:05:39 +010012336 vat_json_object_add_uint (node, "path_count", count);
Neale Ranns097fa662018-05-01 05:17:55 -070012337 fp = mp->mr_route.mr_paths;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012338 for (i = 0; i < count; i++)
12339 {
Neale Ranns0f26c5a2017-03-01 15:12:11 -080012340 vl_api_mpls_fib_path_json_print (node, fp);
12341 fp++;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012342 }
12343}
12344
12345static int
Neale Ranns097fa662018-05-01 05:17:55 -070012346api_mpls_route_dump (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012347{
Neale Ranns097fa662018-05-01 05:17:55 -070012348 unformat_input_t *input = vam->input;
12349 vl_api_mpls_route_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012350 vl_api_control_ping_t *mp_ping;
Neale Ranns097fa662018-05-01 05:17:55 -070012351 u32 table_id;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012352 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012353
Neale Ranns097fa662018-05-01 05:17:55 -070012354 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12355 {
12356 if (unformat (input, "table_id %d", &table_id))
12357 ;
12358 else
12359 break;
12360 }
12361 if (table_id == ~0)
12362 {
12363 errmsg ("missing table id");
12364 return -99;
12365 }
12366
12367 M (MPLS_ROUTE_DUMP, mp);
12368
12369 mp->table.mt_table_id = ntohl (table_id);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012370 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012371
12372 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040012373 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012374 S (mp_ping);
12375
Jon Loeliger56c7b012017-02-01 12:31:41 -060012376 W (ret);
12377 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012378}
12379
Neale Ranns097fa662018-05-01 05:17:55 -070012380#define vl_api_ip_table_details_t_endian vl_noop_handler
12381#define vl_api_ip_table_details_t_print vl_noop_handler
Damjan Marion7cd468a2016-12-19 23:05:39 +010012382
12383static void
Neale Ranns097fa662018-05-01 05:17:55 -070012384vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012385{
12386 vat_main_t *vam = &vat_main;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012387
12388 print (vam->ofp,
Neale Ranns097fa662018-05-01 05:17:55 -070012389 "%s; table-id %d, prefix %U/%d",
12390 mp->table.name, ntohl (mp->table.table_id));
Damjan Marion7cd468a2016-12-19 23:05:39 +010012391}
12392
Neale Ranns097fa662018-05-01 05:17:55 -070012393
12394static void vl_api_ip_table_details_t_handler_json
12395 (vl_api_ip_table_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012396{
12397 vat_main_t *vam = &vat_main;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012398 vat_json_node_t *node = NULL;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012399
12400 if (VAT_JSON_ARRAY != vam->json_tree.type)
12401 {
12402 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12403 vat_json_init_array (&vam->json_tree);
12404 }
12405 node = vat_json_array_add (&vam->json_tree);
12406
12407 vat_json_init_object (node);
Neale Ranns097fa662018-05-01 05:17:55 -070012408 vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
Damjan Marion7cd468a2016-12-19 23:05:39 +010012409}
12410
12411static int
Neale Ranns097fa662018-05-01 05:17:55 -070012412api_ip_table_dump (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012413{
Neale Ranns097fa662018-05-01 05:17:55 -070012414 vl_api_ip_table_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012415 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012416 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012417
Neale Ranns097fa662018-05-01 05:17:55 -070012418 M (IP_TABLE_DUMP, mp);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012419 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012420
12421 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040012422 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012423 S (mp_ping);
12424
Jon Loeliger56c7b012017-02-01 12:31:41 -060012425 W (ret);
12426 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012427}
12428
Neale Ranns5a8123b2017-01-26 01:18:23 -080012429static int
Neale Ranns097fa662018-05-01 05:17:55 -070012430api_ip_mtable_dump (vat_main_t * vam)
Neale Ranns5a8123b2017-01-26 01:18:23 -080012431{
Neale Ranns097fa662018-05-01 05:17:55 -070012432 vl_api_ip_mtable_dump_t *mp;
Neale Ranns5a8123b2017-01-26 01:18:23 -080012433 vl_api_control_ping_t *mp_ping;
12434 int ret;
12435
Neale Ranns097fa662018-05-01 05:17:55 -070012436 M (IP_MTABLE_DUMP, mp);
12437 S (mp);
12438
12439 /* Use a control ping for synchronization */
12440 MPING (CONTROL_PING, mp_ping);
12441 S (mp_ping);
12442
12443 W (ret);
12444 return ret;
12445}
12446
12447static int
12448api_ip_mroute_dump (vat_main_t * vam)
12449{
12450 unformat_input_t *input = vam->input;
12451 vl_api_control_ping_t *mp_ping;
12452 vl_api_ip_mroute_dump_t *mp;
12453 int ret, is_ip6;
12454 u32 table_id;
12455
12456 is_ip6 = 0;
12457 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12458 {
12459 if (unformat (input, "table_id %d", &table_id))
12460 ;
12461 else if (unformat (input, "ip6"))
12462 is_ip6 = 1;
12463 else if (unformat (input, "ip4"))
12464 is_ip6 = 0;
12465 else
12466 break;
12467 }
12468 if (table_id == ~0)
12469 {
12470 errmsg ("missing table id");
12471 return -99;
12472 }
12473
12474 M (IP_MROUTE_DUMP, mp);
12475 mp->table.table_id = table_id;
12476 mp->table.is_ip6 = is_ip6;
Neale Ranns5a8123b2017-01-26 01:18:23 -080012477 S (mp);
12478
12479 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040012480 MPING (CONTROL_PING, mp_ping);
Neale Ranns5a8123b2017-01-26 01:18:23 -080012481 S (mp_ping);
12482
12483 W (ret);
12484 return ret;
12485}
12486
Neale Ranns097fa662018-05-01 05:17:55 -070012487#define vl_api_ip_route_details_t_endian vl_noop_handler
12488#define vl_api_ip_route_details_t_print vl_noop_handler
Damjan Marion7cd468a2016-12-19 23:05:39 +010012489
12490static void
Neale Ranns097fa662018-05-01 05:17:55 -070012491vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012492{
12493 vat_main_t *vam = &vat_main;
Neale Ranns097fa662018-05-01 05:17:55 -070012494 u8 count = mp->route.n_paths;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012495 vl_api_fib_path_t *fp;
12496 int i;
12497
12498 print (vam->ofp,
Neale Ranns097fa662018-05-01 05:17:55 -070012499 "table-id %d, prefix %U/%d",
12500 ntohl (mp->route.table_id),
Paul Vinciguerraab055082019-06-06 14:07:55 -040012501 format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012502 for (i = 0; i < count; i++)
12503 {
Neale Ranns097fa662018-05-01 05:17:55 -070012504 fp = &mp->route.paths[i];
12505
12506 vl_api_fib_path_print (vam, fp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012507 fp++;
12508 }
12509}
12510
Neale Ranns097fa662018-05-01 05:17:55 -070012511static void vl_api_ip_route_details_t_handler_json
12512 (vl_api_ip_route_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012513{
12514 vat_main_t *vam = &vat_main;
Neale Ranns097fa662018-05-01 05:17:55 -070012515 u8 count = mp->route.n_paths;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012516 vat_json_node_t *node = NULL;
12517 struct in_addr ip4;
12518 struct in6_addr ip6;
12519 vl_api_fib_path_t *fp;
12520 int i;
12521
12522 if (VAT_JSON_ARRAY != vam->json_tree.type)
12523 {
12524 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12525 vat_json_init_array (&vam->json_tree);
12526 }
12527 node = vat_json_array_add (&vam->json_tree);
12528
12529 vat_json_init_object (node);
Neale Ranns097fa662018-05-01 05:17:55 -070012530 vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
12531 if (ADDRESS_IP6 == mp->route.prefix.address.af)
12532 {
12533 clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
12534 vat_json_object_add_ip6 (node, "prefix", ip6);
12535 }
12536 else
12537 {
12538 clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
12539 vat_json_object_add_ip4 (node, "prefix", ip4);
12540 }
Paul Vinciguerraab055082019-06-06 14:07:55 -040012541 vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012542 vat_json_object_add_uint (node, "path_count", count);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012543 for (i = 0; i < count; i++)
12544 {
Neale Ranns097fa662018-05-01 05:17:55 -070012545 fp = &mp->route.paths[i];
12546 vl_api_mpls_fib_path_json_print (node, fp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012547 }
12548}
12549
12550static int
Neale Ranns097fa662018-05-01 05:17:55 -070012551api_ip_route_dump (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012552{
Neale Ranns097fa662018-05-01 05:17:55 -070012553 unformat_input_t *input = vam->input;
12554 vl_api_ip_route_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012555 vl_api_control_ping_t *mp_ping;
Neale Ranns097fa662018-05-01 05:17:55 -070012556 u32 table_id;
12557 u8 is_ip6;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012558 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012559
Neale Ranns097fa662018-05-01 05:17:55 -070012560 is_ip6 = 0;
12561 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12562 {
12563 if (unformat (input, "table_id %d", &table_id))
12564 ;
12565 else if (unformat (input, "ip6"))
12566 is_ip6 = 1;
12567 else if (unformat (input, "ip4"))
12568 is_ip6 = 0;
12569 else
12570 break;
12571 }
12572 if (table_id == ~0)
12573 {
12574 errmsg ("missing table id");
12575 return -99;
12576 }
Damjan Marion7cd468a2016-12-19 23:05:39 +010012577
Neale Ranns097fa662018-05-01 05:17:55 -070012578 M (IP_ROUTE_DUMP, mp);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012579
Neale Ranns097fa662018-05-01 05:17:55 -070012580 mp->table.table_id = table_id;
12581 mp->table.is_ip6 = is_ip6;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012582
Neale Ranns5a8123b2017-01-26 01:18:23 -080012583 S (mp);
12584
12585 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040012586 MPING (CONTROL_PING, mp_ping);
Neale Ranns5a8123b2017-01-26 01:18:23 -080012587 S (mp_ping);
12588
12589 W (ret);
12590 return ret;
12591}
12592
Damjan Marion7cd468a2016-12-19 23:05:39 +010012593int
12594api_classify_table_ids (vat_main_t * vam)
12595{
12596 vl_api_classify_table_ids_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012597 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012598
12599 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012600 M (CLASSIFY_TABLE_IDS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012601 mp->context = 0;
12602
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012603 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012604 W (ret);
12605 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012606}
12607
12608int
12609api_classify_table_by_interface (vat_main_t * vam)
12610{
12611 unformat_input_t *input = vam->input;
12612 vl_api_classify_table_by_interface_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012613
12614 u32 sw_if_index = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012615 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012616 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12617 {
12618 if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12619 ;
12620 else if (unformat (input, "sw_if_index %d", &sw_if_index))
12621 ;
12622 else
12623 break;
12624 }
12625 if (sw_if_index == ~0)
12626 {
12627 errmsg ("missing interface name or sw_if_index");
12628 return -99;
12629 }
12630
12631 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012632 M (CLASSIFY_TABLE_BY_INTERFACE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012633 mp->context = 0;
12634 mp->sw_if_index = ntohl (sw_if_index);
12635
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012636 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012637 W (ret);
12638 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012639}
12640
12641int
12642api_classify_table_info (vat_main_t * vam)
12643{
12644 unformat_input_t *input = vam->input;
12645 vl_api_classify_table_info_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012646
12647 u32 table_id = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012648 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012649 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12650 {
12651 if (unformat (input, "table_id %d", &table_id))
12652 ;
12653 else
12654 break;
12655 }
12656 if (table_id == ~0)
12657 {
12658 errmsg ("missing table id");
12659 return -99;
12660 }
12661
12662 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012663 M (CLASSIFY_TABLE_INFO, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012664 mp->context = 0;
12665 mp->table_id = ntohl (table_id);
12666
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012667 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012668 W (ret);
12669 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012670}
12671
12672int
12673api_classify_session_dump (vat_main_t * vam)
12674{
12675 unformat_input_t *input = vam->input;
12676 vl_api_classify_session_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012677 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012678
12679 u32 table_id = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012680 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012681 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12682 {
12683 if (unformat (input, "table_id %d", &table_id))
12684 ;
12685 else
12686 break;
12687 }
12688 if (table_id == ~0)
12689 {
12690 errmsg ("missing table id");
12691 return -99;
12692 }
12693
12694 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012695 M (CLASSIFY_SESSION_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012696 mp->context = 0;
12697 mp->table_id = ntohl (table_id);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012698 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012699
12700 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040012701 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012702 S (mp_ping);
12703
Jon Loeliger56c7b012017-02-01 12:31:41 -060012704 W (ret);
12705 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012706}
12707
12708static void
12709vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
12710{
12711 vat_main_t *vam = &vat_main;
12712
12713 print (vam->ofp, "collector_address %U, collector_port %d, "
12714 "src_address %U, vrf_id %d, path_mtu %u, "
12715 "template_interval %u, udp_checksum %d",
12716 format_ip4_address, mp->collector_address,
12717 ntohs (mp->collector_port),
12718 format_ip4_address, mp->src_address,
12719 ntohl (mp->vrf_id), ntohl (mp->path_mtu),
12720 ntohl (mp->template_interval), mp->udp_checksum);
12721
12722 vam->retval = 0;
12723 vam->result_ready = 1;
12724}
12725
12726static void
12727 vl_api_ipfix_exporter_details_t_handler_json
12728 (vl_api_ipfix_exporter_details_t * mp)
12729{
12730 vat_main_t *vam = &vat_main;
12731 vat_json_node_t node;
12732 struct in_addr collector_address;
12733 struct in_addr src_address;
12734
12735 vat_json_init_object (&node);
12736 clib_memcpy (&collector_address, &mp->collector_address,
12737 sizeof (collector_address));
12738 vat_json_object_add_ip4 (&node, "collector_address", collector_address);
12739 vat_json_object_add_uint (&node, "collector_port",
12740 ntohs (mp->collector_port));
12741 clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
12742 vat_json_object_add_ip4 (&node, "src_address", src_address);
12743 vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
12744 vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
12745 vat_json_object_add_uint (&node, "template_interval",
12746 ntohl (mp->template_interval));
12747 vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
12748
12749 vat_json_print (vam->ofp, &node);
12750 vat_json_free (&node);
12751 vam->retval = 0;
12752 vam->result_ready = 1;
12753}
12754
12755int
12756api_ipfix_exporter_dump (vat_main_t * vam)
12757{
12758 vl_api_ipfix_exporter_dump_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012759 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012760
12761 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012762 M (IPFIX_EXPORTER_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012763 mp->context = 0;
12764
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012765 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012766 W (ret);
12767 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012768}
12769
12770static int
12771api_ipfix_classify_stream_dump (vat_main_t * vam)
12772{
12773 vl_api_ipfix_classify_stream_dump_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012774 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012775
12776 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012777 M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012778 mp->context = 0;
12779
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012780 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012781 W (ret);
12782 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012783 /* NOTREACHED */
12784 return 0;
12785}
12786
12787static void
12788 vl_api_ipfix_classify_stream_details_t_handler
12789 (vl_api_ipfix_classify_stream_details_t * mp)
12790{
12791 vat_main_t *vam = &vat_main;
12792 print (vam->ofp, "domain_id %d, src_port %d",
12793 ntohl (mp->domain_id), ntohs (mp->src_port));
12794 vam->retval = 0;
12795 vam->result_ready = 1;
12796}
12797
12798static void
12799 vl_api_ipfix_classify_stream_details_t_handler_json
12800 (vl_api_ipfix_classify_stream_details_t * mp)
12801{
12802 vat_main_t *vam = &vat_main;
12803 vat_json_node_t node;
12804
12805 vat_json_init_object (&node);
12806 vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
12807 vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
12808
12809 vat_json_print (vam->ofp, &node);
12810 vat_json_free (&node);
12811 vam->retval = 0;
12812 vam->result_ready = 1;
12813}
12814
12815static int
12816api_ipfix_classify_table_dump (vat_main_t * vam)
12817{
12818 vl_api_ipfix_classify_table_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012819 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012820 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012821
12822 if (!vam->json_output)
12823 {
12824 print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
12825 "transport_protocol");
12826 }
12827
12828 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012829 M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012830
12831 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012832 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012833
12834 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040012835 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012836 S (mp_ping);
12837
Jon Loeliger56c7b012017-02-01 12:31:41 -060012838 W (ret);
12839 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012840}
12841
12842static void
12843 vl_api_ipfix_classify_table_details_t_handler
12844 (vl_api_ipfix_classify_table_details_t * mp)
12845{
12846 vat_main_t *vam = &vat_main;
12847 print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
12848 mp->transport_protocol);
12849}
12850
12851static void
12852 vl_api_ipfix_classify_table_details_t_handler_json
12853 (vl_api_ipfix_classify_table_details_t * mp)
12854{
12855 vat_json_node_t *node = NULL;
12856 vat_main_t *vam = &vat_main;
12857
12858 if (VAT_JSON_ARRAY != vam->json_tree.type)
12859 {
12860 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12861 vat_json_init_array (&vam->json_tree);
12862 }
12863
12864 node = vat_json_array_add (&vam->json_tree);
12865 vat_json_init_object (node);
12866
12867 vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
12868 vat_json_object_add_uint (node, "ip_version", mp->ip_version);
12869 vat_json_object_add_uint (node, "transport_protocol",
12870 mp->transport_protocol);
12871}
12872
12873static int
12874api_sw_interface_span_enable_disable (vat_main_t * vam)
12875{
12876 unformat_input_t *i = vam->input;
12877 vl_api_sw_interface_span_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012878 u32 src_sw_if_index = ~0;
12879 u32 dst_sw_if_index = ~0;
12880 u8 state = 3;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012881 int ret;
Eyal Bari001fd402017-07-16 09:34:53 +030012882 u8 is_l2 = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012883
12884 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12885 {
12886 if (unformat
12887 (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
12888 ;
12889 else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
12890 ;
12891 else
12892 if (unformat
12893 (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
12894 ;
12895 else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
12896 ;
12897 else if (unformat (i, "disable"))
12898 state = 0;
12899 else if (unformat (i, "rx"))
12900 state = 1;
12901 else if (unformat (i, "tx"))
12902 state = 2;
12903 else if (unformat (i, "both"))
12904 state = 3;
Eyal Bari001fd402017-07-16 09:34:53 +030012905 else if (unformat (i, "l2"))
12906 is_l2 = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012907 else
12908 break;
12909 }
12910
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012911 M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012912
12913 mp->sw_if_index_from = htonl (src_sw_if_index);
12914 mp->sw_if_index_to = htonl (dst_sw_if_index);
12915 mp->state = state;
Eyal Bari001fd402017-07-16 09:34:53 +030012916 mp->is_l2 = is_l2;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012917
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012918 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012919 W (ret);
12920 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012921}
12922
12923static void
12924vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
12925 * mp)
12926{
12927 vat_main_t *vam = &vat_main;
12928 u8 *sw_if_from_name = 0;
12929 u8 *sw_if_to_name = 0;
12930 u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
12931 u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
12932 char *states[] = { "none", "rx", "tx", "both" };
12933 hash_pair_t *p;
12934
12935 /* *INDENT-OFF* */
12936 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
12937 ({
12938 if ((u32) p->value[0] == sw_if_index_from)
12939 {
12940 sw_if_from_name = (u8 *)(p->key);
12941 if (sw_if_to_name)
12942 break;
12943 }
12944 if ((u32) p->value[0] == sw_if_index_to)
12945 {
12946 sw_if_to_name = (u8 *)(p->key);
12947 if (sw_if_from_name)
12948 break;
12949 }
12950 }));
12951 /* *INDENT-ON* */
Jon Loeliger179ab362018-03-12 14:50:08 -050012952 print (vam->ofp, "%20s => %20s (%s) %s",
12953 sw_if_from_name, sw_if_to_name, states[mp->state],
12954 mp->is_l2 ? "l2" : "device");
Damjan Marion7cd468a2016-12-19 23:05:39 +010012955}
12956
12957static void
12958 vl_api_sw_interface_span_details_t_handler_json
12959 (vl_api_sw_interface_span_details_t * mp)
12960{
12961 vat_main_t *vam = &vat_main;
12962 vat_json_node_t *node = NULL;
12963 u8 *sw_if_from_name = 0;
12964 u8 *sw_if_to_name = 0;
12965 u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
12966 u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
12967 hash_pair_t *p;
12968
12969 /* *INDENT-OFF* */
12970 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
12971 ({
12972 if ((u32) p->value[0] == sw_if_index_from)
12973 {
12974 sw_if_from_name = (u8 *)(p->key);
12975 if (sw_if_to_name)
12976 break;
12977 }
12978 if ((u32) p->value[0] == sw_if_index_to)
12979 {
12980 sw_if_to_name = (u8 *)(p->key);
12981 if (sw_if_from_name)
12982 break;
12983 }
12984 }));
12985 /* *INDENT-ON* */
12986
12987 if (VAT_JSON_ARRAY != vam->json_tree.type)
12988 {
12989 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12990 vat_json_init_array (&vam->json_tree);
12991 }
12992 node = vat_json_array_add (&vam->json_tree);
12993
12994 vat_json_init_object (node);
12995 vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
12996 vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
12997 vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
Neale Ranns05b2bf22017-01-30 06:44:58 -080012998 if (0 != sw_if_to_name)
12999 {
13000 vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
13001 }
Damjan Marion7cd468a2016-12-19 23:05:39 +010013002 vat_json_object_add_uint (node, "state", mp->state);
Jon Loeliger179ab362018-03-12 14:50:08 -050013003 vat_json_object_add_uint (node, "is-l2", mp->is_l2);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013004}
13005
13006static int
13007api_sw_interface_span_dump (vat_main_t * vam)
13008{
Eyal Bari5b311202017-07-31 13:12:30 +030013009 unformat_input_t *input = vam->input;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013010 vl_api_sw_interface_span_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060013011 vl_api_control_ping_t *mp_ping;
Eyal Bari5b311202017-07-31 13:12:30 +030013012 u8 is_l2 = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013013 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013014
Eyal Bari5b311202017-07-31 13:12:30 +030013015 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13016 {
13017 if (unformat (input, "l2"))
13018 is_l2 = 1;
13019 else
13020 break;
13021 }
13022
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013023 M (SW_INTERFACE_SPAN_DUMP, mp);
Eyal Bari5b311202017-07-31 13:12:30 +030013024 mp->is_l2 = is_l2;
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013025 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013026
13027 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040013028 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060013029 S (mp_ping);
13030
Jon Loeliger56c7b012017-02-01 12:31:41 -060013031 W (ret);
13032 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013033}
13034
13035int
13036api_pg_create_interface (vat_main_t * vam)
13037{
13038 unformat_input_t *input = vam->input;
13039 vl_api_pg_create_interface_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013040
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +020013041 u32 if_id = ~0, gso_size = 0;
13042 u8 gso_enabled = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013043 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013044 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13045 {
13046 if (unformat (input, "if_id %d", &if_id))
13047 ;
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +020013048 else if (unformat (input, "gso-enabled"))
13049 {
13050 gso_enabled = 1;
13051 if (unformat (input, "gso-size %u", &gso_size))
13052 ;
13053 else
13054 {
13055 errmsg ("missing gso-size");
13056 return -99;
13057 }
13058 }
Damjan Marion7cd468a2016-12-19 23:05:39 +010013059 else
13060 break;
13061 }
13062 if (if_id == ~0)
13063 {
13064 errmsg ("missing pg interface index");
13065 return -99;
13066 }
13067
13068 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013069 M (PG_CREATE_INTERFACE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013070 mp->context = 0;
13071 mp->interface_id = ntohl (if_id);
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +020013072 mp->gso_enabled = gso_enabled;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013073
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013074 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013075 W (ret);
13076 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013077}
13078
13079int
13080api_pg_capture (vat_main_t * vam)
13081{
13082 unformat_input_t *input = vam->input;
13083 vl_api_pg_capture_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013084
13085 u32 if_id = ~0;
13086 u8 enable = 1;
13087 u32 count = 1;
13088 u8 pcap_file_set = 0;
13089 u8 *pcap_file = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013090 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013091 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13092 {
13093 if (unformat (input, "if_id %d", &if_id))
13094 ;
13095 else if (unformat (input, "pcap %s", &pcap_file))
13096 pcap_file_set = 1;
13097 else if (unformat (input, "count %d", &count))
13098 ;
13099 else if (unformat (input, "disable"))
13100 enable = 0;
13101 else
13102 break;
13103 }
13104 if (if_id == ~0)
13105 {
13106 errmsg ("missing pg interface index");
13107 return -99;
13108 }
13109 if (pcap_file_set > 0)
13110 {
13111 if (vec_len (pcap_file) > 255)
13112 {
13113 errmsg ("pcap file name is too long");
13114 return -99;
13115 }
13116 }
13117
Damjan Marion7cd468a2016-12-19 23:05:39 +010013118 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013119 M (PG_CAPTURE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013120 mp->context = 0;
13121 mp->interface_id = ntohl (if_id);
13122 mp->is_enabled = enable;
13123 mp->count = ntohl (count);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013124 if (pcap_file_set != 0)
13125 {
Jakub Grajciardb863292020-01-30 14:14:15 +010013126 vl_api_vec_to_api_string (pcap_file, &mp->pcap_file_name);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013127 }
13128 vec_free (pcap_file);
13129
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013130 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013131 W (ret);
13132 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013133}
13134
13135int
13136api_pg_enable_disable (vat_main_t * vam)
13137{
13138 unformat_input_t *input = vam->input;
13139 vl_api_pg_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013140
13141 u8 enable = 1;
13142 u8 stream_name_set = 0;
13143 u8 *stream_name = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013144 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013145 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13146 {
13147 if (unformat (input, "stream %s", &stream_name))
13148 stream_name_set = 1;
13149 else if (unformat (input, "disable"))
13150 enable = 0;
13151 else
13152 break;
13153 }
13154
13155 if (stream_name_set > 0)
13156 {
13157 if (vec_len (stream_name) > 255)
13158 {
13159 errmsg ("stream name too long");
13160 return -99;
13161 }
13162 }
13163
Damjan Marion7cd468a2016-12-19 23:05:39 +010013164 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013165 M (PG_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013166 mp->context = 0;
13167 mp->is_enabled = enable;
13168 if (stream_name_set != 0)
13169 {
Jakub Grajciardb863292020-01-30 14:14:15 +010013170 vl_api_vec_to_api_string (stream_name, &mp->stream_name);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013171 }
13172 vec_free (stream_name);
13173
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013174 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013175 W (ret);
13176 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013177}
13178
13179int
Mohsin Kazmif382b062020-08-11 15:00:44 +020013180api_pg_interface_enable_disable_coalesce (vat_main_t * vam)
13181{
13182 unformat_input_t *input = vam->input;
13183 vl_api_pg_interface_enable_disable_coalesce_t *mp;
13184
13185 u32 sw_if_index = ~0;
13186 u8 enable = 1;
13187 int ret;
13188 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13189 {
13190 if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13191 ;
13192 else if (unformat (input, "sw_if_index %d", &sw_if_index))
13193 ;
13194 else if (unformat (input, "disable"))
13195 enable = 0;
13196 else
13197 break;
13198 }
13199
13200 if (sw_if_index == ~0)
13201 {
13202 errmsg ("Interface required but not specified");
13203 return -99;
13204 }
13205
13206 /* Construct the API message */
13207 M (PG_INTERFACE_ENABLE_DISABLE_COALESCE, mp);
13208 mp->context = 0;
13209 mp->coalesce_enabled = enable;
13210 mp->sw_if_index = htonl (sw_if_index);
13211
13212 S (mp);
13213 W (ret);
13214 return ret;
13215}
13216
13217int
Damjan Marion7cd468a2016-12-19 23:05:39 +010013218api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
13219{
13220 unformat_input_t *input = vam->input;
13221 vl_api_ip_source_and_port_range_check_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013222
13223 u16 *low_ports = 0;
13224 u16 *high_ports = 0;
13225 u16 this_low;
13226 u16 this_hi;
Neale Ranns37029302018-08-10 05:30:06 -070013227 vl_api_prefix_t prefix;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013228 u32 tmp, tmp2;
13229 u8 prefix_set = 0;
13230 u32 vrf_id = ~0;
13231 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013232 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013233
13234 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13235 {
Neale Ranns37029302018-08-10 05:30:06 -070013236 if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
13237 prefix_set = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013238 else if (unformat (input, "vrf %d", &vrf_id))
13239 ;
13240 else if (unformat (input, "del"))
13241 is_add = 0;
13242 else if (unformat (input, "port %d", &tmp))
13243 {
13244 if (tmp == 0 || tmp > 65535)
13245 {
13246 errmsg ("port %d out of range", tmp);
13247 return -99;
13248 }
13249 this_low = tmp;
13250 this_hi = this_low + 1;
13251 vec_add1 (low_ports, this_low);
13252 vec_add1 (high_ports, this_hi);
13253 }
13254 else if (unformat (input, "range %d - %d", &tmp, &tmp2))
13255 {
13256 if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
13257 {
13258 errmsg ("incorrect range parameters");
13259 return -99;
13260 }
13261 this_low = tmp;
13262 /* Note: in debug CLI +1 is added to high before
13263 passing to real fn that does "the work"
13264 (ip_source_and_port_range_check_add_del).
13265 This fn is a wrapper around the binary API fn a
13266 control plane will call, which expects this increment
13267 to have occurred. Hence letting the binary API control
13268 plane fn do the increment for consistency between VAT
13269 and other control planes.
13270 */
13271 this_hi = tmp2;
13272 vec_add1 (low_ports, this_low);
13273 vec_add1 (high_ports, this_hi);
13274 }
13275 else
13276 break;
13277 }
13278
13279 if (prefix_set == 0)
13280 {
13281 errmsg ("<address>/<mask> not specified");
13282 return -99;
13283 }
13284
13285 if (vrf_id == ~0)
13286 {
13287 errmsg ("VRF ID required, not specified");
13288 return -99;
13289 }
13290
13291 if (vrf_id == 0)
13292 {
13293 errmsg
13294 ("VRF ID should not be default. Should be distinct VRF for this purpose.");
13295 return -99;
13296 }
13297
13298 if (vec_len (low_ports) == 0)
13299 {
13300 errmsg ("At least one port or port range required");
13301 return -99;
13302 }
13303
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013304 M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013305
13306 mp->is_add = is_add;
13307
Neale Ranns37029302018-08-10 05:30:06 -070013308 clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
Damjan Marion7cd468a2016-12-19 23:05:39 +010013309
Damjan Marion7cd468a2016-12-19 23:05:39 +010013310 mp->number_of_ranges = vec_len (low_ports);
13311
13312 clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
13313 vec_free (low_ports);
13314
13315 clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
13316 vec_free (high_ports);
13317
13318 mp->vrf_id = ntohl (vrf_id);
13319
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013320 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013321 W (ret);
13322 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013323}
13324
13325int
13326api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
13327{
13328 unformat_input_t *input = vam->input;
13329 vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013330 u32 sw_if_index = ~0;
13331 int vrf_set = 0;
13332 u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
13333 u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
13334 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013335 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013336
13337 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13338 {
13339 if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13340 ;
13341 else if (unformat (input, "sw_if_index %d", &sw_if_index))
13342 ;
13343 else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
13344 vrf_set = 1;
13345 else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
13346 vrf_set = 1;
13347 else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
13348 vrf_set = 1;
13349 else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
13350 vrf_set = 1;
13351 else if (unformat (input, "del"))
13352 is_add = 0;
13353 else
13354 break;
13355 }
13356
13357 if (sw_if_index == ~0)
13358 {
13359 errmsg ("Interface required but not specified");
13360 return -99;
13361 }
13362
13363 if (vrf_set == 0)
13364 {
13365 errmsg ("VRF ID required but not specified");
13366 return -99;
13367 }
13368
13369 if (tcp_out_vrf_id == 0
13370 || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
13371 {
13372 errmsg
13373 ("VRF ID should not be default. Should be distinct VRF for this purpose.");
13374 return -99;
13375 }
13376
13377 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013378 M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013379
13380 mp->sw_if_index = ntohl (sw_if_index);
13381 mp->is_add = is_add;
13382 mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
13383 mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
13384 mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
13385 mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
13386
13387 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013388 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013389
13390 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060013391 W (ret);
13392 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013393}
13394
13395static int
Pavel Kotuceke88865d2018-11-28 07:42:11 +010013396api_set_punt (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010013397{
13398 unformat_input_t *i = vam->input;
Neale Ranns50f0ac02019-05-15 02:13:37 -070013399 vl_api_address_family_t af;
Pavel Kotuceke88865d2018-11-28 07:42:11 +010013400 vl_api_set_punt_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013401 u32 protocol = ~0;
13402 u32 port = ~0;
13403 int is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013404 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013405
13406 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13407 {
Neale Ranns50f0ac02019-05-15 02:13:37 -070013408 if (unformat (i, "%U", unformat_vl_api_address_family, &af))
Damjan Marion7cd468a2016-12-19 23:05:39 +010013409 ;
13410 else if (unformat (i, "protocol %d", &protocol))
13411 ;
13412 else if (unformat (i, "port %d", &port))
13413 ;
13414 else if (unformat (i, "del"))
13415 is_add = 0;
13416 else
13417 {
13418 clib_warning ("parse error '%U'", format_unformat_error, i);
13419 return -99;
13420 }
13421 }
13422
Pavel Kotuceke88865d2018-11-28 07:42:11 +010013423 M (SET_PUNT, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013424
13425 mp->is_add = (u8) is_add;
Neale Ranns50f0ac02019-05-15 02:13:37 -070013426 mp->punt.type = PUNT_API_TYPE_L4;
13427 mp->punt.punt.l4.af = af;
13428 mp->punt.punt.l4.protocol = (u8) protocol;
13429 mp->punt.punt.l4.port = htons ((u16) port);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013430
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013431 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013432 W (ret);
13433 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013434}
13435
Damjan Marion7cd468a2016-12-19 23:05:39 +010013436static int
13437api_delete_subif (vat_main_t * vam)
13438{
13439 unformat_input_t *i = vam->input;
13440 vl_api_delete_subif_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013441 u32 sw_if_index = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013442 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013443
13444 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13445 {
13446 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13447 ;
13448 if (unformat (i, "sw_if_index %d", &sw_if_index))
13449 ;
13450 else
13451 break;
13452 }
13453
13454 if (sw_if_index == ~0)
13455 {
13456 errmsg ("missing sw_if_index");
13457 return -99;
13458 }
13459
13460 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013461 M (DELETE_SUBIF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013462 mp->sw_if_index = ntohl (sw_if_index);
13463
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013464 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013465 W (ret);
13466 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013467}
13468
13469#define foreach_pbb_vtr_op \
13470_("disable", L2_VTR_DISABLED) \
13471_("pop", L2_VTR_POP_2) \
13472_("push", L2_VTR_PUSH_2)
13473
13474static int
13475api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
13476{
13477 unformat_input_t *i = vam->input;
13478 vl_api_l2_interface_pbb_tag_rewrite_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013479 u32 sw_if_index = ~0, vtr_op = ~0;
13480 u16 outer_tag = ~0;
13481 u8 dmac[6], smac[6];
13482 u8 dmac_set = 0, smac_set = 0;
13483 u16 vlanid = 0;
13484 u32 sid = ~0;
13485 u32 tmp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013486 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013487
13488 /* Shut up coverity */
Dave Barachb7b92992018-10-17 10:38:51 -040013489 clib_memset (dmac, 0, sizeof (dmac));
13490 clib_memset (smac, 0, sizeof (smac));
Damjan Marion7cd468a2016-12-19 23:05:39 +010013491
13492 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13493 {
13494 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13495 ;
13496 else if (unformat (i, "sw_if_index %d", &sw_if_index))
13497 ;
13498 else if (unformat (i, "vtr_op %d", &vtr_op))
13499 ;
13500#define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
13501 foreach_pbb_vtr_op
13502#undef _
13503 else if (unformat (i, "translate_pbb_stag"))
13504 {
13505 if (unformat (i, "%d", &tmp))
13506 {
13507 vtr_op = L2_VTR_TRANSLATE_2_1;
13508 outer_tag = tmp;
13509 }
13510 else
13511 {
13512 errmsg
13513 ("translate_pbb_stag operation requires outer tag definition");
13514 return -99;
13515 }
13516 }
13517 else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
13518 dmac_set++;
13519 else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
13520 smac_set++;
13521 else if (unformat (i, "sid %d", &sid))
13522 ;
13523 else if (unformat (i, "vlanid %d", &tmp))
13524 vlanid = tmp;
13525 else
13526 {
13527 clib_warning ("parse error '%U'", format_unformat_error, i);
13528 return -99;
13529 }
13530 }
13531
13532 if ((sw_if_index == ~0) || (vtr_op == ~0))
13533 {
13534 errmsg ("missing sw_if_index or vtr operation");
13535 return -99;
13536 }
13537 if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
13538 && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
13539 {
13540 errmsg
13541 ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
13542 return -99;
13543 }
13544
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013545 M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013546 mp->sw_if_index = ntohl (sw_if_index);
13547 mp->vtr_op = ntohl (vtr_op);
13548 mp->outer_tag = ntohs (outer_tag);
13549 clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
13550 clib_memcpy (mp->b_smac, smac, sizeof (smac));
13551 mp->b_vlanid = ntohs (vlanid);
13552 mp->i_sid = ntohl (sid);
13553
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013554 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013555 W (ret);
13556 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013557}
13558
13559static int
13560api_flow_classify_set_interface (vat_main_t * vam)
13561{
13562 unformat_input_t *i = vam->input;
13563 vl_api_flow_classify_set_interface_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013564 u32 sw_if_index;
13565 int sw_if_index_set;
13566 u32 ip4_table_index = ~0;
13567 u32 ip6_table_index = ~0;
13568 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013569 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013570
13571 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13572 {
13573 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13574 sw_if_index_set = 1;
13575 else if (unformat (i, "sw_if_index %d", &sw_if_index))
13576 sw_if_index_set = 1;
13577 else if (unformat (i, "del"))
13578 is_add = 0;
13579 else if (unformat (i, "ip4-table %d", &ip4_table_index))
13580 ;
13581 else if (unformat (i, "ip6-table %d", &ip6_table_index))
13582 ;
13583 else
13584 {
13585 clib_warning ("parse error '%U'", format_unformat_error, i);
13586 return -99;
13587 }
13588 }
13589
13590 if (sw_if_index_set == 0)
13591 {
13592 errmsg ("missing interface name or sw_if_index");
13593 return -99;
13594 }
13595
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013596 M (FLOW_CLASSIFY_SET_INTERFACE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013597
13598 mp->sw_if_index = ntohl (sw_if_index);
13599 mp->ip4_table_index = ntohl (ip4_table_index);
13600 mp->ip6_table_index = ntohl (ip6_table_index);
13601 mp->is_add = is_add;
13602
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013603 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013604 W (ret);
13605 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013606}
13607
13608static int
13609api_flow_classify_dump (vat_main_t * vam)
13610{
13611 unformat_input_t *i = vam->input;
13612 vl_api_flow_classify_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060013613 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013614 u8 type = FLOW_CLASSIFY_N_TABLES;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013615 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013616
13617 if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
13618 ;
13619 else
13620 {
13621 errmsg ("classify table type must be specified");
13622 return -99;
13623 }
13624
13625 if (!vam->json_output)
13626 {
13627 print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
13628 }
13629
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013630 M (FLOW_CLASSIFY_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013631 mp->type = type;
13632 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013633 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013634
13635 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040013636 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060013637 S (mp_ping);
13638
Damjan Marion7cd468a2016-12-19 23:05:39 +010013639 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060013640 W (ret);
13641 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013642}
13643
13644static int
13645api_feature_enable_disable (vat_main_t * vam)
13646{
13647 unformat_input_t *i = vam->input;
13648 vl_api_feature_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013649 u8 *arc_name = 0;
13650 u8 *feature_name = 0;
13651 u32 sw_if_index = ~0;
13652 u8 enable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013653 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013654
13655 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13656 {
13657 if (unformat (i, "arc_name %s", &arc_name))
13658 ;
13659 else if (unformat (i, "feature_name %s", &feature_name))
13660 ;
13661 else
13662 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13663 ;
13664 else if (unformat (i, "sw_if_index %d", &sw_if_index))
13665 ;
13666 else if (unformat (i, "disable"))
13667 enable = 0;
13668 else
13669 break;
13670 }
13671
13672 if (arc_name == 0)
13673 {
13674 errmsg ("missing arc name");
13675 return -99;
13676 }
13677 if (vec_len (arc_name) > 63)
13678 {
13679 errmsg ("arc name too long");
13680 }
13681
13682 if (feature_name == 0)
13683 {
13684 errmsg ("missing feature name");
13685 return -99;
13686 }
13687 if (vec_len (feature_name) > 63)
13688 {
13689 errmsg ("feature name too long");
13690 }
13691
13692 if (sw_if_index == ~0)
13693 {
13694 errmsg ("missing interface name or sw_if_index");
13695 return -99;
13696 }
13697
13698 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013699 M (FEATURE_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013700 mp->sw_if_index = ntohl (sw_if_index);
13701 mp->enable = enable;
13702 clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
13703 clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
13704 vec_free (arc_name);
13705 vec_free (feature_name);
13706
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013707 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013708 W (ret);
13709 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013710}
13711
13712static int
Mohsin Kazmi29467b52019-10-08 19:42:38 +020013713api_feature_gso_enable_disable (vat_main_t * vam)
13714{
13715 unformat_input_t *i = vam->input;
13716 vl_api_feature_gso_enable_disable_t *mp;
13717 u32 sw_if_index = ~0;
13718 u8 enable = 1;
13719 int ret;
13720
13721 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13722 {
13723 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13724 ;
13725 else if (unformat (i, "sw_if_index %d", &sw_if_index))
13726 ;
13727 else if (unformat (i, "enable"))
13728 enable = 1;
13729 else if (unformat (i, "disable"))
13730 enable = 0;
13731 else
13732 break;
13733 }
13734
13735 if (sw_if_index == ~0)
13736 {
13737 errmsg ("missing interface name or sw_if_index");
13738 return -99;
13739 }
13740
13741 /* Construct the API message */
13742 M (FEATURE_GSO_ENABLE_DISABLE, mp);
13743 mp->sw_if_index = ntohl (sw_if_index);
13744 mp->enable_disable = enable;
13745
13746 S (mp);
13747 W (ret);
13748 return ret;
13749}
13750
13751static int
Damjan Marion7cd468a2016-12-19 23:05:39 +010013752api_sw_interface_tag_add_del (vat_main_t * vam)
13753{
13754 unformat_input_t *i = vam->input;
13755 vl_api_sw_interface_tag_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013756 u32 sw_if_index = ~0;
13757 u8 *tag = 0;
13758 u8 enable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013759 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013760
13761 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13762 {
13763 if (unformat (i, "tag %s", &tag))
13764 ;
13765 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13766 ;
13767 else if (unformat (i, "sw_if_index %d", &sw_if_index))
13768 ;
13769 else if (unformat (i, "del"))
13770 enable = 0;
13771 else
13772 break;
13773 }
13774
13775 if (sw_if_index == ~0)
13776 {
13777 errmsg ("missing interface name or sw_if_index");
13778 return -99;
13779 }
13780
13781 if (enable && (tag == 0))
13782 {
13783 errmsg ("no tag specified");
13784 return -99;
13785 }
13786
13787 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013788 M (SW_INTERFACE_TAG_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013789 mp->sw_if_index = ntohl (sw_if_index);
13790 mp->is_add = enable;
13791 if (enable)
Ole Troane5ff5a32019-08-23 22:55:18 +020013792 strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013793 vec_free (tag);
13794
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013795 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013796 W (ret);
13797 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013798}
13799
Matthew Smithe0792fd2019-07-12 11:48:24 -050013800static int
13801api_sw_interface_add_del_mac_address (vat_main_t * vam)
13802{
13803 unformat_input_t *i = vam->input;
13804 vl_api_mac_address_t mac = { 0 };
13805 vl_api_sw_interface_add_del_mac_address_t *mp;
13806 u32 sw_if_index = ~0;
13807 u8 is_add = 1;
13808 u8 mac_set = 0;
13809 int ret;
13810
13811 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13812 {
13813 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13814 ;
13815 else if (unformat (i, "sw_if_index %d", &sw_if_index))
13816 ;
13817 else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
13818 mac_set++;
13819 else if (unformat (i, "del"))
13820 is_add = 0;
13821 else
13822 break;
13823 }
13824
13825 if (sw_if_index == ~0)
13826 {
13827 errmsg ("missing interface name or sw_if_index");
13828 return -99;
13829 }
13830
13831 if (!mac_set)
13832 {
13833 errmsg ("missing MAC address");
13834 return -99;
13835 }
13836
13837 /* Construct the API message */
13838 M (SW_INTERFACE_ADD_DEL_MAC_ADDRESS, mp);
13839 mp->sw_if_index = ntohl (sw_if_index);
13840 mp->is_add = is_add;
13841 clib_memcpy (&mp->addr, &mac, sizeof (mac));
13842
13843 S (mp);
13844 W (ret);
13845 return ret;
13846}
13847
Damjan Marion7cd468a2016-12-19 23:05:39 +010013848static void vl_api_l2_xconnect_details_t_handler
13849 (vl_api_l2_xconnect_details_t * mp)
13850{
13851 vat_main_t *vam = &vat_main;
13852
13853 print (vam->ofp, "%15d%15d",
13854 ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
13855}
13856
13857static void vl_api_l2_xconnect_details_t_handler_json
13858 (vl_api_l2_xconnect_details_t * mp)
13859{
13860 vat_main_t *vam = &vat_main;
13861 vat_json_node_t *node = NULL;
13862
13863 if (VAT_JSON_ARRAY != vam->json_tree.type)
13864 {
13865 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13866 vat_json_init_array (&vam->json_tree);
13867 }
13868 node = vat_json_array_add (&vam->json_tree);
13869
13870 vat_json_init_object (node);
13871 vat_json_object_add_uint (node, "rx_sw_if_index",
13872 ntohl (mp->rx_sw_if_index));
13873 vat_json_object_add_uint (node, "tx_sw_if_index",
13874 ntohl (mp->tx_sw_if_index));
13875}
13876
13877static int
13878api_l2_xconnect_dump (vat_main_t * vam)
13879{
13880 vl_api_l2_xconnect_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060013881 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013882 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013883
13884 if (!vam->json_output)
13885 {
13886 print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
13887 }
13888
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013889 M (L2_XCONNECT_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013890
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013891 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013892
13893 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040013894 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060013895 S (mp_ping);
13896
Jon Loeliger56c7b012017-02-01 12:31:41 -060013897 W (ret);
13898 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013899}
13900
13901static int
Ole Troand7231612018-06-07 10:17:57 +020013902api_hw_interface_set_mtu (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010013903{
13904 unformat_input_t *i = vam->input;
Ole Troand7231612018-06-07 10:17:57 +020013905 vl_api_hw_interface_set_mtu_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013906 u32 sw_if_index = ~0;
13907 u32 mtu = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013908 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013909
13910 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13911 {
13912 if (unformat (i, "mtu %d", &mtu))
13913 ;
13914 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13915 ;
13916 else if (unformat (i, "sw_if_index %d", &sw_if_index))
13917 ;
13918 else
13919 break;
13920 }
13921
13922 if (sw_if_index == ~0)
13923 {
13924 errmsg ("missing interface name or sw_if_index");
13925 return -99;
13926 }
13927
13928 if (mtu == 0)
13929 {
13930 errmsg ("no mtu specified");
13931 return -99;
13932 }
13933
13934 /* Construct the API message */
Ole Troand7231612018-06-07 10:17:57 +020013935 M (HW_INTERFACE_SET_MTU, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013936 mp->sw_if_index = ntohl (sw_if_index);
13937 mp->mtu = ntohs ((u16) mtu);
13938
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013939 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013940 W (ret);
13941 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013942}
13943
Pavel Kotucek6899a302017-06-08 08:46:10 +020013944static int
13945api_p2p_ethernet_add (vat_main_t * vam)
13946{
13947 unformat_input_t *i = vam->input;
13948 vl_api_p2p_ethernet_add_t *mp;
13949 u32 parent_if_index = ~0;
Pavel Kotucek15ac81c2017-06-20 14:00:26 +020013950 u32 sub_id = ~0;
Pavel Kotucek6899a302017-06-08 08:46:10 +020013951 u8 remote_mac[6];
13952 u8 mac_set = 0;
13953 int ret;
13954
Dave Barachb7b92992018-10-17 10:38:51 -040013955 clib_memset (remote_mac, 0, sizeof (remote_mac));
Pavel Kotucek6899a302017-06-08 08:46:10 +020013956 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13957 {
13958 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
13959 ;
13960 else if (unformat (i, "sw_if_index %d", &parent_if_index))
13961 ;
13962 else
13963 if (unformat
13964 (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
13965 mac_set++;
Pavel Kotucek15ac81c2017-06-20 14:00:26 +020013966 else if (unformat (i, "sub_id %d", &sub_id))
13967 ;
Pavel Kotucek6899a302017-06-08 08:46:10 +020013968 else
13969 {
13970 clib_warning ("parse error '%U'", format_unformat_error, i);
13971 return -99;
13972 }
13973 }
13974
13975 if (parent_if_index == ~0)
13976 {
13977 errmsg ("missing interface name or sw_if_index");
13978 return -99;
13979 }
13980 if (mac_set == 0)
13981 {
13982 errmsg ("missing remote mac address");
13983 return -99;
13984 }
Pavel Kotucek15ac81c2017-06-20 14:00:26 +020013985 if (sub_id == ~0)
13986 {
13987 errmsg ("missing sub-interface id");
13988 return -99;
13989 }
Pavel Kotucek6899a302017-06-08 08:46:10 +020013990
13991 M (P2P_ETHERNET_ADD, mp);
13992 mp->parent_if_index = ntohl (parent_if_index);
Pavel Kotucek15ac81c2017-06-20 14:00:26 +020013993 mp->subif_id = ntohl (sub_id);
Pavel Kotucek6899a302017-06-08 08:46:10 +020013994 clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
13995
13996 S (mp);
13997 W (ret);
13998 return ret;
13999}
14000
14001static int
14002api_p2p_ethernet_del (vat_main_t * vam)
14003{
14004 unformat_input_t *i = vam->input;
14005 vl_api_p2p_ethernet_del_t *mp;
14006 u32 parent_if_index = ~0;
14007 u8 remote_mac[6];
14008 u8 mac_set = 0;
14009 int ret;
14010
Dave Barachb7b92992018-10-17 10:38:51 -040014011 clib_memset (remote_mac, 0, sizeof (remote_mac));
Pavel Kotucek6899a302017-06-08 08:46:10 +020014012 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14013 {
14014 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
14015 ;
14016 else if (unformat (i, "sw_if_index %d", &parent_if_index))
14017 ;
14018 else
14019 if (unformat
14020 (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
14021 mac_set++;
14022 else
14023 {
14024 clib_warning ("parse error '%U'", format_unformat_error, i);
14025 return -99;
14026 }
14027 }
14028
14029 if (parent_if_index == ~0)
14030 {
14031 errmsg ("missing interface name or sw_if_index");
14032 return -99;
14033 }
14034 if (mac_set == 0)
14035 {
14036 errmsg ("missing remote mac address");
14037 return -99;
14038 }
14039
14040 M (P2P_ETHERNET_DEL, mp);
14041 mp->parent_if_index = ntohl (parent_if_index);
14042 clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
14043
14044 S (mp);
14045 W (ret);
14046 return ret;
14047}
Damjan Marion7cd468a2016-12-19 23:05:39 +010014048
14049static int
Dave Barach3bbcfab2017-08-15 19:03:44 -040014050api_tcp_configure_src_addresses (vat_main_t * vam)
14051{
14052 vl_api_tcp_configure_src_addresses_t *mp;
14053 unformat_input_t *i = vam->input;
Neale Rannscbe25aa2019-09-30 10:53:31 +000014054 vl_api_address_t first, last;
Dave Barach3bbcfab2017-08-15 19:03:44 -040014055 u8 range_set = 0;
14056 u32 vrf_id = 0;
14057 int ret;
14058
14059 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14060 {
14061 if (unformat (i, "%U - %U",
Neale Rannscbe25aa2019-09-30 10:53:31 +000014062 unformat_vl_api_address, &first,
14063 unformat_vl_api_address, &last))
Dave Barach3bbcfab2017-08-15 19:03:44 -040014064 {
14065 if (range_set)
14066 {
14067 errmsg ("one range per message (range already set)");
14068 return -99;
14069 }
14070 range_set = 1;
14071 }
Dave Barach3bbcfab2017-08-15 19:03:44 -040014072 else if (unformat (i, "vrf %d", &vrf_id))
14073 ;
14074 else
14075 break;
14076 }
14077
14078 if (range_set == 0)
14079 {
14080 errmsg ("address range not set");
14081 return -99;
14082 }
14083
14084 M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
Neale Rannscbe25aa2019-09-30 10:53:31 +000014085
Dave Barach3bbcfab2017-08-15 19:03:44 -040014086 mp->vrf_id = ntohl (vrf_id);
Neale Rannscbe25aa2019-09-30 10:53:31 +000014087 clib_memcpy (&mp->first_address, &first, sizeof (first));
14088 clib_memcpy (&mp->last_address, &last, sizeof (last));
14089
Dave Barach3bbcfab2017-08-15 19:03:44 -040014090 S (mp);
14091 W (ret);
14092 return ret;
14093}
14094
Florin Coras6e8c6672017-11-10 09:03:54 -080014095static void vl_api_app_namespace_add_del_reply_t_handler
14096 (vl_api_app_namespace_add_del_reply_t * mp)
14097{
14098 vat_main_t *vam = &vat_main;
14099 i32 retval = ntohl (mp->retval);
14100 if (vam->async_mode)
14101 {
14102 vam->async_errors += (retval < 0);
14103 }
14104 else
14105 {
14106 vam->retval = retval;
14107 if (retval == 0)
14108 errmsg ("app ns index %d\n", ntohl (mp->appns_index));
14109 vam->result_ready = 1;
14110 }
14111}
14112
14113static void vl_api_app_namespace_add_del_reply_t_handler_json
14114 (vl_api_app_namespace_add_del_reply_t * mp)
14115{
14116 vat_main_t *vam = &vat_main;
14117 vat_json_node_t node;
14118
14119 vat_json_init_object (&node);
14120 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
14121 vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
14122
14123 vat_json_print (vam->ofp, &node);
14124 vat_json_free (&node);
14125
14126 vam->retval = ntohl (mp->retval);
14127 vam->result_ready = 1;
14128}
14129
Dave Barach3bbcfab2017-08-15 19:03:44 -040014130static int
Florin Corascea194d2017-10-02 00:18:51 -070014131api_app_namespace_add_del (vat_main_t * vam)
14132{
14133 vl_api_app_namespace_add_del_t *mp;
14134 unformat_input_t *i = vam->input;
14135 u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
14136 u32 sw_if_index, ip4_fib_id, ip6_fib_id;
14137 u64 secret;
14138 int ret;
14139
14140 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14141 {
14142 if (unformat (i, "id %_%v%_", &ns_id))
14143 ;
14144 else if (unformat (i, "secret %lu", &secret))
14145 secret_set = 1;
14146 else if (unformat (i, "sw_if_index %d", &sw_if_index))
14147 sw_if_index_set = 1;
14148 else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
14149 ;
14150 else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
14151 ;
14152 else
14153 break;
14154 }
14155 if (!ns_id || !secret_set || !sw_if_index_set)
14156 {
14157 errmsg ("namespace id, secret and sw_if_index must be set");
14158 return -99;
14159 }
14160 if (vec_len (ns_id) > 64)
14161 {
14162 errmsg ("namespace id too long");
14163 return -99;
14164 }
14165 M (APP_NAMESPACE_ADD_DEL, mp);
14166
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014167 vl_api_vec_to_api_string (ns_id, &mp->namespace_id);
Florin Coras9a9adb22017-10-26 08:16:59 -070014168 mp->secret = clib_host_to_net_u64 (secret);
Florin Corascea194d2017-10-02 00:18:51 -070014169 mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
14170 mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
14171 mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
14172 vec_free (ns_id);
14173 S (mp);
14174 W (ret);
14175 return ret;
14176}
14177
14178static int
Florin Coras90a63982017-12-19 04:50:01 -080014179api_sock_init_shm (vat_main_t * vam)
14180{
14181#if VPP_API_TEST_BUILTIN == 0
14182 unformat_input_t *i = vam->input;
14183 vl_api_shm_elem_config_t *config = 0;
14184 u64 size = 64 << 20;
14185 int rv;
14186
14187 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14188 {
14189 if (unformat (i, "size %U", unformat_memory_size, &size))
14190 ;
14191 else
14192 break;
14193 }
14194
Dave Barach78958722018-05-10 16:44:27 -040014195 /*
14196 * Canned custom ring allocator config.
14197 * Should probably parse all of this
14198 */
14199 vec_validate (config, 6);
Florin Coras90a63982017-12-19 04:50:01 -080014200 config[0].type = VL_API_VLIB_RING;
Florin Coras90a63982017-12-19 04:50:01 -080014201 config[0].size = 256;
Dave Barach78958722018-05-10 16:44:27 -040014202 config[0].count = 32;
14203
14204 config[1].type = VL_API_VLIB_RING;
Florin Coras90a63982017-12-19 04:50:01 -080014205 config[1].size = 1024;
Dave Barach78958722018-05-10 16:44:27 -040014206 config[1].count = 16;
14207
14208 config[2].type = VL_API_VLIB_RING;
Florin Coras90a63982017-12-19 04:50:01 -080014209 config[2].size = 4096;
Dave Barach78958722018-05-10 16:44:27 -040014210 config[2].count = 2;
14211
14212 config[3].type = VL_API_CLIENT_RING;
14213 config[3].size = 256;
14214 config[3].count = 32;
14215
14216 config[4].type = VL_API_CLIENT_RING;
14217 config[4].size = 1024;
14218 config[4].count = 16;
14219
14220 config[5].type = VL_API_CLIENT_RING;
14221 config[5].size = 4096;
14222 config[5].count = 2;
14223
14224 config[6].type = VL_API_QUEUE;
14225 config[6].count = 128;
14226 config[6].size = sizeof (uword);
14227
Tomasz Kulasek97dcf5b2019-01-31 18:26:32 +010014228 rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
Florin Coras90a63982017-12-19 04:50:01 -080014229 if (!rv)
14230 vam->client_index_invalid = 1;
14231 return rv;
14232#else
14233 return -99;
14234#endif
14235}
14236
Florin Coras6c36f532017-11-03 18:32:34 -070014237static void
14238vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
14239{
14240 vat_main_t *vam = &vat_main;
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014241 fib_prefix_t lcl, rmt;
Florin Coras6c36f532017-11-03 18:32:34 -070014242
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014243 ip_prefix_decode (&mp->lcl, &lcl);
14244 ip_prefix_decode (&mp->rmt, &rmt);
14245
14246 if (lcl.fp_proto == FIB_PROTOCOL_IP4)
Florin Coras6c36f532017-11-03 18:32:34 -070014247 {
Florin Corasc97a7392017-11-05 23:07:07 -080014248 print (vam->ofp,
14249 "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
Steven85dbac02017-11-07 16:29:53 -080014250 clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014251 mp->scope, format_ip4_address, &lcl.fp_addr.ip4, lcl.fp_len,
Steven85dbac02017-11-07 16:29:53 -080014252 clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014253 &rmt.fp_addr.ip4, rmt.fp_len,
14254 clib_net_to_host_u16 (mp->rmt_port),
Steven85dbac02017-11-07 16:29:53 -080014255 clib_net_to_host_u32 (mp->action_index), mp->tag);
Florin Coras6c36f532017-11-03 18:32:34 -070014256 }
14257 else
14258 {
Florin Corasc97a7392017-11-05 23:07:07 -080014259 print (vam->ofp,
14260 "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
Steven85dbac02017-11-07 16:29:53 -080014261 clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014262 mp->scope, format_ip6_address, &lcl.fp_addr.ip6, lcl.fp_len,
Steven85dbac02017-11-07 16:29:53 -080014263 clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014264 &rmt.fp_addr.ip6, rmt.fp_len,
14265 clib_net_to_host_u16 (mp->rmt_port),
Steven85dbac02017-11-07 16:29:53 -080014266 clib_net_to_host_u32 (mp->action_index), mp->tag);
Florin Coras6c36f532017-11-03 18:32:34 -070014267 }
14268}
14269
14270static void
14271vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
14272 mp)
14273{
14274 vat_main_t *vam = &vat_main;
14275 vat_json_node_t *node = NULL;
14276 struct in6_addr ip6;
14277 struct in_addr ip4;
14278
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014279 fib_prefix_t lcl, rmt;
14280
14281 ip_prefix_decode (&mp->lcl, &lcl);
14282 ip_prefix_decode (&mp->rmt, &rmt);
14283
Florin Coras6c36f532017-11-03 18:32:34 -070014284 if (VAT_JSON_ARRAY != vam->json_tree.type)
14285 {
14286 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14287 vat_json_init_array (&vam->json_tree);
14288 }
14289 node = vat_json_array_add (&vam->json_tree);
14290 vat_json_init_object (node);
14291
Florin Coras6c36f532017-11-03 18:32:34 -070014292 vat_json_object_add_uint (node, "appns_index",
14293 clib_net_to_host_u32 (mp->appns_index));
14294 vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
14295 vat_json_object_add_uint (node, "scope", mp->scope);
14296 vat_json_object_add_uint (node, "action_index",
14297 clib_net_to_host_u32 (mp->action_index));
14298 vat_json_object_add_uint (node, "lcl_port",
14299 clib_net_to_host_u16 (mp->lcl_port));
14300 vat_json_object_add_uint (node, "rmt_port",
14301 clib_net_to_host_u16 (mp->rmt_port));
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014302 vat_json_object_add_uint (node, "lcl_plen", lcl.fp_len);
14303 vat_json_object_add_uint (node, "rmt_plen", rmt.fp_len);
Florin Corasc97a7392017-11-05 23:07:07 -080014304 vat_json_object_add_string_copy (node, "tag", mp->tag);
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014305 if (lcl.fp_proto == FIB_PROTOCOL_IP4)
Florin Coras6c36f532017-11-03 18:32:34 -070014306 {
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014307 clib_memcpy (&ip4, &lcl.fp_addr.ip4, sizeof (ip4));
Florin Coras6c36f532017-11-03 18:32:34 -070014308 vat_json_object_add_ip4 (node, "lcl_ip", ip4);
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014309 clib_memcpy (&ip4, &rmt.fp_addr.ip4, sizeof (ip4));
Florin Coras6c36f532017-11-03 18:32:34 -070014310 vat_json_object_add_ip4 (node, "rmt_ip", ip4);
14311 }
14312 else
14313 {
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014314 clib_memcpy (&ip6, &lcl.fp_addr.ip6, sizeof (ip6));
Florin Coras6c36f532017-11-03 18:32:34 -070014315 vat_json_object_add_ip6 (node, "lcl_ip", ip6);
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014316 clib_memcpy (&ip6, &rmt.fp_addr.ip6, sizeof (ip6));
Florin Coras6c36f532017-11-03 18:32:34 -070014317 vat_json_object_add_ip6 (node, "rmt_ip", ip6);
14318 }
14319}
14320
Florin Coras1c710452017-10-17 00:03:13 -070014321static int
14322api_session_rule_add_del (vat_main_t * vam)
14323{
14324 vl_api_session_rule_add_del_t *mp;
14325 unformat_input_t *i = vam->input;
14326 u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
14327 u32 appns_index = 0, scope = 0;
14328 ip4_address_t lcl_ip4, rmt_ip4;
14329 ip6_address_t lcl_ip6, rmt_ip6;
14330 u8 is_ip4 = 1, conn_set = 0;
Florin Corasc97a7392017-11-05 23:07:07 -080014331 u8 is_add = 1, *tag = 0;
Florin Coras1c710452017-10-17 00:03:13 -070014332 int ret;
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014333 fib_prefix_t lcl, rmt;
Florin Coras1c710452017-10-17 00:03:13 -070014334
14335 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14336 {
14337 if (unformat (i, "del"))
14338 is_add = 0;
14339 else if (unformat (i, "add"))
14340 ;
14341 else if (unformat (i, "proto tcp"))
14342 proto = 0;
14343 else if (unformat (i, "proto udp"))
14344 proto = 1;
14345 else if (unformat (i, "appns %d", &appns_index))
14346 ;
14347 else if (unformat (i, "scope %d", &scope))
14348 ;
Florin Corasc97a7392017-11-05 23:07:07 -080014349 else if (unformat (i, "tag %_%v%_", &tag))
14350 ;
Florin Coras1c710452017-10-17 00:03:13 -070014351 else
14352 if (unformat
14353 (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
14354 &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
14355 &rmt_port))
14356 {
14357 is_ip4 = 1;
14358 conn_set = 1;
14359 }
14360 else
14361 if (unformat
14362 (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
14363 &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
14364 &rmt_port))
14365 {
14366 is_ip4 = 0;
14367 conn_set = 1;
14368 }
14369 else if (unformat (i, "action %d", &action))
14370 ;
14371 else
14372 break;
14373 }
14374 if (proto == ~0 || !conn_set || action == ~0)
14375 {
14376 errmsg ("transport proto, connection and action must be set");
14377 return -99;
14378 }
14379
14380 if (scope > 3)
14381 {
14382 errmsg ("scope should be 0-3");
14383 return -99;
14384 }
14385
14386 M (SESSION_RULE_ADD_DEL, mp);
14387
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014388 clib_memset (&lcl, 0, sizeof (lcl));
14389 clib_memset (&rmt, 0, sizeof (rmt));
14390 if (is_ip4)
14391 {
14392 ip_set (&lcl.fp_addr, &lcl_ip4, 1);
14393 ip_set (&rmt.fp_addr, &rmt_ip4, 1);
14394 lcl.fp_len = lcl_plen;
14395 rmt.fp_len = rmt_plen;
14396 }
14397 else
14398 {
14399 ip_set (&lcl.fp_addr, &lcl_ip6, 0);
14400 ip_set (&rmt.fp_addr, &rmt_ip6, 0);
14401 lcl.fp_len = lcl_plen;
14402 rmt.fp_len = rmt_plen;
14403 }
14404
14405
14406 ip_prefix_encode (&lcl, &mp->lcl);
14407 ip_prefix_encode (&rmt, &mp->rmt);
Florin Corasc97a7392017-11-05 23:07:07 -080014408 mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
14409 mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014410 mp->transport_proto =
14411 proto ? TRANSPORT_PROTO_API_UDP : TRANSPORT_PROTO_API_TCP;
Florin Coras1c710452017-10-17 00:03:13 -070014412 mp->action_index = clib_host_to_net_u32 (action);
14413 mp->appns_index = clib_host_to_net_u32 (appns_index);
14414 mp->scope = scope;
14415 mp->is_add = is_add;
Florin Corasc97a7392017-11-05 23:07:07 -080014416 if (tag)
14417 {
14418 clib_memcpy (mp->tag, tag, vec_len (tag));
14419 vec_free (tag);
14420 }
Florin Coras1c710452017-10-17 00:03:13 -070014421
14422 S (mp);
14423 W (ret);
14424 return ret;
14425}
Dave Barach65457162017-10-10 17:53:14 -040014426
14427static int
Florin Coras6c36f532017-11-03 18:32:34 -070014428api_session_rules_dump (vat_main_t * vam)
14429{
14430 vl_api_session_rules_dump_t *mp;
14431 vl_api_control_ping_t *mp_ping;
14432 int ret;
14433
14434 if (!vam->json_output)
14435 {
14436 print (vam->ofp, "%=20s", "Session Rules");
14437 }
14438
14439 M (SESSION_RULES_DUMP, mp);
14440 /* send it... */
14441 S (mp);
14442
14443 /* Use a control ping for synchronization */
14444 MPING (CONTROL_PING, mp_ping);
14445 S (mp_ping);
14446
14447 /* Wait for a reply... */
14448 W (ret);
14449 return ret;
14450}
14451
14452static int
Florin Coras595992c2017-11-06 17:17:08 -080014453api_ip_container_proxy_add_del (vat_main_t * vam)
14454{
14455 vl_api_ip_container_proxy_add_del_t *mp;
14456 unformat_input_t *i = vam->input;
Neale Ranns37029302018-08-10 05:30:06 -070014457 u32 sw_if_index = ~0;
14458 vl_api_prefix_t pfx = { };
Florin Coras595992c2017-11-06 17:17:08 -080014459 u8 is_add = 1;
14460 int ret;
14461
14462 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14463 {
14464 if (unformat (i, "del"))
14465 is_add = 0;
14466 else if (unformat (i, "add"))
14467 ;
Neale Ranns37029302018-08-10 05:30:06 -070014468 if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
14469 ;
Florin Coras595992c2017-11-06 17:17:08 -080014470 else if (unformat (i, "sw_if_index %u", &sw_if_index))
14471 ;
14472 else
14473 break;
14474 }
Paul Vinciguerraab055082019-06-06 14:07:55 -040014475 if (sw_if_index == ~0 || pfx.len == 0)
Florin Coras595992c2017-11-06 17:17:08 -080014476 {
14477 errmsg ("address and sw_if_index must be set");
14478 return -99;
14479 }
14480
14481 M (IP_CONTAINER_PROXY_ADD_DEL, mp);
14482
Florin Coras595992c2017-11-06 17:17:08 -080014483 mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
Florin Coras595992c2017-11-06 17:17:08 -080014484 mp->is_add = is_add;
Neale Ranns37029302018-08-10 05:30:06 -070014485 clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
Florin Coras595992c2017-11-06 17:17:08 -080014486
14487 S (mp);
14488 W (ret);
14489 return ret;
14490}
14491
14492static int
Igor Mikhailov (imichail)582caa32018-04-26 21:33:02 -070014493api_qos_record_enable_disable (vat_main_t * vam)
14494{
14495 unformat_input_t *i = vam->input;
14496 vl_api_qos_record_enable_disable_t *mp;
14497 u32 sw_if_index, qs = 0xff;
14498 u8 sw_if_index_set = 0;
14499 u8 enable = 1;
14500 int ret;
14501
14502 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14503 {
14504 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14505 sw_if_index_set = 1;
14506 else if (unformat (i, "sw_if_index %d", &sw_if_index))
14507 sw_if_index_set = 1;
14508 else if (unformat (i, "%U", unformat_qos_source, &qs))
14509 ;
14510 else if (unformat (i, "disable"))
14511 enable = 0;
14512 else
14513 {
14514 clib_warning ("parse error '%U'", format_unformat_error, i);
14515 return -99;
14516 }
14517 }
14518
14519 if (sw_if_index_set == 0)
14520 {
14521 errmsg ("missing interface name or sw_if_index");
14522 return -99;
14523 }
14524 if (qs == 0xff)
14525 {
14526 errmsg ("input location must be specified");
14527 return -99;
14528 }
14529
14530 M (QOS_RECORD_ENABLE_DISABLE, mp);
14531
Neale Ranns5281a902019-07-23 08:16:19 -070014532 mp->record.sw_if_index = ntohl (sw_if_index);
14533 mp->record.input_source = qs;
Igor Mikhailov (imichail)582caa32018-04-26 21:33:02 -070014534 mp->enable = enable;
14535
14536 S (mp);
14537 W (ret);
14538 return ret;
14539}
14540
Dave Barach048a4e52018-06-01 18:52:25 -040014541
Igor Mikhailov (imichail)582caa32018-04-26 21:33:02 -070014542static int
Damjan Marion7cd468a2016-12-19 23:05:39 +010014543q_or_quit (vat_main_t * vam)
14544{
Dave Barachdef19da2017-02-22 17:29:20 -050014545#if VPP_API_TEST_BUILTIN == 0
Damjan Marion7cd468a2016-12-19 23:05:39 +010014546 longjmp (vam->jump_buf, 1);
Dave Barachdef19da2017-02-22 17:29:20 -050014547#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +010014548 return 0; /* not so much */
14549}
14550
14551static int
14552q (vat_main_t * vam)
14553{
14554 return q_or_quit (vam);
14555}
14556
14557static int
14558quit (vat_main_t * vam)
14559{
14560 return q_or_quit (vam);
14561}
14562
14563static int
14564comment (vat_main_t * vam)
14565{
14566 return 0;
14567}
14568
14569static int
Dave Barachb09f4d02019-07-15 16:00:03 -040014570elog_save (vat_main_t * vam)
14571{
14572#if VPP_API_TEST_BUILTIN == 0
14573 elog_main_t *em = &vam->elog_main;
14574 unformat_input_t *i = vam->input;
14575 char *file, *chroot_file;
14576 clib_error_t *error;
14577
14578 if (!unformat (i, "%s", &file))
14579 {
14580 errmsg ("expected file name, got `%U'", format_unformat_error, i);
14581 return 0;
14582 }
14583
14584 /* It's fairly hard to get "../oopsie" through unformat; just in case */
14585 if (strstr (file, "..") || index (file, '/'))
14586 {
14587 errmsg ("illegal characters in filename '%s'", file);
14588 return 0;
14589 }
14590
14591 chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
14592
14593 vec_free (file);
14594
14595 errmsg ("Saving %wd of %wd events to %s",
14596 elog_n_events_in_buffer (em),
14597 elog_buffer_capacity (em), chroot_file);
14598
14599 error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
14600 vec_free (chroot_file);
14601
14602 if (error)
14603 clib_error_report (error);
14604#else
14605 errmsg ("Use the vpp event loger...");
14606#endif
14607
14608 return 0;
14609}
14610
14611static int
14612elog_setup (vat_main_t * vam)
14613{
14614#if VPP_API_TEST_BUILTIN == 0
14615 elog_main_t *em = &vam->elog_main;
14616 unformat_input_t *i = vam->input;
14617 u32 nevents = 128 << 10;
14618
14619 (void) unformat (i, "nevents %d", &nevents);
14620
14621 elog_init (em, nevents);
14622 vl_api_set_elog_main (em);
14623 vl_api_set_elog_trace_api_messages (1);
14624 errmsg ("Event logger initialized with %u events", nevents);
14625#else
14626 errmsg ("Use the vpp event loger...");
14627#endif
14628 return 0;
14629}
14630
14631static int
14632elog_enable (vat_main_t * vam)
14633{
14634#if VPP_API_TEST_BUILTIN == 0
14635 elog_main_t *em = &vam->elog_main;
14636
14637 elog_enable_disable (em, 1 /* enable */ );
14638 vl_api_set_elog_trace_api_messages (1);
14639 errmsg ("Event logger enabled...");
14640#else
14641 errmsg ("Use the vpp event loger...");
14642#endif
14643 return 0;
14644}
14645
14646static int
14647elog_disable (vat_main_t * vam)
14648{
14649#if VPP_API_TEST_BUILTIN == 0
14650 elog_main_t *em = &vam->elog_main;
14651
14652 elog_enable_disable (em, 0 /* enable */ );
14653 vl_api_set_elog_trace_api_messages (1);
14654 errmsg ("Event logger disabled...");
14655#else
14656 errmsg ("Use the vpp event loger...");
14657#endif
14658 return 0;
14659}
14660
14661static int
Dave Barach048a4e52018-06-01 18:52:25 -040014662statseg (vat_main_t * vam)
14663{
14664 ssvm_private_t *ssvmp = &vam->stat_segment;
14665 ssvm_shared_header_t *shared_header = ssvmp->sh;
14666 vlib_counter_t **counters;
14667 u64 thread0_index1_packets;
14668 u64 thread0_index1_bytes;
14669 f64 vector_rate, input_rate;
14670 uword *p;
14671
14672 uword *counter_vector_by_name;
14673 if (vam->stat_segment_lockp == 0)
14674 {
14675 errmsg ("Stat segment not mapped...");
14676 return -99;
14677 }
14678
14679 /* look up "/if/rx for sw_if_index 1 as a test */
14680
14681 clib_spinlock_lock (vam->stat_segment_lockp);
14682
14683 counter_vector_by_name = (uword *) shared_header->opaque[1];
14684
14685 p = hash_get_mem (counter_vector_by_name, "/if/rx");
14686 if (p == 0)
14687 {
14688 clib_spinlock_unlock (vam->stat_segment_lockp);
14689 errmsg ("/if/tx not found?");
14690 return -99;
14691 }
14692
14693 /* Fish per-thread vector of combined counters from shared memory */
14694 counters = (vlib_counter_t **) p[0];
14695
14696 if (vec_len (counters[0]) < 2)
14697 {
14698 clib_spinlock_unlock (vam->stat_segment_lockp);
14699 errmsg ("/if/tx vector length %d", vec_len (counters[0]));
14700 return -99;
14701 }
14702
14703 /* Read thread 0 sw_if_index 1 counter */
14704 thread0_index1_packets = counters[0][1].packets;
14705 thread0_index1_bytes = counters[0][1].bytes;
14706
14707 p = hash_get_mem (counter_vector_by_name, "vector_rate");
14708 if (p == 0)
14709 {
14710 clib_spinlock_unlock (vam->stat_segment_lockp);
14711 errmsg ("vector_rate not found?");
14712 return -99;
14713 }
14714
14715 vector_rate = *(f64 *) (p[0]);
14716 p = hash_get_mem (counter_vector_by_name, "input_rate");
14717 if (p == 0)
14718 {
14719 clib_spinlock_unlock (vam->stat_segment_lockp);
14720 errmsg ("input_rate not found?");
14721 return -99;
14722 }
14723 input_rate = *(f64 *) (p[0]);
14724
14725 clib_spinlock_unlock (vam->stat_segment_lockp);
14726
14727 print (vam->ofp, "vector_rate %.2f input_rate %.2f",
14728 vector_rate, input_rate);
14729 print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
14730 thread0_index1_packets, thread0_index1_bytes);
14731
14732 return 0;
14733}
14734
14735static int
Damjan Marion7cd468a2016-12-19 23:05:39 +010014736cmd_cmp (void *a1, void *a2)
14737{
14738 u8 **c1 = a1;
14739 u8 **c2 = a2;
14740
14741 return strcmp ((char *) (c1[0]), (char *) (c2[0]));
14742}
14743
14744static int
14745help (vat_main_t * vam)
14746{
14747 u8 **cmds = 0;
14748 u8 *name = 0;
14749 hash_pair_t *p;
14750 unformat_input_t *i = vam->input;
14751 int j;
14752
14753 if (unformat (i, "%s", &name))
14754 {
14755 uword *hs;
14756
14757 vec_add1 (name, 0);
14758
14759 hs = hash_get_mem (vam->help_by_name, name);
14760 if (hs)
14761 print (vam->ofp, "usage: %s %s", name, hs[0]);
14762 else
14763 print (vam->ofp, "No such msg / command '%s'", name);
14764 vec_free (name);
14765 return 0;
14766 }
14767
14768 print (vam->ofp, "Help is available for the following:");
14769
14770 /* *INDENT-OFF* */
14771 hash_foreach_pair (p, vam->function_by_name,
14772 ({
14773 vec_add1 (cmds, (u8 *)(p->key));
14774 }));
14775 /* *INDENT-ON* */
14776
14777 vec_sort_with_function (cmds, cmd_cmp);
14778
14779 for (j = 0; j < vec_len (cmds); j++)
14780 print (vam->ofp, "%s", cmds[j]);
14781
14782 vec_free (cmds);
14783 return 0;
14784}
14785
14786static int
14787set (vat_main_t * vam)
14788{
14789 u8 *name = 0, *value = 0;
14790 unformat_input_t *i = vam->input;
14791
14792 if (unformat (i, "%s", &name))
14793 {
14794 /* The input buffer is a vector, not a string. */
14795 value = vec_dup (i->buffer);
14796 vec_delete (value, i->index, 0);
14797 /* Almost certainly has a trailing newline */
14798 if (value[vec_len (value) - 1] == '\n')
14799 value[vec_len (value) - 1] = 0;
14800 /* Make sure it's a proper string, one way or the other */
14801 vec_add1 (value, 0);
14802 (void) clib_macro_set_value (&vam->macro_main,
14803 (char *) name, (char *) value);
14804 }
14805 else
14806 errmsg ("usage: set <name> <value>");
14807
14808 vec_free (name);
14809 vec_free (value);
14810 return 0;
14811}
14812
14813static int
14814unset (vat_main_t * vam)
14815{
14816 u8 *name = 0;
14817
14818 if (unformat (vam->input, "%s", &name))
14819 if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
14820 errmsg ("unset: %s wasn't set", name);
14821 vec_free (name);
14822 return 0;
14823}
14824
14825typedef struct
14826{
14827 u8 *name;
14828 u8 *value;
14829} macro_sort_t;
14830
14831
14832static int
14833macro_sort_cmp (void *a1, void *a2)
14834{
14835 macro_sort_t *s1 = a1;
14836 macro_sort_t *s2 = a2;
14837
14838 return strcmp ((char *) (s1->name), (char *) (s2->name));
14839}
14840
14841static int
14842dump_macro_table (vat_main_t * vam)
14843{
14844 macro_sort_t *sort_me = 0, *sm;
14845 int i;
14846 hash_pair_t *p;
14847
14848 /* *INDENT-OFF* */
14849 hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
14850 ({
14851 vec_add2 (sort_me, sm, 1);
14852 sm->name = (u8 *)(p->key);
14853 sm->value = (u8 *) (p->value[0]);
14854 }));
14855 /* *INDENT-ON* */
14856
14857 vec_sort_with_function (sort_me, macro_sort_cmp);
14858
14859 if (vec_len (sort_me))
14860 print (vam->ofp, "%-15s%s", "Name", "Value");
14861 else
14862 print (vam->ofp, "The macro table is empty...");
14863
14864 for (i = 0; i < vec_len (sort_me); i++)
14865 print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
14866 return 0;
14867}
14868
14869static int
14870dump_node_table (vat_main_t * vam)
14871{
14872 int i, j;
14873 vlib_node_t *node, *next_node;
14874
14875 if (vec_len (vam->graph_nodes) == 0)
14876 {
14877 print (vam->ofp, "Node table empty, issue get_node_graph...");
14878 return 0;
14879 }
14880
Dave Barach1ddbc012018-06-13 09:26:05 -040014881 for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
Damjan Marion7cd468a2016-12-19 23:05:39 +010014882 {
Dave Barach1ddbc012018-06-13 09:26:05 -040014883 node = vam->graph_nodes[0][i];
Damjan Marion7cd468a2016-12-19 23:05:39 +010014884 print (vam->ofp, "[%d] %s", i, node->name);
14885 for (j = 0; j < vec_len (node->next_nodes); j++)
14886 {
14887 if (node->next_nodes[j] != ~0)
14888 {
Dave Barach1ddbc012018-06-13 09:26:05 -040014889 next_node = vam->graph_nodes[0][node->next_nodes[j]];
Damjan Marion7cd468a2016-12-19 23:05:39 +010014890 print (vam->ofp, " [%d] %s", j, next_node->name);
14891 }
14892 }
14893 }
14894 return 0;
14895}
14896
14897static int
14898value_sort_cmp (void *a1, void *a2)
14899{
14900 name_sort_t *n1 = a1;
14901 name_sort_t *n2 = a2;
14902
14903 if (n1->value < n2->value)
14904 return -1;
14905 if (n1->value > n2->value)
14906 return 1;
14907 return 0;
14908}
14909
14910
14911static int
14912dump_msg_api_table (vat_main_t * vam)
14913{
Dave Barach39d69112019-11-27 11:42:13 -050014914 api_main_t *am = vlibapi_get_main ();
Damjan Marion7cd468a2016-12-19 23:05:39 +010014915 name_sort_t *nses = 0, *ns;
14916 hash_pair_t *hp;
14917 int i;
14918
14919 /* *INDENT-OFF* */
14920 hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
14921 ({
14922 vec_add2 (nses, ns, 1);
14923 ns->name = (u8 *)(hp->key);
14924 ns->value = (u32) hp->value[0];
14925 }));
14926 /* *INDENT-ON* */
14927
14928 vec_sort_with_function (nses, value_sort_cmp);
14929
14930 for (i = 0; i < vec_len (nses); i++)
14931 print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
14932 vec_free (nses);
14933 return 0;
14934}
14935
14936static int
14937get_msg_id (vat_main_t * vam)
14938{
14939 u8 *name_and_crc;
14940 u32 message_index;
14941
14942 if (unformat (vam->input, "%s", &name_and_crc))
14943 {
Florin Corase86a8ed2018-01-05 03:20:25 -080014944 message_index = vl_msg_api_get_msg_index (name_and_crc);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014945 if (message_index == ~0)
14946 {
14947 print (vam->ofp, " '%s' not found", name_and_crc);
14948 return 0;
14949 }
14950 print (vam->ofp, " '%s' has message index %d",
14951 name_and_crc, message_index);
14952 return 0;
14953 }
14954 errmsg ("name_and_crc required...");
14955 return 0;
14956}
14957
14958static int
14959search_node_table (vat_main_t * vam)
14960{
14961 unformat_input_t *line_input = vam->input;
14962 u8 *node_to_find;
14963 int j;
14964 vlib_node_t *node, *next_node;
14965 uword *p;
14966
14967 if (vam->graph_node_index_by_name == 0)
14968 {
14969 print (vam->ofp, "Node table empty, issue get_node_graph...");
14970 return 0;
14971 }
14972
14973 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14974 {
14975 if (unformat (line_input, "%s", &node_to_find))
14976 {
14977 vec_add1 (node_to_find, 0);
14978 p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
14979 if (p == 0)
14980 {
14981 print (vam->ofp, "%s not found...", node_to_find);
14982 goto out;
14983 }
Dave Barach1ddbc012018-06-13 09:26:05 -040014984 node = vam->graph_nodes[0][p[0]];
Damjan Marion7cd468a2016-12-19 23:05:39 +010014985 print (vam->ofp, "[%d] %s", p[0], node->name);
14986 for (j = 0; j < vec_len (node->next_nodes); j++)
14987 {
14988 if (node->next_nodes[j] != ~0)
14989 {
Dave Barach1ddbc012018-06-13 09:26:05 -040014990 next_node = vam->graph_nodes[0][node->next_nodes[j]];
Damjan Marion7cd468a2016-12-19 23:05:39 +010014991 print (vam->ofp, " [%d] %s", j, next_node->name);
14992 }
14993 }
14994 }
14995
14996 else
14997 {
14998 clib_warning ("parse error '%U'", format_unformat_error,
14999 line_input);
15000 return -99;
15001 }
15002
15003 out:
15004 vec_free (node_to_find);
15005
15006 }
15007
15008 return 0;
15009}
15010
15011
15012static int
15013script (vat_main_t * vam)
15014{
15015#if (VPP_API_TEST_BUILTIN==0)
15016 u8 *s = 0;
15017 char *save_current_file;
15018 unformat_input_t save_input;
15019 jmp_buf save_jump_buf;
15020 u32 save_line_number;
15021
15022 FILE *new_fp, *save_ifp;
15023
15024 if (unformat (vam->input, "%s", &s))
15025 {
15026 new_fp = fopen ((char *) s, "r");
15027 if (new_fp == 0)
15028 {
15029 errmsg ("Couldn't open script file %s", s);
15030 vec_free (s);
15031 return -99;
15032 }
15033 }
15034 else
15035 {
15036 errmsg ("Missing script name");
15037 return -99;
15038 }
15039
15040 clib_memcpy (&save_input, &vam->input, sizeof (save_input));
15041 clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
15042 save_ifp = vam->ifp;
15043 save_line_number = vam->input_line_number;
15044 save_current_file = (char *) vam->current_file;
15045
15046 vam->input_line_number = 0;
15047 vam->ifp = new_fp;
15048 vam->current_file = s;
15049 do_one_file (vam);
15050
Sirshak Dasb0861822018-05-29 21:13:21 -050015051 clib_memcpy (&vam->input, &save_input, sizeof (save_input));
Damjan Marion7cd468a2016-12-19 23:05:39 +010015052 clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
15053 vam->ifp = save_ifp;
15054 vam->input_line_number = save_line_number;
15055 vam->current_file = (u8 *) save_current_file;
15056 vec_free (s);
15057
15058 return 0;
15059#else
15060 clib_warning ("use the exec command...");
15061 return -99;
15062#endif
15063}
15064
15065static int
15066echo (vat_main_t * vam)
15067{
15068 print (vam->ofp, "%v", vam->input->buffer);
15069 return 0;
15070}
15071
15072/* List of API message constructors, CLI names map to api_xxx */
15073#define foreach_vpe_api_msg \
Jon Loeligerc83c3b72017-02-23 13:57:35 -060015074_(create_loopback,"[mac <mac-addr>] [instance <instance>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015075_(sw_interface_dump,"") \
15076_(sw_interface_set_flags, \
15077 "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
15078_(sw_interface_add_del_address, \
15079 "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
Stevenad8015b2017-10-29 22:10:46 -070015080_(sw_interface_set_rx_mode, \
15081 "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
Mohsin Kazmi54f7c512018-08-23 18:28:11 +020015082_(sw_interface_set_rx_placement, \
15083 "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]") \
Mohsin Kazmif0b42f42018-09-10 18:11:00 +020015084_(sw_interface_rx_placement_dump, \
15085 "[<intfc> | sw_if_index <id>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015086_(sw_interface_set_table, \
15087 "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]") \
15088_(sw_interface_set_mpls_enable, \
15089 "<intfc> | sw_if_index [disable | dis]") \
15090_(sw_interface_set_vpath, \
15091 "<intfc> | sw_if_index <id> enable | disable") \
15092_(sw_interface_set_vxlan_bypass, \
John Lo2b81eb82017-01-30 13:12:10 -050015093 "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015094_(sw_interface_set_l2_xconnect, \
15095 "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
15096 "enable | disable") \
15097_(sw_interface_set_l2_bridge, \
Eyal Barif24991c2017-04-05 05:33:21 +030015098 "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n" \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015099 "[shg <split-horizon-group>] [bvi]\n" \
15100 "enable | disable") \
Eyal Barif24991c2017-04-05 05:33:21 +030015101_(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015102_(bridge_domain_add_del, \
John Lo70bfcaf2017-11-14 13:19:26 -050015103 "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 +010015104_(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n") \
15105_(l2fib_add_del, \
15106 "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 +030015107_(l2fib_flush_bd, "bd_id <bridge-domain-id>") \
15108_(l2fib_flush_int, "<intfc> | sw_if_index <id>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015109_(l2_flags, \
John Lo8d00fff2017-08-03 00:35:36 -040015110 "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015111_(bridge_flags, \
15112 "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
Damjan Marion8389fb92017-10-13 18:29:53 +020015113_(tap_create_v2, \
Mohsin Kazmi50bd1652020-08-26 11:07:48 +020015114 "id <num> [hw-addr <mac-addr>] [host-if-name <name>] [host-ns <name>] [num-rx-queues <num>] [rx-ring-size <num>] [tx-ring-size <num>] [host-bridge <name>] [host-mac-addr <mac-addr>] [host-ip4-addr <ip4addr/mask>] [host-ip6-addr <ip6addr/mask>] [host-mtu-size <mtu>] [gso | no-gso | csum-offload | gro-coalesce] [persist] [attach] [tun] [packed] [in-order]") \
Damjan Marion8389fb92017-10-13 18:29:53 +020015115_(tap_delete_v2, \
15116 "<vpp-if-name> | sw_if_index <id>") \
15117_(sw_interface_tap_v2_dump, "") \
Mohsin Kazmi518251b2020-09-01 17:17:44 +000015118_(virtio_pci_create_v2, \
Mohsin Kazmie347acb2020-09-28 10:26:33 +000015119 "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 +010015120_(virtio_pci_delete, \
15121 "<vpp-if-name> | sw_if_index <id>") \
15122_(sw_interface_virtio_pci_dump, "") \
Steven9cd2d7a2017-12-20 12:43:01 -080015123_(bond_create, \
15124 "[hw-addr <mac-addr>] {round-robin | active-backup | " \
Alexander Chernavinad9d5282018-12-13 09:08:09 -050015125 "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} " \
Steven Luonga1876b82019-08-20 16:58:00 -070015126 "[id <if-id>]") \
Steven Luongea717862020-07-30 07:31:40 -070015127_(bond_create2, \
15128 "[hw-addr <mac-addr>] {mode round-robin | active-backup | " \
15129 "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} " \
15130 "[id <if-id>] [gso]") \
Steven9cd2d7a2017-12-20 12:43:01 -080015131_(bond_delete, \
15132 "<vpp-if-name> | sw_if_index <id>") \
Steven Luong4c4223e2020-07-15 08:44:54 -070015133_(bond_add_member, \
Steven Luonga1876b82019-08-20 16:58:00 -070015134 "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]") \
Steven Luong4c4223e2020-07-15 08:44:54 -070015135_(bond_detach_member, \
Steven9cd2d7a2017-12-20 12:43:01 -080015136 "sw_if_index <n>") \
Steven Luonga1876b82019-08-20 16:58:00 -070015137 _(sw_interface_set_bond_weight, "<intfc> | sw_if_index <nn> weight <value>") \
Steven Luong4c4223e2020-07-15 08:44:54 -070015138 _(sw_bond_interface_dump, "<intfc> | sw_if_index <nn>") \
15139 _(sw_member_interface_dump, \
Steven9cd2d7a2017-12-20 12:43:01 -080015140 "<vpp-if-name> | sw_if_index <id>") \
Neale Ranns28ab9cc2017-08-14 07:18:42 -070015141_(ip_table_add_del, \
John Loe166fd92018-09-13 14:08:59 -040015142 "table <n> [ipv6] [add | del]\n") \
Neale Ranns097fa662018-05-01 05:17:55 -070015143_(ip_route_add_del, \
John Lo22030432018-09-20 16:07:00 -040015144 "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
15145 "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
John Lo06fda9c2018-10-03 16:32:44 -040015146 "[weight <n>] [drop] [local] [classify <n>] [out-label <n>]\n" \
15147 "[multipath] [count <n>] [del]") \
Neale Ranns32e1c012016-11-22 17:07:28 +000015148_(ip_mroute_add_del, \
15149 "<src> <grp>/<mask> [table-id <n>]\n" \
15150 "[<intfc> | sw_if_index <id>] [local] [del]") \
Neale Ranns28ab9cc2017-08-14 07:18:42 -070015151_(mpls_table_add_del, \
John Loe166fd92018-09-13 14:08:59 -040015152 "table <n> [add | del]\n") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015153_(mpls_route_add_del, \
John Loe166fd92018-09-13 14:08:59 -040015154 "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n" \
15155 "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n" \
15156 "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n" \
15157 "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n" \
John Lo06fda9c2018-10-03 16:32:44 -040015158 "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n" \
15159 "[count <n>] [del]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015160_(mpls_ip_bind_unbind, \
15161 "<label> <addr/len>") \
15162_(mpls_tunnel_add_del, \
John Lo06fda9c2018-10-03 16:32:44 -040015163 "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
15164 "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n" \
15165 "[l2-only] [out-label <n>]") \
John Loe166fd92018-09-13 14:08:59 -040015166_(sr_mpls_policy_add, \
15167 "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]") \
15168_(sr_mpls_policy_del, \
15169 "bsid <id>") \
Neale Rannsd792d9c2017-10-21 10:53:20 -070015170_(bier_table_add_del, \
15171 "<label> <sub-domain> <set> <bsl> [del]") \
15172_(bier_route_add_del, \
15173 "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
15174 "[<intfc> | sw_if_index <id>]" \
15175 "[weight <n>] [del] [multipath]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015176_(sw_interface_set_unnumbered, \
15177 "<intfc> | sw_if_index <id> unnum_if_index <id> [del]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015178_(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>") \
15179_(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n" \
15180 "[outer_vlan_id <n>][inner_vlan_id <n>]\n" \
15181 "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n" \
15182 "[outer_vlan_id_any][inner_vlan_id_any]") \
Neale Ranns9db6ada2019-11-08 12:42:31 +000015183_(ip_table_replace_begin, "table <n> [ipv6]") \
15184_(ip_table_flush, "table <n> [ipv6]") \
15185_(ip_table_replace_end, "table <n> [ipv6]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015186_(set_ip_flow_hash, \
15187 "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]") \
15188_(sw_interface_ip6_enable_disable, \
15189 "<intfc> | sw_if_index <id> enable | disable") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015190_(l2_patch_add_del, \
15191 "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
15192 "enable | disable") \
Pablo Camarillofb380952016-12-07 18:34:18 +010015193_(sr_localsid_add_del, \
15194 "(del) address <addr> next_hop <addr> behavior <beh>\n" \
15195 "fib-table <num> (end.psp) sw_if_index <num>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015196_(classify_add_del_table, \
15197 "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n" \
15198 " [del] [del-chain] mask <mask-value>\n" \
15199 " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n" \
15200 " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]") \
15201_(classify_add_del_session, \
15202 "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n" \
15203 " table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n" \
15204 " [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n" \
15205 " [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]") \
15206_(classify_set_interface_ip_table, \
15207 "<intfc> | sw_if_index <nn> table <nn>") \
15208_(classify_set_interface_l2_tables, \
15209 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
15210 " [other-table <nn>]") \
15211_(get_node_index, "node <node-name") \
15212_(add_node_next, "node <node-name> next <next-node-name>") \
eyal bariaf86a482018-04-17 11:20:27 +030015213_(vxlan_offload_rx, \
15214 "hw { <interface name> | hw_if_index <nn>} " \
15215 "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015216_(vxlan_add_del_tunnel, \
15217 "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n" \
Jon Loeliger3d460bd2018-02-01 16:36:12 -060015218 "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n" \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015219 "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]") \
15220_(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]") \
Neale Ranns5a8844b2019-04-16 07:15:35 +000015221_(gre_tunnel_add_del, \
John Loa43ccae2018-02-13 17:15:23 -050015222 "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n" \
15223 "[teb | erspan <session-id>] [del]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015224_(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]") \
15225_(l2_fib_clear_table, "") \
15226_(l2_interface_efp_filter, "sw_if_index <nn> enable | disable") \
15227_(l2_interface_vlan_tag_rewrite, \
15228 "<intfc> | sw_if_index <nn> \n" \
15229 "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n" \
15230 "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>") \
15231_(create_vhost_user_if, \
15232 "socket <filename> [server] [renumber <dev_instance>] " \
Steven Luong4208a4c2019-05-06 08:51:56 -070015233 "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] " \
Steven Luongbc0d9ff2020-03-23 09:34:59 -070015234 "[mac <mac_address>] [packed]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015235_(modify_vhost_user_if, \
15236 "<intfc> | sw_if_index <nn> socket <filename>\n" \
Steven Luongbc0d9ff2020-03-23 09:34:59 -070015237 "[server] [renumber <dev_instance>] [gso] [packed]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015238_(delete_vhost_user_if, "<intfc> | sw_if_index <nn>") \
Steven Luonga0e8d962020-05-18 17:12:56 -070015239_(sw_interface_vhost_user_dump, "<intfc> | sw_if_index <nn>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015240_(show_version, "") \
Mohsin Kazmi5d64c782018-09-11 20:27:09 +020015241_(show_threads, "") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015242_(vxlan_gpe_add_del_tunnel, \
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080015243 "local <addr> remote <addr> | group <mcast-ip-addr>\n" \
15244 "{ <intfc> | mcast_sw_if_index <nn> } }\n" \
15245 "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n" \
15246 "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015247_(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]") \
15248_(l2_fib_table_dump, "bd_id <bridge-domain-id>") \
15249_(interface_name_renumber, \
15250 "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>") \
15251_(input_acl_set_interface, \
15252 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
15253 " [l2-table <nn>] [del]") \
John Lo8d00fff2017-08-03 00:35:36 -040015254_(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015255_(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)") \
15256_(ip_dump, "ipv4 | ipv6") \
15257_(ipsec_spd_add_del, "spd_id <n> [del]") \
15258_(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n" \
15259 " spid_id <n> ") \
Neale Ranns17dcec02019-01-09 21:22:20 -080015260_(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n" \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015261 " crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n" \
15262 " integ_alg <alg> integ_key <hex>") \
Neale Ranns17dcec02019-01-09 21:22:20 -080015263_(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n" \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015264 " (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n" \
15265 " laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
15266 " [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
Matthew Smithb0972cb2017-05-02 16:20:41 -050015267_(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n" \
15268 " crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
15269 " integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n" \
Matthew Smith8e1039a2018-04-12 07:32:56 -050015270 " local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n" \
15271 " [instance <n>]") \
Matthew Smith28029532017-09-26 13:33:44 -050015272_(ipsec_sa_dump, "[sa_id <n>]") \
Matthew Smithca514fd2017-10-12 12:06:59 -050015273_(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015274_(delete_loopback,"sw_if_index <nn>") \
15275_(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
John Loe26c81f2019-01-07 15:16:33 -050015276_(bd_ip_mac_flush, "bd_id <bridge-domain-id>") \
15277_(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015278_(want_interface_events, "enable|disable") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015279_(get_first_msg_id, "client <name>") \
15280_(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
15281_(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n" \
15282 "fib-id <nn> [ip4][ip6][default]") \
15283_(get_node_graph, " ") \
15284_(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>") \
15285_(ioam_enable, "[trace] [pow] [ppc <encap|decap>]") \
15286_(ioam_disable, "") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015287_(af_packet_create, "name <host interface name> [hw_addr <mac>]") \
15288_(af_packet_delete, "name <host interface name>") \
Mohsin Kazmi04e0bb22018-05-28 18:55:37 +020015289_(af_packet_dump, "") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015290_(policer_add_del, "name <policer name> <params> [del]") \
15291_(policer_dump, "[name <policer name>]") \
15292_(policer_classify_set_interface, \
15293 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
15294 " [l2-table <nn>] [del]") \
15295_(policer_classify_dump, "type [ip4|ip6|l2]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015296_(mpls_tunnel_dump, "tunnel_index <tunnel-id>") \
Neale Ranns097fa662018-05-01 05:17:55 -070015297_(mpls_table_dump, "") \
15298_(mpls_route_dump, "table-id <ID>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015299_(classify_table_ids, "") \
15300_(classify_table_by_interface, "sw_if_index <sw_if_index>") \
15301_(classify_table_info, "table_id <nn>") \
15302_(classify_session_dump, "table_id <nn>") \
15303_(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] " \
15304 "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] " \
15305 "[template_interval <nn>] [udp_checksum]") \
15306_(ipfix_exporter_dump, "") \
15307_(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
15308_(ipfix_classify_stream_dump, "") \
15309_(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
15310_(ipfix_classify_table_dump, "") \
Eyal Bari001fd402017-07-16 09:34:53 +030015311_(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
Eyal Bari5b311202017-07-31 13:12:30 +030015312_(sw_interface_span_dump, "[l2]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015313_(get_next_index, "node-name <node-name> next-node-name <node-name>") \
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +020015314_(pg_create_interface, "if_id <nn> [gso-enabled gso-size <size>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015315_(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]") \
15316_(pg_enable_disable, "[stream <id>] disable") \
Mohsin Kazmif382b062020-08-11 15:00:44 +020015317_(pg_interface_enable_disable_coalesce, "<intf> | sw_if_index <nn> enable | disable") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015318_(ip_source_and_port_range_check_add_del, \
15319 "<ip-addr>/<mask> range <nn>-<nn> vrf <id>") \
15320_(ip_source_and_port_range_check_interface_add_del, \
15321 "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]" \
15322 "[udp-in-vrf <id>] [udp-out-vrf <id>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015323_(delete_subif,"<intfc> | sw_if_index <nn>") \
15324_(l2_interface_pbb_tag_rewrite, \
15325 "<intfc> | sw_if_index <nn> \n" \
15326 "[disable | push | pop | translate_pbb_stag <outer_tag>] \n" \
15327 "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]") \
Pavel Kotuceke88865d2018-11-28 07:42:11 +010015328_(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015329_(flow_classify_set_interface, \
15330 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
15331_(flow_classify_dump, "type [ip4|ip6]") \
Neale Ranns097fa662018-05-01 05:17:55 -070015332_(ip_table_dump, "") \
15333_(ip_route_dump, "table-id [ip4|ip6]") \
15334_(ip_mtable_dump, "") \
15335_(ip_mroute_dump, "table-id [ip4|ip6]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015336_(feature_enable_disable, "arc_name <arc_name> " \
15337 "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]") \
Mohsin Kazmi29467b52019-10-08 19:42:38 +020015338_(feature_gso_enable_disable, "<intfc> | sw_if_index <nn> " \
15339 "[enable | disable] ") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015340_(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>" \
15341"[disable]") \
Matthew Smithe0792fd2019-07-12 11:48:24 -050015342_(sw_interface_add_del_mac_address, "<intfc> | sw_if_index <nn> " \
15343 "mac <mac-address> [del]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015344_(l2_xconnect_dump, "") \
Ole Troand7231612018-06-07 10:17:57 +020015345_(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>") \
Pavel Kotucek6899a302017-06-08 08:46:10 +020015346_(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]") \
Pavel Kotucek15ac81c2017-06-20 14:00:26 +020015347_(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
Steve Shin99a0e602017-07-01 04:16:20 +000015348_(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
Dave Barach59b25652017-09-10 15:04:27 -040015349_(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]") \
Florin Coras90a63982017-12-19 04:50:01 -080015350_(sock_init_shm, "size <nnn>") \
Florin Corascea194d2017-10-02 00:18:51 -070015351_(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
Florin Coras1c710452017-10-17 00:03:13 -070015352_(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> " \
15353 "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>") \
Florin Coras6c36f532017-11-03 18:32:34 -070015354_(session_rules_dump, "") \
Florin Coras595992c2017-11-06 17:17:08 -080015355_(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>") \
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +010015356_(output_acl_set_interface, \
15357 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
15358 " [l2-table <nn>] [del]") \
Ole Troane906aac2018-06-14 14:42:14 +020015359_(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
Damjan Marion7cd468a2016-12-19 23:05:39 +010015360
15361/* List of command functions, CLI names map directly to functions */
15362#define foreach_cli_function \
15363_(comment, "usage: comment <ignore-rest-of-line>") \
15364_(dump_interface_table, "usage: dump_interface_table") \
15365_(dump_sub_interface_table, "usage: dump_sub_interface_table") \
15366_(dump_ipv4_table, "usage: dump_ipv4_table") \
15367_(dump_ipv6_table, "usage: dump_ipv6_table") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015368_(dump_macro_table, "usage: dump_macro_table ") \
15369_(dump_node_table, "usage: dump_node_table") \
15370_(dump_msg_api_table, "usage: dump_msg_api_table") \
Dave Barachb09f4d02019-07-15 16:00:03 -040015371_(elog_setup, "usage: elog_setup [nevents, default 128K]") \
15372_(elog_disable, "usage: elog_disable") \
15373_(elog_enable, "usage: elog_enable") \
15374_(elog_save, "usage: elog_save <filename>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015375_(get_msg_id, "usage: get_msg_id name_and_crc") \
15376_(echo, "usage: echo <message>") \
15377_(exec, "usage: exec <vpe-debug-CLI-command>") \
15378_(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>") \
15379_(help, "usage: help") \
15380_(q, "usage: quit") \
15381_(quit, "usage: quit") \
15382_(search_node_table, "usage: search_node_table <name>...") \
15383_(set, "usage: set <variable-name> <value>") \
15384_(script, "usage: script <file-name>") \
Neale Ranns097fa662018-05-01 05:17:55 -070015385_(statseg, "usage: statseg") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015386_(unset, "usage: unset <variable-name>")
Dave Barach048a4e52018-06-01 18:52:25 -040015387
Damjan Marion7cd468a2016-12-19 23:05:39 +010015388#define _(N,n) \
15389 static void vl_api_##n##_t_handler_uni \
15390 (vl_api_##n##_t * mp) \
15391 { \
15392 vat_main_t * vam = &vat_main; \
15393 if (vam->json_output) { \
15394 vl_api_##n##_t_handler_json(mp); \
15395 } else { \
15396 vl_api_##n##_t_handler(mp); \
15397 } \
15398 }
15399foreach_vpe_api_reply_msg;
Dave Baracha1a093d2017-03-02 13:13:23 -050015400#if VPP_API_TEST_BUILTIN == 0
15401foreach_standalone_reply_msg;
15402#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +010015403#undef _
15404
15405void
15406vat_api_hookup (vat_main_t * vam)
15407{
15408#define _(N,n) \
15409 vl_msg_api_set_handlers(VL_API_##N, #n, \
15410 vl_api_##n##_t_handler_uni, \
15411 vl_noop_handler, \
15412 vl_api_##n##_t_endian, \
15413 vl_api_##n##_t_print, \
15414 sizeof(vl_api_##n##_t), 1);
15415 foreach_vpe_api_reply_msg;
Dave Baracha1a093d2017-03-02 13:13:23 -050015416#if VPP_API_TEST_BUILTIN == 0
15417 foreach_standalone_reply_msg;
15418#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +010015419#undef _
15420
15421#if (VPP_API_TEST_BUILTIN==0)
15422 vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015423
15424 vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
15425
15426 vam->function_by_name = hash_create_string (0, sizeof (uword));
15427
15428 vam->help_by_name = hash_create_string (0, sizeof (uword));
Dave Barach45e4f362017-03-07 12:52:31 -050015429#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +010015430
15431 /* API messages we can send */
15432#define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
15433 foreach_vpe_api_msg;
15434#undef _
15435
15436 /* Help strings */
15437#define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
15438 foreach_vpe_api_msg;
15439#undef _
Damjan Marion7cd468a2016-12-19 23:05:39 +010015440
15441 /* CLI functions */
15442#define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
15443 foreach_cli_function;
15444#undef _
15445
15446 /* Help strings */
15447#define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
15448 foreach_cli_function;
15449#undef _
15450}
15451
Dave Baracha1a093d2017-03-02 13:13:23 -050015452#if VPP_API_TEST_BUILTIN
15453static clib_error_t *
15454vat_api_hookup_shim (vlib_main_t * vm)
15455{
15456 vat_api_hookup (&vat_main);
15457 return 0;
15458}
15459
15460VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
15461#endif
15462
Damjan Marion7cd468a2016-12-19 23:05:39 +010015463/*
15464 * fd.io coding-style-patch-verification: ON
15465 *
15466 * Local Variables:
15467 * eval: (c-set-style "gnu")
15468 * End:
15469 */