blob: 649737bc64f08e8b211c0c54c2b41c39629ab23c [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>
Damjan Marion7cd468a2016-12-19 23:05:39 +010031#include <vnet/vxlan-gpe/vxlan_gpe.h>
Florin Corasb040f982020-10-20 14:59:43 -070032#include <vnet/udp/udp_local.h>
Damjan Marion7cd468a2016-12-19 23:05:39 +010033
34#include <vpp/api/vpe_msg_enum.h>
35#include <vnet/l2/l2_classify.h>
36#include <vnet/l2/l2_vtr.h>
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +010037#include <vnet/classify/in_out_acl.h>
Damjan Marion7cd468a2016-12-19 23:05:39 +010038#include <vnet/classify/policer_classify.h>
39#include <vnet/classify/flow_classify.h>
40#include <vnet/mpls/mpls.h>
41#include <vnet/ipsec/ipsec.h>
Damjan Marion7cd468a2016-12-19 23:05:39 +010042#include <inttypes.h>
Damjan Marion7cd468a2016-12-19 23:05:39 +010043#include <vnet/ip/ip6_hop_by_hop.h>
44#include <vnet/ip/ip_source_and_port_range_check.h>
45#include <vnet/policer/xlate.h>
46#include <vnet/span/span.h>
47#include <vnet/policer/policer.h>
48#include <vnet/policer/police.h>
Neale Ranns32e1c012016-11-22 17:07:28 +000049#include <vnet/mfib/mfib_types.h>
Steven9cd2d7a2017-12-20 12:43:01 -080050#include <vnet/bonding/node.h>
Igor Mikhailov (imichail)582caa32018-04-26 21:33:02 -070051#include <vnet/qos/qos_types.h>
Neale Ranns37029302018-08-10 05:30:06 -070052#include <vnet/ethernet/ethernet_types_api.h>
53#include <vnet/ip/ip_types_api.h>
Damjan Marion7cd468a2016-12-19 23:05:39 +010054#include "vat/json_format.h"
Neale Ranns86327be2018-11-02 09:14:01 -070055#include <vnet/ip/ip_types_api.h>
56#include <vnet/ethernet/ethernet_types_api.h>
Damjan Marion7cd468a2016-12-19 23:05:39 +010057
58#include <inttypes.h>
59#include <sys/stat.h>
60
61#define vl_typedefs /* define message structures */
62#include <vpp/api/vpe_all_api_h.h>
63#undef vl_typedefs
64
65/* declare message handlers for each api */
66
67#define vl_endianfun /* define message structures */
68#include <vpp/api/vpe_all_api_h.h>
69#undef vl_endianfun
70
71/* instantiate all the print functions we know about */
Dave Barachf35a0722019-06-12 16:50:38 -040072#if VPP_API_TEST_BUILTIN == 0
Damjan Marion7cd468a2016-12-19 23:05:39 +010073#define vl_print(handle, ...)
Dave Barachf35a0722019-06-12 16:50:38 -040074#else
75#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
76#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +010077#define vl_printfun
78#include <vpp/api/vpe_all_api_h.h>
79#undef vl_printfun
80
Dave Barach2d6b2d62017-01-25 16:32:08 -050081#define __plugin_msg_base 0
Dave Barachfe6bdfd2017-01-20 19:50:09 -050082#include <vlibapi/vat_helper_macros.h>
83
Ole Troan33a58172019-09-04 09:12:29 +020084#include <vnet/format_fns.h>
85
Dave Barachb09f4d02019-07-15 16:00:03 -040086void vl_api_set_elog_main (elog_main_t * m);
87int vl_api_set_elog_trace_api_messages (int enable);
88
Dave Barach59b25652017-09-10 15:04:27 -040089#if VPP_API_TEST_BUILTIN == 0
90#include <netdb.h>
91
92u32
93vl (void *p)
94{
95 return vec_len (p);
96}
97
98int
99vat_socket_connect (vat_main_t * vam)
100{
Florin Coras66a10032018-12-21 16:23:09 -0800101 int rv;
Dave Barach69eeadc2020-04-14 09:52:26 -0400102 api_main_t *am = vlibapi_get_main ();
Florin Coras90a63982017-12-19 04:50:01 -0800103 vam->socket_client_main = &socket_client_main;
Florin Coras66a10032018-12-21 16:23:09 -0800104 if ((rv = vl_socket_client_connect ((char *) vam->socket_name,
105 "vpp_api_test",
106 0 /* default socket rx, tx buffer */ )))
107 return rv;
Dave Barach69eeadc2020-04-14 09:52:26 -0400108
Florin Coras66a10032018-12-21 16:23:09 -0800109 /* vpp expects the client index in network order */
110 vam->my_client_index = htonl (socket_client_main.client_index);
Dave Barach69eeadc2020-04-14 09:52:26 -0400111 am->my_client_index = vam->my_client_index;
Florin Coras66a10032018-12-21 16:23:09 -0800112 return 0;
Dave Barach59b25652017-09-10 15:04:27 -0400113}
114#else /* vpp built-in case, we don't do sockets... */
115int
116vat_socket_connect (vat_main_t * vam)
117{
118 return 0;
119}
120
Florin Coras90a63982017-12-19 04:50:01 -0800121int
122vl_socket_client_read (int wait)
Dave Barach59b25652017-09-10 15:04:27 -0400123{
Florin Coras90a63982017-12-19 04:50:01 -0800124 return -1;
Dave Barach59b25652017-09-10 15:04:27 -0400125};
Florin Coras90a63982017-12-19 04:50:01 -0800126
127int
128vl_socket_client_write ()
129{
130 return -1;
131};
132
133void *
134vl_socket_client_msg_alloc (int nbytes)
135{
136 return 0;
137}
Dave Barach59b25652017-09-10 15:04:27 -0400138#endif
139
140
Dave Barachfe6bdfd2017-01-20 19:50:09 -0500141f64
142vat_time_now (vat_main_t * vam)
143{
144#if VPP_API_TEST_BUILTIN
145 return vlib_time_now (vam->vlib_main);
146#else
147 return clib_time_now (&vam->clib_time);
148#endif
149}
150
151void
152errmsg (char *fmt, ...)
153{
154 vat_main_t *vam = &vat_main;
155 va_list va;
156 u8 *s;
157
158 va_start (va, fmt);
159 s = va_format (0, fmt, &va);
160 va_end (va);
161
162 vec_add1 (s, 0);
163
164#if VPP_API_TEST_BUILTIN
165 vlib_cli_output (vam->vlib_main, (char *) s);
166#else
167 {
168 if (vam->ifp != stdin)
169 fformat (vam->ofp, "%s(%d): \n", vam->current_file,
170 vam->input_line_number);
Dave Barachb09f4d02019-07-15 16:00:03 -0400171 else
172 fformat (vam->ofp, "%s\n", (char *) s);
Dave Barachfe6bdfd2017-01-20 19:50:09 -0500173 fflush (vam->ofp);
174 }
175#endif
176
177 vec_free (s);
178}
179
Dave Barach4a3f69c2017-02-22 12:44:56 -0500180#if VPP_API_TEST_BUILTIN == 0
Damjan Marion7cd468a2016-12-19 23:05:39 +0100181static uword
182api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
183{
184 vat_main_t *vam = va_arg (*args, vat_main_t *);
185 u32 *result = va_arg (*args, u32 *);
186 u8 *if_name;
187 uword *p;
188
189 if (!unformat (input, "%s", &if_name))
190 return 0;
191
192 p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
193 if (p == 0)
194 return 0;
195 *result = p[0];
196 return 1;
197}
198
eyal bariaf86a482018-04-17 11:20:27 +0300199static uword
200api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
201{
202 return 0;
203}
204
Damjan Marion7cd468a2016-12-19 23:05:39 +0100205/* Parse an IP4 address %d.%d.%d.%d. */
206uword
207unformat_ip4_address (unformat_input_t * input, va_list * args)
208{
209 u8 *result = va_arg (*args, u8 *);
210 unsigned a[4];
211
212 if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
213 return 0;
214
215 if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
216 return 0;
217
218 result[0] = a[0];
219 result[1] = a[1];
220 result[2] = a[2];
221 result[3] = a[3];
222
223 return 1;
224}
225
226uword
227unformat_ethernet_address (unformat_input_t * input, va_list * args)
228{
229 u8 *result = va_arg (*args, u8 *);
230 u32 i, a[6];
231
232 if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
233 &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
234 return 0;
235
236 /* Check range. */
237 for (i = 0; i < 6; i++)
238 if (a[i] >= (1 << 8))
239 return 0;
240
241 for (i = 0; i < 6; i++)
242 result[i] = a[i];
243
244 return 1;
245}
246
247/* Returns ethernet type as an int in host byte order. */
248uword
249unformat_ethernet_type_host_byte_order (unformat_input_t * input,
250 va_list * args)
251{
252 u16 *result = va_arg (*args, u16 *);
253 int type;
254
255 /* Numeric type. */
256 if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
257 {
258 if (type >= (1 << 16))
259 return 0;
260 *result = type;
261 return 1;
262 }
263 return 0;
264}
265
Jakub Grajciar23a386b2020-02-26 11:01:43 +0100266/* Parse an IP46 address. */
267uword
268unformat_ip46_address (unformat_input_t * input, va_list * args)
269{
270 ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
271 ip46_type_t type = va_arg (*args, ip46_type_t);
272 if ((type != IP46_TYPE_IP6) &&
273 unformat (input, "%U", unformat_ip4_address, &ip46->ip4))
274 {
275 ip46_address_mask_ip4 (ip46);
276 return 1;
277 }
278 else if ((type != IP46_TYPE_IP4) &&
279 unformat (input, "%U", unformat_ip6_address, &ip46->ip6))
280 {
281 return 1;
282 }
283 return 0;
284}
285
Damjan Marion7cd468a2016-12-19 23:05:39 +0100286/* Parse an IP6 address. */
287uword
288unformat_ip6_address (unformat_input_t * input, va_list * args)
289{
290 ip6_address_t *result = va_arg (*args, ip6_address_t *);
291 u16 hex_quads[8];
292 uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
293 uword c, n_colon, double_colon_index;
294
295 n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
296 double_colon_index = ARRAY_LEN (hex_quads);
297 while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
298 {
299 hex_digit = 16;
300 if (c >= '0' && c <= '9')
301 hex_digit = c - '0';
302 else if (c >= 'a' && c <= 'f')
303 hex_digit = c + 10 - 'a';
304 else if (c >= 'A' && c <= 'F')
305 hex_digit = c + 10 - 'A';
306 else if (c == ':' && n_colon < 2)
307 n_colon++;
308 else
309 {
310 unformat_put_input (input);
311 break;
312 }
313
314 /* Too many hex quads. */
315 if (n_hex_quads >= ARRAY_LEN (hex_quads))
316 return 0;
317
318 if (hex_digit < 16)
319 {
320 hex_quad = (hex_quad << 4) | hex_digit;
321
322 /* Hex quad must fit in 16 bits. */
323 if (n_hex_digits >= 4)
324 return 0;
325
326 n_colon = 0;
327 n_hex_digits++;
328 }
329
330 /* Save position of :: */
331 if (n_colon == 2)
332 {
333 /* More than one :: ? */
334 if (double_colon_index < ARRAY_LEN (hex_quads))
335 return 0;
336 double_colon_index = n_hex_quads;
337 }
338
339 if (n_colon > 0 && n_hex_digits > 0)
340 {
341 hex_quads[n_hex_quads++] = hex_quad;
342 hex_quad = 0;
343 n_hex_digits = 0;
344 }
345 }
346
347 if (n_hex_digits > 0)
348 hex_quads[n_hex_quads++] = hex_quad;
349
350 {
351 word i;
352
353 /* Expand :: to appropriate number of zero hex quads. */
354 if (double_colon_index < ARRAY_LEN (hex_quads))
355 {
356 word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
357
358 for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
359 hex_quads[n_zero + i] = hex_quads[i];
360
361 for (i = 0; i < n_zero; i++)
362 hex_quads[double_colon_index + i] = 0;
363
364 n_hex_quads = ARRAY_LEN (hex_quads);
365 }
366
367 /* Too few hex quads given. */
368 if (n_hex_quads < ARRAY_LEN (hex_quads))
369 return 0;
370
371 for (i = 0; i < ARRAY_LEN (hex_quads); i++)
372 result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
373
374 return 1;
375 }
376}
377
378uword
379unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
380{
381 u32 *r = va_arg (*args, u32 *);
382
383 if (0);
384#define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
385 foreach_ipsec_policy_action
386#undef _
387 else
388 return 0;
389 return 1;
390}
391
Damjan Marion7cd468a2016-12-19 23:05:39 +0100392u8 *
393format_ipsec_crypto_alg (u8 * s, va_list * args)
394{
395 u32 i = va_arg (*args, u32);
396 u8 *t = 0;
397
398 switch (i)
399 {
400#define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
401 foreach_ipsec_crypto_alg
402#undef _
403 default:
404 return format (s, "unknown");
405 }
406 return format (s, "%s", t);
407}
408
Damjan Marion7cd468a2016-12-19 23:05:39 +0100409u8 *
410format_ipsec_integ_alg (u8 * s, va_list * args)
411{
412 u32 i = va_arg (*args, u32);
413 u8 *t = 0;
414
415 switch (i)
416 {
417#define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
418 foreach_ipsec_integ_alg
419#undef _
420 default:
421 return format (s, "unknown");
422 }
423 return format (s, "%s", t);
424}
425
Dave Barach4a3f69c2017-02-22 12:44:56 -0500426#else /* VPP_API_TEST_BUILTIN == 1 */
427static uword
428api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
429{
Benoît Ganne49ee6842019-04-30 11:50:46 +0200430 vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
Dave Barach4a3f69c2017-02-22 12:44:56 -0500431 vnet_main_t *vnm = vnet_get_main ();
432 u32 *result = va_arg (*args, u32 *);
Dave Barach4a3f69c2017-02-22 12:44:56 -0500433
eyal bariaf86a482018-04-17 11:20:27 +0300434 return unformat (input, "%U", unformat_vnet_sw_interface, vnm, result);
Dave Barach4a3f69c2017-02-22 12:44:56 -0500435}
eyal bariaf86a482018-04-17 11:20:27 +0300436
437static uword
438api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
439{
Benoît Ganne49ee6842019-04-30 11:50:46 +0200440 vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
eyal bariaf86a482018-04-17 11:20:27 +0300441 vnet_main_t *vnm = vnet_get_main ();
442 u32 *result = va_arg (*args, u32 *);
443
444 return unformat (input, "%U", unformat_vnet_hw_interface, vnm, result);
445}
446
Damjan Marion7cd468a2016-12-19 23:05:39 +0100447#endif /* VPP_API_TEST_BUILTIN */
448
Neale Ranns17dcec02019-01-09 21:22:20 -0800449uword
450unformat_ipsec_api_crypto_alg (unformat_input_t * input, va_list * args)
451{
452 u32 *r = va_arg (*args, u32 *);
453
454 if (0);
455#define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_CRYPTO_ALG_##f;
456 foreach_ipsec_crypto_alg
457#undef _
458 else
459 return 0;
460 return 1;
461}
462
463uword
464unformat_ipsec_api_integ_alg (unformat_input_t * input, va_list * args)
465{
466 u32 *r = va_arg (*args, u32 *);
467
468 if (0);
469#define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_INTEG_ALG_##f;
470 foreach_ipsec_integ_alg
471#undef _
472 else
473 return 0;
474 return 1;
475}
476
Damjan Marion7cd468a2016-12-19 23:05:39 +0100477static uword
478unformat_policer_rate_type (unformat_input_t * input, va_list * args)
479{
480 u8 *r = va_arg (*args, u8 *);
481
482 if (unformat (input, "kbps"))
483 *r = SSE2_QOS_RATE_KBPS;
484 else if (unformat (input, "pps"))
485 *r = SSE2_QOS_RATE_PPS;
486 else
487 return 0;
488 return 1;
489}
490
491static uword
492unformat_policer_round_type (unformat_input_t * input, va_list * args)
493{
494 u8 *r = va_arg (*args, u8 *);
495
496 if (unformat (input, "closest"))
497 *r = SSE2_QOS_ROUND_TO_CLOSEST;
498 else if (unformat (input, "up"))
499 *r = SSE2_QOS_ROUND_TO_UP;
500 else if (unformat (input, "down"))
501 *r = SSE2_QOS_ROUND_TO_DOWN;
502 else
503 return 0;
504 return 1;
505}
506
507static uword
508unformat_policer_type (unformat_input_t * input, va_list * args)
509{
510 u8 *r = va_arg (*args, u8 *);
511
512 if (unformat (input, "1r2c"))
513 *r = SSE2_QOS_POLICER_TYPE_1R2C;
514 else if (unformat (input, "1r3c"))
515 *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
516 else if (unformat (input, "2r3c-2698"))
517 *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
518 else if (unformat (input, "2r3c-4115"))
519 *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
520 else if (unformat (input, "2r3c-mef5cf1"))
521 *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
522 else
523 return 0;
524 return 1;
525}
526
527static uword
528unformat_dscp (unformat_input_t * input, va_list * va)
529{
530 u8 *r = va_arg (*va, u8 *);
531
532 if (0);
Brian Russelle3845d72021-02-08 15:33:18 +0000533#define _(v, f) else if (unformat (input, #f)) *r = IP_DSCP_##f;
534 foreach_ip_dscp
Damjan Marion7cd468a2016-12-19 23:05:39 +0100535#undef _
Brian Russelle3845d72021-02-08 15:33:18 +0000536 else return 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +0100537 return 1;
538}
539
540static uword
541unformat_policer_action_type (unformat_input_t * input, va_list * va)
542{
543 sse2_qos_pol_action_params_st *a
544 = va_arg (*va, sse2_qos_pol_action_params_st *);
545
546 if (unformat (input, "drop"))
547 a->action_type = SSE2_QOS_ACTION_DROP;
548 else if (unformat (input, "transmit"))
549 a->action_type = SSE2_QOS_ACTION_TRANSMIT;
550 else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
551 a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
552 else
553 return 0;
554 return 1;
555}
556
557static uword
558unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
559{
560 u32 *r = va_arg (*va, u32 *);
561 u32 tid;
562
563 if (unformat (input, "ip4"))
564 tid = POLICER_CLASSIFY_TABLE_IP4;
565 else if (unformat (input, "ip6"))
566 tid = POLICER_CLASSIFY_TABLE_IP6;
567 else if (unformat (input, "l2"))
568 tid = POLICER_CLASSIFY_TABLE_L2;
569 else
570 return 0;
571
572 *r = tid;
573 return 1;
574}
575
576static uword
577unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
578{
579 u32 *r = va_arg (*va, u32 *);
580 u32 tid;
581
582 if (unformat (input, "ip4"))
583 tid = FLOW_CLASSIFY_TABLE_IP4;
584 else if (unformat (input, "ip6"))
585 tid = FLOW_CLASSIFY_TABLE_IP6;
586 else
587 return 0;
588
589 *r = tid;
590 return 1;
591}
592
Benoît Ganne49ee6842019-04-30 11:50:46 +0200593#if (VPP_API_TEST_BUILTIN==0)
594
Neale Ranns32e1c012016-11-22 17:07:28 +0000595static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
596static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
597static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
598static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
599
600uword
601unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
602{
603 mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
604 mfib_itf_attribute_t attr;
605
606 old = *iflags;
607 FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
608 {
609 if (unformat (input, mfib_itf_flag_long_names[attr]))
610 *iflags |= (1 << attr);
611 }
612 FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
613 {
614 if (unformat (input, mfib_itf_flag_names[attr]))
615 *iflags |= (1 << attr);
616 }
617
618 return (old == *iflags ? 0 : 1);
619}
620
621uword
622unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
623{
624 mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
625 mfib_entry_attribute_t attr;
626
627 old = *eflags;
628 FOR_EACH_MFIB_ATTRIBUTE (attr)
629 {
630 if (unformat (input, mfib_flag_long_names[attr]))
631 *eflags |= (1 << attr);
632 }
633 FOR_EACH_MFIB_ATTRIBUTE (attr)
634 {
635 if (unformat (input, mfib_flag_names[attr]))
636 *eflags |= (1 << attr);
637 }
638
639 return (old == *eflags ? 0 : 1);
640}
641
Damjan Marion7cd468a2016-12-19 23:05:39 +0100642u8 *
643format_ip4_address (u8 * s, va_list * args)
644{
645 u8 *a = va_arg (*args, u8 *);
646 return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
647}
648
649u8 *
650format_ip6_address (u8 * s, va_list * args)
651{
652 ip6_address_t *a = va_arg (*args, ip6_address_t *);
653 u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
654
655 i_max_n_zero = ARRAY_LEN (a->as_u16);
656 max_n_zeros = 0;
657 i_first_zero = i_max_n_zero;
658 n_zeros = 0;
659 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
660 {
661 u32 is_zero = a->as_u16[i] == 0;
662 if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
663 {
664 i_first_zero = i;
665 n_zeros = 0;
666 }
667 n_zeros += is_zero;
668 if ((!is_zero && n_zeros > max_n_zeros)
669 || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
670 {
671 i_max_n_zero = i_first_zero;
672 max_n_zeros = n_zeros;
673 i_first_zero = ARRAY_LEN (a->as_u16);
674 n_zeros = 0;
675 }
676 }
677
678 last_double_colon = 0;
679 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
680 {
681 if (i == i_max_n_zero && max_n_zeros > 1)
682 {
683 s = format (s, "::");
684 i += max_n_zeros - 1;
685 last_double_colon = 1;
686 }
687 else
688 {
689 s = format (s, "%s%x",
690 (last_double_colon || i == 0) ? "" : ":",
691 clib_net_to_host_u16 (a->as_u16[i]));
692 last_double_colon = 0;
693 }
694 }
695
696 return s;
697}
698
699/* Format an IP46 address. */
700u8 *
701format_ip46_address (u8 * s, va_list * args)
702{
703 ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
704 ip46_type_t type = va_arg (*args, ip46_type_t);
705 int is_ip4 = 1;
706
707 switch (type)
708 {
709 case IP46_TYPE_ANY:
710 is_ip4 = ip46_address_is_ip4 (ip46);
711 break;
712 case IP46_TYPE_IP4:
713 is_ip4 = 1;
714 break;
715 case IP46_TYPE_IP6:
716 is_ip4 = 0;
717 break;
718 }
719
720 return is_ip4 ?
721 format (s, "%U", format_ip4_address, &ip46->ip4) :
722 format (s, "%U", format_ip6_address, &ip46->ip6);
723}
724
725u8 *
726format_ethernet_address (u8 * s, va_list * args)
727{
728 u8 *a = va_arg (*args, u8 *);
729
730 return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
731 a[0], a[1], a[2], a[3], a[4], a[5]);
732}
733#endif
734
735static void
Neale Ranns097fa662018-05-01 05:17:55 -0700736increment_v4_address (vl_api_ip4_address_t * i)
Damjan Marion7cd468a2016-12-19 23:05:39 +0100737{
Neale Ranns097fa662018-05-01 05:17:55 -0700738 ip4_address_t *a = (ip4_address_t *) i;
Damjan Marion7cd468a2016-12-19 23:05:39 +0100739 u32 v;
740
741 v = ntohl (a->as_u32) + 1;
742 a->as_u32 = ntohl (v);
743}
744
745static void
Neale Ranns097fa662018-05-01 05:17:55 -0700746increment_v6_address (vl_api_ip6_address_t * i)
Neale Ranns2b5ba952019-04-02 10:15:40 +0000747{
Neale Ranns097fa662018-05-01 05:17:55 -0700748 ip6_address_t *a = (ip6_address_t *) i;
Damjan Marion7cd468a2016-12-19 23:05:39 +0100749 u64 v0, v1;
750
751 v0 = clib_net_to_host_u64 (a->as_u64[0]);
752 v1 = clib_net_to_host_u64 (a->as_u64[1]);
753
754 v1 += 1;
755 if (v1 == 0)
756 v0 += 1;
757 a->as_u64[0] = clib_net_to_host_u64 (v0);
758 a->as_u64[1] = clib_net_to_host_u64 (v1);
759}
760
761static void
Neale Ranns097fa662018-05-01 05:17:55 -0700762increment_address (vl_api_address_t * a)
763{
Dave Barach54582662020-04-21 08:01:16 -0400764 if (a->af == ADDRESS_IP4)
Neale Ranns097fa662018-05-01 05:17:55 -0700765 increment_v4_address (&a->un.ip4);
Dave Barach54582662020-04-21 08:01:16 -0400766 else if (a->af == ADDRESS_IP6)
Neale Ranns097fa662018-05-01 05:17:55 -0700767 increment_v6_address (&a->un.ip6);
768}
769
770static void
771set_ip4_address (vl_api_address_t * a, u32 v)
772{
773 if (a->af == ADDRESS_IP4)
774 {
775 ip4_address_t *i = (ip4_address_t *) & a->un.ip4;
776 i->as_u32 = v;
777 }
778}
779
Jakub Grajciar23a386b2020-02-26 11:01:43 +0100780void
781ip_set (ip46_address_t * dst, void *src, u8 is_ip4)
782{
783 if (is_ip4)
784 dst->ip4.as_u32 = ((ip4_address_t *) src)->as_u32;
785 else
786 clib_memcpy_fast (&dst->ip6, (ip6_address_t *) src,
787 sizeof (ip6_address_t));
788}
789
Neale Ranns097fa662018-05-01 05:17:55 -0700790static void
Mohsin Kazmi57938f62017-10-27 21:28:07 +0200791increment_mac_address (u8 * mac)
Damjan Marion7cd468a2016-12-19 23:05:39 +0100792{
Mohsin Kazmi57938f62017-10-27 21:28:07 +0200793 u64 tmp = *((u64 *) mac);
Damjan Marion7cd468a2016-12-19 23:05:39 +0100794 tmp = clib_net_to_host_u64 (tmp);
795 tmp += 1 << 16; /* skip unused (least significant) octets */
796 tmp = clib_host_to_net_u64 (tmp);
Mohsin Kazmi57938f62017-10-27 21:28:07 +0200797
798 clib_memcpy (mac, &tmp, 6);
Damjan Marion7cd468a2016-12-19 23:05:39 +0100799}
800
Neale Ranns097fa662018-05-01 05:17:55 -0700801static void
802vat_json_object_add_address (vat_json_node_t * node,
803 const char *str, const vl_api_address_t * addr)
804{
805 if (ADDRESS_IP6 == addr->af)
806 {
807 struct in6_addr ip6;
808
809 clib_memcpy (&ip6, &addr->un.ip6, sizeof (ip6));
810 vat_json_object_add_ip6 (node, str, ip6);
811 }
812 else
813 {
814 struct in_addr ip4;
815
816 clib_memcpy (&ip4, &addr->un.ip4, sizeof (ip4));
817 vat_json_object_add_ip4 (node, str, ip4);
818 }
819}
820
821static void
822vat_json_object_add_prefix (vat_json_node_t * node,
823 const vl_api_prefix_t * prefix)
824{
Paul Vinciguerraab055082019-06-06 14:07:55 -0400825 vat_json_object_add_uint (node, "len", prefix->len);
826 vat_json_object_add_address (node, "address", &prefix->address);
Neale Ranns097fa662018-05-01 05:17:55 -0700827}
828
Damjan Marion7cd468a2016-12-19 23:05:39 +0100829static void vl_api_create_loopback_reply_t_handler
830 (vl_api_create_loopback_reply_t * mp)
831{
832 vat_main_t *vam = &vat_main;
833 i32 retval = ntohl (mp->retval);
834
835 vam->retval = retval;
836 vam->regenerate_interface_table = 1;
837 vam->sw_if_index = ntohl (mp->sw_if_index);
838 vam->result_ready = 1;
839}
840
841static void vl_api_create_loopback_reply_t_handler_json
842 (vl_api_create_loopback_reply_t * mp)
843{
844 vat_main_t *vam = &vat_main;
845 vat_json_node_t node;
846
847 vat_json_init_object (&node);
848 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
849 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
850
851 vat_json_print (vam->ofp, &node);
852 vat_json_free (&node);
853 vam->retval = ntohl (mp->retval);
854 vam->result_ready = 1;
855}
856
Jon Loeligerc83c3b72017-02-23 13:57:35 -0600857static void vl_api_create_loopback_instance_reply_t_handler
858 (vl_api_create_loopback_instance_reply_t * mp)
859{
860 vat_main_t *vam = &vat_main;
861 i32 retval = ntohl (mp->retval);
862
863 vam->retval = retval;
864 vam->regenerate_interface_table = 1;
865 vam->sw_if_index = ntohl (mp->sw_if_index);
866 vam->result_ready = 1;
867}
868
869static void vl_api_create_loopback_instance_reply_t_handler_json
870 (vl_api_create_loopback_instance_reply_t * mp)
871{
872 vat_main_t *vam = &vat_main;
873 vat_json_node_t node;
874
875 vat_json_init_object (&node);
876 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
877 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
878
879 vat_json_print (vam->ofp, &node);
880 vat_json_free (&node);
881 vam->retval = ntohl (mp->retval);
882 vam->result_ready = 1;
883}
884
Damjan Marion7cd468a2016-12-19 23:05:39 +0100885static void vl_api_af_packet_create_reply_t_handler
886 (vl_api_af_packet_create_reply_t * mp)
887{
888 vat_main_t *vam = &vat_main;
889 i32 retval = ntohl (mp->retval);
890
891 vam->retval = retval;
892 vam->regenerate_interface_table = 1;
893 vam->sw_if_index = ntohl (mp->sw_if_index);
894 vam->result_ready = 1;
895}
896
897static void vl_api_af_packet_create_reply_t_handler_json
898 (vl_api_af_packet_create_reply_t * mp)
899{
900 vat_main_t *vam = &vat_main;
901 vat_json_node_t node;
902
903 vat_json_init_object (&node);
904 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
905 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
906
907 vat_json_print (vam->ofp, &node);
908 vat_json_free (&node);
909
910 vam->retval = ntohl (mp->retval);
911 vam->result_ready = 1;
912}
913
914static void vl_api_create_vlan_subif_reply_t_handler
915 (vl_api_create_vlan_subif_reply_t * mp)
916{
917 vat_main_t *vam = &vat_main;
918 i32 retval = ntohl (mp->retval);
919
920 vam->retval = retval;
921 vam->regenerate_interface_table = 1;
922 vam->sw_if_index = ntohl (mp->sw_if_index);
923 vam->result_ready = 1;
924}
925
926static void vl_api_create_vlan_subif_reply_t_handler_json
927 (vl_api_create_vlan_subif_reply_t * mp)
928{
929 vat_main_t *vam = &vat_main;
930 vat_json_node_t node;
931
932 vat_json_init_object (&node);
933 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
934 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
935
936 vat_json_print (vam->ofp, &node);
937 vat_json_free (&node);
938
939 vam->retval = ntohl (mp->retval);
940 vam->result_ready = 1;
941}
942
943static void vl_api_create_subif_reply_t_handler
944 (vl_api_create_subif_reply_t * mp)
945{
946 vat_main_t *vam = &vat_main;
947 i32 retval = ntohl (mp->retval);
948
949 vam->retval = retval;
950 vam->regenerate_interface_table = 1;
951 vam->sw_if_index = ntohl (mp->sw_if_index);
952 vam->result_ready = 1;
953}
954
955static void vl_api_create_subif_reply_t_handler_json
956 (vl_api_create_subif_reply_t * mp)
957{
958 vat_main_t *vam = &vat_main;
959 vat_json_node_t node;
960
961 vat_json_init_object (&node);
962 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
963 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
964
965 vat_json_print (vam->ofp, &node);
966 vat_json_free (&node);
967
968 vam->retval = ntohl (mp->retval);
969 vam->result_ready = 1;
970}
971
972static void vl_api_interface_name_renumber_reply_t_handler
973 (vl_api_interface_name_renumber_reply_t * mp)
974{
975 vat_main_t *vam = &vat_main;
976 i32 retval = ntohl (mp->retval);
977
978 vam->retval = retval;
979 vam->regenerate_interface_table = 1;
980 vam->result_ready = 1;
981}
982
983static void vl_api_interface_name_renumber_reply_t_handler_json
984 (vl_api_interface_name_renumber_reply_t * mp)
985{
986 vat_main_t *vam = &vat_main;
987 vat_json_node_t node;
988
989 vat_json_init_object (&node);
990 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
991
992 vat_json_print (vam->ofp, &node);
993 vat_json_free (&node);
994
995 vam->retval = ntohl (mp->retval);
996 vam->result_ready = 1;
997}
998
999/*
1000 * Special-case: build the interface table, maintain
1001 * the next loopback sw_if_index vbl.
1002 */
1003static void vl_api_sw_interface_details_t_handler
1004 (vl_api_sw_interface_details_t * mp)
1005{
1006 vat_main_t *vam = &vat_main;
Ole Troane5ff5a32019-08-23 22:55:18 +02001007 u8 *s = format (0, "%s%c", mp->interface_name, 0);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001008
1009 hash_set_mem (vam->sw_if_index_by_interface_name, s,
1010 ntohl (mp->sw_if_index));
1011
1012 /* In sub interface case, fill the sub interface table entry */
1013 if (mp->sw_if_index != mp->sup_sw_if_index)
1014 {
1015 sw_interface_subif_t *sub = NULL;
1016
1017 vec_add2 (vam->sw_if_subif_table, sub, 1);
1018
1019 vec_validate (sub->interface_name, strlen ((char *) s) + 1);
1020 strncpy ((char *) sub->interface_name, (char *) s,
1021 vec_len (sub->interface_name));
1022 sub->sw_if_index = ntohl (mp->sw_if_index);
1023 sub->sub_id = ntohl (mp->sub_id);
1024
Jakub Grajciar053204a2019-03-18 13:17:53 +01001025 sub->raw_flags = ntohl (mp->sub_if_flags & SUB_IF_API_FLAG_MASK_VNET);
1026
Damjan Marion7cd468a2016-12-19 23:05:39 +01001027 sub->sub_number_of_tags = mp->sub_number_of_tags;
1028 sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
1029 sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001030
1031 /* vlan tag rewrite */
1032 sub->vtr_op = ntohl (mp->vtr_op);
1033 sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
1034 sub->vtr_tag1 = ntohl (mp->vtr_tag1);
1035 sub->vtr_tag2 = ntohl (mp->vtr_tag2);
1036 }
1037}
1038
1039static void vl_api_sw_interface_details_t_handler_json
1040 (vl_api_sw_interface_details_t * mp)
1041{
1042 vat_main_t *vam = &vat_main;
1043 vat_json_node_t *node = NULL;
1044
1045 if (VAT_JSON_ARRAY != vam->json_tree.type)
1046 {
1047 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1048 vat_json_init_array (&vam->json_tree);
1049 }
1050 node = vat_json_array_add (&vam->json_tree);
1051
1052 vat_json_init_object (node);
1053 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1054 vat_json_object_add_uint (node, "sup_sw_if_index",
1055 ntohl (mp->sup_sw_if_index));
Damjan Marion7cd468a2016-12-19 23:05:39 +01001056 vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
1057 sizeof (mp->l2_address));
1058 vat_json_object_add_string_copy (node, "interface_name",
Ole Troane5ff5a32019-08-23 22:55:18 +02001059 mp->interface_name);
Mohsin Kazmide312c22019-09-27 13:44:28 +02001060 vat_json_object_add_string_copy (node, "interface_dev_type",
1061 mp->interface_dev_type);
Jakub Grajciar053204a2019-03-18 13:17:53 +01001062 vat_json_object_add_uint (node, "flags", mp->flags);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001063 vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
1064 vat_json_object_add_uint (node, "link_speed", mp->link_speed);
Damjan Marionfe7d4a22018-04-13 19:43:39 +02001065 vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
Damjan Marion7cd468a2016-12-19 23:05:39 +01001066 vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
Damjan Marion7cd468a2016-12-19 23:05:39 +01001067 vat_json_object_add_uint (node, "sub_number_of_tags",
1068 mp->sub_number_of_tags);
1069 vat_json_object_add_uint (node, "sub_outer_vlan_id",
1070 ntohs (mp->sub_outer_vlan_id));
1071 vat_json_object_add_uint (node, "sub_inner_vlan_id",
1072 ntohs (mp->sub_inner_vlan_id));
Jakub Grajciar053204a2019-03-18 13:17:53 +01001073 vat_json_object_add_uint (node, "sub_if_flags", ntohl (mp->sub_if_flags));
Damjan Marion7cd468a2016-12-19 23:05:39 +01001074 vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1075 vat_json_object_add_uint (node, "vtr_push_dot1q",
1076 ntohl (mp->vtr_push_dot1q));
1077 vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1078 vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
Jakub Grajciar053204a2019-03-18 13:17:53 +01001079 if (ntohl (mp->sub_if_flags) & SUB_IF_API_FLAG_DOT1AH)
Pavel Kotucek65e84572017-01-16 17:01:56 +01001080 {
1081 vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1082 format (0, "%U",
1083 format_ethernet_address,
1084 &mp->b_dmac));
1085 vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1086 format (0, "%U",
1087 format_ethernet_address,
1088 &mp->b_smac));
1089 vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1090 vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1091 }
Damjan Marion7cd468a2016-12-19 23:05:39 +01001092}
1093
Dave Baracha1a093d2017-03-02 13:13:23 -05001094#if VPP_API_TEST_BUILTIN == 0
Neale Rannsa07bd702017-08-07 07:53:49 -07001095static void vl_api_sw_interface_event_t_handler
1096 (vl_api_sw_interface_event_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01001097{
1098 vat_main_t *vam = &vat_main;
1099 if (vam->interface_event_display)
1100 errmsg ("interface flags: sw_if_index %d %s %s",
1101 ntohl (mp->sw_if_index),
Jakub Grajciar053204a2019-03-18 13:17:53 +01001102 ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_ADMIN_UP) ?
1103 "admin-up" : "admin-down",
1104 ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_LINK_UP) ?
1105 "link-up" : "link-down");
Damjan Marion7cd468a2016-12-19 23:05:39 +01001106}
Dave Baracha1a093d2017-03-02 13:13:23 -05001107#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +01001108
Benoît Ganne49ee6842019-04-30 11:50:46 +02001109__clib_unused static void
1110vl_api_sw_interface_event_t_handler_json (vl_api_sw_interface_event_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01001111{
1112 /* JSON output not supported */
1113}
1114
1115static void
1116vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1117{
1118 vat_main_t *vam = &vat_main;
1119 i32 retval = ntohl (mp->retval);
1120
1121 vam->retval = retval;
Damjan Marion7bee80c2017-04-26 15:32:12 +02001122 vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001123 vam->result_ready = 1;
1124}
1125
1126static void
1127vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1128{
1129 vat_main_t *vam = &vat_main;
1130 vat_json_node_t node;
Damjan Marion7cd468a2016-12-19 23:05:39 +01001131 void *oldheap;
1132 u8 *reply;
1133
1134 vat_json_init_object (&node);
1135 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1136 vat_json_object_add_uint (&node, "reply_in_shmem",
1137 ntohl (mp->reply_in_shmem));
1138 /* Toss the shared-memory original... */
Nathan Skrzypczak0aa40132019-11-25 16:29:38 +01001139 oldheap = vl_msg_push_heap ();
Damjan Marion7cd468a2016-12-19 23:05:39 +01001140
Damjan Marion7bee80c2017-04-26 15:32:12 +02001141 reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001142 vec_free (reply);
1143
Nathan Skrzypczak0aa40132019-11-25 16:29:38 +01001144 vl_msg_pop_heap (oldheap);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001145
1146 vat_json_print (vam->ofp, &node);
1147 vat_json_free (&node);
1148
1149 vam->retval = ntohl (mp->retval);
1150 vam->result_ready = 1;
1151}
1152
1153static void
1154vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1155{
1156 vat_main_t *vam = &vat_main;
1157 i32 retval = ntohl (mp->retval);
Dave Barach59b25652017-09-10 15:04:27 -04001158
1159 vec_reset_length (vam->cmd_reply);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001160
1161 vam->retval = retval;
Dave Barach59b25652017-09-10 15:04:27 -04001162 if (retval == 0)
Dave Barach77841402020-04-29 17:04:10 -04001163 vam->cmd_reply = vl_api_from_api_to_new_vec (mp, &mp->reply);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001164 vam->result_ready = 1;
1165}
1166
1167static void
1168vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1169{
1170 vat_main_t *vam = &vat_main;
1171 vat_json_node_t node;
Jakub Grajciar2dbee932020-02-07 11:30:26 +01001172 u8 *reply = 0; /* reply vector */
Damjan Marion7cd468a2016-12-19 23:05:39 +01001173
Dave Barach77841402020-04-29 17:04:10 -04001174 reply = vl_api_from_api_to_new_vec (mp, &mp->reply);
Dave Barach59b25652017-09-10 15:04:27 -04001175 vec_reset_length (vam->cmd_reply);
1176
Damjan Marion7cd468a2016-12-19 23:05:39 +01001177 vat_json_init_object (&node);
1178 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
Jakub Grajciar2dbee932020-02-07 11:30:26 +01001179 vat_json_object_add_string_copy (&node, "reply", reply);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001180
1181 vat_json_print (vam->ofp, &node);
1182 vat_json_free (&node);
Jakub Grajciar2dbee932020-02-07 11:30:26 +01001183 vec_free (reply);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001184
1185 vam->retval = ntohl (mp->retval);
1186 vam->result_ready = 1;
1187}
1188
1189static void vl_api_classify_add_del_table_reply_t_handler
1190 (vl_api_classify_add_del_table_reply_t * mp)
1191{
1192 vat_main_t *vam = &vat_main;
1193 i32 retval = ntohl (mp->retval);
1194 if (vam->async_mode)
1195 {
1196 vam->async_errors += (retval < 0);
1197 }
1198 else
1199 {
1200 vam->retval = retval;
1201 if (retval == 0 &&
1202 ((mp->new_table_index != 0xFFFFFFFF) ||
1203 (mp->skip_n_vectors != 0xFFFFFFFF) ||
1204 (mp->match_n_vectors != 0xFFFFFFFF)))
1205 /*
1206 * Note: this is just barely thread-safe, depends on
1207 * the main thread spinning waiting for an answer...
1208 */
1209 errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1210 ntohl (mp->new_table_index),
1211 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1212 vam->result_ready = 1;
1213 }
1214}
1215
1216static void vl_api_classify_add_del_table_reply_t_handler_json
1217 (vl_api_classify_add_del_table_reply_t * mp)
1218{
1219 vat_main_t *vam = &vat_main;
1220 vat_json_node_t node;
1221
1222 vat_json_init_object (&node);
1223 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1224 vat_json_object_add_uint (&node, "new_table_index",
1225 ntohl (mp->new_table_index));
1226 vat_json_object_add_uint (&node, "skip_n_vectors",
1227 ntohl (mp->skip_n_vectors));
1228 vat_json_object_add_uint (&node, "match_n_vectors",
1229 ntohl (mp->match_n_vectors));
1230
1231 vat_json_print (vam->ofp, &node);
1232 vat_json_free (&node);
1233
1234 vam->retval = ntohl (mp->retval);
1235 vam->result_ready = 1;
1236}
1237
1238static void vl_api_get_node_index_reply_t_handler
1239 (vl_api_get_node_index_reply_t * mp)
1240{
1241 vat_main_t *vam = &vat_main;
1242 i32 retval = ntohl (mp->retval);
1243 if (vam->async_mode)
1244 {
1245 vam->async_errors += (retval < 0);
1246 }
1247 else
1248 {
1249 vam->retval = retval;
1250 if (retval == 0)
1251 errmsg ("node index %d", ntohl (mp->node_index));
1252 vam->result_ready = 1;
1253 }
1254}
1255
1256static void vl_api_get_node_index_reply_t_handler_json
1257 (vl_api_get_node_index_reply_t * mp)
1258{
1259 vat_main_t *vam = &vat_main;
1260 vat_json_node_t node;
1261
1262 vat_json_init_object (&node);
1263 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1264 vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1265
1266 vat_json_print (vam->ofp, &node);
1267 vat_json_free (&node);
1268
1269 vam->retval = ntohl (mp->retval);
1270 vam->result_ready = 1;
1271}
1272
1273static void vl_api_get_next_index_reply_t_handler
1274 (vl_api_get_next_index_reply_t * mp)
1275{
1276 vat_main_t *vam = &vat_main;
1277 i32 retval = ntohl (mp->retval);
1278 if (vam->async_mode)
1279 {
1280 vam->async_errors += (retval < 0);
1281 }
1282 else
1283 {
1284 vam->retval = retval;
1285 if (retval == 0)
1286 errmsg ("next node index %d", ntohl (mp->next_index));
1287 vam->result_ready = 1;
1288 }
1289}
1290
1291static void vl_api_get_next_index_reply_t_handler_json
1292 (vl_api_get_next_index_reply_t * mp)
1293{
1294 vat_main_t *vam = &vat_main;
1295 vat_json_node_t node;
1296
1297 vat_json_init_object (&node);
1298 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1299 vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1300
1301 vat_json_print (vam->ofp, &node);
1302 vat_json_free (&node);
1303
1304 vam->retval = ntohl (mp->retval);
1305 vam->result_ready = 1;
1306}
1307
1308static void vl_api_add_node_next_reply_t_handler
1309 (vl_api_add_node_next_reply_t * mp)
1310{
1311 vat_main_t *vam = &vat_main;
1312 i32 retval = ntohl (mp->retval);
1313 if (vam->async_mode)
1314 {
1315 vam->async_errors += (retval < 0);
1316 }
1317 else
1318 {
1319 vam->retval = retval;
1320 if (retval == 0)
1321 errmsg ("next index %d", ntohl (mp->next_index));
1322 vam->result_ready = 1;
1323 }
1324}
1325
1326static void vl_api_add_node_next_reply_t_handler_json
1327 (vl_api_add_node_next_reply_t * mp)
1328{
1329 vat_main_t *vam = &vat_main;
1330 vat_json_node_t node;
1331
1332 vat_json_init_object (&node);
1333 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1334 vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1335
1336 vat_json_print (vam->ofp, &node);
1337 vat_json_free (&node);
1338
1339 vam->retval = ntohl (mp->retval);
1340 vam->result_ready = 1;
1341}
1342
1343static void vl_api_show_version_reply_t_handler
1344 (vl_api_show_version_reply_t * mp)
1345{
1346 vat_main_t *vam = &vat_main;
1347 i32 retval = ntohl (mp->retval);
1348
1349 if (retval >= 0)
1350 {
Ole Troane5ff5a32019-08-23 22:55:18 +02001351 errmsg (" program: %s", mp->program);
1352 errmsg (" version: %s", mp->version);
1353 errmsg (" build date: %s", mp->build_date);
1354 errmsg ("build directory: %s", mp->build_directory);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001355 }
1356 vam->retval = retval;
1357 vam->result_ready = 1;
1358}
1359
1360static void vl_api_show_version_reply_t_handler_json
1361 (vl_api_show_version_reply_t * mp)
1362{
1363 vat_main_t *vam = &vat_main;
1364 vat_json_node_t node;
1365
1366 vat_json_init_object (&node);
1367 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
Ole Troane5ff5a32019-08-23 22:55:18 +02001368 vat_json_object_add_string_copy (&node, "program", mp->program);
1369 vat_json_object_add_string_copy (&node, "version", mp->version);
1370 vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001371 vat_json_object_add_string_copy (&node, "build_directory",
Ole Troane5ff5a32019-08-23 22:55:18 +02001372 mp->build_directory);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001373
1374 vat_json_print (vam->ofp, &node);
1375 vat_json_free (&node);
1376
1377 vam->retval = ntohl (mp->retval);
1378 vam->result_ready = 1;
1379}
1380
Mohsin Kazmi5d64c782018-09-11 20:27:09 +02001381static void vl_api_show_threads_reply_t_handler
1382 (vl_api_show_threads_reply_t * mp)
1383{
1384 vat_main_t *vam = &vat_main;
1385 i32 retval = ntohl (mp->retval);
1386 int i, count = 0;
1387
1388 if (retval >= 0)
1389 count = ntohl (mp->count);
1390
1391 for (i = 0; i < count; i++)
1392 print (vam->ofp,
1393 "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1394 ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1395 mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1396 ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1397 ntohl (mp->thread_data[i].cpu_socket));
1398
1399 vam->retval = retval;
1400 vam->result_ready = 1;
1401}
1402
1403static void vl_api_show_threads_reply_t_handler_json
1404 (vl_api_show_threads_reply_t * mp)
1405{
1406 vat_main_t *vam = &vat_main;
1407 vat_json_node_t node;
1408 vl_api_thread_data_t *td;
Mohsin Kazmi5df628b2018-10-01 17:41:08 +02001409 i32 retval = ntohl (mp->retval);
1410 int i, count = 0;
1411
1412 if (retval >= 0)
1413 count = ntohl (mp->count);
Mohsin Kazmi5d64c782018-09-11 20:27:09 +02001414
1415 vat_json_init_object (&node);
Mohsin Kazmi5df628b2018-10-01 17:41:08 +02001416 vat_json_object_add_int (&node, "retval", retval);
Mohsin Kazmi5d64c782018-09-11 20:27:09 +02001417 vat_json_object_add_uint (&node, "count", count);
1418
1419 for (i = 0; i < count; i++)
1420 {
1421 td = &mp->thread_data[i];
1422 vat_json_object_add_uint (&node, "id", ntohl (td->id));
1423 vat_json_object_add_string_copy (&node, "name", td->name);
1424 vat_json_object_add_string_copy (&node, "type", td->type);
1425 vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1426 vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1427 vat_json_object_add_int (&node, "core", ntohl (td->id));
1428 vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1429 }
1430
1431 vat_json_print (vam->ofp, &node);
1432 vat_json_free (&node);
1433
Mohsin Kazmi5df628b2018-10-01 17:41:08 +02001434 vam->retval = retval;
Mohsin Kazmi5d64c782018-09-11 20:27:09 +02001435 vam->result_ready = 1;
1436}
1437
1438static int
1439api_show_threads (vat_main_t * vam)
1440{
1441 vl_api_show_threads_t *mp;
1442 int ret;
1443
1444 print (vam->ofp,
1445 "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1446 "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1447
1448 M (SHOW_THREADS, mp);
1449
1450 S (mp);
1451 W (ret);
1452 return ret;
1453}
1454
Damjan Marion7cd468a2016-12-19 23:05:39 +01001455static void
John Lo8d00fff2017-08-03 00:35:36 -04001456vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1457{
1458 u32 n_macs = ntohl (mp->n_macs);
Paul Vinciguerraec11b132018-09-24 05:25:00 -07001459 errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
John Lo8d00fff2017-08-03 00:35:36 -04001460 ntohl (mp->pid), mp->client_index, n_macs);
1461 int i;
1462 for (i = 0; i < n_macs; i++)
1463 {
1464 vl_api_mac_entry_t *mac = &mp->mac[i];
John Loe23c99e2018-03-13 21:53:18 -04001465 errmsg (" [%d] sw_if_index %d mac_addr %U action %d \n",
John Lo8d00fff2017-08-03 00:35:36 -04001466 i + 1, ntohl (mac->sw_if_index),
John Loe23c99e2018-03-13 21:53:18 -04001467 format_ethernet_address, mac->mac_addr, mac->action);
John Lo8d00fff2017-08-03 00:35:36 -04001468 if (i == 1000)
1469 break;
1470 }
1471}
1472
1473static void
1474vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1475{
1476 /* JSON output not supported */
1477}
1478
Ole Troan01384fe2017-05-12 11:55:35 +02001479#define vl_api_bridge_domain_details_t_endian vl_noop_handler
1480#define vl_api_bridge_domain_details_t_print vl_noop_handler
1481
Damjan Marion7cd468a2016-12-19 23:05:39 +01001482/*
1483 * Special-case: build the bridge domain table, maintain
1484 * the next bd id vbl.
1485 */
1486static void vl_api_bridge_domain_details_t_handler
1487 (vl_api_bridge_domain_details_t * mp)
1488{
1489 vat_main_t *vam = &vat_main;
1490 u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
Ole Troan01384fe2017-05-12 11:55:35 +02001491 int i;
Damjan Marion7cd468a2016-12-19 23:05:39 +01001492
Mohsin Kazmi762d83c2018-09-27 15:00:32 +02001493 print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1494 " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
Damjan Marion7cd468a2016-12-19 23:05:39 +01001495
Mohsin Kazmi762d83c2018-09-27 15:00:32 +02001496 print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
Damjan Marion7cd468a2016-12-19 23:05:39 +01001497 ntohl (mp->bd_id), mp->learn, mp->forward,
Mohsin Kazmi762d83c2018-09-27 15:00:32 +02001498 mp->flood, ntohl (mp->bvi_sw_if_index),
1499 ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001500
1501 if (n_sw_ifs)
Ole Troan01384fe2017-05-12 11:55:35 +02001502 {
1503 vl_api_bridge_domain_sw_if_t *sw_ifs;
1504 print (vam->ofp, "\n\n%s %s %s", "sw_if_index", "SHG",
1505 "Interface Name");
1506
1507 sw_ifs = mp->sw_if_details;
1508 for (i = 0; i < n_sw_ifs; i++)
1509 {
1510 u8 *sw_if_name = 0;
1511 u32 sw_if_index;
1512 hash_pair_t *p;
1513
1514 sw_if_index = ntohl (sw_ifs->sw_if_index);
1515
1516 /* *INDENT-OFF* */
1517 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1518 ({
1519 if ((u32) p->value[0] == sw_if_index)
1520 {
1521 sw_if_name = (u8 *)(p->key);
1522 break;
1523 }
1524 }));
1525 /* *INDENT-ON* */
1526 print (vam->ofp, "%7d %3d %s", sw_if_index,
1527 sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1528 "sw_if_index not found!");
1529
1530 sw_ifs++;
1531 }
1532 }
Damjan Marion7cd468a2016-12-19 23:05:39 +01001533}
1534
1535static void vl_api_bridge_domain_details_t_handler_json
1536 (vl_api_bridge_domain_details_t * mp)
1537{
1538 vat_main_t *vam = &vat_main;
1539 vat_json_node_t *node, *array = NULL;
Ole Troan01384fe2017-05-12 11:55:35 +02001540 u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001541
1542 if (VAT_JSON_ARRAY != vam->json_tree.type)
1543 {
1544 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1545 vat_json_init_array (&vam->json_tree);
1546 }
1547 node = vat_json_array_add (&vam->json_tree);
1548
1549 vat_json_init_object (node);
1550 vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1551 vat_json_object_add_uint (node, "flood", mp->flood);
1552 vat_json_object_add_uint (node, "forward", mp->forward);
1553 vat_json_object_add_uint (node, "learn", mp->learn);
1554 vat_json_object_add_uint (node, "bvi_sw_if_index",
1555 ntohl (mp->bvi_sw_if_index));
Ole Troan01384fe2017-05-12 11:55:35 +02001556 vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001557 array = vat_json_object_add (node, "sw_if");
1558 vat_json_init_array (array);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001559
Damjan Marion7cd468a2016-12-19 23:05:39 +01001560
Damjan Marion7cd468a2016-12-19 23:05:39 +01001561
Ole Troan01384fe2017-05-12 11:55:35 +02001562 if (n_sw_ifs)
1563 {
1564 vl_api_bridge_domain_sw_if_t *sw_ifs;
1565 int i;
Damjan Marion7cd468a2016-12-19 23:05:39 +01001566
Ole Troan01384fe2017-05-12 11:55:35 +02001567 sw_ifs = mp->sw_if_details;
1568 for (i = 0; i < n_sw_ifs; i++)
1569 {
1570 node = vat_json_array_add (array);
1571 vat_json_init_object (node);
1572 vat_json_object_add_uint (node, "sw_if_index",
1573 ntohl (sw_ifs->sw_if_index));
1574 vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1575 sw_ifs++;
1576 }
1577 }
Damjan Marion7cd468a2016-12-19 23:05:39 +01001578}
1579
1580static void vl_api_control_ping_reply_t_handler
1581 (vl_api_control_ping_reply_t * mp)
1582{
1583 vat_main_t *vam = &vat_main;
1584 i32 retval = ntohl (mp->retval);
1585 if (vam->async_mode)
1586 {
1587 vam->async_errors += (retval < 0);
1588 }
1589 else
1590 {
1591 vam->retval = retval;
1592 vam->result_ready = 1;
1593 }
Florin Coras90a63982017-12-19 04:50:01 -08001594 if (vam->socket_client_main)
1595 vam->socket_client_main->control_pings_outstanding--;
Damjan Marion7cd468a2016-12-19 23:05:39 +01001596}
1597
1598static void vl_api_control_ping_reply_t_handler_json
1599 (vl_api_control_ping_reply_t * mp)
1600{
1601 vat_main_t *vam = &vat_main;
1602 i32 retval = ntohl (mp->retval);
1603
1604 if (VAT_JSON_NONE != vam->json_tree.type)
1605 {
1606 vat_json_print (vam->ofp, &vam->json_tree);
1607 vat_json_free (&vam->json_tree);
1608 vam->json_tree.type = VAT_JSON_NONE;
1609 }
1610 else
1611 {
1612 /* just print [] */
1613 vat_json_init_array (&vam->json_tree);
1614 vat_json_print (vam->ofp, &vam->json_tree);
1615 vam->json_tree.type = VAT_JSON_NONE;
1616 }
1617
1618 vam->retval = retval;
1619 vam->result_ready = 1;
1620}
1621
1622static void
Eyal Barifead6702017-04-04 04:46:32 +03001623 vl_api_bridge_domain_set_mac_age_reply_t_handler
1624 (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1625{
1626 vat_main_t *vam = &vat_main;
1627 i32 retval = ntohl (mp->retval);
1628 if (vam->async_mode)
1629 {
1630 vam->async_errors += (retval < 0);
1631 }
1632 else
1633 {
1634 vam->retval = retval;
1635 vam->result_ready = 1;
1636 }
1637}
1638
1639static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1640 (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1641{
1642 vat_main_t *vam = &vat_main;
1643 vat_json_node_t node;
1644
1645 vat_json_init_object (&node);
1646 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1647
1648 vat_json_print (vam->ofp, &node);
1649 vat_json_free (&node);
1650
1651 vam->retval = ntohl (mp->retval);
1652 vam->result_ready = 1;
1653}
1654
1655static void
Damjan Marion7cd468a2016-12-19 23:05:39 +01001656vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1657{
1658 vat_main_t *vam = &vat_main;
1659 i32 retval = ntohl (mp->retval);
1660 if (vam->async_mode)
1661 {
1662 vam->async_errors += (retval < 0);
1663 }
1664 else
1665 {
1666 vam->retval = retval;
1667 vam->result_ready = 1;
1668 }
1669}
1670
1671static void vl_api_l2_flags_reply_t_handler_json
1672 (vl_api_l2_flags_reply_t * mp)
1673{
1674 vat_main_t *vam = &vat_main;
1675 vat_json_node_t node;
1676
1677 vat_json_init_object (&node);
1678 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1679 vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1680 ntohl (mp->resulting_feature_bitmap));
1681
1682 vat_json_print (vam->ofp, &node);
1683 vat_json_free (&node);
1684
1685 vam->retval = ntohl (mp->retval);
1686 vam->result_ready = 1;
1687}
1688
1689static void vl_api_bridge_flags_reply_t_handler
1690 (vl_api_bridge_flags_reply_t * mp)
1691{
1692 vat_main_t *vam = &vat_main;
1693 i32 retval = ntohl (mp->retval);
1694 if (vam->async_mode)
1695 {
1696 vam->async_errors += (retval < 0);
1697 }
1698 else
1699 {
1700 vam->retval = retval;
1701 vam->result_ready = 1;
1702 }
1703}
1704
1705static void vl_api_bridge_flags_reply_t_handler_json
1706 (vl_api_bridge_flags_reply_t * mp)
1707{
1708 vat_main_t *vam = &vat_main;
1709 vat_json_node_t node;
1710
1711 vat_json_init_object (&node);
1712 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1713 vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1714 ntohl (mp->resulting_feature_bitmap));
1715
1716 vat_json_print (vam->ofp, &node);
1717 vat_json_free (&node);
1718
1719 vam->retval = ntohl (mp->retval);
1720 vam->result_ready = 1;
1721}
1722
Damjan Marion8389fb92017-10-13 18:29:53 +02001723static void
1724vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1725{
1726 vat_main_t *vam = &vat_main;
1727 i32 retval = ntohl (mp->retval);
1728 if (vam->async_mode)
1729 {
1730 vam->async_errors += (retval < 0);
1731 }
1732 else
1733 {
1734 vam->retval = retval;
1735 vam->sw_if_index = ntohl (mp->sw_if_index);
1736 vam->result_ready = 1;
1737 }
1738
1739}
1740
1741static void vl_api_tap_create_v2_reply_t_handler_json
1742 (vl_api_tap_create_v2_reply_t * mp)
1743{
1744 vat_main_t *vam = &vat_main;
1745 vat_json_node_t node;
1746
1747 vat_json_init_object (&node);
1748 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1749 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1750
1751 vat_json_print (vam->ofp, &node);
1752 vat_json_free (&node);
1753
1754 vam->retval = ntohl (mp->retval);
1755 vam->result_ready = 1;
1756
1757}
1758
1759static void
1760vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1761{
1762 vat_main_t *vam = &vat_main;
1763 i32 retval = ntohl (mp->retval);
1764 if (vam->async_mode)
1765 {
1766 vam->async_errors += (retval < 0);
1767 }
1768 else
1769 {
1770 vam->retval = retval;
1771 vam->result_ready = 1;
1772 }
1773}
1774
1775static void vl_api_tap_delete_v2_reply_t_handler_json
1776 (vl_api_tap_delete_v2_reply_t * mp)
1777{
1778 vat_main_t *vam = &vat_main;
1779 vat_json_node_t node;
1780
1781 vat_json_init_object (&node);
1782 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1783
1784 vat_json_print (vam->ofp, &node);
1785 vat_json_free (&node);
1786
1787 vam->retval = ntohl (mp->retval);
1788 vam->result_ready = 1;
1789}
1790
Steven9cd2d7a2017-12-20 12:43:01 -08001791static void
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01001792vl_api_virtio_pci_create_reply_t_handler (vl_api_virtio_pci_create_reply_t *
1793 mp)
1794{
1795 vat_main_t *vam = &vat_main;
1796 i32 retval = ntohl (mp->retval);
1797 if (vam->async_mode)
1798 {
1799 vam->async_errors += (retval < 0);
1800 }
1801 else
1802 {
1803 vam->retval = retval;
1804 vam->sw_if_index = ntohl (mp->sw_if_index);
1805 vam->result_ready = 1;
1806 }
1807}
1808
1809static void vl_api_virtio_pci_create_reply_t_handler_json
1810 (vl_api_virtio_pci_create_reply_t * mp)
1811{
1812 vat_main_t *vam = &vat_main;
1813 vat_json_node_t node;
1814
1815 vat_json_init_object (&node);
1816 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1817 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1818
1819 vat_json_print (vam->ofp, &node);
1820 vat_json_free (&node);
1821
1822 vam->retval = ntohl (mp->retval);
1823 vam->result_ready = 1;
1824
1825}
1826
1827static void
Mohsin Kazmi518251b2020-09-01 17:17:44 +00001828 vl_api_virtio_pci_create_v2_reply_t_handler
1829 (vl_api_virtio_pci_create_v2_reply_t * mp)
1830{
1831 vat_main_t *vam = &vat_main;
1832 i32 retval = ntohl (mp->retval);
1833 if (vam->async_mode)
1834 {
1835 vam->async_errors += (retval < 0);
1836 }
1837 else
1838 {
1839 vam->retval = retval;
1840 vam->sw_if_index = ntohl (mp->sw_if_index);
1841 vam->result_ready = 1;
1842 }
1843}
1844
1845static void vl_api_virtio_pci_create_v2_reply_t_handler_json
1846 (vl_api_virtio_pci_create_v2_reply_t * mp)
1847{
1848 vat_main_t *vam = &vat_main;
1849 vat_json_node_t node;
1850
1851 vat_json_init_object (&node);
1852 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1853 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1854
1855 vat_json_print (vam->ofp, &node);
1856 vat_json_free (&node);
1857
1858 vam->retval = ntohl (mp->retval);
1859 vam->result_ready = 1;
1860}
1861
1862static void
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01001863vl_api_virtio_pci_delete_reply_t_handler (vl_api_virtio_pci_delete_reply_t *
1864 mp)
1865{
1866 vat_main_t *vam = &vat_main;
1867 i32 retval = ntohl (mp->retval);
1868 if (vam->async_mode)
1869 {
1870 vam->async_errors += (retval < 0);
1871 }
1872 else
1873 {
1874 vam->retval = retval;
1875 vam->result_ready = 1;
1876 }
1877}
1878
1879static void vl_api_virtio_pci_delete_reply_t_handler_json
1880 (vl_api_virtio_pci_delete_reply_t * mp)
1881{
1882 vat_main_t *vam = &vat_main;
1883 vat_json_node_t node;
1884
1885 vat_json_init_object (&node);
1886 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1887
1888 vat_json_print (vam->ofp, &node);
1889 vat_json_free (&node);
1890
1891 vam->retval = ntohl (mp->retval);
1892 vam->result_ready = 1;
1893}
1894
1895static void
Steven9cd2d7a2017-12-20 12:43:01 -08001896vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1897{
1898 vat_main_t *vam = &vat_main;
1899 i32 retval = ntohl (mp->retval);
1900
1901 if (vam->async_mode)
1902 {
1903 vam->async_errors += (retval < 0);
1904 }
1905 else
1906 {
1907 vam->retval = retval;
1908 vam->sw_if_index = ntohl (mp->sw_if_index);
1909 vam->result_ready = 1;
1910 }
1911}
1912
1913static void vl_api_bond_create_reply_t_handler_json
1914 (vl_api_bond_create_reply_t * mp)
1915{
1916 vat_main_t *vam = &vat_main;
1917 vat_json_node_t node;
1918
1919 vat_json_init_object (&node);
1920 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1921 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1922
1923 vat_json_print (vam->ofp, &node);
1924 vat_json_free (&node);
1925
1926 vam->retval = ntohl (mp->retval);
1927 vam->result_ready = 1;
1928}
1929
1930static void
Steven Luongea717862020-07-30 07:31:40 -07001931vl_api_bond_create2_reply_t_handler (vl_api_bond_create2_reply_t * mp)
1932{
1933 vat_main_t *vam = &vat_main;
1934 i32 retval = ntohl (mp->retval);
1935
1936 if (vam->async_mode)
1937 {
1938 vam->async_errors += (retval < 0);
1939 }
1940 else
1941 {
1942 vam->retval = retval;
1943 vam->sw_if_index = ntohl (mp->sw_if_index);
1944 vam->result_ready = 1;
1945 }
1946}
1947
1948static void vl_api_bond_create2_reply_t_handler_json
1949 (vl_api_bond_create2_reply_t * mp)
1950{
1951 vat_main_t *vam = &vat_main;
1952 vat_json_node_t node;
1953
1954 vat_json_init_object (&node);
1955 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1956 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1957
1958 vat_json_print (vam->ofp, &node);
1959 vat_json_free (&node);
1960
1961 vam->retval = ntohl (mp->retval);
1962 vam->result_ready = 1;
1963}
1964
1965static void
Steven9cd2d7a2017-12-20 12:43:01 -08001966vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1967{
1968 vat_main_t *vam = &vat_main;
1969 i32 retval = ntohl (mp->retval);
1970
1971 if (vam->async_mode)
1972 {
1973 vam->async_errors += (retval < 0);
1974 }
1975 else
1976 {
1977 vam->retval = retval;
1978 vam->result_ready = 1;
1979 }
1980}
1981
1982static void vl_api_bond_delete_reply_t_handler_json
1983 (vl_api_bond_delete_reply_t * mp)
1984{
1985 vat_main_t *vam = &vat_main;
1986 vat_json_node_t node;
1987
1988 vat_json_init_object (&node);
1989 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1990
1991 vat_json_print (vam->ofp, &node);
1992 vat_json_free (&node);
1993
1994 vam->retval = ntohl (mp->retval);
1995 vam->result_ready = 1;
1996}
1997
1998static void
Steven Luong4c4223e2020-07-15 08:44:54 -07001999vl_api_bond_add_member_reply_t_handler (vl_api_bond_add_member_reply_t * mp)
Steven9cd2d7a2017-12-20 12:43:01 -08002000{
2001 vat_main_t *vam = &vat_main;
2002 i32 retval = ntohl (mp->retval);
2003
2004 if (vam->async_mode)
2005 {
2006 vam->async_errors += (retval < 0);
2007 }
2008 else
2009 {
2010 vam->retval = retval;
2011 vam->result_ready = 1;
2012 }
2013}
2014
Steven Luong4c4223e2020-07-15 08:44:54 -07002015static void vl_api_bond_add_member_reply_t_handler_json
2016 (vl_api_bond_add_member_reply_t * mp)
Steven9cd2d7a2017-12-20 12:43:01 -08002017{
2018 vat_main_t *vam = &vat_main;
2019 vat_json_node_t node;
2020
2021 vat_json_init_object (&node);
2022 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2023
2024 vat_json_print (vam->ofp, &node);
2025 vat_json_free (&node);
2026
2027 vam->retval = ntohl (mp->retval);
2028 vam->result_ready = 1;
2029}
2030
2031static void
Steven Luong4c4223e2020-07-15 08:44:54 -07002032vl_api_bond_detach_member_reply_t_handler (vl_api_bond_detach_member_reply_t *
2033 mp)
Steven9cd2d7a2017-12-20 12:43:01 -08002034{
2035 vat_main_t *vam = &vat_main;
2036 i32 retval = ntohl (mp->retval);
2037
2038 if (vam->async_mode)
2039 {
2040 vam->async_errors += (retval < 0);
2041 }
2042 else
2043 {
2044 vam->retval = retval;
2045 vam->result_ready = 1;
2046 }
2047}
2048
Steven Luong4c4223e2020-07-15 08:44:54 -07002049static void vl_api_bond_detach_member_reply_t_handler_json
2050 (vl_api_bond_detach_member_reply_t * mp)
Steven9cd2d7a2017-12-20 12:43:01 -08002051{
2052 vat_main_t *vam = &vat_main;
2053 vat_json_node_t node;
2054
2055 vat_json_init_object (&node);
2056 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2057
2058 vat_json_print (vam->ofp, &node);
2059 vat_json_free (&node);
2060
2061 vam->retval = ntohl (mp->retval);
2062 vam->result_ready = 1;
2063}
2064
Steven Luonga1876b82019-08-20 16:58:00 -07002065static int
2066api_sw_interface_set_bond_weight (vat_main_t * vam)
2067{
2068 unformat_input_t *i = vam->input;
2069 vl_api_sw_interface_set_bond_weight_t *mp;
2070 u32 sw_if_index = ~0;
2071 u32 weight = 0;
2072 u8 weight_enter = 0;
2073 int ret;
2074
2075 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2076 {
2077 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2078 ;
2079 else if (unformat (i, "sw_if_index %d", &sw_if_index))
2080 ;
2081 else if (unformat (i, "weight %u", &weight))
2082 weight_enter = 1;
2083 else
2084 break;
2085 }
2086
2087 if (sw_if_index == ~0)
2088 {
2089 errmsg ("missing interface name or sw_if_index");
2090 return -99;
2091 }
2092 if (weight_enter == 0)
2093 {
2094 errmsg ("missing valid weight");
2095 return -99;
2096 }
2097
2098 /* Construct the API message */
2099 M (SW_INTERFACE_SET_BOND_WEIGHT, mp);
2100 mp->sw_if_index = ntohl (sw_if_index);
2101 mp->weight = ntohl (weight);
2102
2103 S (mp);
2104 W (ret);
2105 return ret;
2106}
2107
Steven Luong4c4223e2020-07-15 08:44:54 -07002108static void vl_api_sw_bond_interface_details_t_handler
2109 (vl_api_sw_bond_interface_details_t * mp)
Steven9cd2d7a2017-12-20 12:43:01 -08002110{
2111 vat_main_t *vam = &vat_main;
2112
2113 print (vam->ofp,
2114 "%-16s %-12d %-12U %-13U %-14u %-14u",
2115 mp->interface_name, ntohl (mp->sw_if_index),
Jakub Grajciar3d1ef872019-08-26 12:55:15 +02002116 format_bond_mode, ntohl (mp->mode), format_bond_load_balance,
Steven Luong4c4223e2020-07-15 08:44:54 -07002117 ntohl (mp->lb), ntohl (mp->active_members), ntohl (mp->members));
Steven9cd2d7a2017-12-20 12:43:01 -08002118}
2119
Steven Luong4c4223e2020-07-15 08:44:54 -07002120static void vl_api_sw_bond_interface_details_t_handler_json
2121 (vl_api_sw_bond_interface_details_t * mp)
Steven9cd2d7a2017-12-20 12:43:01 -08002122{
2123 vat_main_t *vam = &vat_main;
2124 vat_json_node_t *node = NULL;
2125
2126 if (VAT_JSON_ARRAY != vam->json_tree.type)
2127 {
2128 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2129 vat_json_init_array (&vam->json_tree);
2130 }
2131 node = vat_json_array_add (&vam->json_tree);
2132
2133 vat_json_init_object (node);
2134 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2135 vat_json_object_add_string_copy (node, "interface_name",
2136 mp->interface_name);
Jakub Grajciar3d1ef872019-08-26 12:55:15 +02002137 vat_json_object_add_uint (node, "mode", ntohl (mp->mode));
2138 vat_json_object_add_uint (node, "load_balance", ntohl (mp->lb));
Steven Luong4c4223e2020-07-15 08:44:54 -07002139 vat_json_object_add_uint (node, "active_members",
2140 ntohl (mp->active_members));
2141 vat_json_object_add_uint (node, "members", ntohl (mp->members));
Steven9cd2d7a2017-12-20 12:43:01 -08002142}
2143
2144static int
Steven Luong4c4223e2020-07-15 08:44:54 -07002145api_sw_bond_interface_dump (vat_main_t * vam)
Steven9cd2d7a2017-12-20 12:43:01 -08002146{
Steven Luong4c4223e2020-07-15 08:44:54 -07002147 unformat_input_t *i = vam->input;
2148 vl_api_sw_bond_interface_dump_t *mp;
Steven9cd2d7a2017-12-20 12:43:01 -08002149 vl_api_control_ping_t *mp_ping;
2150 int ret;
Steven Luong4c4223e2020-07-15 08:44:54 -07002151 u32 sw_if_index = ~0;
2152
2153 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2154 {
2155 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2156 ;
2157 else if (unformat (i, "sw_if_index %d", &sw_if_index))
2158 ;
2159 else
2160 break;
2161 }
Steven9cd2d7a2017-12-20 12:43:01 -08002162
2163 print (vam->ofp,
2164 "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2165 "interface name", "sw_if_index", "mode", "load balance",
Steven Luong4c4223e2020-07-15 08:44:54 -07002166 "active members", "members");
Steven9cd2d7a2017-12-20 12:43:01 -08002167
2168 /* Get list of bond interfaces */
Steven Luong4c4223e2020-07-15 08:44:54 -07002169 M (SW_BOND_INTERFACE_DUMP, mp);
2170 mp->sw_if_index = ntohl (sw_if_index);
Steven9cd2d7a2017-12-20 12:43:01 -08002171 S (mp);
2172
2173 /* Use a control ping for synchronization */
2174 MPING (CONTROL_PING, mp_ping);
2175 S (mp_ping);
2176
2177 W (ret);
2178 return ret;
2179}
2180
Steven Luong4c4223e2020-07-15 08:44:54 -07002181static void vl_api_sw_member_interface_details_t_handler
2182 (vl_api_sw_member_interface_details_t * mp)
Steven9cd2d7a2017-12-20 12:43:01 -08002183{
2184 vat_main_t *vam = &vat_main;
2185
2186 print (vam->ofp,
Steven Luonga1876b82019-08-20 16:58:00 -07002187 "%-25s %-12d %-7d %-12d %-10d %-10d", mp->interface_name,
2188 ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout,
2189 ntohl (mp->weight), mp->is_local_numa);
Steven9cd2d7a2017-12-20 12:43:01 -08002190}
2191
Steven Luong4c4223e2020-07-15 08:44:54 -07002192static void vl_api_sw_member_interface_details_t_handler_json
2193 (vl_api_sw_member_interface_details_t * mp)
Steven9cd2d7a2017-12-20 12:43:01 -08002194{
2195 vat_main_t *vam = &vat_main;
2196 vat_json_node_t *node = NULL;
2197
2198 if (VAT_JSON_ARRAY != vam->json_tree.type)
2199 {
2200 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2201 vat_json_init_array (&vam->json_tree);
2202 }
2203 node = vat_json_array_add (&vam->json_tree);
2204
2205 vat_json_init_object (node);
2206 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2207 vat_json_object_add_string_copy (node, "interface_name",
2208 mp->interface_name);
2209 vat_json_object_add_uint (node, "passive", mp->is_passive);
2210 vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
Steven Luonga1876b82019-08-20 16:58:00 -07002211 vat_json_object_add_uint (node, "weight", ntohl (mp->weight));
2212 vat_json_object_add_uint (node, "is_local_numa", mp->is_local_numa);
Steven9cd2d7a2017-12-20 12:43:01 -08002213}
2214
2215static int
Steven Luong4c4223e2020-07-15 08:44:54 -07002216api_sw_member_interface_dump (vat_main_t * vam)
Steven9cd2d7a2017-12-20 12:43:01 -08002217{
2218 unformat_input_t *i = vam->input;
Steven Luong4c4223e2020-07-15 08:44:54 -07002219 vl_api_sw_member_interface_dump_t *mp;
Steven9cd2d7a2017-12-20 12:43:01 -08002220 vl_api_control_ping_t *mp_ping;
2221 u32 sw_if_index = ~0;
2222 u8 sw_if_index_set = 0;
2223 int ret;
2224
2225 /* Parse args required to build the message */
2226 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2227 {
2228 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2229 sw_if_index_set = 1;
2230 else if (unformat (i, "sw_if_index %d", &sw_if_index))
2231 sw_if_index_set = 1;
2232 else
2233 break;
2234 }
2235
2236 if (sw_if_index_set == 0)
2237 {
2238 errmsg ("missing vpp interface name. ");
2239 return -99;
2240 }
2241
2242 print (vam->ofp,
Steven Luonga1876b82019-08-20 16:58:00 -07002243 "\n%-25s %-12s %-7s %-12s %-10s %-10s",
Steven Luong4c4223e2020-07-15 08:44:54 -07002244 "member interface name", "sw_if_index", "passive", "long_timeout",
Steven Luonga1876b82019-08-20 16:58:00 -07002245 "weight", "local numa");
Steven9cd2d7a2017-12-20 12:43:01 -08002246
2247 /* Get list of bond interfaces */
Steven Luong4c4223e2020-07-15 08:44:54 -07002248 M (SW_MEMBER_INTERFACE_DUMP, mp);
Steven9cd2d7a2017-12-20 12:43:01 -08002249 mp->sw_if_index = ntohl (sw_if_index);
2250 S (mp);
2251
2252 /* Use a control ping for synchronization */
2253 MPING (CONTROL_PING, mp_ping);
2254 S (mp_ping);
2255
2256 W (ret);
2257 return ret;
2258}
2259
Damjan Marion7cd468a2016-12-19 23:05:39 +01002260static void vl_api_mpls_tunnel_add_del_reply_t_handler
2261 (vl_api_mpls_tunnel_add_del_reply_t * mp)
2262{
2263 vat_main_t *vam = &vat_main;
2264 i32 retval = ntohl (mp->retval);
2265 if (vam->async_mode)
2266 {
2267 vam->async_errors += (retval < 0);
2268 }
2269 else
2270 {
2271 vam->retval = retval;
John Lo06fda9c2018-10-03 16:32:44 -04002272 vam->sw_if_index = ntohl (mp->sw_if_index);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002273 vam->result_ready = 1;
2274 }
John Lo06fda9c2018-10-03 16:32:44 -04002275 vam->regenerate_interface_table = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002276}
2277
2278static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2279 (vl_api_mpls_tunnel_add_del_reply_t * mp)
2280{
2281 vat_main_t *vam = &vat_main;
2282 vat_json_node_t node;
2283
2284 vat_json_init_object (&node);
2285 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2286 vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2287 ntohl (mp->sw_if_index));
2288
2289 vat_json_print (vam->ofp, &node);
2290 vat_json_free (&node);
2291
2292 vam->retval = ntohl (mp->retval);
2293 vam->result_ready = 1;
2294}
2295
Damjan Marion7cd468a2016-12-19 23:05:39 +01002296static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2297 (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2298{
2299 vat_main_t *vam = &vat_main;
2300 i32 retval = ntohl (mp->retval);
2301 if (vam->async_mode)
2302 {
2303 vam->async_errors += (retval < 0);
2304 }
2305 else
2306 {
2307 vam->retval = retval;
2308 vam->sw_if_index = ntohl (mp->sw_if_index);
2309 vam->result_ready = 1;
2310 }
Dave Barachf72212e2018-01-11 10:25:07 -05002311 vam->regenerate_interface_table = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002312}
2313
2314static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2315 (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2316{
2317 vat_main_t *vam = &vat_main;
2318 vat_json_node_t node;
2319
2320 vat_json_init_object (&node);
2321 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2322 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2323
2324 vat_json_print (vam->ofp, &node);
2325 vat_json_free (&node);
2326
2327 vam->retval = ntohl (mp->retval);
2328 vam->result_ready = 1;
2329}
2330
eyal bariaf86a482018-04-17 11:20:27 +03002331static void vl_api_vxlan_offload_rx_reply_t_handler
2332 (vl_api_vxlan_offload_rx_reply_t * mp)
2333{
2334 vat_main_t *vam = &vat_main;
2335 i32 retval = ntohl (mp->retval);
2336 if (vam->async_mode)
2337 {
2338 vam->async_errors += (retval < 0);
2339 }
2340 else
2341 {
2342 vam->retval = retval;
2343 vam->result_ready = 1;
2344 }
2345}
2346
2347static void vl_api_vxlan_offload_rx_reply_t_handler_json
2348 (vl_api_vxlan_offload_rx_reply_t * mp)
2349{
2350 vat_main_t *vam = &vat_main;
2351 vat_json_node_t node;
2352
2353 vat_json_init_object (&node);
2354 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2355
2356 vat_json_print (vam->ofp, &node);
2357 vat_json_free (&node);
2358
2359 vam->retval = ntohl (mp->retval);
2360 vam->result_ready = 1;
2361}
2362
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +08002363static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2364 (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2365{
2366 vat_main_t *vam = &vat_main;
2367 i32 retval = ntohl (mp->retval);
2368 if (vam->async_mode)
2369 {
2370 vam->async_errors += (retval < 0);
2371 }
2372 else
2373 {
2374 vam->retval = retval;
2375 vam->sw_if_index = ntohl (mp->sw_if_index);
2376 vam->result_ready = 1;
2377 }
Dave Barachf72212e2018-01-11 10:25:07 -05002378 vam->regenerate_interface_table = 1;
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +08002379}
2380
2381static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2382 (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2383{
2384 vat_main_t *vam = &vat_main;
2385 vat_json_node_t node;
2386
2387 vat_json_init_object (&node);
2388 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2389 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2390
2391 vat_json_print (vam->ofp, &node);
2392 vat_json_free (&node);
2393
2394 vam->retval = ntohl (mp->retval);
2395 vam->result_ready = 1;
2396}
2397
Damjan Marion7cd468a2016-12-19 23:05:39 +01002398static void vl_api_create_vhost_user_if_reply_t_handler
2399 (vl_api_create_vhost_user_if_reply_t * mp)
2400{
2401 vat_main_t *vam = &vat_main;
2402 i32 retval = ntohl (mp->retval);
2403 if (vam->async_mode)
2404 {
2405 vam->async_errors += (retval < 0);
2406 }
2407 else
2408 {
2409 vam->retval = retval;
2410 vam->sw_if_index = ntohl (mp->sw_if_index);
2411 vam->result_ready = 1;
2412 }
Dave Barachf72212e2018-01-11 10:25:07 -05002413 vam->regenerate_interface_table = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002414}
2415
2416static void vl_api_create_vhost_user_if_reply_t_handler_json
2417 (vl_api_create_vhost_user_if_reply_t * mp)
2418{
2419 vat_main_t *vam = &vat_main;
2420 vat_json_node_t node;
2421
2422 vat_json_init_object (&node);
2423 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2424 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2425
2426 vat_json_print (vam->ofp, &node);
2427 vat_json_free (&node);
2428
2429 vam->retval = ntohl (mp->retval);
2430 vam->result_ready = 1;
2431}
2432
Steven Luong27ba5002020-11-17 13:30:44 -08002433static void vl_api_create_vhost_user_if_v2_reply_t_handler
2434 (vl_api_create_vhost_user_if_v2_reply_t * mp)
2435{
2436 vat_main_t *vam = &vat_main;
2437 i32 retval = ntohl (mp->retval);
2438 if (vam->async_mode)
2439 {
2440 vam->async_errors += (retval < 0);
2441 }
2442 else
2443 {
2444 vam->retval = retval;
2445 vam->sw_if_index = ntohl (mp->sw_if_index);
2446 vam->result_ready = 1;
2447 }
2448 vam->regenerate_interface_table = 1;
2449}
2450
2451static void vl_api_create_vhost_user_if_v2_reply_t_handler_json
2452 (vl_api_create_vhost_user_if_v2_reply_t * mp)
2453{
2454 vat_main_t *vam = &vat_main;
2455 vat_json_node_t node;
2456
2457 vat_json_init_object (&node);
2458 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2459 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2460
2461 vat_json_print (vam->ofp, &node);
2462 vat_json_free (&node);
2463
2464 vam->retval = ntohl (mp->retval);
2465 vam->result_ready = 1;
2466}
2467
Damjan Marion7cd468a2016-12-19 23:05:39 +01002468static void vl_api_ip_address_details_t_handler
2469 (vl_api_ip_address_details_t * mp)
2470{
2471 vat_main_t *vam = &vat_main;
2472 static ip_address_details_t empty_ip_address_details = { {0} };
2473 ip_address_details_t *address = NULL;
2474 ip_details_t *current_ip_details = NULL;
2475 ip_details_t *details = NULL;
2476
2477 details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2478
2479 if (!details || vam->current_sw_if_index >= vec_len (details)
2480 || !details[vam->current_sw_if_index].present)
2481 {
2482 errmsg ("ip address details arrived but not stored");
2483 errmsg ("ip_dump should be called first");
2484 return;
2485 }
2486
2487 current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2488
2489#define addresses (current_ip_details->addr)
2490
2491 vec_validate_init_empty (addresses, vec_len (addresses),
2492 empty_ip_address_details);
2493
2494 address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2495
Neale Ranns097fa662018-05-01 05:17:55 -07002496 clib_memcpy (&address->ip, &mp->prefix.address.un, sizeof (address->ip));
Paul Vinciguerraab055082019-06-06 14:07:55 -04002497 address->prefix_length = mp->prefix.len;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002498#undef addresses
2499}
2500
2501static void vl_api_ip_address_details_t_handler_json
2502 (vl_api_ip_address_details_t * mp)
2503{
2504 vat_main_t *vam = &vat_main;
2505 vat_json_node_t *node = NULL;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002506
2507 if (VAT_JSON_ARRAY != vam->json_tree.type)
2508 {
2509 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2510 vat_json_init_array (&vam->json_tree);
2511 }
2512 node = vat_json_array_add (&vam->json_tree);
2513
2514 vat_json_init_object (node);
Neale Ranns097fa662018-05-01 05:17:55 -07002515 vat_json_object_add_prefix (node, &mp->prefix);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002516}
2517
2518static void
2519vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2520{
2521 vat_main_t *vam = &vat_main;
2522 static ip_details_t empty_ip_details = { 0 };
2523 ip_details_t *ip = NULL;
2524 u32 sw_if_index = ~0;
2525
2526 sw_if_index = ntohl (mp->sw_if_index);
2527
2528 vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2529 sw_if_index, empty_ip_details);
2530
2531 ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2532 sw_if_index);
2533
2534 ip->present = 1;
2535}
2536
2537static void
2538vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2539{
2540 vat_main_t *vam = &vat_main;
2541
2542 if (VAT_JSON_ARRAY != vam->json_tree.type)
2543 {
2544 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2545 vat_json_init_array (&vam->json_tree);
2546 }
2547 vat_json_array_add_uint (&vam->json_tree,
2548 clib_net_to_host_u32 (mp->sw_if_index));
2549}
2550
Damjan Marion7cd468a2016-12-19 23:05:39 +01002551static void vl_api_get_first_msg_id_reply_t_handler
2552 (vl_api_get_first_msg_id_reply_t * mp)
2553{
2554 vat_main_t *vam = &vat_main;
2555 i32 retval = ntohl (mp->retval);
2556
2557 if (vam->async_mode)
2558 {
2559 vam->async_errors += (retval < 0);
2560 }
2561 else
2562 {
2563 vam->retval = retval;
2564 vam->result_ready = 1;
2565 }
2566 if (retval >= 0)
2567 {
2568 errmsg ("first message id %d", ntohs (mp->first_msg_id));
2569 }
2570}
2571
2572static void vl_api_get_first_msg_id_reply_t_handler_json
2573 (vl_api_get_first_msg_id_reply_t * mp)
2574{
2575 vat_main_t *vam = &vat_main;
2576 vat_json_node_t node;
2577
2578 vat_json_init_object (&node);
2579 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2580 vat_json_object_add_uint (&node, "first_msg_id",
2581 (uint) ntohs (mp->first_msg_id));
2582
2583 vat_json_print (vam->ofp, &node);
2584 vat_json_free (&node);
2585
2586 vam->retval = ntohl (mp->retval);
2587 vam->result_ready = 1;
2588}
2589
2590static void vl_api_get_node_graph_reply_t_handler
2591 (vl_api_get_node_graph_reply_t * mp)
2592{
2593 vat_main_t *vam = &vat_main;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002594 i32 retval = ntohl (mp->retval);
2595 u8 *pvt_copy, *reply;
2596 void *oldheap;
2597 vlib_node_t *node;
2598 int i;
2599
2600 if (vam->async_mode)
2601 {
2602 vam->async_errors += (retval < 0);
2603 }
2604 else
2605 {
2606 vam->retval = retval;
2607 vam->result_ready = 1;
2608 }
2609
2610 /* "Should never happen..." */
2611 if (retval != 0)
2612 return;
2613
Damjan Marion7bee80c2017-04-26 15:32:12 +02002614 reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002615 pvt_copy = vec_dup (reply);
2616
2617 /* Toss the shared-memory original... */
Nathan Skrzypczak0aa40132019-11-25 16:29:38 +01002618 oldheap = vl_msg_push_heap ();
Damjan Marion7cd468a2016-12-19 23:05:39 +01002619
2620 vec_free (reply);
2621
Nathan Skrzypczak0aa40132019-11-25 16:29:38 +01002622 vl_msg_pop_heap (oldheap);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002623
2624 if (vam->graph_nodes)
2625 {
2626 hash_free (vam->graph_node_index_by_name);
2627
Dave Barach1ddbc012018-06-13 09:26:05 -04002628 for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002629 {
Dave Barach1ddbc012018-06-13 09:26:05 -04002630 node = vam->graph_nodes[0][i];
Damjan Marion7cd468a2016-12-19 23:05:39 +01002631 vec_free (node->name);
2632 vec_free (node->next_nodes);
2633 vec_free (node);
2634 }
Dave Barach1ddbc012018-06-13 09:26:05 -04002635 vec_free (vam->graph_nodes[0]);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002636 vec_free (vam->graph_nodes);
2637 }
2638
2639 vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2640 vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2641 vec_free (pvt_copy);
2642
Dave Barach1ddbc012018-06-13 09:26:05 -04002643 for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002644 {
Dave Barach1ddbc012018-06-13 09:26:05 -04002645 node = vam->graph_nodes[0][i];
Damjan Marion7cd468a2016-12-19 23:05:39 +01002646 hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2647 }
2648}
2649
2650static void vl_api_get_node_graph_reply_t_handler_json
2651 (vl_api_get_node_graph_reply_t * mp)
2652{
2653 vat_main_t *vam = &vat_main;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002654 void *oldheap;
2655 vat_json_node_t node;
2656 u8 *reply;
2657
2658 /* $$$$ make this real? */
2659 vat_json_init_object (&node);
2660 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2661 vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2662
Damjan Marion7bee80c2017-04-26 15:32:12 +02002663 reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002664
2665 /* Toss the shared-memory original... */
Nathan Skrzypczak0aa40132019-11-25 16:29:38 +01002666 oldheap = vl_msg_push_heap ();
Damjan Marion7cd468a2016-12-19 23:05:39 +01002667
2668 vec_free (reply);
2669
Nathan Skrzypczak0aa40132019-11-25 16:29:38 +01002670 vl_msg_pop_heap (oldheap);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002671
2672 vat_json_print (vam->ofp, &node);
2673 vat_json_free (&node);
2674
2675 vam->retval = ntohl (mp->retval);
2676 vam->result_ready = 1;
2677}
2678
Damjan Marion7cd468a2016-12-19 23:05:39 +01002679static u8 *
2680format_policer_type (u8 * s, va_list * va)
2681{
2682 u32 i = va_arg (*va, u32);
2683
2684 if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2685 s = format (s, "1r2c");
2686 else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2687 s = format (s, "1r3c");
2688 else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2689 s = format (s, "2r3c-2698");
2690 else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2691 s = format (s, "2r3c-4115");
2692 else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2693 s = format (s, "2r3c-mef5cf1");
2694 else
2695 s = format (s, "ILLEGAL");
2696 return s;
2697}
2698
2699static u8 *
2700format_policer_rate_type (u8 * s, va_list * va)
2701{
2702 u32 i = va_arg (*va, u32);
2703
2704 if (i == SSE2_QOS_RATE_KBPS)
2705 s = format (s, "kbps");
2706 else if (i == SSE2_QOS_RATE_PPS)
2707 s = format (s, "pps");
2708 else
2709 s = format (s, "ILLEGAL");
2710 return s;
2711}
2712
2713static u8 *
2714format_policer_round_type (u8 * s, va_list * va)
2715{
2716 u32 i = va_arg (*va, u32);
2717
2718 if (i == SSE2_QOS_ROUND_TO_CLOSEST)
2719 s = format (s, "closest");
2720 else if (i == SSE2_QOS_ROUND_TO_UP)
2721 s = format (s, "up");
2722 else if (i == SSE2_QOS_ROUND_TO_DOWN)
2723 s = format (s, "down");
2724 else
2725 s = format (s, "ILLEGAL");
2726 return s;
2727}
2728
2729static u8 *
2730format_policer_action_type (u8 * s, va_list * va)
2731{
2732 u32 i = va_arg (*va, u32);
2733
2734 if (i == SSE2_QOS_ACTION_DROP)
2735 s = format (s, "drop");
2736 else if (i == SSE2_QOS_ACTION_TRANSMIT)
2737 s = format (s, "transmit");
2738 else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2739 s = format (s, "mark-and-transmit");
2740 else
2741 s = format (s, "ILLEGAL");
2742 return s;
2743}
2744
2745static u8 *
2746format_dscp (u8 * s, va_list * va)
2747{
2748 u32 i = va_arg (*va, u32);
2749 char *t = 0;
2750
2751 switch (i)
2752 {
Brian Russelle3845d72021-02-08 15:33:18 +00002753#define _(v, f) \
2754 case IP_DSCP_##f: \
2755 return (format (s, "%s", #f));
2756 foreach_ip_dscp
Damjan Marion7cd468a2016-12-19 23:05:39 +01002757#undef _
Damjan Marion7cd468a2016-12-19 23:05:39 +01002758 }
2759 s = format (s, "%s", t);
Brian Russelle3845d72021-02-08 15:33:18 +00002760 return (format (s, "ILLEGAL"));
Damjan Marion7cd468a2016-12-19 23:05:39 +01002761}
2762
2763static void
2764vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
2765{
2766 vat_main_t *vam = &vat_main;
2767 u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
2768
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002769 if (mp->conform_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
2770 conform_dscp_str = format (0, "%U", format_dscp, mp->conform_action.dscp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002771 else
2772 conform_dscp_str = format (0, "");
2773
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002774 if (mp->exceed_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
2775 exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_action.dscp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002776 else
2777 exceed_dscp_str = format (0, "");
2778
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002779 if (mp->violate_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
2780 violate_dscp_str = format (0, "%U", format_dscp, mp->violate_action.dscp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002781 else
2782 violate_dscp_str = format (0, "");
2783
2784 print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
2785 "rate type %U, round type %U, %s rate, %s color-aware, "
2786 "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
2787 "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
2788 "conform action %U%s, exceed action %U%s, violate action %U%s",
2789 mp->name,
2790 format_policer_type, mp->type,
2791 ntohl (mp->cir),
2792 ntohl (mp->eir),
2793 clib_net_to_host_u64 (mp->cb),
2794 clib_net_to_host_u64 (mp->eb),
2795 format_policer_rate_type, mp->rate_type,
2796 format_policer_round_type, mp->round_type,
2797 mp->single_rate ? "single" : "dual",
2798 mp->color_aware ? "is" : "not",
2799 ntohl (mp->cir_tokens_per_period),
2800 ntohl (mp->pir_tokens_per_period),
2801 ntohl (mp->scale),
2802 ntohl (mp->current_limit),
2803 ntohl (mp->current_bucket),
2804 ntohl (mp->extended_limit),
2805 ntohl (mp->extended_bucket),
2806 clib_net_to_host_u64 (mp->last_update_time),
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002807 format_policer_action_type, mp->conform_action.type,
Damjan Marion7cd468a2016-12-19 23:05:39 +01002808 conform_dscp_str,
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002809 format_policer_action_type, mp->exceed_action.type,
Damjan Marion7cd468a2016-12-19 23:05:39 +01002810 exceed_dscp_str,
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002811 format_policer_action_type, mp->violate_action.type,
Damjan Marion7cd468a2016-12-19 23:05:39 +01002812 violate_dscp_str);
2813
2814 vec_free (conform_dscp_str);
2815 vec_free (exceed_dscp_str);
2816 vec_free (violate_dscp_str);
2817}
2818
2819static void vl_api_policer_details_t_handler_json
2820 (vl_api_policer_details_t * mp)
2821{
2822 vat_main_t *vam = &vat_main;
2823 vat_json_node_t *node;
2824 u8 *rate_type_str, *round_type_str, *type_str;
2825 u8 *conform_action_str, *exceed_action_str, *violate_action_str;
2826
2827 rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
2828 round_type_str =
2829 format (0, "%U", format_policer_round_type, mp->round_type);
2830 type_str = format (0, "%U", format_policer_type, mp->type);
2831 conform_action_str = format (0, "%U", format_policer_action_type,
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002832 mp->conform_action.type);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002833 exceed_action_str = format (0, "%U", format_policer_action_type,
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002834 mp->exceed_action.type);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002835 violate_action_str = format (0, "%U", format_policer_action_type,
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002836 mp->violate_action.type);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002837
2838 if (VAT_JSON_ARRAY != vam->json_tree.type)
2839 {
2840 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2841 vat_json_init_array (&vam->json_tree);
2842 }
2843 node = vat_json_array_add (&vam->json_tree);
2844
2845 vat_json_init_object (node);
2846 vat_json_object_add_string_copy (node, "name", mp->name);
2847 vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
2848 vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
Marek Gradzki59ed4902017-03-21 11:51:54 +01002849 vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
2850 vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
Damjan Marion7cd468a2016-12-19 23:05:39 +01002851 vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
2852 vat_json_object_add_string_copy (node, "round_type", round_type_str);
2853 vat_json_object_add_string_copy (node, "type", type_str);
2854 vat_json_object_add_uint (node, "single_rate", mp->single_rate);
2855 vat_json_object_add_uint (node, "color_aware", mp->color_aware);
2856 vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
2857 vat_json_object_add_uint (node, "cir_tokens_per_period",
2858 ntohl (mp->cir_tokens_per_period));
2859 vat_json_object_add_uint (node, "eir_tokens_per_period",
2860 ntohl (mp->pir_tokens_per_period));
2861 vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
2862 vat_json_object_add_uint (node, "current_bucket",
2863 ntohl (mp->current_bucket));
2864 vat_json_object_add_uint (node, "extended_limit",
2865 ntohl (mp->extended_limit));
2866 vat_json_object_add_uint (node, "extended_bucket",
2867 ntohl (mp->extended_bucket));
2868 vat_json_object_add_uint (node, "last_update_time",
2869 ntohl (mp->last_update_time));
2870 vat_json_object_add_string_copy (node, "conform_action",
2871 conform_action_str);
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002872 if (mp->conform_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002873 {
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002874 u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_action.dscp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002875 vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
2876 vec_free (dscp_str);
2877 }
2878 vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002879 if (mp->exceed_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002880 {
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002881 u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_action.dscp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002882 vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
2883 vec_free (dscp_str);
2884 }
2885 vat_json_object_add_string_copy (node, "violate_action",
2886 violate_action_str);
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002887 if (mp->violate_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002888 {
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002889 u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_action.dscp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002890 vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
2891 vec_free (dscp_str);
2892 }
2893
2894 vec_free (rate_type_str);
2895 vec_free (round_type_str);
2896 vec_free (type_str);
2897 vec_free (conform_action_str);
2898 vec_free (exceed_action_str);
2899 vec_free (violate_action_str);
2900}
2901
2902static void
2903vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
2904 mp)
2905{
2906 vat_main_t *vam = &vat_main;
2907 int i, count = ntohl (mp->count);
2908
2909 if (count > 0)
2910 print (vam->ofp, "classify table ids (%d) : ", count);
2911 for (i = 0; i < count; i++)
2912 {
2913 print (vam->ofp, "%d", ntohl (mp->ids[i]));
2914 print (vam->ofp, (i < count - 1) ? "," : "");
2915 }
2916 vam->retval = ntohl (mp->retval);
2917 vam->result_ready = 1;
2918}
2919
2920static void
2921 vl_api_classify_table_ids_reply_t_handler_json
2922 (vl_api_classify_table_ids_reply_t * mp)
2923{
2924 vat_main_t *vam = &vat_main;
2925 int i, count = ntohl (mp->count);
2926
2927 if (count > 0)
2928 {
2929 vat_json_node_t node;
2930
2931 vat_json_init_object (&node);
2932 for (i = 0; i < count; i++)
2933 {
2934 vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
2935 }
2936 vat_json_print (vam->ofp, &node);
2937 vat_json_free (&node);
2938 }
2939 vam->retval = ntohl (mp->retval);
2940 vam->result_ready = 1;
2941}
2942
2943static void
2944 vl_api_classify_table_by_interface_reply_t_handler
2945 (vl_api_classify_table_by_interface_reply_t * mp)
2946{
2947 vat_main_t *vam = &vat_main;
2948 u32 table_id;
2949
2950 table_id = ntohl (mp->l2_table_id);
2951 if (table_id != ~0)
2952 print (vam->ofp, "l2 table id : %d", table_id);
2953 else
2954 print (vam->ofp, "l2 table id : No input ACL tables configured");
2955 table_id = ntohl (mp->ip4_table_id);
2956 if (table_id != ~0)
2957 print (vam->ofp, "ip4 table id : %d", table_id);
2958 else
2959 print (vam->ofp, "ip4 table id : No input ACL tables configured");
2960 table_id = ntohl (mp->ip6_table_id);
2961 if (table_id != ~0)
2962 print (vam->ofp, "ip6 table id : %d", table_id);
2963 else
2964 print (vam->ofp, "ip6 table id : No input ACL tables configured");
2965 vam->retval = ntohl (mp->retval);
2966 vam->result_ready = 1;
2967}
2968
2969static void
2970 vl_api_classify_table_by_interface_reply_t_handler_json
2971 (vl_api_classify_table_by_interface_reply_t * mp)
2972{
2973 vat_main_t *vam = &vat_main;
2974 vat_json_node_t node;
2975
2976 vat_json_init_object (&node);
2977
2978 vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
2979 vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
2980 vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
2981
2982 vat_json_print (vam->ofp, &node);
2983 vat_json_free (&node);
2984
2985 vam->retval = ntohl (mp->retval);
2986 vam->result_ready = 1;
2987}
2988
2989static void vl_api_policer_add_del_reply_t_handler
2990 (vl_api_policer_add_del_reply_t * mp)
2991{
2992 vat_main_t *vam = &vat_main;
2993 i32 retval = ntohl (mp->retval);
2994 if (vam->async_mode)
2995 {
2996 vam->async_errors += (retval < 0);
2997 }
2998 else
2999 {
3000 vam->retval = retval;
3001 vam->result_ready = 1;
3002 if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3003 /*
3004 * Note: this is just barely thread-safe, depends on
3005 * the main thread spinning waiting for an answer...
3006 */
3007 errmsg ("policer index %d", ntohl (mp->policer_index));
3008 }
3009}
3010
3011static void vl_api_policer_add_del_reply_t_handler_json
3012 (vl_api_policer_add_del_reply_t * mp)
3013{
3014 vat_main_t *vam = &vat_main;
3015 vat_json_node_t node;
3016
3017 vat_json_init_object (&node);
3018 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3019 vat_json_object_add_uint (&node, "policer_index",
3020 ntohl (mp->policer_index));
3021
3022 vat_json_print (vam->ofp, &node);
3023 vat_json_free (&node);
3024
3025 vam->retval = ntohl (mp->retval);
3026 vam->result_ready = 1;
3027}
3028
3029/* Format hex dump. */
3030u8 *
3031format_hex_bytes (u8 * s, va_list * va)
3032{
3033 u8 *bytes = va_arg (*va, u8 *);
3034 int n_bytes = va_arg (*va, int);
3035 uword i;
3036
3037 /* Print short or long form depending on byte count. */
3038 uword short_form = n_bytes <= 32;
Christophe Fontained3c008d2017-10-02 18:10:54 +02003039 u32 indent = format_get_indent (s);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003040
3041 if (n_bytes == 0)
3042 return s;
3043
3044 for (i = 0; i < n_bytes; i++)
3045 {
3046 if (!short_form && (i % 32) == 0)
3047 s = format (s, "%08x: ", i);
3048 s = format (s, "%02x", bytes[i]);
3049 if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3050 s = format (s, "\n%U", format_white_space, indent);
3051 }
3052
3053 return s;
3054}
3055
3056static void
3057vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3058 * mp)
3059{
3060 vat_main_t *vam = &vat_main;
3061 i32 retval = ntohl (mp->retval);
3062 if (retval == 0)
3063 {
3064 print (vam->ofp, "classify table info :");
3065 print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
3066 ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3067 ntohl (mp->miss_next_index));
3068 print (vam->ofp, "nbuckets: %d skip: %d match: %d",
3069 ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3070 ntohl (mp->match_n_vectors));
3071 print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
3072 ntohl (mp->mask_length));
3073 }
3074 vam->retval = retval;
3075 vam->result_ready = 1;
3076}
3077
3078static void
3079 vl_api_classify_table_info_reply_t_handler_json
3080 (vl_api_classify_table_info_reply_t * mp)
3081{
3082 vat_main_t *vam = &vat_main;
3083 vat_json_node_t node;
3084
3085 i32 retval = ntohl (mp->retval);
3086 if (retval == 0)
3087 {
3088 vat_json_init_object (&node);
3089
3090 vat_json_object_add_int (&node, "sessions",
3091 ntohl (mp->active_sessions));
3092 vat_json_object_add_int (&node, "nexttbl",
3093 ntohl (mp->next_table_index));
3094 vat_json_object_add_int (&node, "nextnode",
3095 ntohl (mp->miss_next_index));
3096 vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3097 vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3098 vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3099 u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3100 ntohl (mp->mask_length), 0);
3101 vat_json_object_add_string_copy (&node, "mask", s);
3102
3103 vat_json_print (vam->ofp, &node);
3104 vat_json_free (&node);
3105 }
3106 vam->retval = ntohl (mp->retval);
3107 vam->result_ready = 1;
3108}
3109
3110static void
3111vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3112 mp)
3113{
3114 vat_main_t *vam = &vat_main;
3115
3116 print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3117 ntohl (mp->hit_next_index), ntohl (mp->advance),
3118 ntohl (mp->opaque_index));
3119 print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
3120 ntohl (mp->match_length));
3121}
3122
3123static void
3124 vl_api_classify_session_details_t_handler_json
3125 (vl_api_classify_session_details_t * mp)
3126{
3127 vat_main_t *vam = &vat_main;
3128 vat_json_node_t *node = NULL;
3129
3130 if (VAT_JSON_ARRAY != vam->json_tree.type)
3131 {
3132 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3133 vat_json_init_array (&vam->json_tree);
3134 }
3135 node = vat_json_array_add (&vam->json_tree);
3136
3137 vat_json_init_object (node);
3138 vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3139 vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3140 vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3141 u8 *s =
3142 format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3143 0);
3144 vat_json_object_add_string_copy (node, "match", s);
3145}
3146
3147static void vl_api_pg_create_interface_reply_t_handler
3148 (vl_api_pg_create_interface_reply_t * mp)
3149{
3150 vat_main_t *vam = &vat_main;
3151
3152 vam->retval = ntohl (mp->retval);
3153 vam->result_ready = 1;
3154}
3155
3156static void vl_api_pg_create_interface_reply_t_handler_json
3157 (vl_api_pg_create_interface_reply_t * mp)
3158{
3159 vat_main_t *vam = &vat_main;
3160 vat_json_node_t node;
3161
3162 i32 retval = ntohl (mp->retval);
3163 if (retval == 0)
3164 {
3165 vat_json_init_object (&node);
3166
3167 vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3168
3169 vat_json_print (vam->ofp, &node);
3170 vat_json_free (&node);
3171 }
3172 vam->retval = ntohl (mp->retval);
3173 vam->result_ready = 1;
3174}
3175
3176static void vl_api_policer_classify_details_t_handler
3177 (vl_api_policer_classify_details_t * mp)
3178{
3179 vat_main_t *vam = &vat_main;
3180
3181 print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3182 ntohl (mp->table_index));
3183}
3184
3185static void vl_api_policer_classify_details_t_handler_json
3186 (vl_api_policer_classify_details_t * mp)
3187{
3188 vat_main_t *vam = &vat_main;
3189 vat_json_node_t *node;
3190
3191 if (VAT_JSON_ARRAY != vam->json_tree.type)
3192 {
3193 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3194 vat_json_init_array (&vam->json_tree);
3195 }
3196 node = vat_json_array_add (&vam->json_tree);
3197
3198 vat_json_init_object (node);
3199 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3200 vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3201}
3202
Damjan Marion7cd468a2016-12-19 23:05:39 +01003203static void vl_api_flow_classify_details_t_handler
3204 (vl_api_flow_classify_details_t * mp)
3205{
3206 vat_main_t *vam = &vat_main;
3207
3208 print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3209 ntohl (mp->table_index));
3210}
3211
3212static void vl_api_flow_classify_details_t_handler_json
3213 (vl_api_flow_classify_details_t * mp)
3214{
3215 vat_main_t *vam = &vat_main;
3216 vat_json_node_t *node;
3217
3218 if (VAT_JSON_ARRAY != vam->json_tree.type)
3219 {
3220 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3221 vat_json_init_array (&vam->json_tree);
3222 }
3223 node = vat_json_array_add (&vam->json_tree);
3224
3225 vat_json_init_object (node);
3226 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3227 vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3228}
3229
Damjan Marion7cd468a2016-12-19 23:05:39 +01003230/*
3231 * Generate boilerplate reply handlers, which
3232 * dig the return value out of the xxx_reply_t API message,
3233 * stick it into vam->retval, and set vam->result_ready
3234 *
3235 * Could also do this by pointing N message decode slots at
3236 * a single function, but that could break in subtle ways.
3237 */
3238
3239#define foreach_standard_reply_retval_handler \
3240_(sw_interface_set_flags_reply) \
3241_(sw_interface_add_del_address_reply) \
Stevenad8015b2017-10-29 22:10:46 -07003242_(sw_interface_set_rx_mode_reply) \
Mohsin Kazmi54f7c512018-08-23 18:28:11 +02003243_(sw_interface_set_rx_placement_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003244_(sw_interface_set_table_reply) \
3245_(sw_interface_set_mpls_enable_reply) \
3246_(sw_interface_set_vpath_reply) \
3247_(sw_interface_set_vxlan_bypass_reply) \
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +08003248_(sw_interface_set_vxlan_gpe_bypass_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003249_(sw_interface_set_l2_bridge_reply) \
Steven Luonga1876b82019-08-20 16:58:00 -07003250_(sw_interface_set_bond_weight_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003251_(bridge_domain_add_del_reply) \
3252_(sw_interface_set_l2_xconnect_reply) \
3253_(l2fib_add_del_reply) \
Eyal Barif24991c2017-04-05 05:33:21 +03003254_(l2fib_flush_int_reply) \
3255_(l2fib_flush_bd_reply) \
Neale Ranns097fa662018-05-01 05:17:55 -07003256_(ip_route_add_del_reply) \
Neale Ranns28ab9cc2017-08-14 07:18:42 -07003257_(ip_table_add_del_reply) \
Neale Ranns9db6ada2019-11-08 12:42:31 +00003258_(ip_table_replace_begin_reply) \
3259_(ip_table_flush_reply) \
3260_(ip_table_replace_end_reply) \
Neale Ranns32e1c012016-11-22 17:07:28 +00003261_(ip_mroute_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003262_(mpls_route_add_del_reply) \
Neale Ranns28ab9cc2017-08-14 07:18:42 -07003263_(mpls_table_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003264_(mpls_ip_bind_unbind_reply) \
Neale Rannsd792d9c2017-10-21 10:53:20 -07003265_(bier_route_add_del_reply) \
3266_(bier_table_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003267_(sw_interface_set_unnumbered_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003268_(set_ip_flow_hash_reply) \
3269_(sw_interface_ip6_enable_disable_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003270_(l2_patch_add_del_reply) \
John Loe166fd92018-09-13 14:08:59 -04003271_(sr_mpls_policy_add_reply) \
3272_(sr_mpls_policy_mod_reply) \
3273_(sr_mpls_policy_del_reply) \
Pablo Camarillofb380952016-12-07 18:34:18 +01003274_(sr_policy_add_reply) \
3275_(sr_policy_mod_reply) \
3276_(sr_policy_del_reply) \
3277_(sr_localsid_add_del_reply) \
3278_(sr_steering_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003279_(classify_add_del_session_reply) \
3280_(classify_set_interface_ip_table_reply) \
3281_(classify_set_interface_l2_tables_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003282_(l2_fib_clear_table_reply) \
3283_(l2_interface_efp_filter_reply) \
3284_(l2_interface_vlan_tag_rewrite_reply) \
3285_(modify_vhost_user_if_reply) \
Steven Luong27ba5002020-11-17 13:30:44 -08003286_(modify_vhost_user_if_v2_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003287_(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) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003294_(delete_loopback_reply) \
3295_(bd_ip_mac_add_del_reply) \
John Loe26c81f2019-01-07 15:16:33 -05003296_(bd_ip_mac_flush_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003297_(want_interface_events_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003298_(cop_interface_enable_disable_reply) \
3299_(cop_whitelist_enable_disable_reply) \
3300_(sw_interface_clear_stats_reply) \
Dave Barach65457162017-10-10 17:53:14 -04003301_(ioam_enable_reply) \
3302_(ioam_disable_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003303_(af_packet_delete_reply) \
3304_(policer_classify_set_interface_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003305_(set_ipfix_exporter_reply) \
3306_(set_ipfix_classify_stream_reply) \
3307_(ipfix_classify_table_add_del_reply) \
3308_(flow_classify_set_interface_reply) \
3309_(sw_interface_span_enable_disable_reply) \
3310_(pg_capture_reply) \
3311_(pg_enable_disable_reply) \
Mohsin Kazmif382b062020-08-11 15:00:44 +02003312_(pg_interface_enable_disable_coalesce_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003313_(ip_source_and_port_range_check_add_del_reply) \
3314_(ip_source_and_port_range_check_interface_add_del_reply)\
3315_(delete_subif_reply) \
3316_(l2_interface_pbb_tag_rewrite_reply) \
Pavel Kotuceke88865d2018-11-28 07:42:11 +01003317_(set_punt_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003318_(feature_enable_disable_reply) \
Mohsin Kazmi29467b52019-10-08 19:42:38 +02003319_(feature_gso_enable_disable_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003320_(sw_interface_tag_add_del_reply) \
Matthew Smithe0792fd2019-07-12 11:48:24 -05003321_(sw_interface_add_del_mac_address_reply) \
Ole Troand7231612018-06-07 10:17:57 +02003322_(hw_interface_set_mtu_reply) \
Pavel Kotucek6899a302017-06-08 08:46:10 +02003323_(p2p_ethernet_add_reply) \
Steve Shin99a0e602017-07-01 04:16:20 +00003324_(p2p_ethernet_del_reply) \
Florin Corascea194d2017-10-02 00:18:51 -07003325_(tcp_configure_src_addresses_reply) \
Florin Coras595992c2017-11-06 17:17:08 -08003326_(session_rule_add_del_reply) \
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +01003327_(ip_container_proxy_add_del_reply) \
Igor Mikhailov (imichail)582caa32018-04-26 21:33:02 -07003328_(output_acl_set_interface_reply) \
Chenmin Sund0236f72020-07-27 17:54:40 +08003329_(qos_record_enable_disable_reply) \
3330_(flow_add_reply)
Damjan Marion7cd468a2016-12-19 23:05:39 +01003331
3332#define _(n) \
3333 static void vl_api_##n##_t_handler \
3334 (vl_api_##n##_t * mp) \
3335 { \
3336 vat_main_t * vam = &vat_main; \
3337 i32 retval = ntohl(mp->retval); \
3338 if (vam->async_mode) { \
3339 vam->async_errors += (retval < 0); \
3340 } else { \
3341 vam->retval = retval; \
3342 vam->result_ready = 1; \
3343 } \
3344 }
3345foreach_standard_reply_retval_handler;
3346#undef _
3347
3348#define _(n) \
3349 static void vl_api_##n##_t_handler_json \
3350 (vl_api_##n##_t * mp) \
3351 { \
3352 vat_main_t * vam = &vat_main; \
3353 vat_json_node_t node; \
3354 vat_json_init_object(&node); \
3355 vat_json_object_add_int(&node, "retval", ntohl(mp->retval)); \
3356 vat_json_print(vam->ofp, &node); \
3357 vam->retval = ntohl(mp->retval); \
3358 vam->result_ready = 1; \
3359 }
3360foreach_standard_reply_retval_handler;
3361#undef _
3362
3363/*
3364 * Table of message reply handlers, must include boilerplate handlers
3365 * we just generated
3366 */
3367
3368#define foreach_vpe_api_reply_msg \
3369_(CREATE_LOOPBACK_REPLY, create_loopback_reply) \
Jon Loeligerc83c3b72017-02-23 13:57:35 -06003370_(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003371_(SW_INTERFACE_DETAILS, sw_interface_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003372_(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply) \
3373_(CONTROL_PING_REPLY, control_ping_reply) \
3374_(CLI_REPLY, cli_reply) \
3375_(CLI_INBAND_REPLY, cli_inband_reply) \
3376_(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY, \
3377 sw_interface_add_del_address_reply) \
Stevenad8015b2017-10-29 22:10:46 -07003378_(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply) \
Mohsin Kazmi54f7c512018-08-23 18:28:11 +02003379_(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply) \
Mohsin Kazmif0b42f42018-09-10 18:11:00 +02003380_(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003381_(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply) \
3382_(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
3383_(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply) \
3384_(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +08003385_(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003386_(SW_INTERFACE_SET_L2_XCONNECT_REPLY, \
3387 sw_interface_set_l2_xconnect_reply) \
3388_(SW_INTERFACE_SET_L2_BRIDGE_REPLY, \
3389 sw_interface_set_l2_bridge_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003390_(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply) \
3391_(BRIDGE_DOMAIN_DETAILS, bridge_domain_details) \
Eyal Barifead6702017-04-04 04:46:32 +03003392_(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003393_(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply) \
Eyal Barif24991c2017-04-05 05:33:21 +03003394_(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply) \
3395_(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003396_(L2_FLAGS_REPLY, l2_flags_reply) \
3397_(BRIDGE_FLAGS_REPLY, bridge_flags_reply) \
Damjan Marion8389fb92017-10-13 18:29:53 +02003398_(TAP_CREATE_V2_REPLY, tap_create_v2_reply) \
3399_(TAP_DELETE_V2_REPLY, tap_delete_v2_reply) \
3400_(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details) \
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01003401_(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply) \
Mohsin Kazmi518251b2020-09-01 17:17:44 +00003402_(VIRTIO_PCI_CREATE_V2_REPLY, virtio_pci_create_v2_reply) \
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01003403_(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply) \
3404_(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details) \
Steven9cd2d7a2017-12-20 12:43:01 -08003405_(BOND_CREATE_REPLY, bond_create_reply) \
Steven Luongea717862020-07-30 07:31:40 -07003406_(BOND_CREATE2_REPLY, bond_create2_reply) \
Steven9cd2d7a2017-12-20 12:43:01 -08003407_(BOND_DELETE_REPLY, bond_delete_reply) \
Steven Luong4c4223e2020-07-15 08:44:54 -07003408_(BOND_ADD_MEMBER_REPLY, bond_add_member_reply) \
3409_(BOND_DETACH_MEMBER_REPLY, bond_detach_member_reply) \
Steven Luonga1876b82019-08-20 16:58:00 -07003410_(SW_INTERFACE_SET_BOND_WEIGHT_REPLY, sw_interface_set_bond_weight_reply) \
Steven Luong4c4223e2020-07-15 08:44:54 -07003411_(SW_BOND_INTERFACE_DETAILS, sw_bond_interface_details) \
3412_(SW_MEMBER_INTERFACE_DETAILS, sw_member_interface_details) \
Neale Ranns097fa662018-05-01 05:17:55 -07003413_(IP_ROUTE_ADD_DEL_REPLY, ip_route_add_del_reply) \
Neale Ranns28ab9cc2017-08-14 07:18:42 -07003414_(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply) \
Neale Ranns9db6ada2019-11-08 12:42:31 +00003415_(IP_TABLE_REPLACE_BEGIN_REPLY, ip_table_replace_begin_reply) \
3416_(IP_TABLE_FLUSH_REPLY, ip_table_flush_reply) \
3417_(IP_TABLE_REPLACE_END_REPLY, ip_table_replace_end_reply) \
Neale Ranns32e1c012016-11-22 17:07:28 +00003418_(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply) \
Neale Ranns28ab9cc2017-08-14 07:18:42 -07003419_(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003420_(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply) \
3421_(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply) \
Neale Rannsd792d9c2017-10-21 10:53:20 -07003422_(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply) \
3423_(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003424_(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply) \
3425_(SW_INTERFACE_SET_UNNUMBERED_REPLY, \
3426 sw_interface_set_unnumbered_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003427_(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply) \
3428_(CREATE_SUBIF_REPLY, create_subif_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003429_(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply) \
3430_(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY, \
3431 sw_interface_ip6_enable_disable_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003432_(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply) \
John Loe166fd92018-09-13 14:08:59 -04003433_(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply) \
3434_(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply) \
3435_(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply) \
Pablo Camarillofb380952016-12-07 18:34:18 +01003436_(SR_POLICY_ADD_REPLY, sr_policy_add_reply) \
3437_(SR_POLICY_MOD_REPLY, sr_policy_mod_reply) \
3438_(SR_POLICY_DEL_REPLY, sr_policy_del_reply) \
3439_(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply) \
3440_(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003441_(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply) \
3442_(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply) \
3443_(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY, \
3444classify_set_interface_ip_table_reply) \
3445_(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY, \
3446 classify_set_interface_l2_tables_reply) \
3447_(GET_NODE_INDEX_REPLY, get_node_index_reply) \
3448_(ADD_NODE_NEXT_REPLY, add_node_next_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003449_(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply) \
eyal bariaf86a482018-04-17 11:20:27 +03003450_(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003451_(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003452_(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply) \
3453_(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply) \
3454_(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3455_(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details) \
3456_(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply) \
3457_(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply) \
Steven Luong27ba5002020-11-17 13:30:44 -08003458_(CREATE_VHOST_USER_IF_V2_REPLY, create_vhost_user_if_v2_reply) \
3459_(MODIFY_VHOST_USER_IF_V2_REPLY, modify_vhost_user_if_v2_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003460_(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply) \
3461_(SHOW_VERSION_REPLY, show_version_reply) \
Mohsin Kazmi5d64c782018-09-11 20:27:09 +02003462_(SHOW_THREADS_REPLY, show_threads_reply) \
Ole Troan01384fe2017-05-12 11:55:35 +02003463_(L2_FIB_TABLE_DETAILS, l2_fib_table_details) \
John Loc7b43042018-04-13 16:46:22 -04003464_(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003465_(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details) \
3466_(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply) \
John Lo8d00fff2017-08-03 00:35:36 -04003467_(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply) \
3468_(L2_MACS_EVENT, l2_macs_event) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003469_(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply) \
3470_(IP_ADDRESS_DETAILS, ip_address_details) \
3471_(IP_DETAILS, ip_details) \
3472_(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply) \
3473_(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
Neale Ranns17dcec02019-01-09 21:22:20 -08003474_(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply) \
3475_(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply) \
Matthew Smith28029532017-09-26 13:33:44 -05003476_(IPSEC_SA_DETAILS, ipsec_sa_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003477_(DELETE_LOOPBACK_REPLY, delete_loopback_reply) \
3478_(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply) \
John Loe26c81f2019-01-07 15:16:33 -05003479_(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply) \
Mohsin Kazmi5d82d2f2018-08-13 19:17:54 +02003480_(BD_IP_MAC_DETAILS, bd_ip_mac_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003481_(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003482_(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply) \
3483_(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
3484_(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
3485_(GET_NODE_GRAPH_REPLY, get_node_graph_reply) \
3486_(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply) \
3487_(IOAM_ENABLE_REPLY, ioam_enable_reply) \
3488_(IOAM_DISABLE_REPLY, ioam_disable_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003489_(AF_PACKET_CREATE_REPLY, af_packet_create_reply) \
3490_(AF_PACKET_DELETE_REPLY, af_packet_delete_reply) \
Mohsin Kazmi04e0bb22018-05-28 18:55:37 +02003491_(AF_PACKET_DETAILS, af_packet_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003492_(POLICER_ADD_DEL_REPLY, policer_add_del_reply) \
3493_(POLICER_DETAILS, policer_details) \
3494_(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3495_(POLICER_CLASSIFY_DETAILS, policer_classify_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003496_(MPLS_TUNNEL_DETAILS, mpls_tunnel_details) \
Neale Ranns097fa662018-05-01 05:17:55 -07003497_(MPLS_TABLE_DETAILS, mpls_table_details) \
3498_(MPLS_ROUTE_DETAILS, mpls_route_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003499_(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply) \
3500_(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3501_(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply) \
3502_(CLASSIFY_SESSION_DETAILS, classify_session_details) \
3503_(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply) \
3504_(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details) \
3505_(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply) \
3506_(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details) \
3507_(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
3508_(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details) \
3509_(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
3510_(FLOW_CLASSIFY_DETAILS, flow_classify_details) \
3511_(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
3512_(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details) \
3513_(GET_NEXT_INDEX_REPLY, get_next_index_reply) \
3514_(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply) \
3515_(PG_CAPTURE_REPLY, pg_capture_reply) \
3516_(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply) \
Mohsin Kazmif382b062020-08-11 15:00:44 +02003517_(PG_INTERFACE_ENABLE_DISABLE_COALESCE_REPLY, pg_interface_enable_disable_coalesce_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003518_(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY, \
3519 ip_source_and_port_range_check_add_del_reply) \
3520_(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY, \
3521 ip_source_and_port_range_check_interface_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003522_(DELETE_SUBIF_REPLY, delete_subif_reply) \
3523_(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
Pavel Kotuceke88865d2018-11-28 07:42:11 +01003524_(SET_PUNT_REPLY, set_punt_reply) \
Neale Ranns097fa662018-05-01 05:17:55 -07003525_(IP_TABLE_DETAILS, ip_table_details) \
3526_(IP_ROUTE_DETAILS, ip_route_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003527_(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply) \
Mohsin Kazmi29467b52019-10-08 19:42:38 +02003528_(FEATURE_GSO_ENABLE_DISABLE_REPLY, feature_gso_enable_disable_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003529_(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply) \
Matthew Smithe0792fd2019-07-12 11:48:24 -05003530_(SW_INTERFACE_ADD_DEL_MAC_ADDRESS_REPLY, sw_interface_add_del_mac_address_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003531_(L2_XCONNECT_DETAILS, l2_xconnect_details) \
Ole Troand7231612018-06-07 10:17:57 +02003532_(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply) \
Pavel Kotucek6899a302017-06-08 08:46:10 +02003533_(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply) \
3534_(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply) \
Steve Shin99a0e602017-07-01 04:16:20 +00003535_(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply) \
Florin Corascea194d2017-10-02 00:18:51 -07003536_(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
Dave Barach65457162017-10-10 17:53:14 -04003537_(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply) \
Florin Coras6c36f532017-11-03 18:32:34 -07003538_(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply) \
Florin Coras595992c2017-11-06 17:17:08 -08003539_(SESSION_RULES_DETAILS, session_rules_details) \
3540_(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply) \
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +01003541_(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply) \
Chenmin Sund0236f72020-07-27 17:54:40 +08003542_(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply) \
3543_(FLOW_ADD_REPLY, flow_add_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003544
Dave Baracha1a093d2017-03-02 13:13:23 -05003545#define foreach_standalone_reply_msg \
Ole Troanf49ba0e2018-11-13 14:04:50 +01003546_(SW_INTERFACE_EVENT, sw_interface_event)
Dave Baracha1a093d2017-03-02 13:13:23 -05003547
Damjan Marion7cd468a2016-12-19 23:05:39 +01003548typedef struct
3549{
3550 u8 *name;
3551 u32 value;
3552} name_sort_t;
3553
Damjan Marion7cd468a2016-12-19 23:05:39 +01003554#define STR_VTR_OP_CASE(op) \
3555 case L2_VTR_ ## op: \
3556 return "" # op;
3557
3558static const char *
3559str_vtr_op (u32 vtr_op)
3560{
3561 switch (vtr_op)
3562 {
3563 STR_VTR_OP_CASE (DISABLED);
3564 STR_VTR_OP_CASE (PUSH_1);
3565 STR_VTR_OP_CASE (PUSH_2);
3566 STR_VTR_OP_CASE (POP_1);
3567 STR_VTR_OP_CASE (POP_2);
3568 STR_VTR_OP_CASE (TRANSLATE_1_1);
3569 STR_VTR_OP_CASE (TRANSLATE_1_2);
3570 STR_VTR_OP_CASE (TRANSLATE_2_1);
3571 STR_VTR_OP_CASE (TRANSLATE_2_2);
3572 }
3573
3574 return "UNKNOWN";
3575}
3576
3577static int
3578dump_sub_interface_table (vat_main_t * vam)
3579{
3580 const sw_interface_subif_t *sub = NULL;
3581
3582 if (vam->json_output)
3583 {
3584 clib_warning
3585 ("JSON output supported only for VPE API calls and dump_stats_table");
3586 return -99;
3587 }
3588
3589 print (vam->ofp,
3590 "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
3591 "Interface", "sw_if_index",
3592 "sub id", "dot1ad", "tags", "outer id",
3593 "inner id", "exact", "default", "outer any", "inner any");
3594
3595 vec_foreach (sub, vam->sw_if_subif_table)
3596 {
3597 print (vam->ofp,
3598 "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
3599 sub->interface_name,
3600 sub->sw_if_index,
3601 sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
3602 sub->sub_number_of_tags, sub->sub_outer_vlan_id,
3603 sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
3604 sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
3605 if (sub->vtr_op != L2_VTR_DISABLED)
3606 {
3607 print (vam->ofp,
3608 " vlan-tag-rewrite - op: %-14s [ dot1q: %d "
3609 "tag1: %d tag2: %d ]",
3610 str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
3611 sub->vtr_tag1, sub->vtr_tag2);
3612 }
3613 }
3614
3615 return 0;
3616}
3617
3618static int
3619name_sort_cmp (void *a1, void *a2)
3620{
3621 name_sort_t *n1 = a1;
3622 name_sort_t *n2 = a2;
3623
3624 return strcmp ((char *) n1->name, (char *) n2->name);
3625}
3626
3627static int
3628dump_interface_table (vat_main_t * vam)
3629{
3630 hash_pair_t *p;
3631 name_sort_t *nses = 0, *ns;
3632
3633 if (vam->json_output)
3634 {
3635 clib_warning
3636 ("JSON output supported only for VPE API calls and dump_stats_table");
3637 return -99;
3638 }
3639
3640 /* *INDENT-OFF* */
3641 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3642 ({
3643 vec_add2 (nses, ns, 1);
3644 ns->name = (u8 *)(p->key);
3645 ns->value = (u32) p->value[0];
3646 }));
3647 /* *INDENT-ON* */
3648
3649 vec_sort_with_function (nses, name_sort_cmp);
3650
3651 print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
3652 vec_foreach (ns, nses)
3653 {
3654 print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
3655 }
3656 vec_free (nses);
3657 return 0;
3658}
3659
3660static int
3661dump_ip_table (vat_main_t * vam, int is_ipv6)
3662{
3663 const ip_details_t *det = NULL;
3664 const ip_address_details_t *address = NULL;
3665 u32 i = ~0;
3666
3667 print (vam->ofp, "%-12s", "sw_if_index");
3668
3669 vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
3670 {
3671 i++;
3672 if (!det->present)
3673 {
3674 continue;
3675 }
3676 print (vam->ofp, "%-12d", i);
3677 print (vam->ofp, " %-30s%-13s", "Address", "Prefix length");
3678 if (!det->addr)
3679 {
3680 continue;
3681 }
3682 vec_foreach (address, det->addr)
3683 {
3684 print (vam->ofp,
3685 " %-30U%-13d",
3686 is_ipv6 ? format_ip6_address : format_ip4_address,
3687 address->ip, address->prefix_length);
3688 }
3689 }
3690
3691 return 0;
3692}
3693
3694static int
3695dump_ipv4_table (vat_main_t * vam)
3696{
3697 if (vam->json_output)
3698 {
3699 clib_warning
3700 ("JSON output supported only for VPE API calls and dump_stats_table");
3701 return -99;
3702 }
3703
3704 return dump_ip_table (vam, 0);
3705}
3706
3707static int
3708dump_ipv6_table (vat_main_t * vam)
3709{
3710 if (vam->json_output)
3711 {
3712 clib_warning
3713 ("JSON output supported only for VPE API calls and dump_stats_table");
3714 return -99;
3715 }
3716
3717 return dump_ip_table (vam, 1);
3718}
3719
Damjan Marion7cd468a2016-12-19 23:05:39 +01003720/*
Dave Barach59b25652017-09-10 15:04:27 -04003721 * Pass CLI buffers directly in the CLI_INBAND API message,
3722 * instead of an additional shared memory area.
Damjan Marion7cd468a2016-12-19 23:05:39 +01003723 */
3724static int
3725exec_inband (vat_main_t * vam)
3726{
3727 vl_api_cli_inband_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003728 unformat_input_t *i = vam->input;
Jon Loeliger56c7b012017-02-01 12:31:41 -06003729 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003730
3731 if (vec_len (i->buffer) == 0)
3732 return -1;
3733
3734 if (vam->exec_mode == 0 && unformat (i, "mode"))
3735 {
3736 vam->exec_mode = 1;
3737 return 0;
3738 }
3739 if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
3740 {
3741 vam->exec_mode = 0;
3742 return 0;
3743 }
3744
3745 /*
3746 * In order for the CLI command to work, it
3747 * must be a vector ending in \n, not a C-string ending
3748 * in \n\0.
3749 */
Jakub Grajciar2dbee932020-02-07 11:30:26 +01003750 M2 (CLI_INBAND, mp, vec_len (vam->input->buffer));
3751 vl_api_vec_to_api_string (vam->input->buffer, &mp->cmd);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003752
Jon Loeliger7bc770c2017-01-31 14:03:33 -06003753 S (mp);
Dave Barach59b25652017-09-10 15:04:27 -04003754 W (ret);
3755 /* json responses may or may not include a useful reply... */
3756 if (vec_len (vam->cmd_reply))
Dave Barachcf5e8482017-10-17 11:48:29 -04003757 print (vam->ofp, "%v", (char *) (vam->cmd_reply));
Jon Loeliger56c7b012017-02-01 12:31:41 -06003758 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003759}
3760
Dave Barach59b25652017-09-10 15:04:27 -04003761int
3762exec (vat_main_t * vam)
3763{
3764 return exec_inband (vam);
3765}
3766
Damjan Marion7cd468a2016-12-19 23:05:39 +01003767static int
3768api_create_loopback (vat_main_t * vam)
3769{
3770 unformat_input_t *i = vam->input;
3771 vl_api_create_loopback_t *mp;
Jon Loeligerc83c3b72017-02-23 13:57:35 -06003772 vl_api_create_loopback_instance_t *mp_lbi;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003773 u8 mac_address[6];
3774 u8 mac_set = 0;
Jon Loeligerc83c3b72017-02-23 13:57:35 -06003775 u8 is_specified = 0;
3776 u32 user_instance = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06003777 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003778
Dave Barachb7b92992018-10-17 10:38:51 -04003779 clib_memset (mac_address, 0, sizeof (mac_address));
Damjan Marion7cd468a2016-12-19 23:05:39 +01003780
3781 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3782 {
3783 if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
3784 mac_set = 1;
Jon Loeligerc83c3b72017-02-23 13:57:35 -06003785 if (unformat (i, "instance %d", &user_instance))
3786 is_specified = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003787 else
3788 break;
3789 }
3790
Jon Loeligerc83c3b72017-02-23 13:57:35 -06003791 if (is_specified)
3792 {
3793 M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
3794 mp_lbi->is_specified = is_specified;
3795 if (is_specified)
3796 mp_lbi->user_instance = htonl (user_instance);
3797 if (mac_set)
3798 clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
3799 S (mp_lbi);
3800 }
3801 else
3802 {
3803 /* Construct the API message */
3804 M (CREATE_LOOPBACK, mp);
3805 if (mac_set)
3806 clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
3807 S (mp);
3808 }
Damjan Marion7cd468a2016-12-19 23:05:39 +01003809
Jon Loeliger56c7b012017-02-01 12:31:41 -06003810 W (ret);
3811 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003812}
3813
3814static int
3815api_delete_loopback (vat_main_t * vam)
3816{
3817 unformat_input_t *i = vam->input;
3818 vl_api_delete_loopback_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003819 u32 sw_if_index = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06003820 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003821
3822 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3823 {
3824 if (unformat (i, "sw_if_index %d", &sw_if_index))
3825 ;
3826 else
3827 break;
3828 }
3829
3830 if (sw_if_index == ~0)
3831 {
3832 errmsg ("missing sw_if_index");
3833 return -99;
3834 }
3835
3836 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06003837 M (DELETE_LOOPBACK, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003838 mp->sw_if_index = ntohl (sw_if_index);
3839
Jon Loeliger7bc770c2017-01-31 14:03:33 -06003840 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06003841 W (ret);
3842 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003843}
3844
3845static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01003846api_want_interface_events (vat_main_t * vam)
3847{
3848 unformat_input_t *i = vam->input;
3849 vl_api_want_interface_events_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003850 int enable = -1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06003851 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003852
3853 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3854 {
3855 if (unformat (i, "enable"))
3856 enable = 1;
3857 else if (unformat (i, "disable"))
3858 enable = 0;
3859 else
3860 break;
3861 }
3862
3863 if (enable == -1)
3864 {
3865 errmsg ("missing enable|disable");
3866 return -99;
3867 }
3868
Jon Loeliger8a2aea32017-01-31 13:19:40 -06003869 M (WANT_INTERFACE_EVENTS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003870 mp->enable_disable = enable;
3871
3872 vam->interface_event_display = enable;
3873
Jon Loeliger7bc770c2017-01-31 14:03:33 -06003874 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06003875 W (ret);
3876 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003877}
3878
3879
3880/* Note: non-static, called once to set up the initial intfc table */
3881int
3882api_sw_interface_dump (vat_main_t * vam)
3883{
3884 vl_api_sw_interface_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -06003885 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003886 hash_pair_t *p;
3887 name_sort_t *nses = 0, *ns;
3888 sw_interface_subif_t *sub = NULL;
Jon Loeliger56c7b012017-02-01 12:31:41 -06003889 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003890
3891 /* Toss the old name table */
3892 /* *INDENT-OFF* */
3893 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3894 ({
3895 vec_add2 (nses, ns, 1);
3896 ns->name = (u8 *)(p->key);
3897 ns->value = (u32) p->value[0];
3898 }));
3899 /* *INDENT-ON* */
3900
3901 hash_free (vam->sw_if_index_by_interface_name);
3902
3903 vec_foreach (ns, nses) vec_free (ns->name);
3904
3905 vec_free (nses);
3906
3907 vec_foreach (sub, vam->sw_if_subif_table)
3908 {
3909 vec_free (sub->interface_name);
3910 }
3911 vec_free (vam->sw_if_subif_table);
3912
3913 /* recreate the interface name hash table */
3914 vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
3915
Dave Barachf72212e2018-01-11 10:25:07 -05003916 /*
3917 * Ask for all interface names. Otherwise, the epic catalog of
3918 * name filters becomes ridiculously long, and vat ends up needing
3919 * to be taught about new interface types.
3920 */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06003921 M (SW_INTERFACE_DUMP, mp);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06003922 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003923
3924 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -04003925 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06003926 S (mp_ping);
3927
Jon Loeliger56c7b012017-02-01 12:31:41 -06003928 W (ret);
3929 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003930}
3931
3932static int
3933api_sw_interface_set_flags (vat_main_t * vam)
3934{
3935 unformat_input_t *i = vam->input;
3936 vl_api_sw_interface_set_flags_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003937 u32 sw_if_index;
3938 u8 sw_if_index_set = 0;
Neale Rannsa07bd702017-08-07 07:53:49 -07003939 u8 admin_up = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06003940 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003941
3942 /* Parse args required to build the message */
3943 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3944 {
3945 if (unformat (i, "admin-up"))
3946 admin_up = 1;
3947 else if (unformat (i, "admin-down"))
3948 admin_up = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003949 else
3950 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
3951 sw_if_index_set = 1;
3952 else if (unformat (i, "sw_if_index %d", &sw_if_index))
3953 sw_if_index_set = 1;
3954 else
3955 break;
3956 }
3957
3958 if (sw_if_index_set == 0)
3959 {
3960 errmsg ("missing interface name or sw_if_index");
3961 return -99;
3962 }
3963
3964 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06003965 M (SW_INTERFACE_SET_FLAGS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003966 mp->sw_if_index = ntohl (sw_if_index);
Jakub Grajciar053204a2019-03-18 13:17:53 +01003967 mp->flags = ntohl ((admin_up) ? IF_STATUS_API_FLAG_ADMIN_UP : 0);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003968
3969 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06003970 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003971
3972 /* Wait for a reply, return the good/bad news... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06003973 W (ret);
3974 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003975}
3976
3977static int
Stevenad8015b2017-10-29 22:10:46 -07003978api_sw_interface_set_rx_mode (vat_main_t * vam)
3979{
3980 unformat_input_t *i = vam->input;
3981 vl_api_sw_interface_set_rx_mode_t *mp;
3982 u32 sw_if_index;
3983 u8 sw_if_index_set = 0;
3984 int ret;
3985 u8 queue_id_valid = 0;
3986 u32 queue_id;
Damjan Marioneabd4242020-10-07 20:59:07 +02003987 vnet_hw_if_rx_mode mode = VNET_HW_IF_RX_MODE_UNKNOWN;
Stevenad8015b2017-10-29 22:10:46 -07003988
3989 /* Parse args required to build the message */
3990 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3991 {
3992 if (unformat (i, "queue %d", &queue_id))
3993 queue_id_valid = 1;
3994 else if (unformat (i, "polling"))
Damjan Marioneabd4242020-10-07 20:59:07 +02003995 mode = VNET_HW_IF_RX_MODE_POLLING;
Stevenad8015b2017-10-29 22:10:46 -07003996 else if (unformat (i, "interrupt"))
Damjan Marioneabd4242020-10-07 20:59:07 +02003997 mode = VNET_HW_IF_RX_MODE_INTERRUPT;
Stevenad8015b2017-10-29 22:10:46 -07003998 else if (unformat (i, "adaptive"))
Damjan Marioneabd4242020-10-07 20:59:07 +02003999 mode = VNET_HW_IF_RX_MODE_ADAPTIVE;
Stevenad8015b2017-10-29 22:10:46 -07004000 else
4001 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4002 sw_if_index_set = 1;
4003 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4004 sw_if_index_set = 1;
4005 else
4006 break;
4007 }
4008
4009 if (sw_if_index_set == 0)
4010 {
4011 errmsg ("missing interface name or sw_if_index");
4012 return -99;
4013 }
Damjan Marioneabd4242020-10-07 20:59:07 +02004014 if (mode == VNET_HW_IF_RX_MODE_UNKNOWN)
Stevenad8015b2017-10-29 22:10:46 -07004015 {
4016 errmsg ("missing rx-mode");
4017 return -99;
4018 }
4019
4020 /* Construct the API message */
4021 M (SW_INTERFACE_SET_RX_MODE, mp);
4022 mp->sw_if_index = ntohl (sw_if_index);
Jakub Grajciar053204a2019-03-18 13:17:53 +01004023 mp->mode = (vl_api_rx_mode_t) mode;
Stevenad8015b2017-10-29 22:10:46 -07004024 mp->queue_id_valid = queue_id_valid;
4025 mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
4026
4027 /* send it... */
4028 S (mp);
4029
4030 /* Wait for a reply, return the good/bad news... */
4031 W (ret);
4032 return ret;
4033}
4034
4035static int
Mohsin Kazmi54f7c512018-08-23 18:28:11 +02004036api_sw_interface_set_rx_placement (vat_main_t * vam)
4037{
4038 unformat_input_t *i = vam->input;
4039 vl_api_sw_interface_set_rx_placement_t *mp;
4040 u32 sw_if_index;
4041 u8 sw_if_index_set = 0;
4042 int ret;
4043 u8 is_main = 0;
4044 u32 queue_id, thread_index;
4045
4046 /* Parse args required to build the message */
4047 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4048 {
4049 if (unformat (i, "queue %d", &queue_id))
4050 ;
4051 else if (unformat (i, "main"))
4052 is_main = 1;
4053 else if (unformat (i, "worker %d", &thread_index))
4054 ;
4055 else
4056 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4057 sw_if_index_set = 1;
4058 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4059 sw_if_index_set = 1;
4060 else
4061 break;
4062 }
4063
4064 if (sw_if_index_set == 0)
4065 {
4066 errmsg ("missing interface name or sw_if_index");
4067 return -99;
4068 }
4069
4070 if (is_main)
4071 thread_index = 0;
4072 /* Construct the API message */
4073 M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
4074 mp->sw_if_index = ntohl (sw_if_index);
4075 mp->worker_id = ntohl (thread_index);
4076 mp->queue_id = ntohl (queue_id);
4077 mp->is_main = is_main;
4078
4079 /* send it... */
4080 S (mp);
4081 /* Wait for a reply, return the good/bad news... */
4082 W (ret);
4083 return ret;
4084}
4085
Mohsin Kazmif0b42f42018-09-10 18:11:00 +02004086static void vl_api_sw_interface_rx_placement_details_t_handler
4087 (vl_api_sw_interface_rx_placement_details_t * mp)
4088{
4089 vat_main_t *vam = &vat_main;
4090 u32 worker_id = ntohl (mp->worker_id);
4091
4092 print (vam->ofp,
4093 "\n%-11d %-11s %-6d %-5d %-9s",
4094 ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
4095 worker_id, ntohl (mp->queue_id),
4096 (mp->mode ==
4097 1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
4098}
4099
4100static void vl_api_sw_interface_rx_placement_details_t_handler_json
4101 (vl_api_sw_interface_rx_placement_details_t * mp)
4102{
4103 vat_main_t *vam = &vat_main;
4104 vat_json_node_t *node = NULL;
4105
4106 if (VAT_JSON_ARRAY != vam->json_tree.type)
4107 {
4108 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4109 vat_json_init_array (&vam->json_tree);
4110 }
4111 node = vat_json_array_add (&vam->json_tree);
4112
4113 vat_json_init_object (node);
4114 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4115 vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
4116 vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
4117 vat_json_object_add_uint (node, "mode", mp->mode);
4118}
4119
4120static int
4121api_sw_interface_rx_placement_dump (vat_main_t * vam)
4122{
4123 unformat_input_t *i = vam->input;
4124 vl_api_sw_interface_rx_placement_dump_t *mp;
4125 vl_api_control_ping_t *mp_ping;
4126 int ret;
4127 u32 sw_if_index;
4128 u8 sw_if_index_set = 0;
4129
4130 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4131 {
4132 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4133 sw_if_index_set++;
4134 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4135 sw_if_index_set++;
4136 else
4137 break;
4138 }
4139
4140 print (vam->ofp,
4141 "\n%-11s %-11s %-6s %-5s %-4s",
4142 "sw_if_index", "main/worker", "thread", "queue", "mode");
4143
4144 /* Dump Interface rx placement */
4145 M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
4146
4147 if (sw_if_index_set)
4148 mp->sw_if_index = htonl (sw_if_index);
4149 else
4150 mp->sw_if_index = ~0;
4151
4152 S (mp);
4153
4154 /* Use a control ping for synchronization */
4155 MPING (CONTROL_PING, mp_ping);
4156 S (mp_ping);
4157
4158 W (ret);
4159 return ret;
4160}
4161
Mohsin Kazmi54f7c512018-08-23 18:28:11 +02004162static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01004163api_sw_interface_clear_stats (vat_main_t * vam)
4164{
4165 unformat_input_t *i = vam->input;
4166 vl_api_sw_interface_clear_stats_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004167 u32 sw_if_index;
4168 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004169 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004170
4171 /* Parse args required to build the message */
4172 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4173 {
4174 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4175 sw_if_index_set = 1;
4176 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4177 sw_if_index_set = 1;
4178 else
4179 break;
4180 }
4181
4182 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004183 M (SW_INTERFACE_CLEAR_STATS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004184
4185 if (sw_if_index_set == 1)
4186 mp->sw_if_index = ntohl (sw_if_index);
4187 else
4188 mp->sw_if_index = ~0;
4189
4190 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004191 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004192
4193 /* Wait for a reply, return the good/bad news... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06004194 W (ret);
4195 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004196}
4197
Damjan Marion7cd468a2016-12-19 23:05:39 +01004198static int
4199api_sw_interface_add_del_address (vat_main_t * vam)
4200{
4201 unformat_input_t *i = vam->input;
4202 vl_api_sw_interface_add_del_address_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004203 u32 sw_if_index;
4204 u8 sw_if_index_set = 0;
4205 u8 is_add = 1, del_all = 0;
4206 u32 address_length = 0;
4207 u8 v4_address_set = 0;
4208 u8 v6_address_set = 0;
4209 ip4_address_t v4address;
4210 ip6_address_t v6address;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004211 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004212
4213 /* Parse args required to build the message */
4214 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4215 {
4216 if (unformat (i, "del-all"))
4217 del_all = 1;
4218 else if (unformat (i, "del"))
4219 is_add = 0;
4220 else
4221 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4222 sw_if_index_set = 1;
4223 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4224 sw_if_index_set = 1;
4225 else if (unformat (i, "%U/%d",
4226 unformat_ip4_address, &v4address, &address_length))
4227 v4_address_set = 1;
4228 else if (unformat (i, "%U/%d",
4229 unformat_ip6_address, &v6address, &address_length))
4230 v6_address_set = 1;
4231 else
4232 break;
4233 }
4234
4235 if (sw_if_index_set == 0)
4236 {
4237 errmsg ("missing interface name or sw_if_index");
4238 return -99;
4239 }
4240 if (v4_address_set && v6_address_set)
4241 {
4242 errmsg ("both v4 and v6 addresses set");
4243 return -99;
4244 }
4245 if (!v4_address_set && !v6_address_set && !del_all)
4246 {
4247 errmsg ("no addresses set");
4248 return -99;
4249 }
4250
4251 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004252 M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004253
4254 mp->sw_if_index = ntohl (sw_if_index);
4255 mp->is_add = is_add;
4256 mp->del_all = del_all;
4257 if (v6_address_set)
4258 {
Jakub Grajciar053204a2019-03-18 13:17:53 +01004259 mp->prefix.address.af = ADDRESS_IP6;
4260 clib_memcpy (mp->prefix.address.un.ip6, &v6address, sizeof (v6address));
Damjan Marion7cd468a2016-12-19 23:05:39 +01004261 }
4262 else
4263 {
Jakub Grajciar053204a2019-03-18 13:17:53 +01004264 mp->prefix.address.af = ADDRESS_IP4;
4265 clib_memcpy (mp->prefix.address.un.ip4, &v4address, sizeof (v4address));
Damjan Marion7cd468a2016-12-19 23:05:39 +01004266 }
Jakub Grajciar053204a2019-03-18 13:17:53 +01004267 mp->prefix.len = address_length;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004268
4269 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004270 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004271
4272 /* Wait for a reply, return good/bad news */
Jon Loeliger56c7b012017-02-01 12:31:41 -06004273 W (ret);
4274 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004275}
4276
4277static int
4278api_sw_interface_set_mpls_enable (vat_main_t * vam)
4279{
4280 unformat_input_t *i = vam->input;
4281 vl_api_sw_interface_set_mpls_enable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004282 u32 sw_if_index;
4283 u8 sw_if_index_set = 0;
4284 u8 enable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004285 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004286
4287 /* Parse args required to build the message */
4288 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4289 {
4290 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4291 sw_if_index_set = 1;
4292 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4293 sw_if_index_set = 1;
4294 else if (unformat (i, "disable"))
4295 enable = 0;
4296 else if (unformat (i, "dis"))
4297 enable = 0;
4298 else
4299 break;
4300 }
4301
4302 if (sw_if_index_set == 0)
4303 {
4304 errmsg ("missing interface name or sw_if_index");
4305 return -99;
4306 }
4307
4308 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004309 M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004310
4311 mp->sw_if_index = ntohl (sw_if_index);
4312 mp->enable = enable;
4313
4314 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004315 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004316
4317 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06004318 W (ret);
4319 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004320}
4321
4322static int
4323api_sw_interface_set_table (vat_main_t * vam)
4324{
4325 unformat_input_t *i = vam->input;
4326 vl_api_sw_interface_set_table_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004327 u32 sw_if_index, vrf_id = 0;
4328 u8 sw_if_index_set = 0;
4329 u8 is_ipv6 = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004330 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004331
4332 /* Parse args required to build the message */
4333 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4334 {
4335 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4336 sw_if_index_set = 1;
4337 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4338 sw_if_index_set = 1;
4339 else if (unformat (i, "vrf %d", &vrf_id))
4340 ;
4341 else if (unformat (i, "ipv6"))
4342 is_ipv6 = 1;
4343 else
4344 break;
4345 }
4346
4347 if (sw_if_index_set == 0)
4348 {
4349 errmsg ("missing interface name or sw_if_index");
4350 return -99;
4351 }
4352
4353 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004354 M (SW_INTERFACE_SET_TABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004355
4356 mp->sw_if_index = ntohl (sw_if_index);
4357 mp->is_ipv6 = is_ipv6;
4358 mp->vrf_id = ntohl (vrf_id);
4359
4360 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004361 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004362
4363 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06004364 W (ret);
4365 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004366}
4367
4368static void vl_api_sw_interface_get_table_reply_t_handler
4369 (vl_api_sw_interface_get_table_reply_t * mp)
4370{
4371 vat_main_t *vam = &vat_main;
4372
4373 print (vam->ofp, "%d", ntohl (mp->vrf_id));
4374
4375 vam->retval = ntohl (mp->retval);
4376 vam->result_ready = 1;
4377
4378}
4379
4380static void vl_api_sw_interface_get_table_reply_t_handler_json
4381 (vl_api_sw_interface_get_table_reply_t * mp)
4382{
4383 vat_main_t *vam = &vat_main;
4384 vat_json_node_t node;
4385
4386 vat_json_init_object (&node);
4387 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4388 vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
4389
4390 vat_json_print (vam->ofp, &node);
4391 vat_json_free (&node);
4392
4393 vam->retval = ntohl (mp->retval);
4394 vam->result_ready = 1;
4395}
4396
4397static int
4398api_sw_interface_get_table (vat_main_t * vam)
4399{
4400 unformat_input_t *i = vam->input;
4401 vl_api_sw_interface_get_table_t *mp;
4402 u32 sw_if_index;
4403 u8 sw_if_index_set = 0;
4404 u8 is_ipv6 = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004405 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004406
4407 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4408 {
4409 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4410 sw_if_index_set = 1;
4411 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4412 sw_if_index_set = 1;
4413 else if (unformat (i, "ipv6"))
4414 is_ipv6 = 1;
4415 else
4416 break;
4417 }
4418
4419 if (sw_if_index_set == 0)
4420 {
4421 errmsg ("missing interface name or sw_if_index");
4422 return -99;
4423 }
4424
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004425 M (SW_INTERFACE_GET_TABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004426 mp->sw_if_index = htonl (sw_if_index);
4427 mp->is_ipv6 = is_ipv6;
4428
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004429 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06004430 W (ret);
4431 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004432}
4433
4434static int
4435api_sw_interface_set_vpath (vat_main_t * vam)
4436{
4437 unformat_input_t *i = vam->input;
4438 vl_api_sw_interface_set_vpath_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004439 u32 sw_if_index = 0;
4440 u8 sw_if_index_set = 0;
4441 u8 is_enable = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004442 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004443
4444 /* Parse args required to build the message */
4445 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4446 {
4447 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4448 sw_if_index_set = 1;
4449 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4450 sw_if_index_set = 1;
4451 else if (unformat (i, "enable"))
4452 is_enable = 1;
4453 else if (unformat (i, "disable"))
4454 is_enable = 0;
4455 else
4456 break;
4457 }
4458
4459 if (sw_if_index_set == 0)
4460 {
4461 errmsg ("missing interface name or sw_if_index");
4462 return -99;
4463 }
4464
4465 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004466 M (SW_INTERFACE_SET_VPATH, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004467
4468 mp->sw_if_index = ntohl (sw_if_index);
4469 mp->enable = is_enable;
4470
4471 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004472 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004473
4474 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06004475 W (ret);
4476 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004477}
4478
4479static int
4480api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
4481{
4482 unformat_input_t *i = vam->input;
4483 vl_api_sw_interface_set_vxlan_bypass_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004484 u32 sw_if_index = 0;
4485 u8 sw_if_index_set = 0;
John Lo2b81eb82017-01-30 13:12:10 -05004486 u8 is_enable = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004487 u8 is_ipv6 = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004488 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004489
4490 /* Parse args required to build the message */
4491 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4492 {
4493 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4494 sw_if_index_set = 1;
4495 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4496 sw_if_index_set = 1;
4497 else if (unformat (i, "enable"))
4498 is_enable = 1;
4499 else if (unformat (i, "disable"))
4500 is_enable = 0;
4501 else if (unformat (i, "ip4"))
4502 is_ipv6 = 0;
4503 else if (unformat (i, "ip6"))
4504 is_ipv6 = 1;
4505 else
4506 break;
4507 }
4508
4509 if (sw_if_index_set == 0)
4510 {
4511 errmsg ("missing interface name or sw_if_index");
4512 return -99;
4513 }
4514
4515 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004516 M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004517
4518 mp->sw_if_index = ntohl (sw_if_index);
4519 mp->enable = is_enable;
4520 mp->is_ipv6 = is_ipv6;
4521
4522 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004523 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004524
4525 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06004526 W (ret);
4527 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004528}
4529
Marco Varleseb598f1d2017-09-19 14:25:28 +02004530static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01004531api_sw_interface_set_l2_xconnect (vat_main_t * vam)
4532{
4533 unformat_input_t *i = vam->input;
4534 vl_api_sw_interface_set_l2_xconnect_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004535 u32 rx_sw_if_index;
4536 u8 rx_sw_if_index_set = 0;
4537 u32 tx_sw_if_index;
4538 u8 tx_sw_if_index_set = 0;
4539 u8 enable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004540 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004541
4542 /* Parse args required to build the message */
4543 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4544 {
4545 if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
4546 rx_sw_if_index_set = 1;
4547 else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
4548 tx_sw_if_index_set = 1;
4549 else if (unformat (i, "rx"))
4550 {
4551 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4552 {
4553 if (unformat (i, "%U", api_unformat_sw_if_index, vam,
4554 &rx_sw_if_index))
4555 rx_sw_if_index_set = 1;
4556 }
4557 else
4558 break;
4559 }
4560 else if (unformat (i, "tx"))
4561 {
4562 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4563 {
4564 if (unformat (i, "%U", api_unformat_sw_if_index, vam,
4565 &tx_sw_if_index))
4566 tx_sw_if_index_set = 1;
4567 }
4568 else
4569 break;
4570 }
4571 else if (unformat (i, "enable"))
4572 enable = 1;
4573 else if (unformat (i, "disable"))
4574 enable = 0;
4575 else
4576 break;
4577 }
4578
4579 if (rx_sw_if_index_set == 0)
4580 {
4581 errmsg ("missing rx interface name or rx_sw_if_index");
4582 return -99;
4583 }
4584
4585 if (enable && (tx_sw_if_index_set == 0))
4586 {
4587 errmsg ("missing tx interface name or tx_sw_if_index");
4588 return -99;
4589 }
4590
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004591 M (SW_INTERFACE_SET_L2_XCONNECT, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004592
4593 mp->rx_sw_if_index = ntohl (rx_sw_if_index);
4594 mp->tx_sw_if_index = ntohl (tx_sw_if_index);
4595 mp->enable = enable;
4596
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004597 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06004598 W (ret);
4599 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004600}
4601
4602static int
4603api_sw_interface_set_l2_bridge (vat_main_t * vam)
4604{
4605 unformat_input_t *i = vam->input;
4606 vl_api_sw_interface_set_l2_bridge_t *mp;
Neale Rannsb4743802018-09-05 09:13:57 -07004607 vl_api_l2_port_type_t port_type;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004608 u32 rx_sw_if_index;
4609 u8 rx_sw_if_index_set = 0;
4610 u32 bd_id;
4611 u8 bd_id_set = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004612 u32 shg = 0;
4613 u8 enable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004614 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004615
Neale Rannsb4743802018-09-05 09:13:57 -07004616 port_type = L2_API_PORT_TYPE_NORMAL;
4617
Damjan Marion7cd468a2016-12-19 23:05:39 +01004618 /* Parse args required to build the message */
4619 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4620 {
4621 if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
4622 rx_sw_if_index_set = 1;
4623 else if (unformat (i, "bd_id %d", &bd_id))
4624 bd_id_set = 1;
4625 else
4626 if (unformat
4627 (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
4628 rx_sw_if_index_set = 1;
4629 else if (unformat (i, "shg %d", &shg))
4630 ;
4631 else if (unformat (i, "bvi"))
Neale Rannsb4743802018-09-05 09:13:57 -07004632 port_type = L2_API_PORT_TYPE_BVI;
4633 else if (unformat (i, "uu-fwd"))
4634 port_type = L2_API_PORT_TYPE_UU_FWD;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004635 else if (unformat (i, "enable"))
4636 enable = 1;
4637 else if (unformat (i, "disable"))
4638 enable = 0;
4639 else
4640 break;
4641 }
4642
4643 if (rx_sw_if_index_set == 0)
4644 {
4645 errmsg ("missing rx interface name or sw_if_index");
4646 return -99;
4647 }
4648
4649 if (enable && (bd_id_set == 0))
4650 {
4651 errmsg ("missing bridge domain");
4652 return -99;
4653 }
4654
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004655 M (SW_INTERFACE_SET_L2_BRIDGE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004656
4657 mp->rx_sw_if_index = ntohl (rx_sw_if_index);
4658 mp->bd_id = ntohl (bd_id);
4659 mp->shg = (u8) shg;
Neale Rannsb4743802018-09-05 09:13:57 -07004660 mp->port_type = ntohl (port_type);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004661 mp->enable = enable;
4662
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004663 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06004664 W (ret);
4665 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004666}
4667
4668static int
4669api_bridge_domain_dump (vat_main_t * vam)
4670{
4671 unformat_input_t *i = vam->input;
4672 vl_api_bridge_domain_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -06004673 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004674 u32 bd_id = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004675 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004676
4677 /* Parse args required to build the message */
4678 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4679 {
4680 if (unformat (i, "bd_id %d", &bd_id))
4681 ;
4682 else
4683 break;
4684 }
4685
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004686 M (BRIDGE_DOMAIN_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004687 mp->bd_id = ntohl (bd_id);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004688 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004689
4690 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -04004691 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06004692 S (mp_ping);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004693
Jon Loeliger56c7b012017-02-01 12:31:41 -06004694 W (ret);
4695 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004696}
4697
4698static int
4699api_bridge_domain_add_del (vat_main_t * vam)
4700{
4701 unformat_input_t *i = vam->input;
4702 vl_api_bridge_domain_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004703 u32 bd_id = ~0;
4704 u8 is_add = 1;
4705 u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
Jerome Tollet50570ec2017-09-14 12:53:56 +01004706 u8 *bd_tag = NULL;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004707 u32 mac_age = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004708 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004709
4710 /* Parse args required to build the message */
4711 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4712 {
4713 if (unformat (i, "bd_id %d", &bd_id))
4714 ;
4715 else if (unformat (i, "flood %d", &flood))
4716 ;
4717 else if (unformat (i, "uu-flood %d", &uu_flood))
4718 ;
4719 else if (unformat (i, "forward %d", &forward))
4720 ;
4721 else if (unformat (i, "learn %d", &learn))
4722 ;
4723 else if (unformat (i, "arp-term %d", &arp_term))
4724 ;
4725 else if (unformat (i, "mac-age %d", &mac_age))
4726 ;
Jerome Tollet50570ec2017-09-14 12:53:56 +01004727 else if (unformat (i, "bd-tag %s", &bd_tag))
4728 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004729 else if (unformat (i, "del"))
4730 {
4731 is_add = 0;
4732 flood = uu_flood = forward = learn = 0;
4733 }
4734 else
4735 break;
4736 }
4737
4738 if (bd_id == ~0)
4739 {
4740 errmsg ("missing bridge domain");
Jerome Tollet50570ec2017-09-14 12:53:56 +01004741 ret = -99;
4742 goto done;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004743 }
4744
4745 if (mac_age > 255)
4746 {
4747 errmsg ("mac age must be less than 256 ");
Jerome Tollet50570ec2017-09-14 12:53:56 +01004748 ret = -99;
4749 goto done;
4750 }
4751
John Lo70bfcaf2017-11-14 13:19:26 -05004752 if ((bd_tag) && (vec_len (bd_tag) > 63))
Jerome Tollet50570ec2017-09-14 12:53:56 +01004753 {
4754 errmsg ("bd-tag cannot be longer than 63");
4755 ret = -99;
4756 goto done;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004757 }
4758
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004759 M (BRIDGE_DOMAIN_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004760
4761 mp->bd_id = ntohl (bd_id);
4762 mp->flood = flood;
4763 mp->uu_flood = uu_flood;
4764 mp->forward = forward;
4765 mp->learn = learn;
4766 mp->arp_term = arp_term;
4767 mp->is_add = is_add;
4768 mp->mac_age = (u8) mac_age;
Jerome Tollet50570ec2017-09-14 12:53:56 +01004769 if (bd_tag)
John Lo70bfcaf2017-11-14 13:19:26 -05004770 {
4771 clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
4772 mp->bd_tag[vec_len (bd_tag)] = 0;
4773 }
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004774 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06004775 W (ret);
Jerome Tollet50570ec2017-09-14 12:53:56 +01004776
4777done:
4778 vec_free (bd_tag);
Jon Loeliger56c7b012017-02-01 12:31:41 -06004779 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004780}
4781
4782static int
Eyal Barif24991c2017-04-05 05:33:21 +03004783api_l2fib_flush_bd (vat_main_t * vam)
4784{
4785 unformat_input_t *i = vam->input;
4786 vl_api_l2fib_flush_bd_t *mp;
4787 u32 bd_id = ~0;
4788 int ret;
4789
4790 /* Parse args required to build the message */
4791 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4792 {
4793 if (unformat (i, "bd_id %d", &bd_id));
4794 else
4795 break;
4796 }
4797
4798 if (bd_id == ~0)
4799 {
4800 errmsg ("missing bridge domain");
4801 return -99;
4802 }
4803
4804 M (L2FIB_FLUSH_BD, mp);
4805
4806 mp->bd_id = htonl (bd_id);
4807
4808 S (mp);
4809 W (ret);
4810 return ret;
4811}
4812
4813static int
4814api_l2fib_flush_int (vat_main_t * vam)
4815{
4816 unformat_input_t *i = vam->input;
4817 vl_api_l2fib_flush_int_t *mp;
4818 u32 sw_if_index = ~0;
4819 int ret;
4820
4821 /* Parse args required to build the message */
4822 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4823 {
4824 if (unformat (i, "sw_if_index %d", &sw_if_index));
4825 else
4826 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
4827 else
4828 break;
4829 }
4830
4831 if (sw_if_index == ~0)
4832 {
4833 errmsg ("missing interface name or sw_if_index");
4834 return -99;
4835 }
4836
4837 M (L2FIB_FLUSH_INT, mp);
4838
4839 mp->sw_if_index = ntohl (sw_if_index);
4840
4841 S (mp);
4842 W (ret);
4843 return ret;
4844}
4845
4846static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01004847api_l2fib_add_del (vat_main_t * vam)
4848{
4849 unformat_input_t *i = vam->input;
4850 vl_api_l2fib_add_del_t *mp;
4851 f64 timeout;
Mohsin Kazmi57938f62017-10-27 21:28:07 +02004852 u8 mac[6] = { 0 };
Damjan Marion7cd468a2016-12-19 23:05:39 +01004853 u8 mac_set = 0;
4854 u32 bd_id;
4855 u8 bd_id_set = 0;
John Lo7dbd7262018-05-31 10:25:18 -04004856 u32 sw_if_index = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004857 u8 sw_if_index_set = 0;
4858 u8 is_add = 1;
4859 u8 static_mac = 0;
4860 u8 filter_mac = 0;
4861 u8 bvi_mac = 0;
4862 int count = 1;
4863 f64 before = 0;
4864 int j;
4865
4866 /* Parse args required to build the message */
4867 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4868 {
Mohsin Kazmi57938f62017-10-27 21:28:07 +02004869 if (unformat (i, "mac %U", unformat_ethernet_address, mac))
Damjan Marion7cd468a2016-12-19 23:05:39 +01004870 mac_set = 1;
4871 else if (unformat (i, "bd_id %d", &bd_id))
4872 bd_id_set = 1;
4873 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4874 sw_if_index_set = 1;
4875 else if (unformat (i, "sw_if"))
4876 {
4877 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4878 {
4879 if (unformat
4880 (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4881 sw_if_index_set = 1;
4882 }
4883 else
4884 break;
4885 }
4886 else if (unformat (i, "static"))
4887 static_mac = 1;
4888 else if (unformat (i, "filter"))
4889 {
4890 filter_mac = 1;
4891 static_mac = 1;
4892 }
4893 else if (unformat (i, "bvi"))
4894 {
4895 bvi_mac = 1;
4896 static_mac = 1;
4897 }
4898 else if (unformat (i, "del"))
4899 is_add = 0;
4900 else if (unformat (i, "count %d", &count))
4901 ;
4902 else
4903 break;
4904 }
4905
4906 if (mac_set == 0)
4907 {
4908 errmsg ("missing mac address");
4909 return -99;
4910 }
4911
4912 if (bd_id_set == 0)
4913 {
4914 errmsg ("missing bridge domain");
4915 return -99;
4916 }
4917
4918 if (is_add && sw_if_index_set == 0 && filter_mac == 0)
4919 {
4920 errmsg ("missing interface name or sw_if_index");
4921 return -99;
4922 }
4923
4924 if (count > 1)
4925 {
4926 /* Turn on async mode */
4927 vam->async_mode = 1;
4928 vam->async_errors = 0;
4929 before = vat_time_now (vam);
4930 }
4931
4932 for (j = 0; j < count; j++)
4933 {
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004934 M (L2FIB_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004935
Mohsin Kazmi57938f62017-10-27 21:28:07 +02004936 clib_memcpy (mp->mac, mac, 6);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004937 mp->bd_id = ntohl (bd_id);
4938 mp->is_add = is_add;
John Lo7dbd7262018-05-31 10:25:18 -04004939 mp->sw_if_index = ntohl (sw_if_index);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004940
4941 if (is_add)
4942 {
Damjan Marion7cd468a2016-12-19 23:05:39 +01004943 mp->static_mac = static_mac;
4944 mp->filter_mac = filter_mac;
4945 mp->bvi_mac = bvi_mac;
4946 }
Mohsin Kazmi57938f62017-10-27 21:28:07 +02004947 increment_mac_address (mac);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004948 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004949 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004950 }
4951
4952 if (count > 1)
4953 {
Jon Loeliger2d23eca2017-02-01 13:09:58 -06004954 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004955 f64 after;
4956
4957 /* Shut off async mode */
4958 vam->async_mode = 0;
4959
Dave Barach59b25652017-09-10 15:04:27 -04004960 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06004961 S (mp_ping);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004962
4963 timeout = vat_time_now (vam) + 1.0;
4964 while (vat_time_now (vam) < timeout)
4965 if (vam->result_ready == 1)
4966 goto out;
4967 vam->retval = -99;
4968
4969 out:
4970 if (vam->retval == -99)
4971 errmsg ("timeout");
4972
4973 if (vam->async_errors > 0)
4974 {
4975 errmsg ("%d asynchronous errors", vam->async_errors);
4976 vam->retval = -98;
4977 }
4978 vam->async_errors = 0;
4979 after = vat_time_now (vam);
4980
4981 print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
4982 count, after - before, count / (after - before));
4983 }
4984 else
4985 {
Jon Loeliger56c7b012017-02-01 12:31:41 -06004986 int ret;
4987
Damjan Marion7cd468a2016-12-19 23:05:39 +01004988 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06004989 W (ret);
4990 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004991 }
4992 /* Return the good/bad news */
4993 return (vam->retval);
4994}
4995
4996static int
Eyal Barifead6702017-04-04 04:46:32 +03004997api_bridge_domain_set_mac_age (vat_main_t * vam)
4998{
4999 unformat_input_t *i = vam->input;
5000 vl_api_bridge_domain_set_mac_age_t *mp;
5001 u32 bd_id = ~0;
5002 u32 mac_age = 0;
5003 int ret;
5004
5005 /* Parse args required to build the message */
5006 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5007 {
5008 if (unformat (i, "bd_id %d", &bd_id));
5009 else if (unformat (i, "mac-age %d", &mac_age));
5010 else
5011 break;
5012 }
5013
5014 if (bd_id == ~0)
5015 {
5016 errmsg ("missing bridge domain");
5017 return -99;
5018 }
5019
5020 if (mac_age > 255)
5021 {
5022 errmsg ("mac age must be less than 256 ");
5023 return -99;
5024 }
5025
5026 M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
5027
5028 mp->bd_id = htonl (bd_id);
5029 mp->mac_age = (u8) mac_age;
5030
5031 S (mp);
5032 W (ret);
5033 return ret;
5034}
5035
5036static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01005037api_l2_flags (vat_main_t * vam)
5038{
5039 unformat_input_t *i = vam->input;
5040 vl_api_l2_flags_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005041 u32 sw_if_index;
John Lo8d00fff2017-08-03 00:35:36 -04005042 u32 flags = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005043 u8 sw_if_index_set = 0;
John Lo8d00fff2017-08-03 00:35:36 -04005044 u8 is_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005045 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005046
5047 /* Parse args required to build the message */
5048 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5049 {
5050 if (unformat (i, "sw_if_index %d", &sw_if_index))
5051 sw_if_index_set = 1;
5052 else if (unformat (i, "sw_if"))
5053 {
5054 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5055 {
5056 if (unformat
5057 (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5058 sw_if_index_set = 1;
5059 }
5060 else
5061 break;
5062 }
5063 else if (unformat (i, "learn"))
John Lo8d00fff2017-08-03 00:35:36 -04005064 flags |= L2_LEARN;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005065 else if (unformat (i, "forward"))
John Lo8d00fff2017-08-03 00:35:36 -04005066 flags |= L2_FWD;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005067 else if (unformat (i, "flood"))
John Lo8d00fff2017-08-03 00:35:36 -04005068 flags |= L2_FLOOD;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005069 else if (unformat (i, "uu-flood"))
John Lo8d00fff2017-08-03 00:35:36 -04005070 flags |= L2_UU_FLOOD;
5071 else if (unformat (i, "arp-term"))
5072 flags |= L2_ARP_TERM;
5073 else if (unformat (i, "off"))
5074 is_set = 0;
5075 else if (unformat (i, "disable"))
5076 is_set = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005077 else
5078 break;
5079 }
5080
5081 if (sw_if_index_set == 0)
5082 {
5083 errmsg ("missing interface name or sw_if_index");
5084 return -99;
5085 }
5086
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005087 M (L2_FLAGS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005088
5089 mp->sw_if_index = ntohl (sw_if_index);
John Lo8d00fff2017-08-03 00:35:36 -04005090 mp->feature_bitmap = ntohl (flags);
5091 mp->is_set = is_set;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005092
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005093 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06005094 W (ret);
5095 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005096}
5097
5098static int
5099api_bridge_flags (vat_main_t * vam)
5100{
5101 unformat_input_t *i = vam->input;
5102 vl_api_bridge_flags_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005103 u32 bd_id;
5104 u8 bd_id_set = 0;
5105 u8 is_set = 1;
Neale Rannsb4743802018-09-05 09:13:57 -07005106 bd_flags_t flags = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005107 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005108
5109 /* Parse args required to build the message */
5110 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5111 {
5112 if (unformat (i, "bd_id %d", &bd_id))
5113 bd_id_set = 1;
5114 else if (unformat (i, "learn"))
Neale Rannsb4743802018-09-05 09:13:57 -07005115 flags |= BRIDGE_API_FLAG_LEARN;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005116 else if (unformat (i, "forward"))
Neale Rannsb4743802018-09-05 09:13:57 -07005117 flags |= BRIDGE_API_FLAG_FWD;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005118 else if (unformat (i, "flood"))
Neale Rannsb4743802018-09-05 09:13:57 -07005119 flags |= BRIDGE_API_FLAG_FLOOD;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005120 else if (unformat (i, "uu-flood"))
Neale Rannsb4743802018-09-05 09:13:57 -07005121 flags |= BRIDGE_API_FLAG_UU_FLOOD;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005122 else if (unformat (i, "arp-term"))
Neale Rannsb4743802018-09-05 09:13:57 -07005123 flags |= BRIDGE_API_FLAG_ARP_TERM;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005124 else if (unformat (i, "off"))
5125 is_set = 0;
5126 else if (unformat (i, "disable"))
5127 is_set = 0;
5128 else
5129 break;
5130 }
5131
5132 if (bd_id_set == 0)
5133 {
5134 errmsg ("missing bridge domain");
5135 return -99;
5136 }
5137
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005138 M (BRIDGE_FLAGS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005139
5140 mp->bd_id = ntohl (bd_id);
Neale Rannsb4743802018-09-05 09:13:57 -07005141 mp->flags = ntohl (flags);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005142 mp->is_set = is_set;
5143
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005144 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06005145 W (ret);
5146 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005147}
5148
5149static int
5150api_bd_ip_mac_add_del (vat_main_t * vam)
5151{
Neale Ranns4d5b9172018-10-24 02:57:49 -07005152 vl_api_address_t ip = VL_API_ZERO_ADDRESS;
Ole Troan8006c6a2018-12-17 12:02:26 +01005153 vl_api_mac_address_t mac = { 0 };
Damjan Marion7cd468a2016-12-19 23:05:39 +01005154 unformat_input_t *i = vam->input;
5155 vl_api_bd_ip_mac_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005156 u32 bd_id;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005157 u8 is_add = 1;
5158 u8 bd_id_set = 0;
5159 u8 ip_set = 0;
5160 u8 mac_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005161 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005162
5163
5164 /* Parse args required to build the message */
5165 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5166 {
5167 if (unformat (i, "bd_id %d", &bd_id))
5168 {
5169 bd_id_set++;
5170 }
Neale Ranns4d5b9172018-10-24 02:57:49 -07005171 else if (unformat (i, "%U", unformat_vl_api_address, &ip))
Damjan Marion7cd468a2016-12-19 23:05:39 +01005172 {
5173 ip_set++;
5174 }
Neale Ranns4d5b9172018-10-24 02:57:49 -07005175 else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
Damjan Marion7cd468a2016-12-19 23:05:39 +01005176 {
5177 mac_set++;
5178 }
5179 else if (unformat (i, "del"))
5180 is_add = 0;
5181 else
5182 break;
5183 }
5184
5185 if (bd_id_set == 0)
5186 {
5187 errmsg ("missing bridge domain");
5188 return -99;
5189 }
5190 else if (ip_set == 0)
5191 {
5192 errmsg ("missing IP address");
5193 return -99;
5194 }
5195 else if (mac_set == 0)
5196 {
5197 errmsg ("missing MAC address");
5198 return -99;
5199 }
5200
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005201 M (BD_IP_MAC_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005202
Neale Rannsbc764c82019-06-19 07:07:13 -07005203 mp->entry.bd_id = ntohl (bd_id);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005204 mp->is_add = is_add;
Neale Ranns4d5b9172018-10-24 02:57:49 -07005205
Neale Rannsbc764c82019-06-19 07:07:13 -07005206 clib_memcpy (&mp->entry.ip, &ip, sizeof (ip));
5207 clib_memcpy (&mp->entry.mac, &mac, sizeof (mac));
Neale Ranns4d5b9172018-10-24 02:57:49 -07005208
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005209 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06005210 W (ret);
5211 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005212}
5213
John Loe26c81f2019-01-07 15:16:33 -05005214static int
5215api_bd_ip_mac_flush (vat_main_t * vam)
5216{
5217 unformat_input_t *i = vam->input;
5218 vl_api_bd_ip_mac_flush_t *mp;
5219 u32 bd_id;
5220 u8 bd_id_set = 0;
5221 int ret;
5222
5223 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5224 {
5225 if (unformat (i, "bd_id %d", &bd_id))
5226 {
5227 bd_id_set++;
5228 }
5229 else
5230 break;
5231 }
5232
5233 if (bd_id_set == 0)
5234 {
5235 errmsg ("missing bridge domain");
5236 return -99;
5237 }
5238
5239 M (BD_IP_MAC_FLUSH, mp);
5240
5241 mp->bd_id = ntohl (bd_id);
5242
5243 S (mp);
5244 W (ret);
5245 return ret;
5246}
5247
Mohsin Kazmi5d82d2f2018-08-13 19:17:54 +02005248static void vl_api_bd_ip_mac_details_t_handler
5249 (vl_api_bd_ip_mac_details_t * mp)
5250{
5251 vat_main_t *vam = &vat_main;
Mohsin Kazmi5d82d2f2018-08-13 19:17:54 +02005252
5253 print (vam->ofp,
Neale Rannsbc764c82019-06-19 07:07:13 -07005254 "\n%-5d %U %U",
5255 ntohl (mp->entry.bd_id),
5256 format_vl_api_mac_address, mp->entry.mac,
5257 format_vl_api_address, &mp->entry.ip);
Mohsin Kazmi5d82d2f2018-08-13 19:17:54 +02005258}
5259
5260static void vl_api_bd_ip_mac_details_t_handler_json
5261 (vl_api_bd_ip_mac_details_t * mp)
5262{
5263 vat_main_t *vam = &vat_main;
5264 vat_json_node_t *node = NULL;
5265
5266 if (VAT_JSON_ARRAY != vam->json_tree.type)
5267 {
5268 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5269 vat_json_init_array (&vam->json_tree);
5270 }
5271 node = vat_json_array_add (&vam->json_tree);
5272
5273 vat_json_init_object (node);
Neale Rannsbc764c82019-06-19 07:07:13 -07005274 vat_json_object_add_uint (node, "bd_id", ntohl (mp->entry.bd_id));
Mohsin Kazmi5d82d2f2018-08-13 19:17:54 +02005275 vat_json_object_add_string_copy (node, "mac_address",
Neale Rannsbc764c82019-06-19 07:07:13 -07005276 format (0, "%U", format_vl_api_mac_address,
5277 &mp->entry.mac));
Mohsin Kazmi5d82d2f2018-08-13 19:17:54 +02005278 u8 *ip = 0;
5279
Neale Rannsbc764c82019-06-19 07:07:13 -07005280 ip = format (0, "%U", format_vl_api_address, &mp->entry.ip);
Mohsin Kazmi5d82d2f2018-08-13 19:17:54 +02005281 vat_json_object_add_string_copy (node, "ip_address", ip);
5282 vec_free (ip);
5283}
5284
5285static int
5286api_bd_ip_mac_dump (vat_main_t * vam)
5287{
5288 unformat_input_t *i = vam->input;
5289 vl_api_bd_ip_mac_dump_t *mp;
5290 vl_api_control_ping_t *mp_ping;
5291 int ret;
5292 u32 bd_id;
5293 u8 bd_id_set = 0;
5294
5295 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5296 {
5297 if (unformat (i, "bd_id %d", &bd_id))
5298 {
5299 bd_id_set++;
5300 }
5301 else
5302 break;
5303 }
5304
5305 print (vam->ofp,
5306 "\n%-5s %-7s %-20s %-30s",
5307 "bd_id", "is_ipv6", "mac_address", "ip_address");
5308
5309 /* Dump Bridge Domain Ip to Mac entries */
5310 M (BD_IP_MAC_DUMP, mp);
5311
5312 if (bd_id_set)
5313 mp->bd_id = htonl (bd_id);
5314 else
5315 mp->bd_id = ~0;
5316
5317 S (mp);
5318
5319 /* Use a control ping for synchronization */
5320 MPING (CONTROL_PING, mp_ping);
5321 S (mp_ping);
5322
5323 W (ret);
5324 return ret;
5325}
5326
Damjan Marion7cd468a2016-12-19 23:05:39 +01005327static int
Damjan Marion8389fb92017-10-13 18:29:53 +02005328api_tap_create_v2 (vat_main_t * vam)
5329{
5330 unformat_input_t *i = vam->input;
5331 vl_api_tap_create_v2_t *mp;
5332 u8 mac_address[6];
5333 u8 random_mac = 1;
Damjan Marion2df39092017-12-04 20:03:37 +01005334 u32 id = ~0;
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005335 u32 num_rx_queues = 0;
Damjan Marion2df39092017-12-04 20:03:37 +01005336 u8 *host_if_name = 0;
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005337 u8 host_if_name_set = 0;
Damjan Marion2df39092017-12-04 20:03:37 +01005338 u8 *host_ns = 0;
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005339 u8 host_ns_set = 0;
Damjan Marion2df39092017-12-04 20:03:37 +01005340 u8 host_mac_addr[6];
5341 u8 host_mac_addr_set = 0;
Damjan Marion91c6ef72017-12-01 13:34:24 +01005342 u8 *host_bridge = 0;
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005343 u8 host_bridge_set = 0;
5344 u8 host_ip4_prefix_set = 0;
5345 u8 host_ip6_prefix_set = 0;
Damjan Marion91c6ef72017-12-01 13:34:24 +01005346 ip4_address_t host_ip4_addr;
Damjan Marion7866c452018-01-18 13:35:11 +01005347 ip4_address_t host_ip4_gw;
5348 u8 host_ip4_gw_set = 0;
Damjan Marion91c6ef72017-12-01 13:34:24 +01005349 u32 host_ip4_prefix_len = 0;
5350 ip6_address_t host_ip6_addr;
Damjan Marion7866c452018-01-18 13:35:11 +01005351 ip6_address_t host_ip6_gw;
5352 u8 host_ip6_gw_set = 0;
Damjan Marion91c6ef72017-12-01 13:34:24 +01005353 u32 host_ip6_prefix_len = 0;
Mohsin Kazmi97d54ed2019-06-10 11:20:15 +02005354 u32 host_mtu_size = 0;
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005355 u8 host_mtu_set = 0;
Mohsin Kazmi97d54ed2019-06-10 11:20:15 +02005356 u32 tap_flags = 0;
Damjan Marion8389fb92017-10-13 18:29:53 +02005357 int ret;
Steven9e635692018-03-01 09:36:01 -08005358 u32 rx_ring_sz = 0, tx_ring_sz = 0;
Damjan Marion8389fb92017-10-13 18:29:53 +02005359
Dave Barachb7b92992018-10-17 10:38:51 -04005360 clib_memset (mac_address, 0, sizeof (mac_address));
Damjan Marion8389fb92017-10-13 18:29:53 +02005361
5362 /* Parse args required to build the message */
5363 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5364 {
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005365 if (unformat (i, "id %u", &id))
Damjan Marion91c6ef72017-12-01 13:34:24 +01005366 ;
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005367 else
5368 if (unformat
5369 (i, "hw-addr %U", unformat_ethernet_address, mac_address))
5370 random_mac = 0;
Damjan Marion2df39092017-12-04 20:03:37 +01005371 else if (unformat (i, "host-if-name %s", &host_if_name))
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005372 host_if_name_set = 1;
5373 else if (unformat (i, "num-rx-queues %u", &num_rx_queues))
Damjan Marion91c6ef72017-12-01 13:34:24 +01005374 ;
Damjan Marion2df39092017-12-04 20:03:37 +01005375 else if (unformat (i, "host-ns %s", &host_ns))
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005376 host_ns_set = 1;
Damjan Marion2df39092017-12-04 20:03:37 +01005377 else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
5378 host_mac_addr))
5379 host_mac_addr_set = 1;
Damjan Marion91c6ef72017-12-01 13:34:24 +01005380 else if (unformat (i, "host-bridge %s", &host_bridge))
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005381 host_bridge_set = 1;
5382 else if (unformat (i, "host-ip4-addr %U/%u", unformat_ip4_address,
Damjan Marion91c6ef72017-12-01 13:34:24 +01005383 &host_ip4_addr, &host_ip4_prefix_len))
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005384 host_ip4_prefix_set = 1;
5385 else if (unformat (i, "host-ip6-addr %U/%u", unformat_ip6_address,
Damjan Marion91c6ef72017-12-01 13:34:24 +01005386 &host_ip6_addr, &host_ip6_prefix_len))
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005387 host_ip6_prefix_set = 1;
Damjan Marion7866c452018-01-18 13:35:11 +01005388 else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
5389 &host_ip4_gw))
5390 host_ip4_gw_set = 1;
5391 else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
5392 &host_ip6_gw))
5393 host_ip6_gw_set = 1;
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005394 else if (unformat (i, "rx-ring-size %u", &rx_ring_sz))
Damjan Marion8389fb92017-10-13 18:29:53 +02005395 ;
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005396 else if (unformat (i, "tx-ring-size %u", &tx_ring_sz))
Damjan Marion8389fb92017-10-13 18:29:53 +02005397 ;
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005398 else if (unformat (i, "host-mtu-size %u", &host_mtu_size))
Mohsin Kazmi97d54ed2019-06-10 11:20:15 +02005399 host_mtu_set = 1;
5400 else if (unformat (i, "no-gso"))
Mohsin Kazmid88fc0f2020-04-30 19:05:56 +02005401 tap_flags &= ~TAP_API_FLAG_GSO;
Mohsin Kazmi97d54ed2019-06-10 11:20:15 +02005402 else if (unformat (i, "gso"))
Mohsin Kazmid88fc0f2020-04-30 19:05:56 +02005403 tap_flags |= TAP_API_FLAG_GSO;
Mohsin Kazmiba0061f2019-12-18 17:08:54 +01005404 else if (unformat (i, "csum-offload"))
Mohsin Kazmid88fc0f2020-04-30 19:05:56 +02005405 tap_flags |= TAP_API_FLAG_CSUM_OFFLOAD;
Mohsin Kazmib49bc1a2020-02-14 17:51:04 +00005406 else if (unformat (i, "persist"))
Mohsin Kazmid88fc0f2020-04-30 19:05:56 +02005407 tap_flags |= TAP_API_FLAG_PERSIST;
Mohsin Kazmib49bc1a2020-02-14 17:51:04 +00005408 else if (unformat (i, "attach"))
Mohsin Kazmid88fc0f2020-04-30 19:05:56 +02005409 tap_flags |= TAP_API_FLAG_ATTACH;
5410 else if (unformat (i, "tun"))
5411 tap_flags |= TAP_API_FLAG_TUN;
5412 else if (unformat (i, "gro-coalesce"))
5413 tap_flags |= TAP_API_FLAG_GRO_COALESCE;
Mohsin Kazmi50bd1652020-08-26 11:07:48 +02005414 else if (unformat (i, "packed"))
5415 tap_flags |= TAP_API_FLAG_PACKED;
5416 else if (unformat (i, "in-order"))
5417 tap_flags |= TAP_API_FLAG_IN_ORDER;
Damjan Marion8389fb92017-10-13 18:29:53 +02005418 else
5419 break;
5420 }
5421
Damjan Marion2df39092017-12-04 20:03:37 +01005422 if (vec_len (host_if_name) > 63)
Damjan Marion8389fb92017-10-13 18:29:53 +02005423 {
5424 errmsg ("tap name too long. ");
5425 return -99;
5426 }
Damjan Marion2df39092017-12-04 20:03:37 +01005427 if (vec_len (host_ns) > 63)
Damjan Marion8389fb92017-10-13 18:29:53 +02005428 {
5429 errmsg ("host name space too long. ");
5430 return -99;
5431 }
Damjan Marion91c6ef72017-12-01 13:34:24 +01005432 if (vec_len (host_bridge) > 63)
5433 {
5434 errmsg ("host bridge name too long. ");
5435 return -99;
5436 }
5437 if (host_ip4_prefix_len > 32)
5438 {
5439 errmsg ("host ip4 prefix length not valid. ");
5440 return -99;
5441 }
5442 if (host_ip6_prefix_len > 128)
5443 {
5444 errmsg ("host ip6 prefix length not valid. ");
5445 return -99;
5446 }
Damjan Marion8389fb92017-10-13 18:29:53 +02005447 if (!is_pow2 (rx_ring_sz))
5448 {
5449 errmsg ("rx ring size must be power of 2. ");
5450 return -99;
5451 }
5452 if (rx_ring_sz > 32768)
5453 {
5454 errmsg ("rx ring size must be 32768 or lower. ");
5455 return -99;
5456 }
5457 if (!is_pow2 (tx_ring_sz))
5458 {
5459 errmsg ("tx ring size must be power of 2. ");
5460 return -99;
5461 }
5462 if (tx_ring_sz > 32768)
5463 {
5464 errmsg ("tx ring size must be 32768 or lower. ");
5465 return -99;
5466 }
Mohsin Kazmi97d54ed2019-06-10 11:20:15 +02005467 if (host_mtu_set && (host_mtu_size < 64 || host_mtu_size > 65355))
5468 {
5469 errmsg ("host MTU size must be in between 64 and 65355. ");
5470 return -99;
5471 }
Damjan Marion8389fb92017-10-13 18:29:53 +02005472
Damjan Marion8389fb92017-10-13 18:29:53 +02005473 /* Construct the API message */
5474 M (TAP_CREATE_V2, mp);
5475
Steven9e635692018-03-01 09:36:01 -08005476 mp->id = ntohl (id);
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005477 mp->use_random_mac = random_mac;
5478 mp->num_rx_queues = (u8) num_rx_queues;
Steven9e635692018-03-01 09:36:01 -08005479 mp->tx_ring_sz = ntohs (tx_ring_sz);
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005480 mp->rx_ring_sz = ntohs (rx_ring_sz);
Mohsin Kazmi97d54ed2019-06-10 11:20:15 +02005481 mp->host_mtu_set = host_mtu_set;
5482 mp->host_mtu_size = ntohl (host_mtu_size);
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005483 mp->host_mac_addr_set = host_mac_addr_set;
5484 mp->host_ip4_prefix_set = host_ip4_prefix_set;
5485 mp->host_ip6_prefix_set = host_ip6_prefix_set;
5486 mp->host_ip4_gw_set = host_ip4_gw_set;
5487 mp->host_ip6_gw_set = host_ip6_gw_set;
Mohsin Kazmi97d54ed2019-06-10 11:20:15 +02005488 mp->tap_flags = ntohl (tap_flags);
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005489 mp->host_namespace_set = host_ns_set;
5490 mp->host_if_name_set = host_if_name_set;
5491 mp->host_bridge_set = host_bridge_set;
Damjan Marion2df39092017-12-04 20:03:37 +01005492
Steven9e635692018-03-01 09:36:01 -08005493 if (random_mac == 0)
Damjan Marion2df39092017-12-04 20:03:37 +01005494 clib_memcpy (mp->mac_address, mac_address, 6);
5495 if (host_mac_addr_set)
5496 clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005497 if (host_if_name_set)
Damjan Marion2df39092017-12-04 20:03:37 +01005498 clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005499 if (host_ns_set)
Damjan Marion2df39092017-12-04 20:03:37 +01005500 clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005501 if (host_bridge_set)
Damjan Marion91c6ef72017-12-01 13:34:24 +01005502 clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005503 if (host_ip4_prefix_set)
5504 {
5505 clib_memcpy (mp->host_ip4_prefix.address, &host_ip4_addr, 4);
5506 mp->host_ip4_prefix.len = (u8) host_ip4_prefix_len;
5507 }
5508 if (host_ip6_prefix_set)
5509 {
5510 clib_memcpy (mp->host_ip6_prefix.address, &host_ip6_addr, 16);
5511 mp->host_ip6_prefix.len = (u8) host_ip6_prefix_len;
5512 }
Damjan Marion7866c452018-01-18 13:35:11 +01005513 if (host_ip4_gw_set)
5514 clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
5515 if (host_ip6_gw_set)
5516 clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
Damjan Marion8389fb92017-10-13 18:29:53 +02005517
Damjan Marion2df39092017-12-04 20:03:37 +01005518 vec_free (host_ns);
5519 vec_free (host_if_name);
5520 vec_free (host_bridge);
Damjan Marion8389fb92017-10-13 18:29:53 +02005521
5522 /* send it... */
5523 S (mp);
5524
5525 /* Wait for a reply... */
5526 W (ret);
5527 return ret;
5528}
5529
5530static int
5531api_tap_delete_v2 (vat_main_t * vam)
5532{
5533 unformat_input_t *i = vam->input;
5534 vl_api_tap_delete_v2_t *mp;
5535 u32 sw_if_index = ~0;
5536 u8 sw_if_index_set = 0;
5537 int ret;
5538
5539 /* Parse args required to build the message */
5540 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5541 {
5542 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5543 sw_if_index_set = 1;
5544 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5545 sw_if_index_set = 1;
5546 else
5547 break;
5548 }
5549
5550 if (sw_if_index_set == 0)
5551 {
5552 errmsg ("missing vpp interface name. ");
5553 return -99;
5554 }
5555
5556 /* Construct the API message */
5557 M (TAP_DELETE_V2, mp);
5558
5559 mp->sw_if_index = ntohl (sw_if_index);
5560
5561 /* send it... */
5562 S (mp);
5563
5564 /* Wait for a reply... */
5565 W (ret);
5566 return ret;
5567}
5568
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005569uword
jialv01082ebeb2019-09-10 00:23:55 +08005570unformat_vlib_pci_addr (unformat_input_t * input, va_list * args)
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005571{
jialv01082ebeb2019-09-10 00:23:55 +08005572 vlib_pci_addr_t *addr = va_arg (*args, vlib_pci_addr_t *);
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005573 u32 x[4];
5574
5575 if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
5576 return 0;
5577
5578 addr->domain = x[0];
5579 addr->bus = x[1];
5580 addr->slot = x[2];
5581 addr->function = x[3];
5582
5583 return 1;
5584}
5585
5586static int
Mohsin Kazmi518251b2020-09-01 17:17:44 +00005587api_virtio_pci_create_v2 (vat_main_t * vam)
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005588{
5589 unformat_input_t *i = vam->input;
Mohsin Kazmi518251b2020-09-01 17:17:44 +00005590 vl_api_virtio_pci_create_v2_t *mp;
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005591 u8 mac_address[6];
5592 u8 random_mac = 1;
5593 u32 pci_addr = 0;
5594 u64 features = (u64) ~ (0ULL);
Mohsin Kazmi518251b2020-09-01 17:17:44 +00005595 u32 virtio_flags = 0;
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005596 int ret;
5597
5598 clib_memset (mac_address, 0, sizeof (mac_address));
5599
5600 /* Parse args required to build the message */
5601 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5602 {
5603 if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
5604 {
5605 random_mac = 0;
5606 }
jialv01082ebeb2019-09-10 00:23:55 +08005607 else if (unformat (i, "pci-addr %U", unformat_vlib_pci_addr, &pci_addr))
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005608 ;
5609 else if (unformat (i, "features 0x%llx", &features))
5610 ;
Mohsin Kazmibbd6b742019-05-02 13:54:59 +02005611 else if (unformat (i, "gso-enabled"))
Mohsin Kazmi518251b2020-09-01 17:17:44 +00005612 virtio_flags |= VIRTIO_API_FLAG_GSO;
Mohsin Kazmi6d4af892020-01-03 15:11:53 +00005613 else if (unformat (i, "csum-offload-enabled"))
Mohsin Kazmi518251b2020-09-01 17:17:44 +00005614 virtio_flags |= VIRTIO_API_FLAG_CSUM_OFFLOAD;
5615 else if (unformat (i, "gro-coalesce"))
5616 virtio_flags |= VIRTIO_API_FLAG_GRO_COALESCE;
5617 else if (unformat (i, "packed"))
5618 virtio_flags |= VIRTIO_API_FLAG_PACKED;
5619 else if (unformat (i, "in-order"))
5620 virtio_flags |= VIRTIO_API_FLAG_IN_ORDER;
Mohsin Kazmie347acb2020-09-28 10:26:33 +00005621 else if (unformat (i, "buffering"))
5622 virtio_flags |= VIRTIO_API_FLAG_BUFFERING;
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005623 else
5624 break;
5625 }
5626
5627 if (pci_addr == 0)
5628 {
5629 errmsg ("pci address must be non zero. ");
5630 return -99;
5631 }
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005632
5633 /* Construct the API message */
Mohsin Kazmi518251b2020-09-01 17:17:44 +00005634 M (VIRTIO_PCI_CREATE_V2, mp);
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005635
5636 mp->use_random_mac = random_mac;
5637
Jakub Grajciar2c504f82019-09-26 10:34:41 +02005638 mp->pci_addr.domain = htons (((vlib_pci_addr_t) pci_addr).domain);
5639 mp->pci_addr.bus = ((vlib_pci_addr_t) pci_addr).bus;
5640 mp->pci_addr.slot = ((vlib_pci_addr_t) pci_addr).slot;
5641 mp->pci_addr.function = ((vlib_pci_addr_t) pci_addr).function;
5642
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005643 mp->features = clib_host_to_net_u64 (features);
Mohsin Kazmi518251b2020-09-01 17:17:44 +00005644 mp->virtio_flags = clib_host_to_net_u32 (virtio_flags);
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005645
5646 if (random_mac == 0)
5647 clib_memcpy (mp->mac_address, mac_address, 6);
5648
5649 /* send it... */
5650 S (mp);
5651
5652 /* Wait for a reply... */
5653 W (ret);
5654 return ret;
5655}
5656
5657static int
5658api_virtio_pci_delete (vat_main_t * vam)
5659{
5660 unformat_input_t *i = vam->input;
5661 vl_api_virtio_pci_delete_t *mp;
5662 u32 sw_if_index = ~0;
5663 u8 sw_if_index_set = 0;
5664 int ret;
5665
5666 /* Parse args required to build the message */
5667 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5668 {
5669 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5670 sw_if_index_set = 1;
5671 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5672 sw_if_index_set = 1;
5673 else
5674 break;
5675 }
5676
5677 if (sw_if_index_set == 0)
5678 {
5679 errmsg ("missing vpp interface name. ");
5680 return -99;
5681 }
5682
5683 /* Construct the API message */
5684 M (VIRTIO_PCI_DELETE, mp);
5685
5686 mp->sw_if_index = htonl (sw_if_index);
5687
5688 /* send it... */
5689 S (mp);
5690
5691 /* Wait for a reply... */
5692 W (ret);
5693 return ret;
5694}
5695
Damjan Marion8389fb92017-10-13 18:29:53 +02005696static int
Steven9cd2d7a2017-12-20 12:43:01 -08005697api_bond_create (vat_main_t * vam)
5698{
5699 unformat_input_t *i = vam->input;
5700 vl_api_bond_create_t *mp;
5701 u8 mac_address[6];
5702 u8 custom_mac = 0;
5703 int ret;
5704 u8 mode;
5705 u8 lb;
5706 u8 mode_is_set = 0;
Alexander Chernavinad9d5282018-12-13 09:08:09 -05005707 u32 id = ~0;
Zhiyong Yang751e3f32019-06-26 05:49:14 -04005708 u8 numa_only = 0;
Steven9cd2d7a2017-12-20 12:43:01 -08005709
Dave Barachb7b92992018-10-17 10:38:51 -04005710 clib_memset (mac_address, 0, sizeof (mac_address));
Steven9cd2d7a2017-12-20 12:43:01 -08005711 lb = BOND_LB_L2;
5712
5713 /* Parse args required to build the message */
5714 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5715 {
5716 if (unformat (i, "mode %U", unformat_bond_mode, &mode))
5717 mode_is_set = 1;
5718 else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
5719 && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
5720 ;
5721 else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
5722 mac_address))
5723 custom_mac = 1;
Zhiyong Yang751e3f32019-06-26 05:49:14 -04005724 else if (unformat (i, "numa-only"))
5725 numa_only = 1;
Alexander Chernavinad9d5282018-12-13 09:08:09 -05005726 else if (unformat (i, "id %u", &id))
5727 ;
Steven9cd2d7a2017-12-20 12:43:01 -08005728 else
5729 break;
5730 }
5731
5732 if (mode_is_set == 0)
5733 {
5734 errmsg ("Missing bond mode. ");
5735 return -99;
5736 }
5737
5738 /* Construct the API message */
5739 M (BOND_CREATE, mp);
5740
5741 mp->use_custom_mac = custom_mac;
5742
Jakub Grajciar3d1ef872019-08-26 12:55:15 +02005743 mp->mode = htonl (mode);
5744 mp->lb = htonl (lb);
Alexander Chernavinad9d5282018-12-13 09:08:09 -05005745 mp->id = htonl (id);
Zhiyong Yang751e3f32019-06-26 05:49:14 -04005746 mp->numa_only = numa_only;
Steven9cd2d7a2017-12-20 12:43:01 -08005747
5748 if (custom_mac)
5749 clib_memcpy (mp->mac_address, mac_address, 6);
5750
5751 /* send it... */
5752 S (mp);
5753
5754 /* Wait for a reply... */
5755 W (ret);
5756 return ret;
5757}
5758
5759static int
Steven Luongea717862020-07-30 07:31:40 -07005760api_bond_create2 (vat_main_t * vam)
5761{
5762 unformat_input_t *i = vam->input;
5763 vl_api_bond_create2_t *mp;
5764 u8 mac_address[6];
5765 u8 custom_mac = 0;
5766 int ret;
5767 u8 mode;
5768 u8 lb;
5769 u8 mode_is_set = 0;
5770 u32 id = ~0;
5771 u8 numa_only = 0;
5772 u8 gso = 0;
5773
5774 clib_memset (mac_address, 0, sizeof (mac_address));
5775 lb = BOND_LB_L2;
5776
5777 /* Parse args required to build the message */
5778 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5779 {
5780 if (unformat (i, "mode %U", unformat_bond_mode, &mode))
5781 mode_is_set = 1;
5782 else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
5783 && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
5784 ;
5785 else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
5786 mac_address))
5787 custom_mac = 1;
5788 else if (unformat (i, "numa-only"))
5789 numa_only = 1;
5790 else if (unformat (i, "gso"))
5791 gso = 1;
5792 else if (unformat (i, "id %u", &id))
5793 ;
5794 else
5795 break;
5796 }
5797
5798 if (mode_is_set == 0)
5799 {
5800 errmsg ("Missing bond mode. ");
5801 return -99;
5802 }
5803
5804 /* Construct the API message */
5805 M (BOND_CREATE2, mp);
5806
5807 mp->use_custom_mac = custom_mac;
5808
5809 mp->mode = htonl (mode);
5810 mp->lb = htonl (lb);
5811 mp->id = htonl (id);
5812 mp->numa_only = numa_only;
5813 mp->enable_gso = gso;
5814
5815 if (custom_mac)
5816 clib_memcpy (mp->mac_address, mac_address, 6);
5817
5818 /* send it... */
5819 S (mp);
5820
5821 /* Wait for a reply... */
5822 W (ret);
5823 return ret;
5824}
5825
5826static int
Steven9cd2d7a2017-12-20 12:43:01 -08005827api_bond_delete (vat_main_t * vam)
5828{
5829 unformat_input_t *i = vam->input;
5830 vl_api_bond_delete_t *mp;
5831 u32 sw_if_index = ~0;
5832 u8 sw_if_index_set = 0;
5833 int ret;
5834
5835 /* Parse args required to build the message */
5836 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5837 {
5838 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5839 sw_if_index_set = 1;
5840 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5841 sw_if_index_set = 1;
5842 else
5843 break;
5844 }
5845
5846 if (sw_if_index_set == 0)
5847 {
5848 errmsg ("missing vpp interface name. ");
5849 return -99;
5850 }
5851
5852 /* Construct the API message */
5853 M (BOND_DELETE, mp);
5854
5855 mp->sw_if_index = ntohl (sw_if_index);
5856
5857 /* send it... */
5858 S (mp);
5859
5860 /* Wait for a reply... */
5861 W (ret);
5862 return ret;
5863}
5864
5865static int
Steven Luong4c4223e2020-07-15 08:44:54 -07005866api_bond_add_member (vat_main_t * vam)
Steven9cd2d7a2017-12-20 12:43:01 -08005867{
5868 unformat_input_t *i = vam->input;
Steven Luong4c4223e2020-07-15 08:44:54 -07005869 vl_api_bond_add_member_t *mp;
Steven9cd2d7a2017-12-20 12:43:01 -08005870 u32 bond_sw_if_index;
5871 int ret;
5872 u8 is_passive;
5873 u8 is_long_timeout;
5874 u32 bond_sw_if_index_is_set = 0;
5875 u32 sw_if_index;
5876 u8 sw_if_index_is_set = 0;
5877
5878 /* Parse args required to build the message */
5879 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5880 {
5881 if (unformat (i, "sw_if_index %d", &sw_if_index))
5882 sw_if_index_is_set = 1;
5883 else if (unformat (i, "bond %u", &bond_sw_if_index))
5884 bond_sw_if_index_is_set = 1;
5885 else if (unformat (i, "passive %d", &is_passive))
5886 ;
5887 else if (unformat (i, "long-timeout %d", &is_long_timeout))
5888 ;
5889 else
5890 break;
5891 }
5892
5893 if (bond_sw_if_index_is_set == 0)
5894 {
5895 errmsg ("Missing bond sw_if_index. ");
5896 return -99;
5897 }
5898 if (sw_if_index_is_set == 0)
5899 {
Steven Luong4c4223e2020-07-15 08:44:54 -07005900 errmsg ("Missing member sw_if_index. ");
Steven9cd2d7a2017-12-20 12:43:01 -08005901 return -99;
5902 }
5903
5904 /* Construct the API message */
Steven Luong4c4223e2020-07-15 08:44:54 -07005905 M (BOND_ADD_MEMBER, mp);
Steven9cd2d7a2017-12-20 12:43:01 -08005906
5907 mp->bond_sw_if_index = ntohl (bond_sw_if_index);
5908 mp->sw_if_index = ntohl (sw_if_index);
5909 mp->is_long_timeout = is_long_timeout;
5910 mp->is_passive = is_passive;
5911
5912 /* send it... */
5913 S (mp);
5914
5915 /* Wait for a reply... */
5916 W (ret);
5917 return ret;
5918}
5919
5920static int
Steven Luong4c4223e2020-07-15 08:44:54 -07005921api_bond_detach_member (vat_main_t * vam)
Steven9cd2d7a2017-12-20 12:43:01 -08005922{
5923 unformat_input_t *i = vam->input;
Steven Luong4c4223e2020-07-15 08:44:54 -07005924 vl_api_bond_detach_member_t *mp;
Steven9cd2d7a2017-12-20 12:43:01 -08005925 u32 sw_if_index = ~0;
5926 u8 sw_if_index_set = 0;
5927 int ret;
5928
5929 /* Parse args required to build the message */
5930 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5931 {
5932 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5933 sw_if_index_set = 1;
5934 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5935 sw_if_index_set = 1;
5936 else
5937 break;
5938 }
5939
5940 if (sw_if_index_set == 0)
5941 {
5942 errmsg ("missing vpp interface name. ");
5943 return -99;
5944 }
5945
5946 /* Construct the API message */
Steven Luong4c4223e2020-07-15 08:44:54 -07005947 M (BOND_DETACH_MEMBER, mp);
Steven9cd2d7a2017-12-20 12:43:01 -08005948
5949 mp->sw_if_index = ntohl (sw_if_index);
5950
5951 /* send it... */
5952 S (mp);
5953
5954 /* Wait for a reply... */
5955 W (ret);
5956 return ret;
5957}
5958
5959static int
Neale Ranns28ab9cc2017-08-14 07:18:42 -07005960api_ip_table_add_del (vat_main_t * vam)
5961{
5962 unformat_input_t *i = vam->input;
5963 vl_api_ip_table_add_del_t *mp;
5964 u32 table_id = ~0;
5965 u8 is_ipv6 = 0;
5966 u8 is_add = 1;
5967 int ret = 0;
5968
5969 /* Parse args required to build the message */
5970 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5971 {
5972 if (unformat (i, "ipv6"))
5973 is_ipv6 = 1;
5974 else if (unformat (i, "del"))
5975 is_add = 0;
5976 else if (unformat (i, "add"))
5977 is_add = 1;
5978 else if (unformat (i, "table %d", &table_id))
5979 ;
5980 else
5981 {
5982 clib_warning ("parse error '%U'", format_unformat_error, i);
5983 return -99;
5984 }
5985 }
5986
5987 if (~0 == table_id)
5988 {
5989 errmsg ("missing table-ID");
5990 return -99;
5991 }
5992
5993 /* Construct the API message */
5994 M (IP_TABLE_ADD_DEL, mp);
5995
Neale Ranns097fa662018-05-01 05:17:55 -07005996 mp->table.table_id = ntohl (table_id);
5997 mp->table.is_ip6 = is_ipv6;
Neale Ranns28ab9cc2017-08-14 07:18:42 -07005998 mp->is_add = is_add;
5999
6000 /* send it... */
6001 S (mp);
6002
6003 /* Wait for a reply... */
6004 W (ret);
6005
6006 return ret;
6007}
6008
Neale Ranns097fa662018-05-01 05:17:55 -07006009uword
6010unformat_fib_path (unformat_input_t * input, va_list * args)
6011{
6012 vat_main_t *vam = va_arg (*args, vat_main_t *);
6013 vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
6014 u32 weight, preference;
6015 mpls_label_t out_label;
6016
6017 clib_memset (path, 0, sizeof (*path));
6018 path->weight = 1;
6019 path->sw_if_index = ~0;
6020 path->rpf_id = ~0;
6021 path->n_labels = 0;
6022
6023 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
6024 {
6025 if (unformat (input, "%U %U",
6026 unformat_vl_api_ip4_address,
6027 &path->nh.address.ip4,
6028 api_unformat_sw_if_index, vam, &path->sw_if_index))
6029 {
6030 path->proto = FIB_API_PATH_NH_PROTO_IP4;
6031 }
6032 else if (unformat (input, "%U %U",
6033 unformat_vl_api_ip6_address,
6034 &path->nh.address.ip6,
6035 api_unformat_sw_if_index, vam, &path->sw_if_index))
6036 {
6037 path->proto = FIB_API_PATH_NH_PROTO_IP6;
6038 }
6039 else if (unformat (input, "weight %u", &weight))
6040 {
6041 path->weight = weight;
6042 }
6043 else if (unformat (input, "preference %u", &preference))
6044 {
6045 path->preference = preference;
6046 }
6047 else if (unformat (input, "%U next-hop-table %d",
6048 unformat_vl_api_ip4_address,
6049 &path->nh.address.ip4, &path->table_id))
6050 {
6051 path->proto = FIB_API_PATH_NH_PROTO_IP4;
6052 }
6053 else if (unformat (input, "%U next-hop-table %d",
6054 unformat_vl_api_ip6_address,
6055 &path->nh.address.ip6, &path->table_id))
6056 {
6057 path->proto = FIB_API_PATH_NH_PROTO_IP6;
6058 }
6059 else if (unformat (input, "%U",
6060 unformat_vl_api_ip4_address, &path->nh.address.ip4))
6061 {
6062 /*
6063 * the recursive next-hops are by default in the default table
6064 */
6065 path->table_id = 0;
6066 path->sw_if_index = ~0;
6067 path->proto = FIB_API_PATH_NH_PROTO_IP4;
6068 }
6069 else if (unformat (input, "%U",
6070 unformat_vl_api_ip6_address, &path->nh.address.ip6))
6071 {
6072 /*
6073 * the recursive next-hops are by default in the default table
6074 */
6075 path->table_id = 0;
6076 path->sw_if_index = ~0;
6077 path->proto = FIB_API_PATH_NH_PROTO_IP6;
6078 }
6079 else if (unformat (input, "resolve-via-host"))
6080 {
6081 path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
6082 }
6083 else if (unformat (input, "resolve-via-attached"))
6084 {
6085 path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
6086 }
6087 else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
6088 {
6089 path->type = FIB_API_PATH_TYPE_LOCAL;
6090 path->sw_if_index = ~0;
6091 path->proto = FIB_API_PATH_NH_PROTO_IP4;
6092 }
6093 else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
6094 {
6095 path->type = FIB_API_PATH_TYPE_LOCAL;
6096 path->sw_if_index = ~0;
6097 path->proto = FIB_API_PATH_NH_PROTO_IP6;
6098 }
6099 else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
6100 ;
6101 else if (unformat (input, "via-label %d", &path->nh.via_label))
6102 {
6103 path->proto = FIB_API_PATH_NH_PROTO_MPLS;
6104 path->sw_if_index = ~0;
6105 }
6106 else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
6107 {
6108 path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
6109 path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
6110 }
6111 else if (unformat (input, "local"))
6112 {
6113 path->type = FIB_API_PATH_TYPE_LOCAL;
6114 }
6115 else if (unformat (input, "out-labels"))
6116 {
6117 while (unformat (input, "%d", &out_label))
6118 {
6119 path->label_stack[path->n_labels].label = out_label;
6120 path->label_stack[path->n_labels].is_uniform = 0;
6121 path->label_stack[path->n_labels].ttl = 64;
6122 path->n_labels++;
6123 }
6124 }
6125 else if (unformat (input, "via"))
6126 {
6127 /* new path, back up and return */
6128 unformat_put_input (input);
6129 unformat_put_input (input);
6130 unformat_put_input (input);
6131 unformat_put_input (input);
6132 break;
6133 }
6134 else
6135 {
6136 return (0);
6137 }
6138 }
6139
6140 path->proto = ntohl (path->proto);
6141 path->type = ntohl (path->type);
6142 path->flags = ntohl (path->flags);
6143 path->table_id = ntohl (path->table_id);
6144 path->sw_if_index = ntohl (path->sw_if_index);
6145
6146 return (1);
6147}
6148
Neale Ranns28ab9cc2017-08-14 07:18:42 -07006149static int
Neale Ranns097fa662018-05-01 05:17:55 -07006150api_ip_route_add_del (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +01006151{
6152 unformat_input_t *i = vam->input;
Neale Ranns097fa662018-05-01 05:17:55 -07006153 vl_api_ip_route_add_del_t *mp;
6154 u32 vrf_id = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006155 u8 is_add = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006156 u8 is_multipath = 0;
Neale Ranns097fa662018-05-01 05:17:55 -07006157 u8 prefix_set = 0;
6158 u8 path_count = 0;
6159 vl_api_prefix_t pfx = { };
6160 vl_api_fib_path_t paths[8];
Damjan Marion7cd468a2016-12-19 23:05:39 +01006161 int count = 1;
6162 int j;
6163 f64 before = 0;
6164 u32 random_add_del = 0;
6165 u32 *random_vector = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006166 u32 random_seed = 0xdeaddabe;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006167
6168 /* Parse args required to build the message */
6169 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6170 {
Neale Ranns097fa662018-05-01 05:17:55 -07006171 if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
6172 prefix_set = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006173 else if (unformat (i, "del"))
6174 is_add = 0;
6175 else if (unformat (i, "add"))
6176 is_add = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006177 else if (unformat (i, "vrf %d", &vrf_id))
6178 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006179 else if (unformat (i, "count %d", &count))
6180 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006181 else if (unformat (i, "random"))
6182 random_add_del = 1;
Neale Ranns097fa662018-05-01 05:17:55 -07006183 else if (unformat (i, "multipath"))
6184 is_multipath = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006185 else if (unformat (i, "seed %d", &random_seed))
6186 ;
6187 else
Neale Ranns097fa662018-05-01 05:17:55 -07006188 if (unformat
6189 (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
6190 {
6191 path_count++;
6192 if (8 == path_count)
6193 {
6194 errmsg ("max 8 paths");
6195 return -99;
6196 }
6197 }
6198 else
Damjan Marion7cd468a2016-12-19 23:05:39 +01006199 {
6200 clib_warning ("parse error '%U'", format_unformat_error, i);
6201 return -99;
6202 }
6203 }
6204
Neale Ranns097fa662018-05-01 05:17:55 -07006205 if (!path_count)
Damjan Marion7cd468a2016-12-19 23:05:39 +01006206 {
Neale Ranns097fa662018-05-01 05:17:55 -07006207 errmsg ("specify a path; via ...");
Damjan Marion7cd468a2016-12-19 23:05:39 +01006208 return -99;
6209 }
Neale Ranns097fa662018-05-01 05:17:55 -07006210 if (prefix_set == 0)
Damjan Marion7cd468a2016-12-19 23:05:39 +01006211 {
Neale Ranns097fa662018-05-01 05:17:55 -07006212 errmsg ("missing prefix");
Damjan Marion7cd468a2016-12-19 23:05:39 +01006213 return -99;
6214 }
6215
6216 /* Generate a pile of unique, random routes */
6217 if (random_add_del)
6218 {
Neale Ranns097fa662018-05-01 05:17:55 -07006219 ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006220 u32 this_random_address;
Neale Ranns097fa662018-05-01 05:17:55 -07006221 uword *random_hash;
6222
Damjan Marion7cd468a2016-12-19 23:05:39 +01006223 random_hash = hash_create (count, sizeof (uword));
6224
Neale Ranns097fa662018-05-01 05:17:55 -07006225 hash_set (random_hash, i->as_u32, 1);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006226 for (j = 0; j <= count; j++)
6227 {
6228 do
6229 {
6230 this_random_address = random_u32 (&random_seed);
6231 this_random_address =
6232 clib_host_to_net_u32 (this_random_address);
6233 }
6234 while (hash_get (random_hash, this_random_address));
6235 vec_add1 (random_vector, this_random_address);
6236 hash_set (random_hash, this_random_address, 1);
6237 }
6238 hash_free (random_hash);
Neale Ranns097fa662018-05-01 05:17:55 -07006239 set_ip4_address (&pfx.address, random_vector[0]);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006240 }
6241
6242 if (count > 1)
6243 {
6244 /* Turn on async mode */
6245 vam->async_mode = 1;
6246 vam->async_errors = 0;
6247 before = vat_time_now (vam);
6248 }
6249
6250 for (j = 0; j < count; j++)
6251 {
6252 /* Construct the API message */
Neale Ranns097fa662018-05-01 05:17:55 -07006253 M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006254
6255 mp->is_add = is_add;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006256 mp->is_multipath = is_multipath;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006257
Neale Ranns097fa662018-05-01 05:17:55 -07006258 clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
6259 mp->route.table_id = ntohl (vrf_id);
6260 mp->route.n_paths = path_count;
6261
6262 clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
6263
6264 if (random_add_del)
6265 set_ip4_address (&pfx.address, random_vector[j + 1]);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006266 else
Neale Ranns097fa662018-05-01 05:17:55 -07006267 increment_address (&pfx.address);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006268 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006269 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006270 /* If we receive SIGTERM, stop now... */
6271 if (vam->do_exit)
6272 break;
6273 }
6274
6275 /* When testing multiple add/del ops, use a control-ping to sync */
6276 if (count > 1)
6277 {
Jon Loeliger2d23eca2017-02-01 13:09:58 -06006278 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006279 f64 after;
Jon Loeliger1f9191f2017-01-31 15:27:19 -06006280 f64 timeout;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006281
6282 /* Shut off async mode */
6283 vam->async_mode = 0;
6284
Dave Barach59b25652017-09-10 15:04:27 -04006285 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06006286 S (mp_ping);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006287
6288 timeout = vat_time_now (vam) + 1.0;
6289 while (vat_time_now (vam) < timeout)
6290 if (vam->result_ready == 1)
6291 goto out;
6292 vam->retval = -99;
6293
6294 out:
6295 if (vam->retval == -99)
6296 errmsg ("timeout");
6297
6298 if (vam->async_errors > 0)
6299 {
6300 errmsg ("%d asynchronous errors", vam->async_errors);
6301 vam->retval = -98;
6302 }
6303 vam->async_errors = 0;
6304 after = vat_time_now (vam);
6305
6306 /* slim chance, but we might have eaten SIGTERM on the first iteration */
6307 if (j > 0)
6308 count = j;
6309
6310 print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6311 count, after - before, count / (after - before));
6312 }
6313 else
6314 {
Jon Loeliger56c7b012017-02-01 12:31:41 -06006315 int ret;
6316
Damjan Marion7cd468a2016-12-19 23:05:39 +01006317 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06006318 W (ret);
6319 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006320 }
6321
6322 /* Return the good/bad news */
6323 return (vam->retval);
6324}
6325
6326static int
Neale Ranns32e1c012016-11-22 17:07:28 +00006327api_ip_mroute_add_del (vat_main_t * vam)
6328{
6329 unformat_input_t *i = vam->input;
Neale Ranns097fa662018-05-01 05:17:55 -07006330 u8 path_set = 0, prefix_set = 0, is_add = 1;
Neale Ranns32e1c012016-11-22 17:07:28 +00006331 vl_api_ip_mroute_add_del_t *mp;
Neale Ranns32e1c012016-11-22 17:07:28 +00006332 mfib_entry_flags_t eflags = 0;
Neale Ranns097fa662018-05-01 05:17:55 -07006333 vl_api_mfib_path_t path;
6334 vl_api_mprefix_t pfx = { };
6335 u32 vrf_id = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006336 int ret;
Neale Ranns32e1c012016-11-22 17:07:28 +00006337
6338 /* Parse args required to build the message */
6339 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6340 {
Neale Ranns097fa662018-05-01 05:17:55 -07006341 if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
Neale Ranns32e1c012016-11-22 17:07:28 +00006342 {
Neale Ranns097fa662018-05-01 05:17:55 -07006343 prefix_set = 1;
6344 pfx.grp_address_length = htons (pfx.grp_address_length);
Neale Ranns32e1c012016-11-22 17:07:28 +00006345 }
6346 else if (unformat (i, "del"))
6347 is_add = 0;
6348 else if (unformat (i, "add"))
6349 is_add = 1;
6350 else if (unformat (i, "vrf %d", &vrf_id))
6351 ;
Neale Ranns097fa662018-05-01 05:17:55 -07006352 else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
6353 path.itf_flags = htonl (path.itf_flags);
Neale Ranns32e1c012016-11-22 17:07:28 +00006354 else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
6355 ;
Neale Ranns097fa662018-05-01 05:17:55 -07006356 else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
6357 path_set = 1;
Neale Ranns32e1c012016-11-22 17:07:28 +00006358 else
6359 {
6360 clib_warning ("parse error '%U'", format_unformat_error, i);
6361 return -99;
6362 }
6363 }
6364
Neale Ranns097fa662018-05-01 05:17:55 -07006365 if (prefix_set == 0)
Neale Ranns32e1c012016-11-22 17:07:28 +00006366 {
6367 errmsg ("missing addresses\n");
6368 return -99;
6369 }
Neale Ranns097fa662018-05-01 05:17:55 -07006370 if (path_set == 0)
6371 {
6372 errmsg ("missing path\n");
6373 return -99;
6374 }
Neale Ranns32e1c012016-11-22 17:07:28 +00006375
6376 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006377 M (IP_MROUTE_ADD_DEL, mp);
Neale Ranns32e1c012016-11-22 17:07:28 +00006378
Neale Ranns32e1c012016-11-22 17:07:28 +00006379 mp->is_add = is_add;
Neale Ranns097fa662018-05-01 05:17:55 -07006380 mp->is_multipath = 1;
Neale Ranns32e1c012016-11-22 17:07:28 +00006381
Neale Ranns097fa662018-05-01 05:17:55 -07006382 clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
6383 mp->route.table_id = htonl (vrf_id);
6384 mp->route.n_paths = 1;
6385 mp->route.entry_flags = htonl (eflags);
Neale Ranns32e1c012016-11-22 17:07:28 +00006386
Neale Ranns097fa662018-05-01 05:17:55 -07006387 clib_memcpy (&mp->route.paths, &path, sizeof (path));
Neale Ranns32e1c012016-11-22 17:07:28 +00006388
6389 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006390 S (mp);
Neale Ranns32e1c012016-11-22 17:07:28 +00006391 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06006392 W (ret);
6393 return ret;
Neale Ranns32e1c012016-11-22 17:07:28 +00006394}
6395
6396static int
Neale Ranns28ab9cc2017-08-14 07:18:42 -07006397api_mpls_table_add_del (vat_main_t * vam)
6398{
6399 unformat_input_t *i = vam->input;
6400 vl_api_mpls_table_add_del_t *mp;
6401 u32 table_id = ~0;
6402 u8 is_add = 1;
6403 int ret = 0;
6404
6405 /* Parse args required to build the message */
6406 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6407 {
Florin Corasd0a59722017-10-15 17:41:21 +00006408 if (unformat (i, "table %d", &table_id))
6409 ;
6410 else if (unformat (i, "del"))
Neale Ranns28ab9cc2017-08-14 07:18:42 -07006411 is_add = 0;
6412 else if (unformat (i, "add"))
6413 is_add = 1;
6414 else
6415 {
6416 clib_warning ("parse error '%U'", format_unformat_error, i);
6417 return -99;
6418 }
6419 }
6420
6421 if (~0 == table_id)
6422 {
6423 errmsg ("missing table-ID");
6424 return -99;
6425 }
6426
6427 /* Construct the API message */
6428 M (MPLS_TABLE_ADD_DEL, mp);
6429
Neale Ranns097fa662018-05-01 05:17:55 -07006430 mp->mt_table.mt_table_id = ntohl (table_id);
Neale Ranns28ab9cc2017-08-14 07:18:42 -07006431 mp->mt_is_add = is_add;
6432
6433 /* send it... */
6434 S (mp);
6435
6436 /* Wait for a reply... */
6437 W (ret);
6438
6439 return ret;
6440}
6441
6442static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01006443api_mpls_route_add_del (vat_main_t * vam)
6444{
Neale Ranns097fa662018-05-01 05:17:55 -07006445 u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
6446 mpls_label_t local_label = MPLS_LABEL_INVALID;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006447 unformat_input_t *i = vam->input;
6448 vl_api_mpls_route_add_del_t *mp;
Neale Ranns097fa662018-05-01 05:17:55 -07006449 vl_api_fib_path_t paths[8];
6450 int count = 1, j;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006451 f64 before = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006452
6453 /* Parse args required to build the message */
6454 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6455 {
Neale Ranns097fa662018-05-01 05:17:55 -07006456 if (unformat (i, "%d", &local_label))
Damjan Marion7cd468a2016-12-19 23:05:39 +01006457 ;
6458 else if (unformat (i, "eos"))
6459 is_eos = 1;
6460 else if (unformat (i, "non-eos"))
6461 is_eos = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006462 else if (unformat (i, "del"))
6463 is_add = 0;
6464 else if (unformat (i, "add"))
6465 is_add = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006466 else if (unformat (i, "multipath"))
6467 is_multipath = 1;
6468 else if (unformat (i, "count %d", &count))
6469 ;
John Loe166fd92018-09-13 14:08:59 -04006470 else
6471 if (unformat
Neale Ranns097fa662018-05-01 05:17:55 -07006472 (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
John Loe166fd92018-09-13 14:08:59 -04006473 {
Neale Ranns097fa662018-05-01 05:17:55 -07006474 path_count++;
6475 if (8 == path_count)
6476 {
6477 errmsg ("max 8 paths");
6478 return -99;
6479 }
John Loe166fd92018-09-13 14:08:59 -04006480 }
Damjan Marion7cd468a2016-12-19 23:05:39 +01006481 else
6482 {
6483 clib_warning ("parse error '%U'", format_unformat_error, i);
6484 return -99;
6485 }
6486 }
6487
Neale Ranns097fa662018-05-01 05:17:55 -07006488 if (!path_count)
Damjan Marion7cd468a2016-12-19 23:05:39 +01006489 {
Neale Ranns097fa662018-05-01 05:17:55 -07006490 errmsg ("specify a path; via ...");
Damjan Marion7cd468a2016-12-19 23:05:39 +01006491 return -99;
6492 }
6493
6494 if (MPLS_LABEL_INVALID == local_label)
6495 {
6496 errmsg ("missing label");
6497 return -99;
6498 }
6499
6500 if (count > 1)
6501 {
6502 /* Turn on async mode */
6503 vam->async_mode = 1;
6504 vam->async_errors = 0;
6505 before = vat_time_now (vam);
6506 }
6507
6508 for (j = 0; j < count; j++)
6509 {
6510 /* Construct the API message */
Neale Ranns097fa662018-05-01 05:17:55 -07006511 M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006512
6513 mp->mr_is_add = is_add;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006514 mp->mr_is_multipath = is_multipath;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006515
Neale Ranns097fa662018-05-01 05:17:55 -07006516 mp->mr_route.mr_label = local_label;
6517 mp->mr_route.mr_eos = is_eos;
6518 mp->mr_route.mr_table_id = 0;
6519 mp->mr_route.mr_n_paths = path_count;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006520
Neale Ranns097fa662018-05-01 05:17:55 -07006521 clib_memcpy (&mp->mr_route.mr_paths, paths,
6522 sizeof (paths[0]) * path_count);
Neale Rannsda78f952017-05-24 09:15:43 -07006523
Damjan Marion7cd468a2016-12-19 23:05:39 +01006524 local_label++;
6525
6526 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006527 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006528 /* If we receive SIGTERM, stop now... */
6529 if (vam->do_exit)
6530 break;
6531 }
6532
6533 /* When testing multiple add/del ops, use a control-ping to sync */
6534 if (count > 1)
6535 {
Jon Loeliger2d23eca2017-02-01 13:09:58 -06006536 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006537 f64 after;
Jon Loeliger1f9191f2017-01-31 15:27:19 -06006538 f64 timeout;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006539
6540 /* Shut off async mode */
6541 vam->async_mode = 0;
6542
Dave Barach59b25652017-09-10 15:04:27 -04006543 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06006544 S (mp_ping);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006545
6546 timeout = vat_time_now (vam) + 1.0;
6547 while (vat_time_now (vam) < timeout)
6548 if (vam->result_ready == 1)
6549 goto out;
6550 vam->retval = -99;
6551
6552 out:
6553 if (vam->retval == -99)
6554 errmsg ("timeout");
6555
6556 if (vam->async_errors > 0)
6557 {
6558 errmsg ("%d asynchronous errors", vam->async_errors);
6559 vam->retval = -98;
6560 }
6561 vam->async_errors = 0;
6562 after = vat_time_now (vam);
6563
6564 /* slim chance, but we might have eaten SIGTERM on the first iteration */
6565 if (j > 0)
6566 count = j;
6567
6568 print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6569 count, after - before, count / (after - before));
6570 }
6571 else
6572 {
Jon Loeliger56c7b012017-02-01 12:31:41 -06006573 int ret;
6574
Damjan Marion7cd468a2016-12-19 23:05:39 +01006575 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06006576 W (ret);
6577 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006578 }
6579
6580 /* Return the good/bad news */
6581 return (vam->retval);
Neale Ranns097fa662018-05-01 05:17:55 -07006582 return (0);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006583}
6584
6585static int
6586api_mpls_ip_bind_unbind (vat_main_t * vam)
6587{
6588 unformat_input_t *i = vam->input;
6589 vl_api_mpls_ip_bind_unbind_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006590 u32 ip_table_id = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006591 u8 is_bind = 1;
Neale Ranns097fa662018-05-01 05:17:55 -07006592 vl_api_prefix_t pfx;
6593 u8 prefix_set = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006594 mpls_label_t local_label = MPLS_LABEL_INVALID;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006595 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006596
6597 /* Parse args required to build the message */
6598 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6599 {
Neale Ranns097fa662018-05-01 05:17:55 -07006600 if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
6601 prefix_set = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006602 else if (unformat (i, "%d", &local_label))
6603 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006604 else if (unformat (i, "table-id %d", &ip_table_id))
6605 ;
6606 else if (unformat (i, "unbind"))
6607 is_bind = 0;
6608 else if (unformat (i, "bind"))
6609 is_bind = 1;
6610 else
6611 {
6612 clib_warning ("parse error '%U'", format_unformat_error, i);
6613 return -99;
6614 }
6615 }
6616
Neale Ranns097fa662018-05-01 05:17:55 -07006617 if (!prefix_set)
Damjan Marion7cd468a2016-12-19 23:05:39 +01006618 {
Neale Ranns097fa662018-05-01 05:17:55 -07006619 errmsg ("IP prefix not set");
Damjan Marion7cd468a2016-12-19 23:05:39 +01006620 return -99;
6621 }
6622
6623 if (MPLS_LABEL_INVALID == local_label)
6624 {
6625 errmsg ("missing label");
6626 return -99;
6627 }
6628
6629 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006630 M (MPLS_IP_BIND_UNBIND, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006631
Damjan Marion7cd468a2016-12-19 23:05:39 +01006632 mp->mb_is_bind = is_bind;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006633 mp->mb_ip_table_id = ntohl (ip_table_id);
6634 mp->mb_mpls_table_id = 0;
6635 mp->mb_label = ntohl (local_label);
Neale Ranns097fa662018-05-01 05:17:55 -07006636 clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
Damjan Marion7cd468a2016-12-19 23:05:39 +01006637
6638 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006639 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006640
6641 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06006642 W (ret);
6643 return ret;
Neale Ranns097fa662018-05-01 05:17:55 -07006644 return (0);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006645}
6646
6647static int
John Loe166fd92018-09-13 14:08:59 -04006648api_sr_mpls_policy_add (vat_main_t * vam)
6649{
6650 unformat_input_t *i = vam->input;
6651 vl_api_sr_mpls_policy_add_t *mp;
6652 u32 bsid = 0;
6653 u32 weight = 1;
6654 u8 type = 0;
6655 u8 n_segments = 0;
6656 u32 sid;
6657 u32 *segments = NULL;
6658 int ret;
6659
6660 /* Parse args required to build the message */
6661 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6662 {
6663 if (unformat (i, "bsid %d", &bsid))
6664 ;
6665 else if (unformat (i, "weight %d", &weight))
6666 ;
6667 else if (unformat (i, "spray"))
6668 type = 1;
6669 else if (unformat (i, "next %d", &sid))
6670 {
6671 n_segments += 1;
6672 vec_add1 (segments, htonl (sid));
6673 }
6674 else
6675 {
6676 clib_warning ("parse error '%U'", format_unformat_error, i);
6677 return -99;
6678 }
6679 }
6680
6681 if (bsid == 0)
6682 {
6683 errmsg ("bsid not set");
6684 return -99;
6685 }
6686
6687 if (n_segments == 0)
6688 {
6689 errmsg ("no sid in segment stack");
6690 return -99;
6691 }
6692
6693 /* Construct the API message */
6694 M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
6695
6696 mp->bsid = htonl (bsid);
6697 mp->weight = htonl (weight);
Jakub Grajciar00ec4012020-01-31 10:17:29 +01006698 mp->is_spray = type;
John Loe166fd92018-09-13 14:08:59 -04006699 mp->n_segments = n_segments;
6700 memcpy (mp->segments, segments, sizeof (u32) * n_segments);
6701 vec_free (segments);
6702
6703 /* send it... */
6704 S (mp);
6705
6706 /* Wait for a reply... */
6707 W (ret);
6708 return ret;
6709}
6710
6711static int
6712api_sr_mpls_policy_del (vat_main_t * vam)
6713{
6714 unformat_input_t *i = vam->input;
6715 vl_api_sr_mpls_policy_del_t *mp;
6716 u32 bsid = 0;
6717 int ret;
6718
6719 /* Parse args required to build the message */
6720 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6721 {
6722 if (unformat (i, "bsid %d", &bsid))
6723 ;
6724 else
6725 {
6726 clib_warning ("parse error '%U'", format_unformat_error, i);
6727 return -99;
6728 }
6729 }
6730
6731 if (bsid == 0)
6732 {
6733 errmsg ("bsid not set");
6734 return -99;
6735 }
6736
6737 /* Construct the API message */
6738 M (SR_MPLS_POLICY_DEL, mp);
6739
6740 mp->bsid = htonl (bsid);
6741
6742 /* send it... */
6743 S (mp);
6744
6745 /* Wait for a reply... */
6746 W (ret);
6747 return ret;
6748}
6749
6750static int
Neale Rannsd792d9c2017-10-21 10:53:20 -07006751api_bier_table_add_del (vat_main_t * vam)
6752{
6753 unformat_input_t *i = vam->input;
6754 vl_api_bier_table_add_del_t *mp;
6755 u8 is_add = 1;
6756 u32 set = 0, sub_domain = 0, hdr_len = 3;
6757 mpls_label_t local_label = MPLS_LABEL_INVALID;
6758 int ret;
6759
6760 /* Parse args required to build the message */
6761 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6762 {
6763 if (unformat (i, "sub-domain %d", &sub_domain))
6764 ;
6765 else if (unformat (i, "set %d", &set))
6766 ;
6767 else if (unformat (i, "label %d", &local_label))
6768 ;
6769 else if (unformat (i, "hdr-len %d", &hdr_len))
6770 ;
6771 else if (unformat (i, "add"))
6772 is_add = 1;
6773 else if (unformat (i, "del"))
6774 is_add = 0;
6775 else
6776 {
6777 clib_warning ("parse error '%U'", format_unformat_error, i);
6778 return -99;
6779 }
6780 }
6781
6782 if (MPLS_LABEL_INVALID == local_label)
6783 {
6784 errmsg ("missing label\n");
6785 return -99;
6786 }
6787
6788 /* Construct the API message */
6789 M (BIER_TABLE_ADD_DEL, mp);
6790
6791 mp->bt_is_add = is_add;
6792 mp->bt_label = ntohl (local_label);
6793 mp->bt_tbl_id.bt_set = set;
6794 mp->bt_tbl_id.bt_sub_domain = sub_domain;
6795 mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
6796
6797 /* send it... */
6798 S (mp);
6799
6800 /* Wait for a reply... */
6801 W (ret);
6802
6803 return (ret);
6804}
6805
6806static int
6807api_bier_route_add_del (vat_main_t * vam)
6808{
6809 unformat_input_t *i = vam->input;
6810 vl_api_bier_route_add_del_t *mp;
6811 u8 is_add = 1;
6812 u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
6813 ip4_address_t v4_next_hop_address;
6814 ip6_address_t v6_next_hop_address;
6815 u8 next_hop_set = 0;
6816 u8 next_hop_proto_is_ip4 = 1;
6817 mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6818 int ret;
6819
6820 /* Parse args required to build the message */
6821 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6822 {
6823 if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
6824 {
6825 next_hop_proto_is_ip4 = 1;
6826 next_hop_set = 1;
6827 }
6828 else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
6829 {
6830 next_hop_proto_is_ip4 = 0;
6831 next_hop_set = 1;
6832 }
6833 if (unformat (i, "sub-domain %d", &sub_domain))
6834 ;
6835 else if (unformat (i, "set %d", &set))
6836 ;
6837 else if (unformat (i, "hdr-len %d", &hdr_len))
6838 ;
6839 else if (unformat (i, "bp %d", &bp))
6840 ;
6841 else if (unformat (i, "add"))
6842 is_add = 1;
6843 else if (unformat (i, "del"))
6844 is_add = 0;
6845 else if (unformat (i, "out-label %d", &next_hop_out_label))
6846 ;
6847 else
6848 {
6849 clib_warning ("parse error '%U'", format_unformat_error, i);
6850 return -99;
6851 }
6852 }
6853
6854 if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
6855 {
6856 errmsg ("next hop / label set\n");
6857 return -99;
6858 }
6859 if (0 == bp)
6860 {
6861 errmsg ("bit=position not set\n");
6862 return -99;
6863 }
6864
6865 /* Construct the API message */
Neale Ranns31ed7442018-02-23 05:29:09 -08006866 M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
Neale Rannsd792d9c2017-10-21 10:53:20 -07006867
6868 mp->br_is_add = is_add;
Neale Ranns097fa662018-05-01 05:17:55 -07006869 mp->br_route.br_tbl_id.bt_set = set;
6870 mp->br_route.br_tbl_id.bt_sub_domain = sub_domain;
6871 mp->br_route.br_tbl_id.bt_hdr_len_id = hdr_len;
6872 mp->br_route.br_bp = ntohs (bp);
6873 mp->br_route.br_n_paths = 1;
6874 mp->br_route.br_paths[0].n_labels = 1;
6875 mp->br_route.br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
6876 mp->br_route.br_paths[0].proto = (next_hop_proto_is_ip4 ?
6877 FIB_API_PATH_NH_PROTO_IP4 :
6878 FIB_API_PATH_NH_PROTO_IP6);
Neale Rannsd792d9c2017-10-21 10:53:20 -07006879
6880 if (next_hop_proto_is_ip4)
6881 {
Neale Ranns097fa662018-05-01 05:17:55 -07006882 clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip4,
Neale Rannsd792d9c2017-10-21 10:53:20 -07006883 &v4_next_hop_address, sizeof (v4_next_hop_address));
6884 }
6885 else
6886 {
Neale Ranns097fa662018-05-01 05:17:55 -07006887 clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip6,
Neale Rannsd792d9c2017-10-21 10:53:20 -07006888 &v6_next_hop_address, sizeof (v6_next_hop_address));
6889 }
6890
6891 /* send it... */
6892 S (mp);
6893
6894 /* Wait for a reply... */
6895 W (ret);
6896
6897 return (ret);
6898}
6899
6900static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01006901api_mpls_tunnel_add_del (vat_main_t * vam)
6902{
6903 unformat_input_t *i = vam->input;
6904 vl_api_mpls_tunnel_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006905
Neale Ranns097fa662018-05-01 05:17:55 -07006906 vl_api_fib_path_t paths[8];
Damjan Marion7cd468a2016-12-19 23:05:39 +01006907 u32 sw_if_index = ~0;
Neale Ranns097fa662018-05-01 05:17:55 -07006908 u8 path_count = 0;
6909 u8 l2_only = 0;
6910 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006911 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006912
6913 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6914 {
6915 if (unformat (i, "add"))
6916 is_add = 1;
John Lo06fda9c2018-10-03 16:32:44 -04006917 else
6918 if (unformat
6919 (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
6920 is_add = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006921 else if (unformat (i, "del sw_if_index %d", &sw_if_index))
6922 is_add = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006923 else if (unformat (i, "l2-only"))
6924 l2_only = 1;
Neale Ranns097fa662018-05-01 05:17:55 -07006925 else
6926 if (unformat
6927 (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
John Lo06fda9c2018-10-03 16:32:44 -04006928 {
Neale Ranns097fa662018-05-01 05:17:55 -07006929 path_count++;
6930 if (8 == path_count)
6931 {
6932 errmsg ("max 8 paths");
6933 return -99;
6934 }
John Lo06fda9c2018-10-03 16:32:44 -04006935 }
Damjan Marion7cd468a2016-12-19 23:05:39 +01006936 else
6937 {
6938 clib_warning ("parse error '%U'", format_unformat_error, i);
6939 return -99;
6940 }
6941 }
6942
Neale Ranns097fa662018-05-01 05:17:55 -07006943 M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006944
Damjan Marion7cd468a2016-12-19 23:05:39 +01006945 mp->mt_is_add = is_add;
Neale Ranns097fa662018-05-01 05:17:55 -07006946 mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
6947 mp->mt_tunnel.mt_l2_only = l2_only;
6948 mp->mt_tunnel.mt_is_multicast = 0;
6949 mp->mt_tunnel.mt_n_paths = path_count;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006950
Neale Ranns097fa662018-05-01 05:17:55 -07006951 clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
6952 sizeof (paths[0]) * path_count);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006953
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006954 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06006955 W (ret);
6956 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006957}
6958
6959static int
6960api_sw_interface_set_unnumbered (vat_main_t * vam)
6961{
6962 unformat_input_t *i = vam->input;
6963 vl_api_sw_interface_set_unnumbered_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006964 u32 sw_if_index;
6965 u32 unnum_sw_index = ~0;
6966 u8 is_add = 1;
6967 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006968 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006969
6970 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6971 {
6972 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6973 sw_if_index_set = 1;
6974 else if (unformat (i, "sw_if_index %d", &sw_if_index))
6975 sw_if_index_set = 1;
6976 else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
6977 ;
6978 else if (unformat (i, "del"))
6979 is_add = 0;
6980 else
6981 {
6982 clib_warning ("parse error '%U'", format_unformat_error, i);
6983 return -99;
6984 }
6985 }
6986
6987 if (sw_if_index_set == 0)
6988 {
6989 errmsg ("missing interface name or sw_if_index");
6990 return -99;
6991 }
6992
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006993 M (SW_INTERFACE_SET_UNNUMBERED, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006994
6995 mp->sw_if_index = ntohl (sw_if_index);
6996 mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
6997 mp->is_add = is_add;
6998
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006999 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007000 W (ret);
7001 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007002}
7003
Damjan Marion7cd468a2016-12-19 23:05:39 +01007004
7005static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01007006api_create_vlan_subif (vat_main_t * vam)
7007{
7008 unformat_input_t *i = vam->input;
7009 vl_api_create_vlan_subif_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007010 u32 sw_if_index;
7011 u8 sw_if_index_set = 0;
7012 u32 vlan_id;
7013 u8 vlan_id_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007014 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007015
7016 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7017 {
7018 if (unformat (i, "sw_if_index %d", &sw_if_index))
7019 sw_if_index_set = 1;
7020 else
7021 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7022 sw_if_index_set = 1;
7023 else if (unformat (i, "vlan %d", &vlan_id))
7024 vlan_id_set = 1;
7025 else
7026 {
7027 clib_warning ("parse error '%U'", format_unformat_error, i);
7028 return -99;
7029 }
7030 }
7031
7032 if (sw_if_index_set == 0)
7033 {
7034 errmsg ("missing interface name or sw_if_index");
7035 return -99;
7036 }
7037
7038 if (vlan_id_set == 0)
7039 {
7040 errmsg ("missing vlan_id");
7041 return -99;
7042 }
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007043 M (CREATE_VLAN_SUBIF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007044
7045 mp->sw_if_index = ntohl (sw_if_index);
7046 mp->vlan_id = ntohl (vlan_id);
7047
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007048 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007049 W (ret);
7050 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007051}
7052
7053#define foreach_create_subif_bit \
7054_(no_tags) \
7055_(one_tag) \
7056_(two_tags) \
7057_(dot1ad) \
7058_(exact_match) \
7059_(default_sub) \
7060_(outer_vlan_id_any) \
7061_(inner_vlan_id_any)
7062
Jakub Grajciar053204a2019-03-18 13:17:53 +01007063#define foreach_create_subif_flag \
7064_(0, "no_tags") \
7065_(1, "one_tag") \
7066_(2, "two_tags") \
7067_(3, "dot1ad") \
7068_(4, "exact_match") \
7069_(5, "default_sub") \
7070_(6, "outer_vlan_id_any") \
7071_(7, "inner_vlan_id_any")
7072
Damjan Marion7cd468a2016-12-19 23:05:39 +01007073static int
7074api_create_subif (vat_main_t * vam)
7075{
7076 unformat_input_t *i = vam->input;
7077 vl_api_create_subif_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007078 u32 sw_if_index;
7079 u8 sw_if_index_set = 0;
7080 u32 sub_id;
7081 u8 sub_id_set = 0;
Jakub Grajciar053204a2019-03-18 13:17:53 +01007082 u32 __attribute__ ((unused)) no_tags = 0;
7083 u32 __attribute__ ((unused)) one_tag = 0;
7084 u32 __attribute__ ((unused)) two_tags = 0;
7085 u32 __attribute__ ((unused)) dot1ad = 0;
7086 u32 __attribute__ ((unused)) exact_match = 0;
7087 u32 __attribute__ ((unused)) default_sub = 0;
7088 u32 __attribute__ ((unused)) outer_vlan_id_any = 0;
7089 u32 __attribute__ ((unused)) inner_vlan_id_any = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007090 u32 tmp;
7091 u16 outer_vlan_id = 0;
7092 u16 inner_vlan_id = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007093 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007094
7095 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7096 {
7097 if (unformat (i, "sw_if_index %d", &sw_if_index))
7098 sw_if_index_set = 1;
7099 else
7100 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7101 sw_if_index_set = 1;
7102 else if (unformat (i, "sub_id %d", &sub_id))
7103 sub_id_set = 1;
7104 else if (unformat (i, "outer_vlan_id %d", &tmp))
7105 outer_vlan_id = tmp;
7106 else if (unformat (i, "inner_vlan_id %d", &tmp))
7107 inner_vlan_id = tmp;
7108
7109#define _(a) else if (unformat (i, #a)) a = 1 ;
7110 foreach_create_subif_bit
7111#undef _
7112 else
7113 {
7114 clib_warning ("parse error '%U'", format_unformat_error, i);
7115 return -99;
7116 }
7117 }
7118
7119 if (sw_if_index_set == 0)
7120 {
7121 errmsg ("missing interface name or sw_if_index");
7122 return -99;
7123 }
7124
7125 if (sub_id_set == 0)
7126 {
7127 errmsg ("missing sub_id");
7128 return -99;
7129 }
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007130 M (CREATE_SUBIF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007131
7132 mp->sw_if_index = ntohl (sw_if_index);
7133 mp->sub_id = ntohl (sub_id);
7134
Jakub Grajciar053204a2019-03-18 13:17:53 +01007135#define _(a,b) mp->sub_if_flags |= (1 << a);
7136 foreach_create_subif_flag;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007137#undef _
7138
7139 mp->outer_vlan_id = ntohs (outer_vlan_id);
7140 mp->inner_vlan_id = ntohs (inner_vlan_id);
7141
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007142 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007143 W (ret);
7144 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007145}
7146
7147static int
Neale Ranns9db6ada2019-11-08 12:42:31 +00007148api_ip_table_replace_begin (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +01007149{
7150 unformat_input_t *i = vam->input;
Neale Ranns9db6ada2019-11-08 12:42:31 +00007151 vl_api_ip_table_replace_begin_t *mp;
7152 u32 table_id = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007153 u8 is_ipv6 = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007154
Jon Loeliger56c7b012017-02-01 12:31:41 -06007155 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007156 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7157 {
Neale Ranns9db6ada2019-11-08 12:42:31 +00007158 if (unformat (i, "table %d", &table_id))
7159 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007160 else if (unformat (i, "ipv6"))
7161 is_ipv6 = 1;
7162 else
7163 {
7164 clib_warning ("parse error '%U'", format_unformat_error, i);
7165 return -99;
7166 }
7167 }
7168
Neale Ranns9db6ada2019-11-08 12:42:31 +00007169 M (IP_TABLE_REPLACE_BEGIN, mp);
7170
7171 mp->table.table_id = ntohl (table_id);
7172 mp->table.is_ip6 = is_ipv6;
7173
7174 S (mp);
7175 W (ret);
7176 return ret;
7177}
7178
7179static int
7180api_ip_table_flush (vat_main_t * vam)
7181{
7182 unformat_input_t *i = vam->input;
7183 vl_api_ip_table_flush_t *mp;
7184 u32 table_id = 0;
7185 u8 is_ipv6 = 0;
7186
7187 int ret;
7188 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
Damjan Marion7cd468a2016-12-19 23:05:39 +01007189 {
Neale Ranns9db6ada2019-11-08 12:42:31 +00007190 if (unformat (i, "table %d", &table_id))
7191 ;
7192 else if (unformat (i, "ipv6"))
7193 is_ipv6 = 1;
7194 else
7195 {
7196 clib_warning ("parse error '%U'", format_unformat_error, i);
7197 return -99;
7198 }
Damjan Marion7cd468a2016-12-19 23:05:39 +01007199 }
7200
Neale Ranns9db6ada2019-11-08 12:42:31 +00007201 M (IP_TABLE_FLUSH, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007202
Neale Ranns9db6ada2019-11-08 12:42:31 +00007203 mp->table.table_id = ntohl (table_id);
7204 mp->table.is_ip6 = is_ipv6;
7205
7206 S (mp);
7207 W (ret);
7208 return ret;
7209}
7210
7211static int
7212api_ip_table_replace_end (vat_main_t * vam)
7213{
7214 unformat_input_t *i = vam->input;
7215 vl_api_ip_table_replace_end_t *mp;
7216 u32 table_id = 0;
7217 u8 is_ipv6 = 0;
7218
7219 int ret;
7220 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7221 {
7222 if (unformat (i, "table %d", &table_id))
7223 ;
7224 else if (unformat (i, "ipv6"))
7225 is_ipv6 = 1;
7226 else
7227 {
7228 clib_warning ("parse error '%U'", format_unformat_error, i);
7229 return -99;
7230 }
7231 }
7232
7233 M (IP_TABLE_REPLACE_END, mp);
7234
7235 mp->table.table_id = ntohl (table_id);
7236 mp->table.is_ip6 = is_ipv6;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007237
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007238 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007239 W (ret);
7240 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007241}
7242
7243static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01007244api_set_ip_flow_hash (vat_main_t * vam)
7245{
7246 unformat_input_t *i = vam->input;
7247 vl_api_set_ip_flow_hash_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007248 u32 vrf_id = 0;
7249 u8 is_ipv6 = 0;
7250 u8 vrf_id_set = 0;
7251 u8 src = 0;
7252 u8 dst = 0;
7253 u8 sport = 0;
7254 u8 dport = 0;
7255 u8 proto = 0;
7256 u8 reverse = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007257 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007258
7259 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7260 {
7261 if (unformat (i, "vrf %d", &vrf_id))
7262 vrf_id_set = 1;
7263 else if (unformat (i, "ipv6"))
7264 is_ipv6 = 1;
7265 else if (unformat (i, "src"))
7266 src = 1;
7267 else if (unformat (i, "dst"))
7268 dst = 1;
7269 else if (unformat (i, "sport"))
7270 sport = 1;
7271 else if (unformat (i, "dport"))
7272 dport = 1;
7273 else if (unformat (i, "proto"))
7274 proto = 1;
7275 else if (unformat (i, "reverse"))
7276 reverse = 1;
7277
7278 else
7279 {
7280 clib_warning ("parse error '%U'", format_unformat_error, i);
7281 return -99;
7282 }
7283 }
7284
7285 if (vrf_id_set == 0)
7286 {
7287 errmsg ("missing vrf id");
7288 return -99;
7289 }
7290
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007291 M (SET_IP_FLOW_HASH, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007292 mp->src = src;
7293 mp->dst = dst;
7294 mp->sport = sport;
7295 mp->dport = dport;
7296 mp->proto = proto;
7297 mp->reverse = reverse;
7298 mp->vrf_id = ntohl (vrf_id);
7299 mp->is_ipv6 = is_ipv6;
7300
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007301 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007302 W (ret);
7303 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007304}
7305
7306static int
7307api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7308{
7309 unformat_input_t *i = vam->input;
7310 vl_api_sw_interface_ip6_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007311 u32 sw_if_index;
7312 u8 sw_if_index_set = 0;
7313 u8 enable = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007314 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007315
7316 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7317 {
7318 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7319 sw_if_index_set = 1;
7320 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7321 sw_if_index_set = 1;
7322 else if (unformat (i, "enable"))
7323 enable = 1;
7324 else if (unformat (i, "disable"))
7325 enable = 0;
7326 else
7327 {
7328 clib_warning ("parse error '%U'", format_unformat_error, i);
7329 return -99;
7330 }
7331 }
7332
7333 if (sw_if_index_set == 0)
7334 {
7335 errmsg ("missing interface name or sw_if_index");
7336 return -99;
7337 }
7338
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007339 M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007340
7341 mp->sw_if_index = ntohl (sw_if_index);
7342 mp->enable = enable;
7343
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007344 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007345 W (ret);
7346 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007347}
7348
Damjan Marion7cd468a2016-12-19 23:05:39 +01007349
7350static int
7351api_l2_patch_add_del (vat_main_t * vam)
7352{
7353 unformat_input_t *i = vam->input;
7354 vl_api_l2_patch_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007355 u32 rx_sw_if_index;
7356 u8 rx_sw_if_index_set = 0;
7357 u32 tx_sw_if_index;
7358 u8 tx_sw_if_index_set = 0;
7359 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007360 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007361
7362 /* Parse args required to build the message */
7363 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7364 {
7365 if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7366 rx_sw_if_index_set = 1;
7367 else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7368 tx_sw_if_index_set = 1;
7369 else if (unformat (i, "rx"))
7370 {
7371 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7372 {
7373 if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7374 &rx_sw_if_index))
7375 rx_sw_if_index_set = 1;
7376 }
7377 else
7378 break;
7379 }
7380 else if (unformat (i, "tx"))
7381 {
7382 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7383 {
7384 if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7385 &tx_sw_if_index))
7386 tx_sw_if_index_set = 1;
7387 }
7388 else
7389 break;
7390 }
7391 else if (unformat (i, "del"))
7392 is_add = 0;
7393 else
7394 break;
7395 }
7396
7397 if (rx_sw_if_index_set == 0)
7398 {
7399 errmsg ("missing rx interface name or rx_sw_if_index");
7400 return -99;
7401 }
7402
7403 if (tx_sw_if_index_set == 0)
7404 {
7405 errmsg ("missing tx interface name or tx_sw_if_index");
7406 return -99;
7407 }
7408
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007409 M (L2_PATCH_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007410
7411 mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7412 mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7413 mp->is_add = is_add;
7414
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007415 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007416 W (ret);
7417 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007418}
7419
Pablo Camarillofb380952016-12-07 18:34:18 +01007420u8 is_del;
7421u8 localsid_addr[16];
7422u8 end_psp;
7423u8 behavior;
7424u32 sw_if_index;
7425u32 vlan_index;
7426u32 fib_table;
7427u8 nh_addr[16];
7428
7429static int
7430api_sr_localsid_add_del (vat_main_t * vam)
7431{
7432 unformat_input_t *i = vam->input;
7433 vl_api_sr_localsid_add_del_t *mp;
7434
7435 u8 is_del;
7436 ip6_address_t localsid;
7437 u8 end_psp = 0;
7438 u8 behavior = ~0;
7439 u32 sw_if_index;
7440 u32 fib_table = ~(u32) 0;
Jakub Grajciar0938eba2020-03-04 13:08:27 +01007441 ip46_address_t nh_addr;
7442 clib_memset (&nh_addr, 0, sizeof (ip46_address_t));
Pablo Camarillofb380952016-12-07 18:34:18 +01007443
7444 bool nexthop_set = 0;
7445
7446 int ret;
7447
7448 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7449 {
7450 if (unformat (i, "del"))
7451 is_del = 1;
7452 else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
Jakub Grajciar0938eba2020-03-04 13:08:27 +01007453 else if (unformat (i, "next-hop %U", unformat_ip46_address, &nh_addr))
Pablo Camarillofb380952016-12-07 18:34:18 +01007454 nexthop_set = 1;
7455 else if (unformat (i, "behavior %u", &behavior));
7456 else if (unformat (i, "sw_if_index %u", &sw_if_index));
7457 else if (unformat (i, "fib-table %u", &fib_table));
7458 else if (unformat (i, "end.psp %u", &behavior));
7459 else
7460 break;
7461 }
7462
7463 M (SR_LOCALSID_ADD_DEL, mp);
7464
Jakub Grajciar0938eba2020-03-04 13:08:27 +01007465 clib_memcpy (mp->localsid, &localsid, sizeof (mp->localsid));
Tetsuya Murakami1b81e6e2019-11-06 11:05:51 -08007466
Pablo Camarillofb380952016-12-07 18:34:18 +01007467 if (nexthop_set)
Pablo Camarillo3337bd22018-06-19 15:49:02 +02007468 {
Jakub Grajciar0938eba2020-03-04 13:08:27 +01007469 clib_memcpy (&mp->nh_addr.un, &nh_addr, sizeof (mp->nh_addr.un));
Pablo Camarillo3337bd22018-06-19 15:49:02 +02007470 }
Pablo Camarillofb380952016-12-07 18:34:18 +01007471 mp->behavior = behavior;
7472 mp->sw_if_index = ntohl (sw_if_index);
7473 mp->fib_table = ntohl (fib_table);
7474 mp->end_psp = end_psp;
7475 mp->is_del = is_del;
7476
7477 S (mp);
7478 W (ret);
7479 return ret;
7480}
7481
Damjan Marion7cd468a2016-12-19 23:05:39 +01007482static int
7483api_ioam_enable (vat_main_t * vam)
7484{
7485 unformat_input_t *input = vam->input;
7486 vl_api_ioam_enable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007487 u32 id = 0;
7488 int has_trace_option = 0;
7489 int has_pot_option = 0;
7490 int has_seqno_option = 0;
7491 int has_analyse_option = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007492 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007493
7494 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7495 {
7496 if (unformat (input, "trace"))
7497 has_trace_option = 1;
7498 else if (unformat (input, "pot"))
7499 has_pot_option = 1;
7500 else if (unformat (input, "seqno"))
7501 has_seqno_option = 1;
7502 else if (unformat (input, "analyse"))
7503 has_analyse_option = 1;
7504 else
7505 break;
7506 }
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007507 M (IOAM_ENABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007508 mp->id = htons (id);
7509 mp->seqno = has_seqno_option;
7510 mp->analyse = has_analyse_option;
7511 mp->pot_enable = has_pot_option;
7512 mp->trace_enable = has_trace_option;
7513
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007514 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007515 W (ret);
7516 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007517}
7518
7519
7520static int
7521api_ioam_disable (vat_main_t * vam)
7522{
7523 vl_api_ioam_disable_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007524 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007525
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007526 M (IOAM_DISABLE, mp);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007527 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007528 W (ret);
7529 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007530}
7531
Damjan Marion7cd468a2016-12-19 23:05:39 +01007532#define foreach_tcp_proto_field \
7533_(src_port) \
7534_(dst_port)
7535
7536#define foreach_udp_proto_field \
7537_(src_port) \
7538_(dst_port)
7539
7540#define foreach_ip4_proto_field \
7541_(src_address) \
7542_(dst_address) \
7543_(tos) \
7544_(length) \
7545_(fragment_id) \
7546_(ttl) \
7547_(protocol) \
7548_(checksum)
7549
Dave Barach4a3f69c2017-02-22 12:44:56 -05007550typedef struct
7551{
7552 u16 src_port, dst_port;
7553} tcpudp_header_t;
7554
7555#if VPP_API_TEST_BUILTIN == 0
Damjan Marion7cd468a2016-12-19 23:05:39 +01007556uword
7557unformat_tcp_mask (unformat_input_t * input, va_list * args)
7558{
7559 u8 **maskp = va_arg (*args, u8 **);
7560 u8 *mask = 0;
7561 u8 found_something = 0;
7562 tcp_header_t *tcp;
7563
7564#define _(a) u8 a=0;
7565 foreach_tcp_proto_field;
7566#undef _
7567
7568 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7569 {
7570 if (0);
7571#define _(a) else if (unformat (input, #a)) a=1;
7572 foreach_tcp_proto_field
7573#undef _
7574 else
7575 break;
7576 }
7577
7578#define _(a) found_something += a;
7579 foreach_tcp_proto_field;
7580#undef _
7581
7582 if (found_something == 0)
7583 return 0;
7584
7585 vec_validate (mask, sizeof (*tcp) - 1);
7586
7587 tcp = (tcp_header_t *) mask;
7588
Dave Barachb7b92992018-10-17 10:38:51 -04007589#define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
Damjan Marion7cd468a2016-12-19 23:05:39 +01007590 foreach_tcp_proto_field;
7591#undef _
7592
7593 *maskp = mask;
7594 return 1;
7595}
7596
7597uword
7598unformat_udp_mask (unformat_input_t * input, va_list * args)
7599{
7600 u8 **maskp = va_arg (*args, u8 **);
7601 u8 *mask = 0;
7602 u8 found_something = 0;
7603 udp_header_t *udp;
7604
7605#define _(a) u8 a=0;
7606 foreach_udp_proto_field;
7607#undef _
7608
7609 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7610 {
7611 if (0);
7612#define _(a) else if (unformat (input, #a)) a=1;
7613 foreach_udp_proto_field
7614#undef _
7615 else
7616 break;
7617 }
7618
7619#define _(a) found_something += a;
7620 foreach_udp_proto_field;
7621#undef _
7622
7623 if (found_something == 0)
7624 return 0;
7625
7626 vec_validate (mask, sizeof (*udp) - 1);
7627
7628 udp = (udp_header_t *) mask;
7629
Dave Barachb7b92992018-10-17 10:38:51 -04007630#define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
Damjan Marion7cd468a2016-12-19 23:05:39 +01007631 foreach_udp_proto_field;
7632#undef _
7633
7634 *maskp = mask;
7635 return 1;
7636}
7637
Damjan Marion7cd468a2016-12-19 23:05:39 +01007638uword
7639unformat_l4_mask (unformat_input_t * input, va_list * args)
7640{
7641 u8 **maskp = va_arg (*args, u8 **);
7642 u16 src_port = 0, dst_port = 0;
7643 tcpudp_header_t *tcpudp;
7644
7645 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7646 {
7647 if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
7648 return 1;
7649 else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
7650 return 1;
7651 else if (unformat (input, "src_port"))
7652 src_port = 0xFFFF;
7653 else if (unformat (input, "dst_port"))
7654 dst_port = 0xFFFF;
7655 else
7656 return 0;
7657 }
7658
7659 if (!src_port && !dst_port)
7660 return 0;
7661
7662 u8 *mask = 0;
7663 vec_validate (mask, sizeof (tcpudp_header_t) - 1);
7664
7665 tcpudp = (tcpudp_header_t *) mask;
7666 tcpudp->src_port = src_port;
7667 tcpudp->dst_port = dst_port;
7668
7669 *maskp = mask;
7670
7671 return 1;
7672}
7673
7674uword
7675unformat_ip4_mask (unformat_input_t * input, va_list * args)
7676{
7677 u8 **maskp = va_arg (*args, u8 **);
7678 u8 *mask = 0;
7679 u8 found_something = 0;
7680 ip4_header_t *ip;
7681
7682#define _(a) u8 a=0;
7683 foreach_ip4_proto_field;
7684#undef _
7685 u8 version = 0;
7686 u8 hdr_length = 0;
7687
7688
7689 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7690 {
7691 if (unformat (input, "version"))
7692 version = 1;
7693 else if (unformat (input, "hdr_length"))
7694 hdr_length = 1;
7695 else if (unformat (input, "src"))
7696 src_address = 1;
7697 else if (unformat (input, "dst"))
7698 dst_address = 1;
7699 else if (unformat (input, "proto"))
7700 protocol = 1;
7701
7702#define _(a) else if (unformat (input, #a)) a=1;
7703 foreach_ip4_proto_field
7704#undef _
7705 else
7706 break;
7707 }
7708
7709#define _(a) found_something += a;
7710 foreach_ip4_proto_field;
7711#undef _
7712
7713 if (found_something == 0)
7714 return 0;
7715
7716 vec_validate (mask, sizeof (*ip) - 1);
7717
7718 ip = (ip4_header_t *) mask;
7719
Dave Barachb7b92992018-10-17 10:38:51 -04007720#define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
Damjan Marion7cd468a2016-12-19 23:05:39 +01007721 foreach_ip4_proto_field;
7722#undef _
7723
7724 ip->ip_version_and_header_length = 0;
7725
7726 if (version)
7727 ip->ip_version_and_header_length |= 0xF0;
7728
7729 if (hdr_length)
7730 ip->ip_version_and_header_length |= 0x0F;
7731
7732 *maskp = mask;
7733 return 1;
7734}
7735
7736#define foreach_ip6_proto_field \
7737_(src_address) \
7738_(dst_address) \
7739_(payload_length) \
7740_(hop_limit) \
7741_(protocol)
7742
7743uword
7744unformat_ip6_mask (unformat_input_t * input, va_list * args)
7745{
7746 u8 **maskp = va_arg (*args, u8 **);
7747 u8 *mask = 0;
7748 u8 found_something = 0;
7749 ip6_header_t *ip;
7750 u32 ip_version_traffic_class_and_flow_label;
7751
7752#define _(a) u8 a=0;
7753 foreach_ip6_proto_field;
7754#undef _
7755 u8 version = 0;
7756 u8 traffic_class = 0;
7757 u8 flow_label = 0;
7758
7759 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7760 {
7761 if (unformat (input, "version"))
7762 version = 1;
7763 else if (unformat (input, "traffic-class"))
7764 traffic_class = 1;
7765 else if (unformat (input, "flow-label"))
7766 flow_label = 1;
7767 else if (unformat (input, "src"))
7768 src_address = 1;
7769 else if (unformat (input, "dst"))
7770 dst_address = 1;
7771 else if (unformat (input, "proto"))
7772 protocol = 1;
7773
7774#define _(a) else if (unformat (input, #a)) a=1;
7775 foreach_ip6_proto_field
7776#undef _
7777 else
7778 break;
7779 }
7780
7781#define _(a) found_something += a;
7782 foreach_ip6_proto_field;
7783#undef _
7784
7785 if (found_something == 0)
7786 return 0;
7787
7788 vec_validate (mask, sizeof (*ip) - 1);
7789
7790 ip = (ip6_header_t *) mask;
7791
Dave Barachb7b92992018-10-17 10:38:51 -04007792#define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
Damjan Marion7cd468a2016-12-19 23:05:39 +01007793 foreach_ip6_proto_field;
7794#undef _
7795
7796 ip_version_traffic_class_and_flow_label = 0;
7797
7798 if (version)
7799 ip_version_traffic_class_and_flow_label |= 0xF0000000;
7800
7801 if (traffic_class)
7802 ip_version_traffic_class_and_flow_label |= 0x0FF00000;
7803
7804 if (flow_label)
7805 ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
7806
7807 ip->ip_version_traffic_class_and_flow_label =
7808 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
7809
7810 *maskp = mask;
7811 return 1;
7812}
7813
7814uword
7815unformat_l3_mask (unformat_input_t * input, va_list * args)
7816{
7817 u8 **maskp = va_arg (*args, u8 **);
7818
7819 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7820 {
7821 if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
7822 return 1;
7823 else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
7824 return 1;
7825 else
7826 break;
7827 }
7828 return 0;
7829}
7830
7831uword
7832unformat_l2_mask (unformat_input_t * input, va_list * args)
7833{
7834 u8 **maskp = va_arg (*args, u8 **);
7835 u8 *mask = 0;
7836 u8 src = 0;
7837 u8 dst = 0;
7838 u8 proto = 0;
7839 u8 tag1 = 0;
7840 u8 tag2 = 0;
7841 u8 ignore_tag1 = 0;
7842 u8 ignore_tag2 = 0;
7843 u8 cos1 = 0;
7844 u8 cos2 = 0;
7845 u8 dot1q = 0;
7846 u8 dot1ad = 0;
7847 int len = 14;
7848
7849 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7850 {
7851 if (unformat (input, "src"))
7852 src = 1;
7853 else if (unformat (input, "dst"))
7854 dst = 1;
7855 else if (unformat (input, "proto"))
7856 proto = 1;
7857 else if (unformat (input, "tag1"))
7858 tag1 = 1;
7859 else if (unformat (input, "tag2"))
7860 tag2 = 1;
7861 else if (unformat (input, "ignore-tag1"))
7862 ignore_tag1 = 1;
7863 else if (unformat (input, "ignore-tag2"))
7864 ignore_tag2 = 1;
7865 else if (unformat (input, "cos1"))
7866 cos1 = 1;
7867 else if (unformat (input, "cos2"))
7868 cos2 = 1;
7869 else if (unformat (input, "dot1q"))
7870 dot1q = 1;
7871 else if (unformat (input, "dot1ad"))
7872 dot1ad = 1;
7873 else
7874 break;
7875 }
7876 if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
7877 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
7878 return 0;
7879
7880 if (tag1 || ignore_tag1 || cos1 || dot1q)
7881 len = 18;
7882 if (tag2 || ignore_tag2 || cos2 || dot1ad)
7883 len = 22;
7884
7885 vec_validate (mask, len - 1);
7886
7887 if (dst)
Dave Barachb7b92992018-10-17 10:38:51 -04007888 clib_memset (mask, 0xff, 6);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007889
7890 if (src)
Dave Barachb7b92992018-10-17 10:38:51 -04007891 clib_memset (mask + 6, 0xff, 6);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007892
7893 if (tag2 || dot1ad)
7894 {
7895 /* inner vlan tag */
7896 if (tag2)
7897 {
7898 mask[19] = 0xff;
7899 mask[18] = 0x0f;
7900 }
7901 if (cos2)
7902 mask[18] |= 0xe0;
7903 if (proto)
7904 mask[21] = mask[20] = 0xff;
7905 if (tag1)
7906 {
7907 mask[15] = 0xff;
7908 mask[14] = 0x0f;
7909 }
7910 if (cos1)
7911 mask[14] |= 0xe0;
7912 *maskp = mask;
7913 return 1;
7914 }
7915 if (tag1 | dot1q)
7916 {
7917 if (tag1)
7918 {
7919 mask[15] = 0xff;
7920 mask[14] = 0x0f;
7921 }
7922 if (cos1)
7923 mask[14] |= 0xe0;
7924 if (proto)
7925 mask[16] = mask[17] = 0xff;
7926
7927 *maskp = mask;
7928 return 1;
7929 }
7930 if (cos2)
7931 mask[18] |= 0xe0;
7932 if (cos1)
7933 mask[14] |= 0xe0;
7934 if (proto)
7935 mask[12] = mask[13] = 0xff;
7936
7937 *maskp = mask;
7938 return 1;
7939}
7940
7941uword
7942unformat_classify_mask (unformat_input_t * input, va_list * args)
7943{
7944 u8 **maskp = va_arg (*args, u8 **);
7945 u32 *skipp = va_arg (*args, u32 *);
7946 u32 *matchp = va_arg (*args, u32 *);
7947 u32 match;
7948 u8 *mask = 0;
7949 u8 *l2 = 0;
7950 u8 *l3 = 0;
7951 u8 *l4 = 0;
7952 int i;
7953
7954 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7955 {
7956 if (unformat (input, "hex %U", unformat_hex_string, &mask))
7957 ;
7958 else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
7959 ;
7960 else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
7961 ;
7962 else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
7963 ;
7964 else
7965 break;
7966 }
7967
7968 if (l4 && !l3)
7969 {
7970 vec_free (mask);
7971 vec_free (l2);
7972 vec_free (l4);
7973 return 0;
7974 }
7975
7976 if (mask || l2 || l3 || l4)
7977 {
7978 if (l2 || l3 || l4)
7979 {
7980 /* "With a free Ethernet header in every package" */
7981 if (l2 == 0)
7982 vec_validate (l2, 13);
7983 mask = l2;
7984 if (vec_len (l3))
7985 {
7986 vec_append (mask, l3);
7987 vec_free (l3);
7988 }
7989 if (vec_len (l4))
7990 {
7991 vec_append (mask, l4);
7992 vec_free (l4);
7993 }
7994 }
7995
7996 /* Scan forward looking for the first significant mask octet */
7997 for (i = 0; i < vec_len (mask); i++)
7998 if (mask[i])
7999 break;
8000
8001 /* compute (skip, match) params */
8002 *skipp = i / sizeof (u32x4);
8003 vec_delete (mask, *skipp * sizeof (u32x4), 0);
8004
8005 /* Pad mask to an even multiple of the vector size */
8006 while (vec_len (mask) % sizeof (u32x4))
8007 vec_add1 (mask, 0);
8008
8009 match = vec_len (mask) / sizeof (u32x4);
8010
8011 for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
8012 {
8013 u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
8014 if (*tmp || *(tmp + 1))
8015 break;
8016 match--;
8017 }
8018 if (match == 0)
8019 clib_warning ("BUG: match 0");
8020
8021 _vec_len (mask) = match * sizeof (u32x4);
8022
8023 *matchp = match;
8024 *maskp = mask;
8025
8026 return 1;
8027 }
8028
8029 return 0;
8030}
Dave Barach4a3f69c2017-02-22 12:44:56 -05008031#endif /* VPP_API_TEST_BUILTIN */
Damjan Marion7cd468a2016-12-19 23:05:39 +01008032
8033#define foreach_l2_next \
8034_(drop, DROP) \
8035_(ethernet, ETHERNET_INPUT) \
8036_(ip4, IP4_INPUT) \
8037_(ip6, IP6_INPUT)
8038
8039uword
8040unformat_l2_next_index (unformat_input_t * input, va_list * args)
8041{
8042 u32 *miss_next_indexp = va_arg (*args, u32 *);
8043 u32 next_index = 0;
8044 u32 tmp;
8045
8046#define _(n,N) \
8047 if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
8048 foreach_l2_next;
8049#undef _
8050
8051 if (unformat (input, "%d", &tmp))
8052 {
8053 next_index = tmp;
8054 goto out;
8055 }
8056
8057 return 0;
8058
8059out:
8060 *miss_next_indexp = next_index;
8061 return 1;
8062}
8063
8064#define foreach_ip_next \
8065_(drop, DROP) \
8066_(local, LOCAL) \
8067_(rewrite, REWRITE)
8068
8069uword
Dave Barach4a3f69c2017-02-22 12:44:56 -05008070api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
Damjan Marion7cd468a2016-12-19 23:05:39 +01008071{
8072 u32 *miss_next_indexp = va_arg (*args, u32 *);
8073 u32 next_index = 0;
8074 u32 tmp;
8075
8076#define _(n,N) \
8077 if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
8078 foreach_ip_next;
8079#undef _
8080
8081 if (unformat (input, "%d", &tmp))
8082 {
8083 next_index = tmp;
8084 goto out;
8085 }
8086
8087 return 0;
8088
8089out:
8090 *miss_next_indexp = next_index;
8091 return 1;
8092}
8093
8094#define foreach_acl_next \
8095_(deny, DENY)
8096
8097uword
Dave Barach4a3f69c2017-02-22 12:44:56 -05008098api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
Damjan Marion7cd468a2016-12-19 23:05:39 +01008099{
8100 u32 *miss_next_indexp = va_arg (*args, u32 *);
8101 u32 next_index = 0;
8102 u32 tmp;
8103
8104#define _(n,N) \
8105 if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
8106 foreach_acl_next;
8107#undef _
8108
8109 if (unformat (input, "permit"))
8110 {
8111 next_index = ~0;
8112 goto out;
8113 }
8114 else if (unformat (input, "%d", &tmp))
8115 {
8116 next_index = tmp;
8117 goto out;
8118 }
8119
8120 return 0;
8121
8122out:
8123 *miss_next_indexp = next_index;
8124 return 1;
8125}
8126
8127uword
8128unformat_policer_precolor (unformat_input_t * input, va_list * args)
8129{
8130 u32 *r = va_arg (*args, u32 *);
8131
8132 if (unformat (input, "conform-color"))
8133 *r = POLICE_CONFORM;
8134 else if (unformat (input, "exceed-color"))
8135 *r = POLICE_EXCEED;
8136 else
8137 return 0;
8138
8139 return 1;
8140}
8141
8142static int
8143api_classify_add_del_table (vat_main_t * vam)
8144{
8145 unformat_input_t *i = vam->input;
8146 vl_api_classify_add_del_table_t *mp;
8147
8148 u32 nbuckets = 2;
8149 u32 skip = ~0;
8150 u32 match = ~0;
8151 int is_add = 1;
8152 int del_chain = 0;
8153 u32 table_index = ~0;
8154 u32 next_table_index = ~0;
8155 u32 miss_next_index = ~0;
8156 u32 memory_size = 32 << 20;
8157 u8 *mask = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008158 u32 current_data_flag = 0;
8159 int current_data_offset = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008160 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008161
8162 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8163 {
8164 if (unformat (i, "del"))
8165 is_add = 0;
8166 else if (unformat (i, "del-chain"))
8167 {
8168 is_add = 0;
8169 del_chain = 1;
8170 }
8171 else if (unformat (i, "buckets %d", &nbuckets))
8172 ;
8173 else if (unformat (i, "memory_size %d", &memory_size))
8174 ;
8175 else if (unformat (i, "skip %d", &skip))
8176 ;
8177 else if (unformat (i, "match %d", &match))
8178 ;
8179 else if (unformat (i, "table %d", &table_index))
8180 ;
8181 else if (unformat (i, "mask %U", unformat_classify_mask,
8182 &mask, &skip, &match))
8183 ;
8184 else if (unformat (i, "next-table %d", &next_table_index))
8185 ;
Dave Barach4a3f69c2017-02-22 12:44:56 -05008186 else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
Damjan Marion7cd468a2016-12-19 23:05:39 +01008187 &miss_next_index))
8188 ;
8189 else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
8190 &miss_next_index))
8191 ;
Dave Barach4a3f69c2017-02-22 12:44:56 -05008192 else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
Damjan Marion7cd468a2016-12-19 23:05:39 +01008193 &miss_next_index))
8194 ;
8195 else if (unformat (i, "current-data-flag %d", &current_data_flag))
8196 ;
8197 else if (unformat (i, "current-data-offset %d", &current_data_offset))
8198 ;
8199 else
8200 break;
8201 }
8202
8203 if (is_add && mask == 0)
8204 {
8205 errmsg ("Mask required");
8206 return -99;
8207 }
8208
8209 if (is_add && skip == ~0)
8210 {
8211 errmsg ("skip count required");
8212 return -99;
8213 }
8214
8215 if (is_add && match == ~0)
8216 {
8217 errmsg ("match count required");
8218 return -99;
8219 }
8220
8221 if (!is_add && table_index == ~0)
8222 {
8223 errmsg ("table index required for delete");
8224 return -99;
8225 }
8226
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008227 M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
Damjan Marion7cd468a2016-12-19 23:05:39 +01008228
8229 mp->is_add = is_add;
8230 mp->del_chain = del_chain;
8231 mp->table_index = ntohl (table_index);
8232 mp->nbuckets = ntohl (nbuckets);
8233 mp->memory_size = ntohl (memory_size);
8234 mp->skip_n_vectors = ntohl (skip);
8235 mp->match_n_vectors = ntohl (match);
8236 mp->next_table_index = ntohl (next_table_index);
8237 mp->miss_next_index = ntohl (miss_next_index);
8238 mp->current_data_flag = ntohl (current_data_flag);
8239 mp->current_data_offset = ntohl (current_data_offset);
Juraj Sloboda75282452018-06-12 14:20:49 +02008240 mp->mask_len = ntohl (vec_len (mask));
Damjan Marion7cd468a2016-12-19 23:05:39 +01008241 clib_memcpy (mp->mask, mask, vec_len (mask));
8242
8243 vec_free (mask);
8244
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008245 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008246 W (ret);
8247 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008248}
8249
Dave Barach4a3f69c2017-02-22 12:44:56 -05008250#if VPP_API_TEST_BUILTIN == 0
Damjan Marion7cd468a2016-12-19 23:05:39 +01008251uword
8252unformat_l4_match (unformat_input_t * input, va_list * args)
8253{
8254 u8 **matchp = va_arg (*args, u8 **);
8255
8256 u8 *proto_header = 0;
8257 int src_port = 0;
8258 int dst_port = 0;
8259
8260 tcpudp_header_t h;
8261
8262 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8263 {
8264 if (unformat (input, "src_port %d", &src_port))
8265 ;
8266 else if (unformat (input, "dst_port %d", &dst_port))
8267 ;
8268 else
8269 return 0;
8270 }
8271
8272 h.src_port = clib_host_to_net_u16 (src_port);
8273 h.dst_port = clib_host_to_net_u16 (dst_port);
8274 vec_validate (proto_header, sizeof (h) - 1);
8275 memcpy (proto_header, &h, sizeof (h));
8276
8277 *matchp = proto_header;
8278
8279 return 1;
8280}
8281
8282uword
8283unformat_ip4_match (unformat_input_t * input, va_list * args)
8284{
8285 u8 **matchp = va_arg (*args, u8 **);
8286 u8 *match = 0;
8287 ip4_header_t *ip;
8288 int version = 0;
8289 u32 version_val;
8290 int hdr_length = 0;
8291 u32 hdr_length_val;
8292 int src = 0, dst = 0;
8293 ip4_address_t src_val, dst_val;
8294 int proto = 0;
8295 u32 proto_val;
8296 int tos = 0;
8297 u32 tos_val;
8298 int length = 0;
8299 u32 length_val;
8300 int fragment_id = 0;
8301 u32 fragment_id_val;
8302 int ttl = 0;
8303 int ttl_val;
8304 int checksum = 0;
8305 u32 checksum_val;
8306
8307 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8308 {
8309 if (unformat (input, "version %d", &version_val))
8310 version = 1;
8311 else if (unformat (input, "hdr_length %d", &hdr_length_val))
8312 hdr_length = 1;
8313 else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
8314 src = 1;
8315 else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
8316 dst = 1;
8317 else if (unformat (input, "proto %d", &proto_val))
8318 proto = 1;
8319 else if (unformat (input, "tos %d", &tos_val))
8320 tos = 1;
8321 else if (unformat (input, "length %d", &length_val))
8322 length = 1;
8323 else if (unformat (input, "fragment_id %d", &fragment_id_val))
8324 fragment_id = 1;
8325 else if (unformat (input, "ttl %d", &ttl_val))
8326 ttl = 1;
8327 else if (unformat (input, "checksum %d", &checksum_val))
8328 checksum = 1;
8329 else
8330 break;
8331 }
8332
8333 if (version + hdr_length + src + dst + proto + tos + length + fragment_id
8334 + ttl + checksum == 0)
8335 return 0;
8336
8337 /*
8338 * Aligned because we use the real comparison functions
8339 */
8340 vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8341
8342 ip = (ip4_header_t *) match;
8343
8344 /* These are realistically matched in practice */
8345 if (src)
8346 ip->src_address.as_u32 = src_val.as_u32;
8347
8348 if (dst)
8349 ip->dst_address.as_u32 = dst_val.as_u32;
8350
8351 if (proto)
8352 ip->protocol = proto_val;
8353
8354
8355 /* These are not, but they're included for completeness */
8356 if (version)
8357 ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
8358
8359 if (hdr_length)
8360 ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
8361
8362 if (tos)
8363 ip->tos = tos_val;
8364
8365 if (length)
8366 ip->length = clib_host_to_net_u16 (length_val);
8367
8368 if (ttl)
8369 ip->ttl = ttl_val;
8370
8371 if (checksum)
8372 ip->checksum = clib_host_to_net_u16 (checksum_val);
8373
8374 *matchp = match;
8375 return 1;
8376}
8377
8378uword
8379unformat_ip6_match (unformat_input_t * input, va_list * args)
8380{
8381 u8 **matchp = va_arg (*args, u8 **);
8382 u8 *match = 0;
8383 ip6_header_t *ip;
8384 int version = 0;
8385 u32 version_val;
8386 u8 traffic_class = 0;
8387 u32 traffic_class_val = 0;
8388 u8 flow_label = 0;
8389 u8 flow_label_val;
8390 int src = 0, dst = 0;
8391 ip6_address_t src_val, dst_val;
8392 int proto = 0;
8393 u32 proto_val;
8394 int payload_length = 0;
8395 u32 payload_length_val;
8396 int hop_limit = 0;
8397 int hop_limit_val;
8398 u32 ip_version_traffic_class_and_flow_label;
8399
8400 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8401 {
8402 if (unformat (input, "version %d", &version_val))
8403 version = 1;
8404 else if (unformat (input, "traffic_class %d", &traffic_class_val))
8405 traffic_class = 1;
8406 else if (unformat (input, "flow_label %d", &flow_label_val))
8407 flow_label = 1;
8408 else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
8409 src = 1;
8410 else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
8411 dst = 1;
8412 else if (unformat (input, "proto %d", &proto_val))
8413 proto = 1;
8414 else if (unformat (input, "payload_length %d", &payload_length_val))
8415 payload_length = 1;
8416 else if (unformat (input, "hop_limit %d", &hop_limit_val))
8417 hop_limit = 1;
8418 else
8419 break;
8420 }
8421
8422 if (version + traffic_class + flow_label + src + dst + proto +
8423 payload_length + hop_limit == 0)
8424 return 0;
8425
8426 /*
8427 * Aligned because we use the real comparison functions
8428 */
8429 vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8430
8431 ip = (ip6_header_t *) match;
8432
8433 if (src)
8434 clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
8435
8436 if (dst)
8437 clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
8438
8439 if (proto)
8440 ip->protocol = proto_val;
8441
8442 ip_version_traffic_class_and_flow_label = 0;
8443
8444 if (version)
8445 ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
8446
8447 if (traffic_class)
8448 ip_version_traffic_class_and_flow_label |=
8449 (traffic_class_val & 0xFF) << 20;
8450
8451 if (flow_label)
8452 ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
8453
8454 ip->ip_version_traffic_class_and_flow_label =
8455 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8456
8457 if (payload_length)
8458 ip->payload_length = clib_host_to_net_u16 (payload_length_val);
8459
8460 if (hop_limit)
8461 ip->hop_limit = hop_limit_val;
8462
8463 *matchp = match;
8464 return 1;
8465}
8466
8467uword
8468unformat_l3_match (unformat_input_t * input, va_list * args)
8469{
8470 u8 **matchp = va_arg (*args, u8 **);
8471
8472 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8473 {
8474 if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
8475 return 1;
8476 else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
8477 return 1;
8478 else
8479 break;
8480 }
8481 return 0;
8482}
8483
8484uword
8485unformat_vlan_tag (unformat_input_t * input, va_list * args)
8486{
8487 u8 *tagp = va_arg (*args, u8 *);
8488 u32 tag;
8489
8490 if (unformat (input, "%d", &tag))
8491 {
8492 tagp[0] = (tag >> 8) & 0x0F;
8493 tagp[1] = tag & 0xFF;
8494 return 1;
8495 }
8496
8497 return 0;
8498}
8499
8500uword
8501unformat_l2_match (unformat_input_t * input, va_list * args)
8502{
8503 u8 **matchp = va_arg (*args, u8 **);
8504 u8 *match = 0;
8505 u8 src = 0;
8506 u8 src_val[6];
8507 u8 dst = 0;
8508 u8 dst_val[6];
8509 u8 proto = 0;
8510 u16 proto_val;
8511 u8 tag1 = 0;
8512 u8 tag1_val[2];
8513 u8 tag2 = 0;
8514 u8 tag2_val[2];
8515 int len = 14;
8516 u8 ignore_tag1 = 0;
8517 u8 ignore_tag2 = 0;
8518 u8 cos1 = 0;
8519 u8 cos2 = 0;
8520 u32 cos1_val = 0;
8521 u32 cos2_val = 0;
8522
8523 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8524 {
8525 if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
8526 src = 1;
8527 else
8528 if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
8529 dst = 1;
8530 else if (unformat (input, "proto %U",
8531 unformat_ethernet_type_host_byte_order, &proto_val))
8532 proto = 1;
8533 else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
8534 tag1 = 1;
8535 else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
8536 tag2 = 1;
8537 else if (unformat (input, "ignore-tag1"))
8538 ignore_tag1 = 1;
8539 else if (unformat (input, "ignore-tag2"))
8540 ignore_tag2 = 1;
8541 else if (unformat (input, "cos1 %d", &cos1_val))
8542 cos1 = 1;
8543 else if (unformat (input, "cos2 %d", &cos2_val))
8544 cos2 = 1;
8545 else
8546 break;
8547 }
8548 if ((src + dst + proto + tag1 + tag2 +
8549 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8550 return 0;
8551
8552 if (tag1 || ignore_tag1 || cos1)
8553 len = 18;
8554 if (tag2 || ignore_tag2 || cos2)
8555 len = 22;
8556
8557 vec_validate_aligned (match, len - 1, sizeof (u32x4));
8558
8559 if (dst)
8560 clib_memcpy (match, dst_val, 6);
8561
8562 if (src)
8563 clib_memcpy (match + 6, src_val, 6);
8564
8565 if (tag2)
8566 {
8567 /* inner vlan tag */
8568 match[19] = tag2_val[1];
8569 match[18] = tag2_val[0];
8570 if (cos2)
8571 match[18] |= (cos2_val & 0x7) << 5;
8572 if (proto)
8573 {
8574 match[21] = proto_val & 0xff;
8575 match[20] = proto_val >> 8;
8576 }
8577 if (tag1)
8578 {
8579 match[15] = tag1_val[1];
8580 match[14] = tag1_val[0];
8581 }
8582 if (cos1)
8583 match[14] |= (cos1_val & 0x7) << 5;
8584 *matchp = match;
8585 return 1;
8586 }
8587 if (tag1)
8588 {
8589 match[15] = tag1_val[1];
8590 match[14] = tag1_val[0];
8591 if (proto)
8592 {
8593 match[17] = proto_val & 0xff;
8594 match[16] = proto_val >> 8;
8595 }
8596 if (cos1)
8597 match[14] |= (cos1_val & 0x7) << 5;
8598
8599 *matchp = match;
8600 return 1;
8601 }
8602 if (cos2)
8603 match[18] |= (cos2_val & 0x7) << 5;
8604 if (cos1)
8605 match[14] |= (cos1_val & 0x7) << 5;
8606 if (proto)
8607 {
8608 match[13] = proto_val & 0xff;
8609 match[12] = proto_val >> 8;
8610 }
8611
8612 *matchp = match;
8613 return 1;
8614}
Igor Mikhailov (imichail)582caa32018-04-26 21:33:02 -07008615
8616uword
8617unformat_qos_source (unformat_input_t * input, va_list * args)
8618{
8619 int *qs = va_arg (*args, int *);
8620
8621 if (unformat (input, "ip"))
8622 *qs = QOS_SOURCE_IP;
8623 else if (unformat (input, "mpls"))
8624 *qs = QOS_SOURCE_MPLS;
8625 else if (unformat (input, "ext"))
8626 *qs = QOS_SOURCE_EXT;
8627 else if (unformat (input, "vlan"))
8628 *qs = QOS_SOURCE_VLAN;
8629 else
8630 return 0;
8631
8632 return 1;
8633}
Dave Barach4a3f69c2017-02-22 12:44:56 -05008634#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +01008635
8636uword
Dave Barach4a3f69c2017-02-22 12:44:56 -05008637api_unformat_classify_match (unformat_input_t * input, va_list * args)
Damjan Marion7cd468a2016-12-19 23:05:39 +01008638{
8639 u8 **matchp = va_arg (*args, u8 **);
8640 u32 skip_n_vectors = va_arg (*args, u32);
8641 u32 match_n_vectors = va_arg (*args, u32);
8642
8643 u8 *match = 0;
8644 u8 *l2 = 0;
8645 u8 *l3 = 0;
8646 u8 *l4 = 0;
8647
8648 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8649 {
8650 if (unformat (input, "hex %U", unformat_hex_string, &match))
8651 ;
8652 else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
8653 ;
8654 else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
8655 ;
8656 else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
8657 ;
8658 else
8659 break;
8660 }
8661
8662 if (l4 && !l3)
8663 {
8664 vec_free (match);
8665 vec_free (l2);
8666 vec_free (l4);
8667 return 0;
8668 }
8669
8670 if (match || l2 || l3 || l4)
8671 {
8672 if (l2 || l3 || l4)
8673 {
8674 /* "Win a free Ethernet header in every packet" */
8675 if (l2 == 0)
8676 vec_validate_aligned (l2, 13, sizeof (u32x4));
8677 match = l2;
8678 if (vec_len (l3))
8679 {
8680 vec_append_aligned (match, l3, sizeof (u32x4));
8681 vec_free (l3);
8682 }
8683 if (vec_len (l4))
8684 {
8685 vec_append_aligned (match, l4, sizeof (u32x4));
8686 vec_free (l4);
8687 }
8688 }
8689
8690 /* Make sure the vector is big enough even if key is all 0's */
8691 vec_validate_aligned
8692 (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
8693 sizeof (u32x4));
8694
8695 /* Set size, include skipped vectors */
8696 _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
8697
8698 *matchp = match;
8699
8700 return 1;
8701 }
8702
8703 return 0;
8704}
8705
8706static int
8707api_classify_add_del_session (vat_main_t * vam)
8708{
8709 unformat_input_t *i = vam->input;
8710 vl_api_classify_add_del_session_t *mp;
8711 int is_add = 1;
8712 u32 table_index = ~0;
8713 u32 hit_next_index = ~0;
8714 u32 opaque_index = ~0;
8715 u8 *match = 0;
8716 i32 advance = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008717 u32 skip_n_vectors = 0;
8718 u32 match_n_vectors = 0;
8719 u32 action = 0;
8720 u32 metadata = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008721 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008722
8723 /*
8724 * Warning: you have to supply skip_n and match_n
8725 * because the API client cant simply look at the classify
8726 * table object.
8727 */
8728
8729 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8730 {
8731 if (unformat (i, "del"))
8732 is_add = 0;
Dave Barach4a3f69c2017-02-22 12:44:56 -05008733 else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
Damjan Marion7cd468a2016-12-19 23:05:39 +01008734 &hit_next_index))
8735 ;
8736 else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
8737 &hit_next_index))
8738 ;
Dave Barach4a3f69c2017-02-22 12:44:56 -05008739 else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
Damjan Marion7cd468a2016-12-19 23:05:39 +01008740 &hit_next_index))
8741 ;
8742 else if (unformat (i, "policer-hit-next %d", &hit_next_index))
8743 ;
8744 else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
8745 ;
8746 else if (unformat (i, "opaque-index %d", &opaque_index))
8747 ;
8748 else if (unformat (i, "skip_n %d", &skip_n_vectors))
8749 ;
8750 else if (unformat (i, "match_n %d", &match_n_vectors))
8751 ;
Dave Barach4a3f69c2017-02-22 12:44:56 -05008752 else if (unformat (i, "match %U", api_unformat_classify_match,
Damjan Marion7cd468a2016-12-19 23:05:39 +01008753 &match, skip_n_vectors, match_n_vectors))
8754 ;
8755 else if (unformat (i, "advance %d", &advance))
8756 ;
8757 else if (unformat (i, "table-index %d", &table_index))
8758 ;
8759 else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
8760 action = 1;
8761 else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
8762 action = 2;
8763 else if (unformat (i, "action %d", &action))
8764 ;
8765 else if (unformat (i, "metadata %d", &metadata))
8766 ;
8767 else
8768 break;
8769 }
8770
8771 if (table_index == ~0)
8772 {
8773 errmsg ("Table index required");
8774 return -99;
8775 }
8776
8777 if (is_add && match == 0)
8778 {
8779 errmsg ("Match value required");
8780 return -99;
8781 }
8782
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008783 M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
Damjan Marion7cd468a2016-12-19 23:05:39 +01008784
8785 mp->is_add = is_add;
8786 mp->table_index = ntohl (table_index);
8787 mp->hit_next_index = ntohl (hit_next_index);
8788 mp->opaque_index = ntohl (opaque_index);
8789 mp->advance = ntohl (advance);
8790 mp->action = action;
8791 mp->metadata = ntohl (metadata);
Juraj Sloboda75282452018-06-12 14:20:49 +02008792 mp->match_len = ntohl (vec_len (match));
Damjan Marion7cd468a2016-12-19 23:05:39 +01008793 clib_memcpy (mp->match, match, vec_len (match));
8794 vec_free (match);
8795
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008796 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008797 W (ret);
8798 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008799}
8800
8801static int
8802api_classify_set_interface_ip_table (vat_main_t * vam)
8803{
8804 unformat_input_t *i = vam->input;
8805 vl_api_classify_set_interface_ip_table_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008806 u32 sw_if_index;
8807 int sw_if_index_set;
8808 u32 table_index = ~0;
8809 u8 is_ipv6 = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008810 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008811
8812 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8813 {
8814 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8815 sw_if_index_set = 1;
8816 else if (unformat (i, "sw_if_index %d", &sw_if_index))
8817 sw_if_index_set = 1;
8818 else if (unformat (i, "table %d", &table_index))
8819 ;
8820 else
8821 {
8822 clib_warning ("parse error '%U'", format_unformat_error, i);
8823 return -99;
8824 }
8825 }
8826
8827 if (sw_if_index_set == 0)
8828 {
8829 errmsg ("missing interface name or sw_if_index");
8830 return -99;
8831 }
8832
8833
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008834 M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008835
8836 mp->sw_if_index = ntohl (sw_if_index);
8837 mp->table_index = ntohl (table_index);
8838 mp->is_ipv6 = is_ipv6;
8839
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008840 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008841 W (ret);
8842 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008843}
8844
8845static int
8846api_classify_set_interface_l2_tables (vat_main_t * vam)
8847{
8848 unformat_input_t *i = vam->input;
8849 vl_api_classify_set_interface_l2_tables_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008850 u32 sw_if_index;
8851 int sw_if_index_set;
8852 u32 ip4_table_index = ~0;
8853 u32 ip6_table_index = ~0;
8854 u32 other_table_index = ~0;
8855 u32 is_input = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008856 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008857
8858 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8859 {
8860 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8861 sw_if_index_set = 1;
8862 else if (unformat (i, "sw_if_index %d", &sw_if_index))
8863 sw_if_index_set = 1;
8864 else if (unformat (i, "ip4-table %d", &ip4_table_index))
8865 ;
8866 else if (unformat (i, "ip6-table %d", &ip6_table_index))
8867 ;
8868 else if (unformat (i, "other-table %d", &other_table_index))
8869 ;
8870 else if (unformat (i, "is-input %d", &is_input))
8871 ;
8872 else
8873 {
8874 clib_warning ("parse error '%U'", format_unformat_error, i);
8875 return -99;
8876 }
8877 }
8878
8879 if (sw_if_index_set == 0)
8880 {
8881 errmsg ("missing interface name or sw_if_index");
8882 return -99;
8883 }
8884
8885
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008886 M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008887
8888 mp->sw_if_index = ntohl (sw_if_index);
8889 mp->ip4_table_index = ntohl (ip4_table_index);
8890 mp->ip6_table_index = ntohl (ip6_table_index);
8891 mp->other_table_index = ntohl (other_table_index);
8892 mp->is_input = (u8) is_input;
8893
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008894 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008895 W (ret);
8896 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008897}
8898
8899static int
8900api_set_ipfix_exporter (vat_main_t * vam)
8901{
8902 unformat_input_t *i = vam->input;
8903 vl_api_set_ipfix_exporter_t *mp;
8904 ip4_address_t collector_address;
8905 u8 collector_address_set = 0;
8906 u32 collector_port = ~0;
8907 ip4_address_t src_address;
8908 u8 src_address_set = 0;
8909 u32 vrf_id = ~0;
8910 u32 path_mtu = ~0;
8911 u32 template_interval = ~0;
8912 u8 udp_checksum = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008913 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008914
8915 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8916 {
8917 if (unformat (i, "collector_address %U", unformat_ip4_address,
8918 &collector_address))
8919 collector_address_set = 1;
8920 else if (unformat (i, "collector_port %d", &collector_port))
8921 ;
8922 else if (unformat (i, "src_address %U", unformat_ip4_address,
8923 &src_address))
8924 src_address_set = 1;
8925 else if (unformat (i, "vrf_id %d", &vrf_id))
8926 ;
8927 else if (unformat (i, "path_mtu %d", &path_mtu))
8928 ;
8929 else if (unformat (i, "template_interval %d", &template_interval))
8930 ;
8931 else if (unformat (i, "udp_checksum"))
8932 udp_checksum = 1;
8933 else
8934 break;
8935 }
8936
8937 if (collector_address_set == 0)
8938 {
8939 errmsg ("collector_address required");
8940 return -99;
8941 }
8942
8943 if (src_address_set == 0)
8944 {
8945 errmsg ("src_address required");
8946 return -99;
8947 }
8948
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008949 M (SET_IPFIX_EXPORTER, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008950
Jakub Grajciar2f71a882019-10-10 14:21:22 +02008951 memcpy (mp->collector_address.un.ip4, collector_address.data,
Damjan Marion7cd468a2016-12-19 23:05:39 +01008952 sizeof (collector_address.data));
8953 mp->collector_port = htons ((u16) collector_port);
Jakub Grajciar2f71a882019-10-10 14:21:22 +02008954 memcpy (mp->src_address.un.ip4, src_address.data,
8955 sizeof (src_address.data));
Damjan Marion7cd468a2016-12-19 23:05:39 +01008956 mp->vrf_id = htonl (vrf_id);
8957 mp->path_mtu = htonl (path_mtu);
8958 mp->template_interval = htonl (template_interval);
8959 mp->udp_checksum = udp_checksum;
8960
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008961 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008962 W (ret);
8963 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008964}
8965
8966static int
8967api_set_ipfix_classify_stream (vat_main_t * vam)
8968{
8969 unformat_input_t *i = vam->input;
8970 vl_api_set_ipfix_classify_stream_t *mp;
8971 u32 domain_id = 0;
8972 u32 src_port = UDP_DST_PORT_ipfix;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008973 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008974
8975 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8976 {
8977 if (unformat (i, "domain %d", &domain_id))
8978 ;
8979 else if (unformat (i, "src_port %d", &src_port))
8980 ;
8981 else
8982 {
8983 errmsg ("unknown input `%U'", format_unformat_error, i);
8984 return -99;
8985 }
8986 }
8987
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008988 M (SET_IPFIX_CLASSIFY_STREAM, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008989
8990 mp->domain_id = htonl (domain_id);
8991 mp->src_port = htons ((u16) src_port);
8992
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008993 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008994 W (ret);
8995 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008996}
8997
8998static int
8999api_ipfix_classify_table_add_del (vat_main_t * vam)
9000{
9001 unformat_input_t *i = vam->input;
9002 vl_api_ipfix_classify_table_add_del_t *mp;
9003 int is_add = -1;
9004 u32 classify_table_index = ~0;
9005 u8 ip_version = 0;
9006 u8 transport_protocol = 255;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009007 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009008
9009 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9010 {
9011 if (unformat (i, "add"))
9012 is_add = 1;
9013 else if (unformat (i, "del"))
9014 is_add = 0;
9015 else if (unformat (i, "table %d", &classify_table_index))
9016 ;
9017 else if (unformat (i, "ip4"))
9018 ip_version = 4;
9019 else if (unformat (i, "ip6"))
9020 ip_version = 6;
9021 else if (unformat (i, "tcp"))
9022 transport_protocol = 6;
9023 else if (unformat (i, "udp"))
9024 transport_protocol = 17;
9025 else
9026 {
9027 errmsg ("unknown input `%U'", format_unformat_error, i);
9028 return -99;
9029 }
9030 }
9031
9032 if (is_add == -1)
9033 {
9034 errmsg ("expecting: add|del");
9035 return -99;
9036 }
9037 if (classify_table_index == ~0)
9038 {
9039 errmsg ("classifier table not specified");
9040 return -99;
9041 }
9042 if (ip_version == 0)
9043 {
9044 errmsg ("IP version not specified");
9045 return -99;
9046 }
9047
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009048 M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009049
9050 mp->is_add = is_add;
9051 mp->table_id = htonl (classify_table_index);
9052 mp->ip_version = ip_version;
9053 mp->transport_protocol = transport_protocol;
9054
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009055 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06009056 W (ret);
9057 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009058}
9059
9060static int
9061api_get_node_index (vat_main_t * vam)
9062{
9063 unformat_input_t *i = vam->input;
9064 vl_api_get_node_index_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009065 u8 *name = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009066 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009067
9068 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9069 {
9070 if (unformat (i, "node %s", &name))
9071 ;
9072 else
9073 break;
9074 }
9075 if (name == 0)
9076 {
9077 errmsg ("node name required");
9078 return -99;
9079 }
9080 if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9081 {
9082 errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9083 return -99;
9084 }
9085
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009086 M (GET_NODE_INDEX, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009087 clib_memcpy (mp->node_name, name, vec_len (name));
9088 vec_free (name);
9089
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009090 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06009091 W (ret);
9092 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009093}
9094
9095static int
9096api_get_next_index (vat_main_t * vam)
9097{
9098 unformat_input_t *i = vam->input;
9099 vl_api_get_next_index_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009100 u8 *node_name = 0, *next_node_name = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009101 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009102
9103 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9104 {
9105 if (unformat (i, "node-name %s", &node_name))
9106 ;
9107 else if (unformat (i, "next-node-name %s", &next_node_name))
9108 break;
9109 }
9110
9111 if (node_name == 0)
9112 {
9113 errmsg ("node name required");
9114 return -99;
9115 }
9116 if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
9117 {
9118 errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9119 return -99;
9120 }
9121
9122 if (next_node_name == 0)
9123 {
9124 errmsg ("next node name required");
9125 return -99;
9126 }
9127 if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
9128 {
9129 errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
9130 return -99;
9131 }
9132
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009133 M (GET_NEXT_INDEX, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009134 clib_memcpy (mp->node_name, node_name, vec_len (node_name));
9135 clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
9136 vec_free (node_name);
9137 vec_free (next_node_name);
9138
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009139 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06009140 W (ret);
9141 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009142}
9143
9144static int
9145api_add_node_next (vat_main_t * vam)
9146{
9147 unformat_input_t *i = vam->input;
9148 vl_api_add_node_next_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009149 u8 *name = 0;
9150 u8 *next = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009151 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009152
9153 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9154 {
9155 if (unformat (i, "node %s", &name))
9156 ;
9157 else if (unformat (i, "next %s", &next))
9158 ;
9159 else
9160 break;
9161 }
9162 if (name == 0)
9163 {
9164 errmsg ("node name required");
9165 return -99;
9166 }
9167 if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9168 {
9169 errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9170 return -99;
9171 }
9172 if (next == 0)
9173 {
9174 errmsg ("next node required");
9175 return -99;
9176 }
9177 if (vec_len (next) >= ARRAY_LEN (mp->next_name))
9178 {
9179 errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
9180 return -99;
9181 }
9182
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009183 M (ADD_NODE_NEXT, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009184 clib_memcpy (mp->node_name, name, vec_len (name));
9185 clib_memcpy (mp->next_name, next, vec_len (next));
9186 vec_free (name);
9187 vec_free (next);
9188
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009189 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06009190 W (ret);
9191 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009192}
9193
Damjan Marion8389fb92017-10-13 18:29:53 +02009194static void vl_api_sw_interface_tap_v2_details_t_handler
9195 (vl_api_sw_interface_tap_v2_details_t * mp)
9196{
9197 vat_main_t *vam = &vat_main;
9198
Jakub Grajciar5de4fb72019-09-03 10:40:01 +02009199 u8 *ip4 =
9200 format (0, "%U/%d", format_ip4_address, mp->host_ip4_prefix.address,
9201 mp->host_ip4_prefix.len);
9202 u8 *ip6 =
9203 format (0, "%U/%d", format_ip6_address, mp->host_ip6_prefix.address,
9204 mp->host_ip6_prefix.len);
Milan Lenco73e7f422017-12-14 10:04:25 +01009205
9206 print (vam->ofp,
Andrew Yourtchenko754f24b2019-01-07 20:56:46 +01009207 "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
Milan Lenco73e7f422017-12-14 10:04:25 +01009208 mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
9209 ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
9210 format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
Andrew Yourtchenko754f24b2019-01-07 20:56:46 +01009211 mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
Milan Lenco73e7f422017-12-14 10:04:25 +01009212
9213 vec_free (ip4);
9214 vec_free (ip6);
Damjan Marion8389fb92017-10-13 18:29:53 +02009215}
9216
9217static void vl_api_sw_interface_tap_v2_details_t_handler_json
9218 (vl_api_sw_interface_tap_v2_details_t * mp)
9219{
9220 vat_main_t *vam = &vat_main;
9221 vat_json_node_t *node = NULL;
9222
9223 if (VAT_JSON_ARRAY != vam->json_tree.type)
9224 {
9225 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9226 vat_json_init_array (&vam->json_tree);
9227 }
9228 node = vat_json_array_add (&vam->json_tree);
9229
9230 vat_json_init_object (node);
Milan Lenco73e7f422017-12-14 10:04:25 +01009231 vat_json_object_add_uint (node, "id", ntohl (mp->id));
Damjan Marion8389fb92017-10-13 18:29:53 +02009232 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
Andrew Yourtchenko754f24b2019-01-07 20:56:46 +01009233 vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
Damjan Marion8389fb92017-10-13 18:29:53 +02009234 vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
Milan Lenco73e7f422017-12-14 10:04:25 +01009235 vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
9236 vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
9237 vat_json_object_add_string_copy (node, "host_mac_addr",
9238 format (0, "%U", format_ethernet_address,
9239 &mp->host_mac_addr));
9240 vat_json_object_add_string_copy (node, "host_namespace",
9241 mp->host_namespace);
9242 vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
9243 vat_json_object_add_string_copy (node, "host_ip4_addr",
9244 format (0, "%U/%d", format_ip4_address,
Jakub Grajciar5de4fb72019-09-03 10:40:01 +02009245 mp->host_ip4_prefix.address,
9246 mp->host_ip4_prefix.len));
9247 vat_json_object_add_string_copy (node, "host_ip6_prefix",
Milan Lenco73e7f422017-12-14 10:04:25 +01009248 format (0, "%U/%d", format_ip6_address,
Jakub Grajciar5de4fb72019-09-03 10:40:01 +02009249 mp->host_ip6_prefix.address,
9250 mp->host_ip6_prefix.len));
Milan Lenco73e7f422017-12-14 10:04:25 +01009251
Damjan Marion8389fb92017-10-13 18:29:53 +02009252}
9253
9254static int
9255api_sw_interface_tap_v2_dump (vat_main_t * vam)
9256{
9257 vl_api_sw_interface_tap_v2_dump_t *mp;
9258 vl_api_control_ping_t *mp_ping;
9259 int ret;
9260
Milan Lenco73e7f422017-12-14 10:04:25 +01009261 print (vam->ofp,
9262 "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
9263 "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
9264 "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
9265 "host_ip6_addr");
9266
Damjan Marion8389fb92017-10-13 18:29:53 +02009267 /* Get list of tap interfaces */
9268 M (SW_INTERFACE_TAP_V2_DUMP, mp);
9269 S (mp);
9270
9271 /* Use a control ping for synchronization */
9272 MPING (CONTROL_PING, mp_ping);
9273 S (mp_ping);
9274
9275 W (ret);
9276 return ret;
9277}
9278
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01009279static void vl_api_sw_interface_virtio_pci_details_t_handler
9280 (vl_api_sw_interface_virtio_pci_details_t * mp)
9281{
9282 vat_main_t *vam = &vat_main;
9283
9284 typedef union
9285 {
9286 struct
9287 {
9288 u16 domain;
9289 u8 bus;
9290 u8 slot:5;
9291 u8 function:3;
9292 };
9293 u32 as_u32;
9294 } pci_addr_t;
9295 pci_addr_t addr;
Jakub Grajciar2c504f82019-09-26 10:34:41 +02009296
9297 addr.domain = ntohs (mp->pci_addr.domain);
9298 addr.bus = mp->pci_addr.bus;
9299 addr.slot = mp->pci_addr.slot;
9300 addr.function = mp->pci_addr.function;
9301
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01009302 u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
9303 addr.slot, addr.function);
9304
9305 print (vam->ofp,
9306 "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
9307 pci_addr, ntohl (mp->sw_if_index),
9308 ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
9309 format_ethernet_address, mp->mac_addr,
9310 clib_net_to_host_u64 (mp->features));
9311 vec_free (pci_addr);
9312}
9313
9314static void vl_api_sw_interface_virtio_pci_details_t_handler_json
9315 (vl_api_sw_interface_virtio_pci_details_t * mp)
9316{
9317 vat_main_t *vam = &vat_main;
9318 vat_json_node_t *node = NULL;
Jakub Grajciar2c504f82019-09-26 10:34:41 +02009319 vlib_pci_addr_t pci_addr;
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01009320
9321 if (VAT_JSON_ARRAY != vam->json_tree.type)
9322 {
9323 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9324 vat_json_init_array (&vam->json_tree);
9325 }
9326 node = vat_json_array_add (&vam->json_tree);
9327
Jakub Grajciar2c504f82019-09-26 10:34:41 +02009328 pci_addr.domain = ntohs (mp->pci_addr.domain);
9329 pci_addr.bus = mp->pci_addr.bus;
9330 pci_addr.slot = mp->pci_addr.slot;
9331 pci_addr.function = mp->pci_addr.function;
9332
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01009333 vat_json_init_object (node);
Jakub Grajciar2c504f82019-09-26 10:34:41 +02009334 vat_json_object_add_uint (node, "pci-addr", pci_addr.as_u32);
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01009335 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9336 vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
9337 vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
9338 vat_json_object_add_uint (node, "features",
9339 clib_net_to_host_u64 (mp->features));
9340 vat_json_object_add_string_copy (node, "mac_addr",
9341 format (0, "%U", format_ethernet_address,
9342 &mp->mac_addr));
9343}
9344
9345static int
9346api_sw_interface_virtio_pci_dump (vat_main_t * vam)
9347{
9348 vl_api_sw_interface_virtio_pci_dump_t *mp;
9349 vl_api_control_ping_t *mp_ping;
9350 int ret;
9351
9352 print (vam->ofp,
9353 "\n%-12s %-12s %-12s %-12s %-17s %-08s",
9354 "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
9355 "mac_addr", "features");
9356
9357 /* Get list of tap interfaces */
9358 M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
9359 S (mp);
9360
9361 /* Use a control ping for synchronization */
9362 MPING (CONTROL_PING, mp_ping);
9363 S (mp_ping);
9364
9365 W (ret);
9366 return ret;
9367}
9368
eyal bariaf86a482018-04-17 11:20:27 +03009369static int
9370api_vxlan_offload_rx (vat_main_t * vam)
9371{
9372 unformat_input_t *line_input = vam->input;
9373 vl_api_vxlan_offload_rx_t *mp;
9374 u32 hw_if_index = ~0, rx_if_index = ~0;
9375 u8 is_add = 1;
9376 int ret;
9377
9378 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9379 {
9380 if (unformat (line_input, "del"))
9381 is_add = 0;
9382 else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
9383 &hw_if_index))
9384 ;
9385 else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
9386 ;
9387 else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
9388 &rx_if_index))
9389 ;
9390 else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
9391 ;
9392 else
9393 {
9394 errmsg ("parse error '%U'", format_unformat_error, line_input);
9395 return -99;
9396 }
9397 }
9398
9399 if (hw_if_index == ~0)
9400 {
9401 errmsg ("no hw interface");
9402 return -99;
9403 }
9404
9405 if (rx_if_index == ~0)
9406 {
9407 errmsg ("no rx tunnel");
9408 return -99;
9409 }
9410
9411 M (VXLAN_OFFLOAD_RX, mp);
9412
9413 mp->hw_if_index = ntohl (hw_if_index);
9414 mp->sw_if_index = ntohl (rx_if_index);
9415 mp->enable = is_add;
9416
9417 S (mp);
9418 W (ret);
9419 return ret;
9420}
9421
Damjan Marion7cd468a2016-12-19 23:05:39 +01009422static uword unformat_vxlan_decap_next
9423 (unformat_input_t * input, va_list * args)
9424{
9425 u32 *result = va_arg (*args, u32 *);
9426 u32 tmp;
9427
9428 if (unformat (input, "l2"))
9429 *result = VXLAN_INPUT_NEXT_L2_INPUT;
9430 else if (unformat (input, "%d", &tmp))
9431 *result = tmp;
9432 else
9433 return 0;
9434 return 1;
9435}
9436
9437static int
9438api_vxlan_add_del_tunnel (vat_main_t * vam)
9439{
9440 unformat_input_t *line_input = vam->input;
9441 vl_api_vxlan_add_del_tunnel_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009442 ip46_address_t src, dst;
9443 u8 is_add = 1;
9444 u8 ipv4_set = 0, ipv6_set = 0;
9445 u8 src_set = 0;
9446 u8 dst_set = 0;
9447 u8 grp_set = 0;
Jon Loeliger3d460bd2018-02-01 16:36:12 -06009448 u32 instance = ~0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009449 u32 mcast_sw_if_index = ~0;
9450 u32 encap_vrf_id = 0;
9451 u32 decap_next_index = ~0;
9452 u32 vni = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009453 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009454
9455 /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
Dave Barachb7b92992018-10-17 10:38:51 -04009456 clib_memset (&src, 0, sizeof src);
9457 clib_memset (&dst, 0, sizeof dst);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009458
9459 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9460 {
9461 if (unformat (line_input, "del"))
9462 is_add = 0;
Jon Loeliger3d460bd2018-02-01 16:36:12 -06009463 else if (unformat (line_input, "instance %d", &instance))
9464 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009465 else
9466 if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
9467 {
9468 ipv4_set = 1;
9469 src_set = 1;
9470 }
9471 else
9472 if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
9473 {
9474 ipv4_set = 1;
9475 dst_set = 1;
9476 }
9477 else
9478 if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
9479 {
9480 ipv6_set = 1;
9481 src_set = 1;
9482 }
9483 else
9484 if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
9485 {
9486 ipv6_set = 1;
9487 dst_set = 1;
9488 }
9489 else if (unformat (line_input, "group %U %U",
9490 unformat_ip4_address, &dst.ip4,
9491 api_unformat_sw_if_index, vam, &mcast_sw_if_index))
9492 {
9493 grp_set = dst_set = 1;
9494 ipv4_set = 1;
9495 }
9496 else if (unformat (line_input, "group %U",
9497 unformat_ip4_address, &dst.ip4))
9498 {
9499 grp_set = dst_set = 1;
9500 ipv4_set = 1;
9501 }
9502 else if (unformat (line_input, "group %U %U",
9503 unformat_ip6_address, &dst.ip6,
9504 api_unformat_sw_if_index, vam, &mcast_sw_if_index))
9505 {
9506 grp_set = dst_set = 1;
9507 ipv6_set = 1;
9508 }
9509 else if (unformat (line_input, "group %U",
9510 unformat_ip6_address, &dst.ip6))
9511 {
9512 grp_set = dst_set = 1;
9513 ipv6_set = 1;
9514 }
9515 else
9516 if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
9517 ;
9518 else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
9519 ;
9520 else if (unformat (line_input, "decap-next %U",
9521 unformat_vxlan_decap_next, &decap_next_index))
9522 ;
9523 else if (unformat (line_input, "vni %d", &vni))
9524 ;
9525 else
9526 {
9527 errmsg ("parse error '%U'", format_unformat_error, line_input);
9528 return -99;
9529 }
9530 }
9531
9532 if (src_set == 0)
9533 {
9534 errmsg ("tunnel src address not specified");
9535 return -99;
9536 }
9537 if (dst_set == 0)
9538 {
9539 errmsg ("tunnel dst address not specified");
9540 return -99;
9541 }
9542
9543 if (grp_set && !ip46_address_is_multicast (&dst))
9544 {
9545 errmsg ("tunnel group address not multicast");
9546 return -99;
9547 }
9548 if (grp_set && mcast_sw_if_index == ~0)
9549 {
9550 errmsg ("tunnel nonexistent multicast device");
9551 return -99;
9552 }
9553 if (grp_set == 0 && ip46_address_is_multicast (&dst))
9554 {
9555 errmsg ("tunnel dst address must be unicast");
9556 return -99;
9557 }
9558
9559
9560 if (ipv4_set && ipv6_set)
9561 {
9562 errmsg ("both IPv4 and IPv6 addresses specified");
9563 return -99;
9564 }
9565
9566 if ((vni == 0) || (vni >> 24))
9567 {
9568 errmsg ("vni not specified or out of range");
9569 return -99;
9570 }
9571
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009572 M (VXLAN_ADD_DEL_TUNNEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009573
9574 if (ipv6_set)
9575 {
Jakub Grajciar7c0eb562020-03-02 13:55:31 +01009576 clib_memcpy (mp->src_address.un.ip6, &src.ip6, sizeof (src.ip6));
9577 clib_memcpy (mp->dst_address.un.ip6, &dst.ip6, sizeof (dst.ip6));
Damjan Marion7cd468a2016-12-19 23:05:39 +01009578 }
9579 else
9580 {
Jakub Grajciar7c0eb562020-03-02 13:55:31 +01009581 clib_memcpy (mp->src_address.un.ip4, &src.ip4, sizeof (src.ip4));
9582 clib_memcpy (mp->dst_address.un.ip4, &dst.ip4, sizeof (dst.ip4));
Damjan Marion7cd468a2016-12-19 23:05:39 +01009583 }
Jakub Grajciar7c0eb562020-03-02 13:55:31 +01009584 mp->src_address.af = ipv6_set;
9585 mp->dst_address.af = ipv6_set;
Jon Loeliger3d460bd2018-02-01 16:36:12 -06009586
9587 mp->instance = htonl (instance);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009588 mp->encap_vrf_id = ntohl (encap_vrf_id);
9589 mp->decap_next_index = ntohl (decap_next_index);
9590 mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
9591 mp->vni = ntohl (vni);
9592 mp->is_add = is_add;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009593
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009594 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06009595 W (ret);
9596 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009597}
9598
9599static void vl_api_vxlan_tunnel_details_t_handler
9600 (vl_api_vxlan_tunnel_details_t * mp)
9601{
9602 vat_main_t *vam = &vat_main;
Jakub Grajciar7c0eb562020-03-02 13:55:31 +01009603 ip46_address_t src =
9604 to_ip46 (mp->dst_address.af, (u8 *) & mp->dst_address.un);
9605 ip46_address_t dst =
9606 to_ip46 (mp->dst_address.af, (u8 *) & mp->src_address.un);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009607
Jon Loeliger3d460bd2018-02-01 16:36:12 -06009608 print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
Damjan Marion7cd468a2016-12-19 23:05:39 +01009609 ntohl (mp->sw_if_index),
Jon Loeliger3d460bd2018-02-01 16:36:12 -06009610 ntohl (mp->instance),
Damjan Marion7cd468a2016-12-19 23:05:39 +01009611 format_ip46_address, &src, IP46_TYPE_ANY,
9612 format_ip46_address, &dst, IP46_TYPE_ANY,
9613 ntohl (mp->encap_vrf_id),
9614 ntohl (mp->decap_next_index), ntohl (mp->vni),
9615 ntohl (mp->mcast_sw_if_index));
9616}
9617
9618static void vl_api_vxlan_tunnel_details_t_handler_json
9619 (vl_api_vxlan_tunnel_details_t * mp)
9620{
9621 vat_main_t *vam = &vat_main;
9622 vat_json_node_t *node = NULL;
9623
9624 if (VAT_JSON_ARRAY != vam->json_tree.type)
9625 {
9626 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9627 vat_json_init_array (&vam->json_tree);
9628 }
9629 node = vat_json_array_add (&vam->json_tree);
9630
9631 vat_json_init_object (node);
9632 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
Jon Loeliger3d460bd2018-02-01 16:36:12 -06009633
9634 vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
9635
Jakub Grajciar7c0eb562020-03-02 13:55:31 +01009636 if (mp->src_address.af)
Damjan Marion7cd468a2016-12-19 23:05:39 +01009637 {
9638 struct in6_addr ip6;
9639
Jakub Grajciar7c0eb562020-03-02 13:55:31 +01009640 clib_memcpy (&ip6, mp->src_address.un.ip6, sizeof (ip6));
Damjan Marion7cd468a2016-12-19 23:05:39 +01009641 vat_json_object_add_ip6 (node, "src_address", ip6);
Jakub Grajciar7c0eb562020-03-02 13:55:31 +01009642 clib_memcpy (&ip6, mp->dst_address.un.ip6, sizeof (ip6));
Damjan Marion7cd468a2016-12-19 23:05:39 +01009643 vat_json_object_add_ip6 (node, "dst_address", ip6);
9644 }
9645 else
9646 {
9647 struct in_addr ip4;
9648
Jakub Grajciar7c0eb562020-03-02 13:55:31 +01009649 clib_memcpy (&ip4, mp->src_address.un.ip4, sizeof (ip4));
Damjan Marion7cd468a2016-12-19 23:05:39 +01009650 vat_json_object_add_ip4 (node, "src_address", ip4);
Jakub Grajciar7c0eb562020-03-02 13:55:31 +01009651 clib_memcpy (&ip4, mp->dst_address.un.ip4, sizeof (ip4));
Damjan Marion7cd468a2016-12-19 23:05:39 +01009652 vat_json_object_add_ip4 (node, "dst_address", ip4);
9653 }
9654 vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
9655 vat_json_object_add_uint (node, "decap_next_index",
9656 ntohl (mp->decap_next_index));
9657 vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
Damjan Marion7cd468a2016-12-19 23:05:39 +01009658 vat_json_object_add_uint (node, "mcast_sw_if_index",
9659 ntohl (mp->mcast_sw_if_index));
9660}
9661
9662static int
9663api_vxlan_tunnel_dump (vat_main_t * vam)
9664{
9665 unformat_input_t *i = vam->input;
9666 vl_api_vxlan_tunnel_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -06009667 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009668 u32 sw_if_index;
9669 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009670 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009671
9672 /* Parse args required to build the message */
9673 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9674 {
9675 if (unformat (i, "sw_if_index %d", &sw_if_index))
9676 sw_if_index_set = 1;
9677 else
9678 break;
9679 }
9680
9681 if (sw_if_index_set == 0)
9682 {
9683 sw_if_index = ~0;
9684 }
9685
9686 if (!vam->json_output)
9687 {
Jon Loeliger3d460bd2018-02-01 16:36:12 -06009688 print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
9689 "sw_if_index", "instance", "src_address", "dst_address",
Damjan Marion7cd468a2016-12-19 23:05:39 +01009690 "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
9691 }
9692
9693 /* Get list of vxlan-tunnel interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009694 M (VXLAN_TUNNEL_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009695
9696 mp->sw_if_index = htonl (sw_if_index);
9697
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009698 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009699
9700 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -04009701 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06009702 S (mp_ping);
9703
Jon Loeliger56c7b012017-02-01 12:31:41 -06009704 W (ret);
9705 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009706}
9707
9708static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01009709api_l2_fib_clear_table (vat_main_t * vam)
9710{
9711// unformat_input_t * i = vam->input;
9712 vl_api_l2_fib_clear_table_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009713 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009714
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009715 M (L2_FIB_CLEAR_TABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009716
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009717 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06009718 W (ret);
9719 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009720}
9721
9722static int
9723api_l2_interface_efp_filter (vat_main_t * vam)
9724{
9725 unformat_input_t *i = vam->input;
9726 vl_api_l2_interface_efp_filter_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009727 u32 sw_if_index;
9728 u8 enable = 1;
9729 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009730 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009731
9732 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9733 {
9734 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9735 sw_if_index_set = 1;
9736 else if (unformat (i, "sw_if_index %d", &sw_if_index))
9737 sw_if_index_set = 1;
9738 else if (unformat (i, "enable"))
9739 enable = 1;
9740 else if (unformat (i, "disable"))
9741 enable = 0;
9742 else
9743 {
9744 clib_warning ("parse error '%U'", format_unformat_error, i);
9745 return -99;
9746 }
9747 }
9748
9749 if (sw_if_index_set == 0)
9750 {
9751 errmsg ("missing sw_if_index");
9752 return -99;
9753 }
9754
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009755 M (L2_INTERFACE_EFP_FILTER, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009756
9757 mp->sw_if_index = ntohl (sw_if_index);
9758 mp->enable_disable = enable;
9759
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009760 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06009761 W (ret);
9762 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009763}
9764
9765#define foreach_vtr_op \
9766_("disable", L2_VTR_DISABLED) \
9767_("push-1", L2_VTR_PUSH_1) \
9768_("push-2", L2_VTR_PUSH_2) \
9769_("pop-1", L2_VTR_POP_1) \
9770_("pop-2", L2_VTR_POP_2) \
9771_("translate-1-1", L2_VTR_TRANSLATE_1_1) \
9772_("translate-1-2", L2_VTR_TRANSLATE_1_2) \
9773_("translate-2-1", L2_VTR_TRANSLATE_2_1) \
9774_("translate-2-2", L2_VTR_TRANSLATE_2_2)
9775
9776static int
9777api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
9778{
9779 unformat_input_t *i = vam->input;
9780 vl_api_l2_interface_vlan_tag_rewrite_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009781 u32 sw_if_index;
9782 u8 sw_if_index_set = 0;
9783 u8 vtr_op_set = 0;
9784 u32 vtr_op = 0;
9785 u32 push_dot1q = 1;
9786 u32 tag1 = ~0;
9787 u32 tag2 = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009788 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009789
9790 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9791 {
9792 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9793 sw_if_index_set = 1;
9794 else if (unformat (i, "sw_if_index %d", &sw_if_index))
9795 sw_if_index_set = 1;
9796 else if (unformat (i, "vtr_op %d", &vtr_op))
9797 vtr_op_set = 1;
9798#define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
9799 foreach_vtr_op
9800#undef _
9801 else if (unformat (i, "push_dot1q %d", &push_dot1q))
9802 ;
9803 else if (unformat (i, "tag1 %d", &tag1))
9804 ;
9805 else if (unformat (i, "tag2 %d", &tag2))
9806 ;
9807 else
9808 {
9809 clib_warning ("parse error '%U'", format_unformat_error, i);
9810 return -99;
9811 }
9812 }
9813
9814 if ((sw_if_index_set == 0) || (vtr_op_set == 0))
9815 {
9816 errmsg ("missing vtr operation or sw_if_index");
9817 return -99;
9818 }
9819
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009820 M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
9821 mp->sw_if_index = ntohl (sw_if_index);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009822 mp->vtr_op = ntohl (vtr_op);
9823 mp->push_dot1q = ntohl (push_dot1q);
9824 mp->tag1 = ntohl (tag1);
9825 mp->tag2 = ntohl (tag2);
9826
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009827 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06009828 W (ret);
9829 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009830}
9831
9832static int
9833api_create_vhost_user_if (vat_main_t * vam)
9834{
9835 unformat_input_t *i = vam->input;
9836 vl_api_create_vhost_user_if_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009837 u8 *file_name;
9838 u8 is_server = 0;
9839 u8 file_name_set = 0;
9840 u32 custom_dev_instance = ~0;
9841 u8 hwaddr[6];
9842 u8 use_custom_mac = 0;
Mohsin Kazmiee2e58f2018-08-21 16:07:03 +02009843 u8 disable_mrg_rxbuf = 0;
9844 u8 disable_indirect_desc = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009845 u8 *tag = 0;
Steven Luong4208a4c2019-05-06 08:51:56 -07009846 u8 enable_gso = 0;
Steven Luongbc0d9ff2020-03-23 09:34:59 -07009847 u8 enable_packed = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009848 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009849
9850 /* Shut up coverity */
Dave Barachb7b92992018-10-17 10:38:51 -04009851 clib_memset (hwaddr, 0, sizeof (hwaddr));
Damjan Marion7cd468a2016-12-19 23:05:39 +01009852
9853 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9854 {
9855 if (unformat (i, "socket %s", &file_name))
9856 {
9857 file_name_set = 1;
9858 }
9859 else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
9860 ;
9861 else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
9862 use_custom_mac = 1;
9863 else if (unformat (i, "server"))
9864 is_server = 1;
Mohsin Kazmiee2e58f2018-08-21 16:07:03 +02009865 else if (unformat (i, "disable_mrg_rxbuf"))
9866 disable_mrg_rxbuf = 1;
9867 else if (unformat (i, "disable_indirect_desc"))
9868 disable_indirect_desc = 1;
Steven Luong4208a4c2019-05-06 08:51:56 -07009869 else if (unformat (i, "gso"))
9870 enable_gso = 1;
Steven Luongbc0d9ff2020-03-23 09:34:59 -07009871 else if (unformat (i, "packed"))
9872 enable_packed = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009873 else if (unformat (i, "tag %s", &tag))
9874 ;
9875 else
9876 break;
9877 }
9878
9879 if (file_name_set == 0)
9880 {
9881 errmsg ("missing socket file name");
9882 return -99;
9883 }
9884
9885 if (vec_len (file_name) > 255)
9886 {
9887 errmsg ("socket file name too long");
9888 return -99;
9889 }
9890 vec_add1 (file_name, 0);
9891
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009892 M (CREATE_VHOST_USER_IF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009893
9894 mp->is_server = is_server;
Mohsin Kazmiee2e58f2018-08-21 16:07:03 +02009895 mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
9896 mp->disable_indirect_desc = disable_indirect_desc;
Steven Luong4208a4c2019-05-06 08:51:56 -07009897 mp->enable_gso = enable_gso;
Steven Luongbc0d9ff2020-03-23 09:34:59 -07009898 mp->enable_packed = enable_packed;
Steven Luong27ba5002020-11-17 13:30:44 -08009899 mp->custom_dev_instance = ntohl (custom_dev_instance);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009900 clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
9901 vec_free (file_name);
9902 if (custom_dev_instance != ~0)
Steven Luong27ba5002020-11-17 13:30:44 -08009903 mp->renumber = 1;
Mohsin Kazmiee2e58f2018-08-21 16:07:03 +02009904
Damjan Marion7cd468a2016-12-19 23:05:39 +01009905 mp->use_custom_mac = use_custom_mac;
9906 clib_memcpy (mp->mac_address, hwaddr, 6);
9907 if (tag)
9908 strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
9909 vec_free (tag);
9910
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009911 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06009912 W (ret);
9913 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009914}
9915
9916static int
9917api_modify_vhost_user_if (vat_main_t * vam)
9918{
9919 unformat_input_t *i = vam->input;
9920 vl_api_modify_vhost_user_if_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009921 u8 *file_name;
9922 u8 is_server = 0;
9923 u8 file_name_set = 0;
9924 u32 custom_dev_instance = ~0;
9925 u8 sw_if_index_set = 0;
9926 u32 sw_if_index = (u32) ~ 0;
Steven Luong4208a4c2019-05-06 08:51:56 -07009927 u8 enable_gso = 0;
Steven Luongbc0d9ff2020-03-23 09:34:59 -07009928 u8 enable_packed = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009929 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009930
9931 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9932 {
9933 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9934 sw_if_index_set = 1;
9935 else if (unformat (i, "sw_if_index %d", &sw_if_index))
9936 sw_if_index_set = 1;
9937 else if (unformat (i, "socket %s", &file_name))
9938 {
9939 file_name_set = 1;
9940 }
9941 else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
9942 ;
9943 else if (unformat (i, "server"))
9944 is_server = 1;
Steven Luong4208a4c2019-05-06 08:51:56 -07009945 else if (unformat (i, "gso"))
9946 enable_gso = 1;
Steven Luongbc0d9ff2020-03-23 09:34:59 -07009947 else if (unformat (i, "packed"))
9948 enable_packed = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009949 else
9950 break;
9951 }
9952
9953 if (sw_if_index_set == 0)
9954 {
9955 errmsg ("missing sw_if_index or interface name");
9956 return -99;
9957 }
9958
9959 if (file_name_set == 0)
9960 {
9961 errmsg ("missing socket file name");
9962 return -99;
9963 }
9964
9965 if (vec_len (file_name) > 255)
9966 {
9967 errmsg ("socket file name too long");
9968 return -99;
9969 }
9970 vec_add1 (file_name, 0);
9971
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009972 M (MODIFY_VHOST_USER_IF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009973
9974 mp->sw_if_index = ntohl (sw_if_index);
9975 mp->is_server = is_server;
Steven Luong4208a4c2019-05-06 08:51:56 -07009976 mp->enable_gso = enable_gso;
Steven Luongbc0d9ff2020-03-23 09:34:59 -07009977 mp->enable_packed = enable_packed;
Steven Luong27ba5002020-11-17 13:30:44 -08009978 mp->custom_dev_instance = ntohl (custom_dev_instance);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009979 clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
9980 vec_free (file_name);
9981 if (custom_dev_instance != ~0)
Steven Luong27ba5002020-11-17 13:30:44 -08009982 mp->renumber = 1;
9983
9984 S (mp);
9985 W (ret);
9986 return ret;
9987}
9988
9989static int
9990api_create_vhost_user_if_v2 (vat_main_t * vam)
9991{
9992 unformat_input_t *i = vam->input;
9993 vl_api_create_vhost_user_if_v2_t *mp;
9994 u8 *file_name;
9995 u8 is_server = 0;
9996 u8 file_name_set = 0;
9997 u32 custom_dev_instance = ~0;
9998 u8 hwaddr[6];
9999 u8 use_custom_mac = 0;
10000 u8 disable_mrg_rxbuf = 0;
10001 u8 disable_indirect_desc = 0;
10002 u8 *tag = 0;
10003 u8 enable_gso = 0;
10004 u8 enable_packed = 0;
10005 u8 enable_event_idx = 0;
10006 int ret;
10007
10008 /* Shut up coverity */
10009 clib_memset (hwaddr, 0, sizeof (hwaddr));
10010
10011 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
Damjan Marion7cd468a2016-12-19 23:05:39 +010010012 {
Steven Luong27ba5002020-11-17 13:30:44 -080010013 if (unformat (i, "socket %s", &file_name))
10014 {
10015 file_name_set = 1;
10016 }
10017 else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10018 ;
10019 else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
10020 use_custom_mac = 1;
10021 else if (unformat (i, "server"))
10022 is_server = 1;
10023 else if (unformat (i, "disable_mrg_rxbuf"))
10024 disable_mrg_rxbuf = 1;
10025 else if (unformat (i, "disable_indirect_desc"))
10026 disable_indirect_desc = 1;
10027 else if (unformat (i, "gso"))
10028 enable_gso = 1;
10029 else if (unformat (i, "packed"))
10030 enable_packed = 1;
10031 else if (unformat (i, "event-idx"))
10032 enable_event_idx = 1;
10033 else if (unformat (i, "tag %s", &tag))
10034 ;
10035 else
10036 break;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010037 }
10038
Steven Luong27ba5002020-11-17 13:30:44 -080010039 if (file_name_set == 0)
10040 {
10041 errmsg ("missing socket file name");
10042 return -99;
10043 }
10044
10045 if (vec_len (file_name) > 255)
10046 {
10047 errmsg ("socket file name too long");
10048 return -99;
10049 }
10050 vec_add1 (file_name, 0);
10051
10052 M (CREATE_VHOST_USER_IF_V2, mp);
10053
10054 mp->is_server = is_server;
10055 mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
10056 mp->disable_indirect_desc = disable_indirect_desc;
10057 mp->enable_gso = enable_gso;
10058 mp->enable_packed = enable_packed;
10059 mp->enable_event_idx = enable_event_idx;
10060 mp->custom_dev_instance = ntohl (custom_dev_instance);
10061 clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10062 vec_free (file_name);
10063 if (custom_dev_instance != ~0)
10064 mp->renumber = 1;
10065
10066 mp->use_custom_mac = use_custom_mac;
10067 clib_memcpy (mp->mac_address, hwaddr, 6);
10068 if (tag)
10069 strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
10070 vec_free (tag);
10071
10072 S (mp);
10073 W (ret);
10074 return ret;
10075}
10076
10077static int
10078api_modify_vhost_user_if_v2 (vat_main_t * vam)
10079{
10080 unformat_input_t *i = vam->input;
10081 vl_api_modify_vhost_user_if_v2_t *mp;
10082 u8 *file_name;
10083 u8 is_server = 0;
10084 u8 file_name_set = 0;
10085 u32 custom_dev_instance = ~0;
10086 u8 sw_if_index_set = 0;
10087 u32 sw_if_index = (u32) ~ 0;
10088 u8 enable_gso = 0;
10089 u8 enable_packed = 0;
10090 u8 enable_event_idx = 0;
10091 int ret;
10092
10093 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10094 {
10095 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10096 sw_if_index_set = 1;
10097 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10098 sw_if_index_set = 1;
10099 else if (unformat (i, "socket %s", &file_name))
10100 {
10101 file_name_set = 1;
10102 }
10103 else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10104 ;
10105 else if (unformat (i, "server"))
10106 is_server = 1;
10107 else if (unformat (i, "gso"))
10108 enable_gso = 1;
10109 else if (unformat (i, "packed"))
10110 enable_packed = 1;
10111 else if (unformat (i, "event-idx"))
10112 enable_event_idx = 1;
10113 else
10114 break;
10115 }
10116
10117 if (sw_if_index_set == 0)
10118 {
10119 errmsg ("missing sw_if_index or interface name");
10120 return -99;
10121 }
10122
10123 if (file_name_set == 0)
10124 {
10125 errmsg ("missing socket file name");
10126 return -99;
10127 }
10128
10129 if (vec_len (file_name) > 255)
10130 {
10131 errmsg ("socket file name too long");
10132 return -99;
10133 }
10134 vec_add1 (file_name, 0);
10135
10136 M (MODIFY_VHOST_USER_IF_V2, mp);
10137
10138 mp->sw_if_index = ntohl (sw_if_index);
10139 mp->is_server = is_server;
10140 mp->enable_gso = enable_gso;
10141 mp->enable_packed = enable_packed;
10142 mp->enable_event_idx = enable_event_idx;
10143 mp->custom_dev_instance = ntohl (custom_dev_instance);
10144 clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10145 vec_free (file_name);
10146 if (custom_dev_instance != ~0)
10147 mp->renumber = 1;
10148
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010149 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010150 W (ret);
10151 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010152}
10153
10154static int
10155api_delete_vhost_user_if (vat_main_t * vam)
10156{
10157 unformat_input_t *i = vam->input;
10158 vl_api_delete_vhost_user_if_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010159 u32 sw_if_index = ~0;
10160 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010161 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010162
10163 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10164 {
10165 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10166 sw_if_index_set = 1;
10167 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10168 sw_if_index_set = 1;
10169 else
10170 break;
10171 }
10172
10173 if (sw_if_index_set == 0)
10174 {
10175 errmsg ("missing sw_if_index or interface name");
10176 return -99;
10177 }
10178
10179
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010180 M (DELETE_VHOST_USER_IF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010181
10182 mp->sw_if_index = ntohl (sw_if_index);
10183
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010184 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010185 W (ret);
10186 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010187}
10188
10189static void vl_api_sw_interface_vhost_user_details_t_handler
10190 (vl_api_sw_interface_vhost_user_details_t * mp)
10191{
10192 vat_main_t *vam = &vat_main;
Jakub Grajciar5d4c99f2019-09-26 10:21:59 +020010193 u64 features;
10194
10195 features =
10196 clib_net_to_host_u32 (mp->features_first_32) | ((u64)
10197 clib_net_to_host_u32
10198 (mp->features_last_32) <<
10199 32);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010200
Steven Luong150bf5a2020-11-17 15:56:10 -080010201 print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %16llx %6d %7d %s",
10202 (char *) mp->interface_name, ntohl (mp->sw_if_index),
10203 ntohl (mp->virtio_net_hdr_sz), features, mp->is_server,
Stevenf3b53642017-05-01 14:03:02 -070010204 ntohl (mp->num_regions), (char *) mp->sock_filename);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010205 print (vam->ofp, " Status: '%s'", strerror (ntohl (mp->sock_errno)));
10206}
10207
10208static void vl_api_sw_interface_vhost_user_details_t_handler_json
10209 (vl_api_sw_interface_vhost_user_details_t * mp)
10210{
10211 vat_main_t *vam = &vat_main;
10212 vat_json_node_t *node = NULL;
10213
10214 if (VAT_JSON_ARRAY != vam->json_tree.type)
10215 {
10216 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10217 vat_json_init_array (&vam->json_tree);
10218 }
10219 node = vat_json_array_add (&vam->json_tree);
10220
10221 vat_json_init_object (node);
10222 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10223 vat_json_object_add_string_copy (node, "interface_name",
10224 mp->interface_name);
10225 vat_json_object_add_uint (node, "virtio_net_hdr_sz",
10226 ntohl (mp->virtio_net_hdr_sz));
Jakub Grajciar5d4c99f2019-09-26 10:21:59 +020010227 vat_json_object_add_uint (node, "features_first_32",
10228 clib_net_to_host_u32 (mp->features_first_32));
10229 vat_json_object_add_uint (node, "features_last_32",
10230 clib_net_to_host_u32 (mp->features_last_32));
Damjan Marion7cd468a2016-12-19 23:05:39 +010010231 vat_json_object_add_uint (node, "is_server", mp->is_server);
10232 vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
10233 vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
10234 vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
10235}
10236
10237static int
10238api_sw_interface_vhost_user_dump (vat_main_t * vam)
10239{
Steven Luonga0e8d962020-05-18 17:12:56 -070010240 unformat_input_t *i = vam->input;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010241 vl_api_sw_interface_vhost_user_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010242 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010243 int ret;
Steven Luonga0e8d962020-05-18 17:12:56 -070010244 u32 sw_if_index = ~0;
10245
10246 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10247 {
10248 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10249 ;
10250 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10251 ;
10252 else
10253 break;
10254 }
10255
Steven Luong150bf5a2020-11-17 15:56:10 -080010256 print (vam->ofp, "Interface name idx hdr_sz features "
10257 "server regions filename");
Damjan Marion7cd468a2016-12-19 23:05:39 +010010258
10259 /* Get list of vhost-user interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010260 M (SW_INTERFACE_VHOST_USER_DUMP, mp);
Steven Luonga0e8d962020-05-18 17:12:56 -070010261 mp->sw_if_index = ntohl (sw_if_index);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010262 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010263
10264 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040010265 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010266 S (mp_ping);
10267
Jon Loeliger56c7b012017-02-01 12:31:41 -060010268 W (ret);
10269 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010270}
10271
10272static int
10273api_show_version (vat_main_t * vam)
10274{
10275 vl_api_show_version_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010276 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010277
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010278 M (SHOW_VERSION, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010279
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010280 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010281 W (ret);
10282 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010283}
10284
10285
10286static int
10287api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
10288{
10289 unformat_input_t *line_input = vam->input;
10290 vl_api_vxlan_gpe_add_del_tunnel_t *mp;
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010291 ip46_address_t local, remote;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010292 u8 is_add = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010293 u8 local_set = 0;
10294 u8 remote_set = 0;
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010295 u8 grp_set = 0;
10296 u32 mcast_sw_if_index = ~0;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010297 u32 encap_vrf_id = 0;
10298 u32 decap_vrf_id = 0;
10299 u8 protocol = ~0;
10300 u32 vni;
10301 u8 vni_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010302 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010303
10304 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10305 {
10306 if (unformat (line_input, "del"))
10307 is_add = 0;
10308 else if (unformat (line_input, "local %U",
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010309 unformat_ip46_address, &local))
Damjan Marion7cd468a2016-12-19 23:05:39 +010010310 {
10311 local_set = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010312 }
10313 else if (unformat (line_input, "remote %U",
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010314 unformat_ip46_address, &remote))
Damjan Marion7cd468a2016-12-19 23:05:39 +010010315 {
10316 remote_set = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010317 }
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010318 else if (unformat (line_input, "group %U %U",
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010319 unformat_ip46_address, &remote,
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010320 api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10321 {
10322 grp_set = remote_set = 1;
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010323 }
10324 else if (unformat (line_input, "group %U",
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010325 unformat_ip46_address, &remote))
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010326 {
10327 grp_set = remote_set = 1;
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010328 }
10329 else
10330 if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10331 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010332 else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10333 ;
10334 else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
10335 ;
10336 else if (unformat (line_input, "vni %d", &vni))
10337 vni_set = 1;
10338 else if (unformat (line_input, "next-ip4"))
10339 protocol = 1;
10340 else if (unformat (line_input, "next-ip6"))
10341 protocol = 2;
10342 else if (unformat (line_input, "next-ethernet"))
10343 protocol = 3;
10344 else if (unformat (line_input, "next-nsh"))
10345 protocol = 4;
10346 else
10347 {
10348 errmsg ("parse error '%U'", format_unformat_error, line_input);
10349 return -99;
10350 }
10351 }
10352
10353 if (local_set == 0)
10354 {
10355 errmsg ("tunnel local address not specified");
10356 return -99;
10357 }
10358 if (remote_set == 0)
10359 {
10360 errmsg ("tunnel remote address not specified");
10361 return -99;
10362 }
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010363 if (grp_set && mcast_sw_if_index == ~0)
10364 {
10365 errmsg ("tunnel nonexistent multicast device");
10366 return -99;
10367 }
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010368 if (ip46_address_is_ip4 (&local) != ip46_address_is_ip4 (&remote))
Damjan Marion7cd468a2016-12-19 23:05:39 +010010369 {
10370 errmsg ("both IPv4 and IPv6 addresses specified");
10371 return -99;
10372 }
10373
10374 if (vni_set == 0)
10375 {
10376 errmsg ("vni not specified");
10377 return -99;
10378 }
10379
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010380 M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010381
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010382 ip_address_encode (&local,
10383 ip46_address_is_ip4 (&local) ? IP46_TYPE_IP4 :
10384 IP46_TYPE_IP6, &mp->local);
10385 ip_address_encode (&remote,
10386 ip46_address_is_ip4 (&remote) ? IP46_TYPE_IP4 :
10387 IP46_TYPE_IP6, &mp->remote);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010388
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010389 mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010390 mp->encap_vrf_id = ntohl (encap_vrf_id);
10391 mp->decap_vrf_id = ntohl (decap_vrf_id);
10392 mp->protocol = protocol;
10393 mp->vni = ntohl (vni);
10394 mp->is_add = is_add;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010395
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010396 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010397 W (ret);
10398 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010399}
10400
10401static void vl_api_vxlan_gpe_tunnel_details_t_handler
10402 (vl_api_vxlan_gpe_tunnel_details_t * mp)
10403{
10404 vat_main_t *vam = &vat_main;
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010405 ip46_address_t local, remote;
10406
10407 ip_address_decode (&mp->local, &local);
10408 ip_address_decode (&mp->remote, &remote);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010409
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010410 print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
Damjan Marion7cd468a2016-12-19 23:05:39 +010010411 ntohl (mp->sw_if_index),
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010412 format_ip46_address, &local, IP46_TYPE_ANY,
10413 format_ip46_address, &remote, IP46_TYPE_ANY,
10414 ntohl (mp->vni), mp->protocol,
10415 ntohl (mp->mcast_sw_if_index),
Damjan Marion7cd468a2016-12-19 23:05:39 +010010416 ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
10417}
10418
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010419
Damjan Marion7cd468a2016-12-19 23:05:39 +010010420static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
10421 (vl_api_vxlan_gpe_tunnel_details_t * mp)
10422{
10423 vat_main_t *vam = &vat_main;
10424 vat_json_node_t *node = NULL;
10425 struct in_addr ip4;
10426 struct in6_addr ip6;
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010427 ip46_address_t local, remote;
10428
10429 ip_address_decode (&mp->local, &local);
10430 ip_address_decode (&mp->remote, &remote);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010431
10432 if (VAT_JSON_ARRAY != vam->json_tree.type)
10433 {
10434 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10435 vat_json_init_array (&vam->json_tree);
10436 }
10437 node = vat_json_array_add (&vam->json_tree);
10438
10439 vat_json_init_object (node);
10440 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010441 if (ip46_address_is_ip4 (&local))
Damjan Marion7cd468a2016-12-19 23:05:39 +010010442 {
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010443 clib_memcpy (&ip4, &local.ip4, sizeof (ip4));
10444 vat_json_object_add_ip4 (node, "local", ip4);
10445 clib_memcpy (&ip4, &remote.ip4, sizeof (ip4));
10446 vat_json_object_add_ip4 (node, "remote", ip4);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010447 }
10448 else
10449 {
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010450 clib_memcpy (&ip6, &local.ip6, sizeof (ip6));
10451 vat_json_object_add_ip6 (node, "local", ip6);
10452 clib_memcpy (&ip6, &remote.ip6, sizeof (ip6));
10453 vat_json_object_add_ip6 (node, "remote", ip6);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010454 }
10455 vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10456 vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010457 vat_json_object_add_uint (node, "mcast_sw_if_index",
10458 ntohl (mp->mcast_sw_if_index));
Damjan Marion7cd468a2016-12-19 23:05:39 +010010459 vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10460 vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
10461 vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10462}
10463
10464static int
10465api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
10466{
10467 unformat_input_t *i = vam->input;
10468 vl_api_vxlan_gpe_tunnel_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010469 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010470 u32 sw_if_index;
10471 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010472 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010473
10474 /* Parse args required to build the message */
10475 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10476 {
10477 if (unformat (i, "sw_if_index %d", &sw_if_index))
10478 sw_if_index_set = 1;
10479 else
10480 break;
10481 }
10482
10483 if (sw_if_index_set == 0)
10484 {
10485 sw_if_index = ~0;
10486 }
10487
10488 if (!vam->json_output)
10489 {
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010490 print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
Damjan Marion7cd468a2016-12-19 23:05:39 +010010491 "sw_if_index", "local", "remote", "vni",
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010492 "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
Damjan Marion7cd468a2016-12-19 23:05:39 +010010493 }
10494
10495 /* Get list of vxlan-tunnel interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010496 M (VXLAN_GPE_TUNNEL_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010497
10498 mp->sw_if_index = htonl (sw_if_index);
10499
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010500 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010501
10502 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040010503 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010504 S (mp_ping);
10505
Jon Loeliger56c7b012017-02-01 12:31:41 -060010506 W (ret);
10507 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010508}
10509
Ole Troan01384fe2017-05-12 11:55:35 +020010510static void vl_api_l2_fib_table_details_t_handler
10511 (vl_api_l2_fib_table_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010010512{
10513 vat_main_t *vam = &vat_main;
10514
10515 print (vam->ofp, "%3" PRIu32 " %U %3" PRIu32
10516 " %d %d %d",
Mohsin Kazmi57938f62017-10-27 21:28:07 +020010517 ntohl (mp->bd_id), format_ethernet_address, mp->mac,
Damjan Marion7cd468a2016-12-19 23:05:39 +010010518 ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
10519 mp->bvi_mac);
10520}
10521
Ole Troan01384fe2017-05-12 11:55:35 +020010522static void vl_api_l2_fib_table_details_t_handler_json
10523 (vl_api_l2_fib_table_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010010524{
10525 vat_main_t *vam = &vat_main;
10526 vat_json_node_t *node = NULL;
10527
10528 if (VAT_JSON_ARRAY != vam->json_tree.type)
10529 {
10530 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10531 vat_json_init_array (&vam->json_tree);
10532 }
10533 node = vat_json_array_add (&vam->json_tree);
10534
10535 vat_json_init_object (node);
10536 vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
Mohsin Kazmi57938f62017-10-27 21:28:07 +020010537 vat_json_object_add_bytes (node, "mac", mp->mac, 6);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010538 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10539 vat_json_object_add_uint (node, "static_mac", mp->static_mac);
10540 vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
10541 vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
10542}
10543
10544static int
10545api_l2_fib_table_dump (vat_main_t * vam)
10546{
10547 unformat_input_t *i = vam->input;
10548 vl_api_l2_fib_table_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010549 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010550 u32 bd_id;
10551 u8 bd_id_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010552 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010553
10554 /* Parse args required to build the message */
10555 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10556 {
10557 if (unformat (i, "bd_id %d", &bd_id))
10558 bd_id_set = 1;
10559 else
10560 break;
10561 }
10562
10563 if (bd_id_set == 0)
10564 {
10565 errmsg ("missing bridge domain");
10566 return -99;
10567 }
10568
10569 print (vam->ofp, "BD-ID Mac Address sw-ndx Static Filter BVI");
10570
10571 /* Get list of l2 fib entries */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010572 M (L2_FIB_TABLE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010573
10574 mp->bd_id = ntohl (bd_id);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010575 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010576
10577 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040010578 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010579 S (mp_ping);
10580
Jon Loeliger56c7b012017-02-01 12:31:41 -060010581 W (ret);
10582 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010583}
10584
10585
10586static int
10587api_interface_name_renumber (vat_main_t * vam)
10588{
10589 unformat_input_t *line_input = vam->input;
10590 vl_api_interface_name_renumber_t *mp;
10591 u32 sw_if_index = ~0;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010592 u32 new_show_dev_instance = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010593 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010594
10595 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10596 {
10597 if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
10598 &sw_if_index))
10599 ;
10600 else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
10601 ;
10602 else if (unformat (line_input, "new_show_dev_instance %d",
10603 &new_show_dev_instance))
10604 ;
10605 else
10606 break;
10607 }
10608
10609 if (sw_if_index == ~0)
10610 {
10611 errmsg ("missing interface name or sw_if_index");
10612 return -99;
10613 }
10614
10615 if (new_show_dev_instance == ~0)
10616 {
10617 errmsg ("missing new_show_dev_instance");
10618 return -99;
10619 }
10620
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010621 M (INTERFACE_NAME_RENUMBER, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010622
10623 mp->sw_if_index = ntohl (sw_if_index);
10624 mp->new_show_dev_instance = ntohl (new_show_dev_instance);
10625
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010626 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010627 W (ret);
10628 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010629}
10630
10631static int
John Lo8d00fff2017-08-03 00:35:36 -040010632api_want_l2_macs_events (vat_main_t * vam)
10633{
10634 unformat_input_t *line_input = vam->input;
10635 vl_api_want_l2_macs_events_t *mp;
10636 u8 enable_disable = 1;
10637 u32 scan_delay = 0;
10638 u32 max_macs_in_event = 0;
10639 u32 learn_limit = 0;
10640 int ret;
10641
10642 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10643 {
10644 if (unformat (line_input, "learn-limit %d", &learn_limit))
10645 ;
10646 else if (unformat (line_input, "scan-delay %d", &scan_delay))
10647 ;
10648 else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
10649 ;
10650 else if (unformat (line_input, "disable"))
10651 enable_disable = 0;
10652 else
10653 break;
10654 }
10655
10656 M (WANT_L2_MACS_EVENTS, mp);
10657 mp->enable_disable = enable_disable;
10658 mp->pid = htonl (getpid ());
10659 mp->learn_limit = htonl (learn_limit);
10660 mp->scan_delay = (u8) scan_delay;
10661 mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
10662 S (mp);
10663 W (ret);
10664 return ret;
10665}
10666
10667static int
Damjan Marion7cd468a2016-12-19 23:05:39 +010010668api_input_acl_set_interface (vat_main_t * vam)
10669{
10670 unformat_input_t *i = vam->input;
10671 vl_api_input_acl_set_interface_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010672 u32 sw_if_index;
10673 int sw_if_index_set;
10674 u32 ip4_table_index = ~0;
10675 u32 ip6_table_index = ~0;
10676 u32 l2_table_index = ~0;
10677 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010678 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010679
10680 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10681 {
10682 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10683 sw_if_index_set = 1;
10684 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10685 sw_if_index_set = 1;
10686 else if (unformat (i, "del"))
10687 is_add = 0;
10688 else if (unformat (i, "ip4-table %d", &ip4_table_index))
10689 ;
10690 else if (unformat (i, "ip6-table %d", &ip6_table_index))
10691 ;
10692 else if (unformat (i, "l2-table %d", &l2_table_index))
10693 ;
10694 else
10695 {
10696 clib_warning ("parse error '%U'", format_unformat_error, i);
10697 return -99;
10698 }
10699 }
10700
10701 if (sw_if_index_set == 0)
10702 {
10703 errmsg ("missing interface name or sw_if_index");
10704 return -99;
10705 }
10706
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010707 M (INPUT_ACL_SET_INTERFACE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010708
10709 mp->sw_if_index = ntohl (sw_if_index);
10710 mp->ip4_table_index = ntohl (ip4_table_index);
10711 mp->ip6_table_index = ntohl (ip6_table_index);
10712 mp->l2_table_index = ntohl (l2_table_index);
10713 mp->is_add = is_add;
10714
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010715 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010716 W (ret);
10717 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010718}
10719
10720static int
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +010010721api_output_acl_set_interface (vat_main_t * vam)
10722{
10723 unformat_input_t *i = vam->input;
10724 vl_api_output_acl_set_interface_t *mp;
10725 u32 sw_if_index;
10726 int sw_if_index_set;
10727 u32 ip4_table_index = ~0;
10728 u32 ip6_table_index = ~0;
10729 u32 l2_table_index = ~0;
10730 u8 is_add = 1;
10731 int ret;
10732
10733 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10734 {
10735 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10736 sw_if_index_set = 1;
10737 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10738 sw_if_index_set = 1;
10739 else if (unformat (i, "del"))
10740 is_add = 0;
10741 else if (unformat (i, "ip4-table %d", &ip4_table_index))
10742 ;
10743 else if (unformat (i, "ip6-table %d", &ip6_table_index))
10744 ;
10745 else if (unformat (i, "l2-table %d", &l2_table_index))
10746 ;
10747 else
10748 {
10749 clib_warning ("parse error '%U'", format_unformat_error, i);
10750 return -99;
10751 }
10752 }
10753
10754 if (sw_if_index_set == 0)
10755 {
10756 errmsg ("missing interface name or sw_if_index");
10757 return -99;
10758 }
10759
10760 M (OUTPUT_ACL_SET_INTERFACE, mp);
10761
10762 mp->sw_if_index = ntohl (sw_if_index);
10763 mp->ip4_table_index = ntohl (ip4_table_index);
10764 mp->ip6_table_index = ntohl (ip6_table_index);
10765 mp->l2_table_index = ntohl (l2_table_index);
10766 mp->is_add = is_add;
10767
10768 S (mp);
10769 W (ret);
10770 return ret;
10771}
10772
10773static int
Damjan Marion7cd468a2016-12-19 23:05:39 +010010774api_ip_address_dump (vat_main_t * vam)
10775{
10776 unformat_input_t *i = vam->input;
10777 vl_api_ip_address_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010778 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010779 u32 sw_if_index = ~0;
10780 u8 sw_if_index_set = 0;
10781 u8 ipv4_set = 0;
10782 u8 ipv6_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010783 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010784
10785 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10786 {
10787 if (unformat (i, "sw_if_index %d", &sw_if_index))
10788 sw_if_index_set = 1;
10789 else
10790 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10791 sw_if_index_set = 1;
10792 else if (unformat (i, "ipv4"))
10793 ipv4_set = 1;
10794 else if (unformat (i, "ipv6"))
10795 ipv6_set = 1;
10796 else
10797 break;
10798 }
10799
10800 if (ipv4_set && ipv6_set)
10801 {
10802 errmsg ("ipv4 and ipv6 flags cannot be both set");
10803 return -99;
10804 }
10805
10806 if ((!ipv4_set) && (!ipv6_set))
10807 {
10808 errmsg ("no ipv4 nor ipv6 flag set");
10809 return -99;
10810 }
10811
10812 if (sw_if_index_set == 0)
10813 {
10814 errmsg ("missing interface name or sw_if_index");
10815 return -99;
10816 }
10817
10818 vam->current_sw_if_index = sw_if_index;
10819 vam->is_ipv6 = ipv6_set;
10820
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010821 M (IP_ADDRESS_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010822 mp->sw_if_index = ntohl (sw_if_index);
10823 mp->is_ipv6 = ipv6_set;
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010824 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010825
10826 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040010827 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010828 S (mp_ping);
10829
Jon Loeliger56c7b012017-02-01 12:31:41 -060010830 W (ret);
10831 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010832}
10833
10834static int
10835api_ip_dump (vat_main_t * vam)
10836{
10837 vl_api_ip_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010838 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010839 unformat_input_t *in = vam->input;
10840 int ipv4_set = 0;
10841 int ipv6_set = 0;
10842 int is_ipv6;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010843 int i;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010844 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010845
10846 while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
10847 {
10848 if (unformat (in, "ipv4"))
10849 ipv4_set = 1;
10850 else if (unformat (in, "ipv6"))
10851 ipv6_set = 1;
10852 else
10853 break;
10854 }
10855
10856 if (ipv4_set && ipv6_set)
10857 {
10858 errmsg ("ipv4 and ipv6 flags cannot be both set");
10859 return -99;
10860 }
10861
10862 if ((!ipv4_set) && (!ipv6_set))
10863 {
10864 errmsg ("no ipv4 nor ipv6 flag set");
10865 return -99;
10866 }
10867
10868 is_ipv6 = ipv6_set;
10869 vam->is_ipv6 = is_ipv6;
10870
10871 /* free old data */
10872 for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
10873 {
10874 vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
10875 }
10876 vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
10877
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010878 M (IP_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010879 mp->is_ipv6 = ipv6_set;
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010880 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010881
10882 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040010883 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010884 S (mp_ping);
10885
Jon Loeliger56c7b012017-02-01 12:31:41 -060010886 W (ret);
10887 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010888}
10889
10890static int
10891api_ipsec_spd_add_del (vat_main_t * vam)
10892{
10893 unformat_input_t *i = vam->input;
10894 vl_api_ipsec_spd_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010895 u32 spd_id = ~0;
10896 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010897 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010898
10899 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10900 {
10901 if (unformat (i, "spd_id %d", &spd_id))
10902 ;
10903 else if (unformat (i, "del"))
10904 is_add = 0;
10905 else
10906 {
10907 clib_warning ("parse error '%U'", format_unformat_error, i);
10908 return -99;
10909 }
10910 }
10911 if (spd_id == ~0)
10912 {
10913 errmsg ("spd_id must be set");
10914 return -99;
10915 }
10916
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010917 M (IPSEC_SPD_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010918
10919 mp->spd_id = ntohl (spd_id);
10920 mp->is_add = is_add;
10921
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010922 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010923 W (ret);
10924 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010925}
10926
10927static int
10928api_ipsec_interface_add_del_spd (vat_main_t * vam)
10929{
10930 unformat_input_t *i = vam->input;
10931 vl_api_ipsec_interface_add_del_spd_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010932 u32 sw_if_index;
10933 u8 sw_if_index_set = 0;
10934 u32 spd_id = (u32) ~ 0;
10935 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010936 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010937
10938 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10939 {
10940 if (unformat (i, "del"))
10941 is_add = 0;
10942 else if (unformat (i, "spd_id %d", &spd_id))
10943 ;
10944 else
10945 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10946 sw_if_index_set = 1;
10947 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10948 sw_if_index_set = 1;
10949 else
10950 {
10951 clib_warning ("parse error '%U'", format_unformat_error, i);
10952 return -99;
10953 }
10954
10955 }
10956
10957 if (spd_id == (u32) ~ 0)
10958 {
10959 errmsg ("spd_id must be set");
10960 return -99;
10961 }
10962
10963 if (sw_if_index_set == 0)
10964 {
10965 errmsg ("missing interface name or sw_if_index");
10966 return -99;
10967 }
10968
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010969 M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010970
10971 mp->spd_id = ntohl (spd_id);
10972 mp->sw_if_index = ntohl (sw_if_index);
10973 mp->is_add = is_add;
10974
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010975 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010976 W (ret);
10977 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010978}
10979
10980static int
Neale Ranns17dcec02019-01-09 21:22:20 -080010981api_ipsec_spd_entry_add_del (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010010982{
10983 unformat_input_t *i = vam->input;
Neale Ranns17dcec02019-01-09 21:22:20 -080010984 vl_api_ipsec_spd_entry_add_del_t *mp;
Benoît Ganne49ee6842019-04-30 11:50:46 +020010985 u8 is_add = 1, is_outbound = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010986 u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
10987 i32 priority = 0;
10988 u32 rport_start = 0, rport_stop = (u32) ~ 0;
10989 u32 lport_start = 0, lport_stop = (u32) ~ 0;
Neale Ranns17dcec02019-01-09 21:22:20 -080010990 vl_api_address_t laddr_start = { }, laddr_stop =
10991 {
10992 }, raddr_start =
10993 {
10994 }, raddr_stop =
10995 {
10996 };
Jon Loeliger56c7b012017-02-01 12:31:41 -060010997 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010998
Damjan Marion7cd468a2016-12-19 23:05:39 +010010999 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11000 {
11001 if (unformat (i, "del"))
11002 is_add = 0;
11003 if (unformat (i, "outbound"))
11004 is_outbound = 1;
11005 if (unformat (i, "inbound"))
11006 is_outbound = 0;
11007 else if (unformat (i, "spd_id %d", &spd_id))
11008 ;
11009 else if (unformat (i, "sa_id %d", &sa_id))
11010 ;
11011 else if (unformat (i, "priority %d", &priority))
11012 ;
11013 else if (unformat (i, "protocol %d", &protocol))
11014 ;
11015 else if (unformat (i, "lport_start %d", &lport_start))
11016 ;
11017 else if (unformat (i, "lport_stop %d", &lport_stop))
11018 ;
11019 else if (unformat (i, "rport_start %d", &rport_start))
11020 ;
11021 else if (unformat (i, "rport_stop %d", &rport_stop))
11022 ;
Neale Ranns17dcec02019-01-09 21:22:20 -080011023 else if (unformat (i, "laddr_start %U",
11024 unformat_vl_api_address, &laddr_start))
Benoît Ganne49ee6842019-04-30 11:50:46 +020011025 ;
Neale Ranns17dcec02019-01-09 21:22:20 -080011026 else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
11027 &laddr_stop))
Benoît Ganne49ee6842019-04-30 11:50:46 +020011028 ;
Neale Ranns17dcec02019-01-09 21:22:20 -080011029 else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
11030 &raddr_start))
Benoît Ganne49ee6842019-04-30 11:50:46 +020011031 ;
Neale Ranns17dcec02019-01-09 21:22:20 -080011032 else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
11033 &raddr_stop))
Benoît Ganne49ee6842019-04-30 11:50:46 +020011034 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011035 else
11036 if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
11037 {
11038 if (policy == IPSEC_POLICY_ACTION_RESOLVE)
11039 {
11040 clib_warning ("unsupported action: 'resolve'");
11041 return -99;
11042 }
11043 }
11044 else
11045 {
11046 clib_warning ("parse error '%U'", format_unformat_error, i);
11047 return -99;
11048 }
11049
11050 }
11051
Neale Ranns17dcec02019-01-09 21:22:20 -080011052 M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011053
Damjan Marion7cd468a2016-12-19 23:05:39 +010011054 mp->is_add = is_add;
Neale Ranns17dcec02019-01-09 21:22:20 -080011055
11056 mp->entry.spd_id = ntohl (spd_id);
11057 mp->entry.priority = ntohl (priority);
11058 mp->entry.is_outbound = is_outbound;
11059
11060 clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
11061 sizeof (vl_api_address_t));
11062 clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
11063 sizeof (vl_api_address_t));
11064 clib_memcpy (&mp->entry.local_address_start, &laddr_start,
11065 sizeof (vl_api_address_t));
11066 clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
11067 sizeof (vl_api_address_t));
11068
11069 mp->entry.protocol = (u8) protocol;
11070 mp->entry.local_port_start = ntohs ((u16) lport_start);
11071 mp->entry.local_port_stop = ntohs ((u16) lport_stop);
11072 mp->entry.remote_port_start = ntohs ((u16) rport_start);
11073 mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
11074 mp->entry.policy = (u8) policy;
11075 mp->entry.sa_id = ntohl (sa_id);
Neale Ranns17dcec02019-01-09 21:22:20 -080011076
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011077 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011078 W (ret);
11079 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011080}
11081
11082static int
Neale Ranns17dcec02019-01-09 21:22:20 -080011083api_ipsec_sad_entry_add_del (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010011084{
11085 unformat_input_t *i = vam->input;
Neale Ranns17dcec02019-01-09 21:22:20 -080011086 vl_api_ipsec_sad_entry_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011087 u32 sad_id = 0, spi = 0;
11088 u8 *ck = 0, *ik = 0;
11089 u8 is_add = 1;
11090
Neale Ranns17dcec02019-01-09 21:22:20 -080011091 vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
11092 vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
11093 vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
11094 vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
11095 vl_api_address_t tun_src, tun_dst;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011096 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011097
11098 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11099 {
11100 if (unformat (i, "del"))
11101 is_add = 0;
11102 else if (unformat (i, "sad_id %d", &sad_id))
11103 ;
11104 else if (unformat (i, "spi %d", &spi))
11105 ;
11106 else if (unformat (i, "esp"))
Neale Ranns17dcec02019-01-09 21:22:20 -080011107 protocol = IPSEC_API_PROTO_ESP;
11108 else
11109 if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
Damjan Marion7cd468a2016-12-19 23:05:39 +010011110 {
Neale Ranns17dcec02019-01-09 21:22:20 -080011111 flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
11112 if (ADDRESS_IP6 == tun_src.af)
11113 flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011114 }
11115 else
Neale Ranns17dcec02019-01-09 21:22:20 -080011116 if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
Damjan Marion7cd468a2016-12-19 23:05:39 +010011117 {
Neale Ranns17dcec02019-01-09 21:22:20 -080011118 flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
11119 if (ADDRESS_IP6 == tun_src.af)
11120 flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011121 }
Neale Ranns17dcec02019-01-09 21:22:20 -080011122 else
11123 if (unformat (i, "crypto_alg %U",
11124 unformat_ipsec_api_crypto_alg, &crypto_alg))
11125 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011126 else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11127 ;
Neale Ranns17dcec02019-01-09 21:22:20 -080011128 else if (unformat (i, "integ_alg %U",
11129 unformat_ipsec_api_integ_alg, &integ_alg))
11130 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011131 else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11132 ;
11133 else
11134 {
11135 clib_warning ("parse error '%U'", format_unformat_error, i);
11136 return -99;
11137 }
11138
11139 }
11140
Neale Ranns17dcec02019-01-09 21:22:20 -080011141 M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011142
Damjan Marion7cd468a2016-12-19 23:05:39 +010011143 mp->is_add = is_add;
Neale Ranns17dcec02019-01-09 21:22:20 -080011144 mp->entry.sad_id = ntohl (sad_id);
11145 mp->entry.protocol = protocol;
11146 mp->entry.spi = ntohl (spi);
11147 mp->entry.flags = flags;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011148
Neale Ranns17dcec02019-01-09 21:22:20 -080011149 mp->entry.crypto_algorithm = crypto_alg;
11150 mp->entry.integrity_algorithm = integ_alg;
11151 mp->entry.crypto_key.length = vec_len (ck);
11152 mp->entry.integrity_key.length = vec_len (ik);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011153
Neale Ranns17dcec02019-01-09 21:22:20 -080011154 if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
11155 mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
11156
11157 if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
11158 mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011159
11160 if (ck)
Neale Ranns17dcec02019-01-09 21:22:20 -080011161 clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011162 if (ik)
Neale Ranns17dcec02019-01-09 21:22:20 -080011163 clib_memcpy (mp->entry.integrity_key.data, ik,
11164 mp->entry.integrity_key.length);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011165
Neale Ranns17dcec02019-01-09 21:22:20 -080011166 if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
Damjan Marion7cd468a2016-12-19 23:05:39 +010011167 {
Neale Ranns17dcec02019-01-09 21:22:20 -080011168 clib_memcpy (&mp->entry.tunnel_src, &tun_src,
11169 sizeof (mp->entry.tunnel_src));
11170 clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
11171 sizeof (mp->entry.tunnel_dst));
Damjan Marion7cd468a2016-12-19 23:05:39 +010011172 }
11173
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011174 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011175 W (ret);
11176 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011177}
11178
Matthew Smith28029532017-09-26 13:33:44 -050011179static void
11180vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
11181{
11182 vat_main_t *vam = &vat_main;
11183
11184 print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
Neale Ranns8d7c5022019-02-06 01:41:05 -080011185 "crypto_key %U integ_alg %u integ_key %U flags %x "
Matthew Smith28029532017-09-26 13:33:44 -050011186 "tunnel_src_addr %U tunnel_dst_addr %U "
11187 "salt %u seq_outbound %lu last_seq_inbound %lu "
Matthew Smith48d32b42020-04-02 07:45:49 -050011188 "replay_window %lu stat_index %u\n",
Neale Ranns8d7c5022019-02-06 01:41:05 -080011189 ntohl (mp->entry.sad_id),
11190 ntohl (mp->sw_if_index),
11191 ntohl (mp->entry.spi),
11192 ntohl (mp->entry.protocol),
11193 ntohl (mp->entry.crypto_algorithm),
11194 format_hex_bytes, mp->entry.crypto_key.data,
11195 mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
11196 format_hex_bytes, mp->entry.integrity_key.data,
11197 mp->entry.integrity_key.length, ntohl (mp->entry.flags),
11198 format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
11199 &mp->entry.tunnel_dst, ntohl (mp->salt),
Matthew Smith28029532017-09-26 13:33:44 -050011200 clib_net_to_host_u64 (mp->seq_outbound),
11201 clib_net_to_host_u64 (mp->last_seq_inbound),
Matthew Smith48d32b42020-04-02 07:45:49 -050011202 clib_net_to_host_u64 (mp->replay_window), ntohl (mp->stat_index));
Matthew Smith28029532017-09-26 13:33:44 -050011203}
11204
11205#define vl_api_ipsec_sa_details_t_endian vl_noop_handler
11206#define vl_api_ipsec_sa_details_t_print vl_noop_handler
11207
11208static void vl_api_ipsec_sa_details_t_handler_json
11209 (vl_api_ipsec_sa_details_t * mp)
11210{
11211 vat_main_t *vam = &vat_main;
11212 vat_json_node_t *node = NULL;
Neale Ranns8d7c5022019-02-06 01:41:05 -080011213 vl_api_ipsec_sad_flags_t flags;
Matthew Smith28029532017-09-26 13:33:44 -050011214
11215 if (VAT_JSON_ARRAY != vam->json_tree.type)
11216 {
11217 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11218 vat_json_init_array (&vam->json_tree);
11219 }
11220 node = vat_json_array_add (&vam->json_tree);
11221
11222 vat_json_init_object (node);
Neale Ranns8d7c5022019-02-06 01:41:05 -080011223 vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
Matthew Smith28029532017-09-26 13:33:44 -050011224 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
Neale Ranns8d7c5022019-02-06 01:41:05 -080011225 vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
11226 vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
11227 vat_json_object_add_uint (node, "crypto_alg",
11228 ntohl (mp->entry.crypto_algorithm));
11229 vat_json_object_add_uint (node, "integ_alg",
11230 ntohl (mp->entry.integrity_algorithm));
11231 flags = ntohl (mp->entry.flags);
11232 vat_json_object_add_uint (node, "use_esn",
Damjan Marion1e3aa5e2019-03-28 10:58:59 +010011233 ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
Neale Ranns8d7c5022019-02-06 01:41:05 -080011234 vat_json_object_add_uint (node, "use_anti_replay",
11235 ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
11236 vat_json_object_add_uint (node, "is_tunnel",
11237 ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
11238 vat_json_object_add_uint (node, "is_tunnel_ip6",
11239 ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
11240 vat_json_object_add_uint (node, "udp_encap",
11241 ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
11242 vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
11243 mp->entry.crypto_key.length);
11244 vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
11245 mp->entry.integrity_key.length);
Neale Ranns5a8844b2019-04-16 07:15:35 +000011246 vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
11247 vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
Matthew Smith28029532017-09-26 13:33:44 -050011248 vat_json_object_add_uint (node, "replay_window",
11249 clib_net_to_host_u64 (mp->replay_window));
Matthew Smith48d32b42020-04-02 07:45:49 -050011250 vat_json_object_add_uint (node, "stat_index", ntohl (mp->stat_index));
Matthew Smith28029532017-09-26 13:33:44 -050011251}
11252
11253static int
11254api_ipsec_sa_dump (vat_main_t * vam)
11255{
11256 unformat_input_t *i = vam->input;
11257 vl_api_ipsec_sa_dump_t *mp;
11258 vl_api_control_ping_t *mp_ping;
11259 u32 sa_id = ~0;
11260 int ret;
11261
11262 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11263 {
11264 if (unformat (i, "sa_id %d", &sa_id))
11265 ;
11266 else
11267 {
11268 clib_warning ("parse error '%U'", format_unformat_error, i);
11269 return -99;
11270 }
11271 }
11272
11273 M (IPSEC_SA_DUMP, mp);
11274
11275 mp->sa_id = ntohl (sa_id);
11276
11277 S (mp);
11278
11279 /* Use a control ping for synchronization */
11280 M (CONTROL_PING, mp_ping);
11281 S (mp_ping);
11282
11283 W (ret);
11284 return ret;
11285}
11286
Matthew Smithb0972cb2017-05-02 16:20:41 -050011287static int
Damjan Marion7cd468a2016-12-19 23:05:39 +010011288api_get_first_msg_id (vat_main_t * vam)
11289{
11290 vl_api_get_first_msg_id_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011291 unformat_input_t *i = vam->input;
11292 u8 *name;
11293 u8 name_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011294 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011295
11296 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11297 {
11298 if (unformat (i, "client %s", &name))
11299 name_set = 1;
11300 else
11301 break;
11302 }
11303
11304 if (name_set == 0)
11305 {
11306 errmsg ("missing client name");
11307 return -99;
11308 }
11309 vec_add1 (name, 0);
11310
11311 if (vec_len (name) > 63)
11312 {
11313 errmsg ("client name too long");
11314 return -99;
11315 }
11316
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011317 M (GET_FIRST_MSG_ID, mp);
Ole Troan7adaa222019-08-27 15:05:27 +020011318 clib_memcpy (mp->name, name, vec_len (name));
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011319 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011320 W (ret);
11321 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011322}
11323
11324static int
11325api_cop_interface_enable_disable (vat_main_t * vam)
11326{
11327 unformat_input_t *line_input = vam->input;
11328 vl_api_cop_interface_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011329 u32 sw_if_index = ~0;
11330 u8 enable_disable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011331 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011332
11333 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11334 {
11335 if (unformat (line_input, "disable"))
11336 enable_disable = 0;
11337 if (unformat (line_input, "enable"))
11338 enable_disable = 1;
11339 else if (unformat (line_input, "%U", api_unformat_sw_if_index,
11340 vam, &sw_if_index))
11341 ;
11342 else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11343 ;
11344 else
11345 break;
11346 }
11347
11348 if (sw_if_index == ~0)
11349 {
11350 errmsg ("missing interface name or sw_if_index");
11351 return -99;
11352 }
11353
11354 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011355 M (COP_INTERFACE_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011356 mp->sw_if_index = ntohl (sw_if_index);
11357 mp->enable_disable = enable_disable;
11358
11359 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011360 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011361 /* Wait for the reply */
Jon Loeliger56c7b012017-02-01 12:31:41 -060011362 W (ret);
11363 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011364}
11365
11366static int
11367api_cop_whitelist_enable_disable (vat_main_t * vam)
11368{
11369 unformat_input_t *line_input = vam->input;
11370 vl_api_cop_whitelist_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011371 u32 sw_if_index = ~0;
11372 u8 ip4 = 0, ip6 = 0, default_cop = 0;
11373 u32 fib_id = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011374 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011375
11376 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11377 {
11378 if (unformat (line_input, "ip4"))
11379 ip4 = 1;
11380 else if (unformat (line_input, "ip6"))
11381 ip6 = 1;
11382 else if (unformat (line_input, "default"))
11383 default_cop = 1;
11384 else if (unformat (line_input, "%U", api_unformat_sw_if_index,
11385 vam, &sw_if_index))
11386 ;
11387 else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11388 ;
11389 else if (unformat (line_input, "fib-id %d", &fib_id))
11390 ;
11391 else
11392 break;
11393 }
11394
11395 if (sw_if_index == ~0)
11396 {
11397 errmsg ("missing interface name or sw_if_index");
11398 return -99;
11399 }
11400
11401 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011402 M (COP_WHITELIST_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011403 mp->sw_if_index = ntohl (sw_if_index);
11404 mp->fib_id = ntohl (fib_id);
11405 mp->ip4 = ip4;
11406 mp->ip6 = ip6;
11407 mp->default_cop = default_cop;
11408
11409 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011410 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011411 /* Wait for the reply */
Jon Loeliger56c7b012017-02-01 12:31:41 -060011412 W (ret);
11413 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011414}
11415
11416static int
11417api_get_node_graph (vat_main_t * vam)
11418{
11419 vl_api_get_node_graph_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011420 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011421
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011422 M (GET_NODE_GRAPH, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011423
11424 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011425 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011426 /* Wait for the reply */
Jon Loeliger56c7b012017-02-01 12:31:41 -060011427 W (ret);
11428 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011429}
11430
Damjan Marion7cd468a2016-12-19 23:05:39 +010011431static int
11432api_af_packet_create (vat_main_t * vam)
11433{
11434 unformat_input_t *i = vam->input;
11435 vl_api_af_packet_create_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011436 u8 *host_if_name = 0;
11437 u8 hw_addr[6];
11438 u8 random_hw_addr = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011439 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011440
Dave Barachb7b92992018-10-17 10:38:51 -040011441 clib_memset (hw_addr, 0, sizeof (hw_addr));
Damjan Marion7cd468a2016-12-19 23:05:39 +010011442
11443 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11444 {
11445 if (unformat (i, "name %s", &host_if_name))
11446 vec_add1 (host_if_name, 0);
11447 else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
11448 random_hw_addr = 0;
11449 else
11450 break;
11451 }
11452
11453 if (!vec_len (host_if_name))
11454 {
11455 errmsg ("host-interface name must be specified");
11456 return -99;
11457 }
11458
11459 if (vec_len (host_if_name) > 64)
11460 {
11461 errmsg ("host-interface name too long");
11462 return -99;
11463 }
11464
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011465 M (AF_PACKET_CREATE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011466
11467 clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
11468 clib_memcpy (mp->hw_addr, hw_addr, 6);
11469 mp->use_random_hw_addr = random_hw_addr;
11470 vec_free (host_if_name);
11471
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011472 S (mp);
Dave Baracha1a093d2017-03-02 13:13:23 -050011473
11474 /* *INDENT-OFF* */
11475 W2 (ret,
11476 ({
11477 if (ret == 0)
11478 fprintf (vam->ofp ? vam->ofp : stderr,
11479 " new sw_if_index = %d\n", vam->sw_if_index);
11480 }));
11481 /* *INDENT-ON* */
Jon Loeliger56c7b012017-02-01 12:31:41 -060011482 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011483}
11484
11485static int
11486api_af_packet_delete (vat_main_t * vam)
11487{
11488 unformat_input_t *i = vam->input;
11489 vl_api_af_packet_delete_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011490 u8 *host_if_name = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011491 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011492
11493 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11494 {
11495 if (unformat (i, "name %s", &host_if_name))
11496 vec_add1 (host_if_name, 0);
11497 else
11498 break;
11499 }
11500
11501 if (!vec_len (host_if_name))
11502 {
11503 errmsg ("host-interface name must be specified");
11504 return -99;
11505 }
11506
11507 if (vec_len (host_if_name) > 64)
11508 {
11509 errmsg ("host-interface name too long");
11510 return -99;
11511 }
11512
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011513 M (AF_PACKET_DELETE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011514
11515 clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
11516 vec_free (host_if_name);
11517
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011518 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011519 W (ret);
11520 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011521}
11522
Mohsin Kazmi04e0bb22018-05-28 18:55:37 +020011523static void vl_api_af_packet_details_t_handler
11524 (vl_api_af_packet_details_t * mp)
11525{
11526 vat_main_t *vam = &vat_main;
11527
11528 print (vam->ofp, "%-16s %d",
11529 mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
11530}
11531
11532static void vl_api_af_packet_details_t_handler_json
11533 (vl_api_af_packet_details_t * mp)
11534{
11535 vat_main_t *vam = &vat_main;
11536 vat_json_node_t *node = NULL;
11537
11538 if (VAT_JSON_ARRAY != vam->json_tree.type)
11539 {
11540 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11541 vat_json_init_array (&vam->json_tree);
11542 }
11543 node = vat_json_array_add (&vam->json_tree);
11544
11545 vat_json_init_object (node);
11546 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11547 vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
11548}
11549
11550static int
11551api_af_packet_dump (vat_main_t * vam)
11552{
11553 vl_api_af_packet_dump_t *mp;
11554 vl_api_control_ping_t *mp_ping;
11555 int ret;
11556
11557 print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
11558 /* Get list of tap interfaces */
11559 M (AF_PACKET_DUMP, mp);
11560 S (mp);
11561
11562 /* Use a control ping for synchronization */
11563 MPING (CONTROL_PING, mp_ping);
11564 S (mp_ping);
11565
11566 W (ret);
11567 return ret;
11568}
11569
Damjan Marion7cd468a2016-12-19 23:05:39 +010011570static int
11571api_policer_add_del (vat_main_t * vam)
11572{
11573 unformat_input_t *i = vam->input;
11574 vl_api_policer_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011575 u8 is_add = 1;
11576 u8 *name = 0;
11577 u32 cir = 0;
11578 u32 eir = 0;
11579 u64 cb = 0;
11580 u64 eb = 0;
11581 u8 rate_type = 0;
11582 u8 round_type = 0;
11583 u8 type = 0;
11584 u8 color_aware = 0;
11585 sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011586 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011587
11588 conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
11589 conform_action.dscp = 0;
11590 exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
11591 exceed_action.dscp = 0;
11592 violate_action.action_type = SSE2_QOS_ACTION_DROP;
11593 violate_action.dscp = 0;
11594
11595 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11596 {
11597 if (unformat (i, "del"))
11598 is_add = 0;
11599 else if (unformat (i, "name %s", &name))
11600 vec_add1 (name, 0);
11601 else if (unformat (i, "cir %u", &cir))
11602 ;
11603 else if (unformat (i, "eir %u", &eir))
11604 ;
11605 else if (unformat (i, "cb %u", &cb))
11606 ;
11607 else if (unformat (i, "eb %u", &eb))
11608 ;
11609 else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
11610 &rate_type))
11611 ;
11612 else if (unformat (i, "round_type %U", unformat_policer_round_type,
11613 &round_type))
11614 ;
11615 else if (unformat (i, "type %U", unformat_policer_type, &type))
11616 ;
11617 else if (unformat (i, "conform_action %U", unformat_policer_action_type,
11618 &conform_action))
11619 ;
11620 else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
11621 &exceed_action))
11622 ;
11623 else if (unformat (i, "violate_action %U", unformat_policer_action_type,
11624 &violate_action))
11625 ;
11626 else if (unformat (i, "color-aware"))
11627 color_aware = 1;
11628 else
11629 break;
11630 }
11631
11632 if (!vec_len (name))
11633 {
11634 errmsg ("policer name must be specified");
11635 return -99;
11636 }
11637
11638 if (vec_len (name) > 64)
11639 {
11640 errmsg ("policer name too long");
11641 return -99;
11642 }
11643
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011644 M (POLICER_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011645
11646 clib_memcpy (mp->name, name, vec_len (name));
11647 vec_free (name);
11648 mp->is_add = is_add;
Neale Rannsd91c1db2017-07-31 02:30:50 -070011649 mp->cir = ntohl (cir);
11650 mp->eir = ntohl (eir);
11651 mp->cb = clib_net_to_host_u64 (cb);
11652 mp->eb = clib_net_to_host_u64 (eb);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011653 mp->rate_type = rate_type;
11654 mp->round_type = round_type;
11655 mp->type = type;
Jakub Grajciarcd01fb42020-03-02 13:16:53 +010011656 mp->conform_action.type = conform_action.action_type;
11657 mp->conform_action.dscp = conform_action.dscp;
11658 mp->exceed_action.type = exceed_action.action_type;
11659 mp->exceed_action.dscp = exceed_action.dscp;
11660 mp->violate_action.type = violate_action.action_type;
11661 mp->violate_action.dscp = violate_action.dscp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011662 mp->color_aware = color_aware;
11663
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011664 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011665 W (ret);
11666 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011667}
11668
11669static int
11670api_policer_dump (vat_main_t * vam)
11671{
11672 unformat_input_t *i = vam->input;
11673 vl_api_policer_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011674 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011675 u8 *match_name = 0;
11676 u8 match_name_valid = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011677 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011678
11679 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11680 {
11681 if (unformat (i, "name %s", &match_name))
11682 {
11683 vec_add1 (match_name, 0);
11684 match_name_valid = 1;
11685 }
11686 else
11687 break;
11688 }
11689
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011690 M (POLICER_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011691 mp->match_name_valid = match_name_valid;
11692 clib_memcpy (mp->match_name, match_name, vec_len (match_name));
11693 vec_free (match_name);
11694 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011695 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011696
11697 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040011698 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011699 S (mp_ping);
11700
Damjan Marion7cd468a2016-12-19 23:05:39 +010011701 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060011702 W (ret);
11703 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011704}
11705
11706static int
11707api_policer_classify_set_interface (vat_main_t * vam)
11708{
11709 unformat_input_t *i = vam->input;
11710 vl_api_policer_classify_set_interface_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011711 u32 sw_if_index;
11712 int sw_if_index_set;
11713 u32 ip4_table_index = ~0;
11714 u32 ip6_table_index = ~0;
11715 u32 l2_table_index = ~0;
11716 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011717 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011718
11719 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11720 {
11721 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11722 sw_if_index_set = 1;
11723 else if (unformat (i, "sw_if_index %d", &sw_if_index))
11724 sw_if_index_set = 1;
11725 else if (unformat (i, "del"))
11726 is_add = 0;
11727 else if (unformat (i, "ip4-table %d", &ip4_table_index))
11728 ;
11729 else if (unformat (i, "ip6-table %d", &ip6_table_index))
11730 ;
11731 else if (unformat (i, "l2-table %d", &l2_table_index))
11732 ;
11733 else
11734 {
11735 clib_warning ("parse error '%U'", format_unformat_error, i);
11736 return -99;
11737 }
11738 }
11739
11740 if (sw_if_index_set == 0)
11741 {
11742 errmsg ("missing interface name or sw_if_index");
11743 return -99;
11744 }
11745
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011746 M (POLICER_CLASSIFY_SET_INTERFACE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011747
11748 mp->sw_if_index = ntohl (sw_if_index);
11749 mp->ip4_table_index = ntohl (ip4_table_index);
11750 mp->ip6_table_index = ntohl (ip6_table_index);
11751 mp->l2_table_index = ntohl (l2_table_index);
11752 mp->is_add = is_add;
11753
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011754 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011755 W (ret);
11756 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011757}
11758
11759static int
11760api_policer_classify_dump (vat_main_t * vam)
11761{
11762 unformat_input_t *i = vam->input;
11763 vl_api_policer_classify_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011764 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011765 u8 type = POLICER_CLASSIFY_N_TABLES;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011766 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011767
11768 if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
11769 ;
11770 else
11771 {
11772 errmsg ("classify table type must be specified");
11773 return -99;
11774 }
11775
11776 if (!vam->json_output)
11777 {
11778 print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
11779 }
11780
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011781 M (POLICER_CLASSIFY_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011782 mp->type = type;
11783 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011784 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011785
11786 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040011787 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011788 S (mp_ping);
11789
Damjan Marion7cd468a2016-12-19 23:05:39 +010011790 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060011791 W (ret);
11792 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011793}
11794
Neale Ranns097fa662018-05-01 05:17:55 -070011795static u8 *
11796format_fib_api_path_nh_proto (u8 * s, va_list * args)
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011797{
Neale Ranns097fa662018-05-01 05:17:55 -070011798 vl_api_fib_path_nh_proto_t proto =
11799 va_arg (*args, vl_api_fib_path_nh_proto_t);
11800
11801 switch (proto)
11802 {
11803 case FIB_API_PATH_NH_PROTO_IP4:
11804 s = format (s, "ip4");
11805 break;
11806 case FIB_API_PATH_NH_PROTO_IP6:
11807 s = format (s, "ip6");
11808 break;
11809 case FIB_API_PATH_NH_PROTO_MPLS:
11810 s = format (s, "mpls");
11811 break;
11812 case FIB_API_PATH_NH_PROTO_BIER:
11813 s = format (s, "bier");
11814 break;
11815 case FIB_API_PATH_NH_PROTO_ETHERNET:
11816 s = format (s, "ethernet");
11817 break;
11818 }
11819
11820 return (s);
11821}
11822
11823static u8 *
11824format_vl_api_ip_address_union (u8 * s, va_list * args)
11825{
Jakub Grajciar7dd63e52020-03-19 08:03:55 +010011826 vl_api_address_family_t af = va_arg (*args, int);
Neale Ranns097fa662018-05-01 05:17:55 -070011827 const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
11828
11829 switch (af)
11830 {
11831 case ADDRESS_IP4:
11832 s = format (s, "%U", format_ip4_address, u->ip4);
11833 break;
11834 case ADDRESS_IP6:
11835 s = format (s, "%U", format_ip6_address, u->ip6);
11836 break;
11837 }
11838 return (s);
11839}
11840
11841static u8 *
11842format_vl_api_fib_path_type (u8 * s, va_list * args)
11843{
11844 vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
11845
11846 switch (t)
11847 {
11848 case FIB_API_PATH_TYPE_NORMAL:
11849 s = format (s, "normal");
11850 break;
11851 case FIB_API_PATH_TYPE_LOCAL:
11852 s = format (s, "local");
11853 break;
11854 case FIB_API_PATH_TYPE_DROP:
11855 s = format (s, "drop");
11856 break;
11857 case FIB_API_PATH_TYPE_UDP_ENCAP:
11858 s = format (s, "udp-encap");
11859 break;
11860 case FIB_API_PATH_TYPE_BIER_IMP:
11861 s = format (s, "bier-imp");
11862 break;
11863 case FIB_API_PATH_TYPE_ICMP_UNREACH:
11864 s = format (s, "unreach");
11865 break;
11866 case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
11867 s = format (s, "prohibit");
11868 break;
11869 case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
11870 s = format (s, "src-lookup");
11871 break;
11872 case FIB_API_PATH_TYPE_DVR:
11873 s = format (s, "dvr");
11874 break;
11875 case FIB_API_PATH_TYPE_INTERFACE_RX:
11876 s = format (s, "interface-rx");
11877 break;
11878 case FIB_API_PATH_TYPE_CLASSIFY:
11879 s = format (s, "classify");
11880 break;
11881 }
11882
11883 return (s);
11884}
11885
11886static void
11887vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
11888{
11889 print (vam->ofp,
11890 " weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
11891 ntohl (fp->weight), ntohl (fp->sw_if_index),
11892 format_vl_api_fib_path_type, fp->type,
11893 format_fib_api_path_nh_proto, fp->proto,
11894 format_vl_api_ip_address_union, &fp->nh.address);
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011895}
11896
11897static void
11898vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
Neale Ranns31ed7442018-02-23 05:29:09 -080011899 vl_api_fib_path_t * fp)
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011900{
11901 struct in_addr ip4;
11902 struct in6_addr ip6;
11903
11904 vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
11905 vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
Neale Ranns097fa662018-05-01 05:17:55 -070011906 vat_json_object_add_uint (node, "type", fp->type);
11907 vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
11908 if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011909 {
Neale Ranns097fa662018-05-01 05:17:55 -070011910 clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011911 vat_json_object_add_ip4 (node, "next_hop", ip4);
11912 }
Dave Barachc35f3e82020-04-02 10:44:09 -040011913 else if (fp->proto == FIB_API_PATH_NH_PROTO_IP6)
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011914 {
Neale Ranns097fa662018-05-01 05:17:55 -070011915 clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011916 vat_json_object_add_ip6 (node, "next_hop", ip6);
11917 }
11918}
11919
11920static void
11921vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010011922{
11923 vat_main_t *vam = &vat_main;
Neale Ranns097fa662018-05-01 05:17:55 -070011924 int count = ntohl (mp->mt_tunnel.mt_n_paths);
Neale Ranns31ed7442018-02-23 05:29:09 -080011925 vl_api_fib_path_t *fp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011926 i32 i;
11927
Neale Ranns097fa662018-05-01 05:17:55 -070011928 print (vam->ofp, "sw_if_index %d via:",
11929 ntohl (mp->mt_tunnel.mt_sw_if_index));
11930 fp = mp->mt_tunnel.mt_paths;
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011931 for (i = 0; i < count; i++)
Damjan Marion7cd468a2016-12-19 23:05:39 +010011932 {
Neale Ranns097fa662018-05-01 05:17:55 -070011933 vl_api_fib_path_print (vam, fp);
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011934 fp++;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011935 }
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011936
Damjan Marion7cd468a2016-12-19 23:05:39 +010011937 print (vam->ofp, "");
11938}
11939
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011940#define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
11941#define vl_api_mpls_tunnel_details_t_print vl_noop_handler
11942
11943static void
11944vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010011945{
11946 vat_main_t *vam = &vat_main;
11947 vat_json_node_t *node = NULL;
Neale Ranns097fa662018-05-01 05:17:55 -070011948 int count = ntohl (mp->mt_tunnel.mt_n_paths);
Neale Ranns31ed7442018-02-23 05:29:09 -080011949 vl_api_fib_path_t *fp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011950 i32 i;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011951
11952 if (VAT_JSON_ARRAY != vam->json_tree.type)
11953 {
11954 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11955 vat_json_init_array (&vam->json_tree);
11956 }
11957 node = vat_json_array_add (&vam->json_tree);
11958
11959 vat_json_init_object (node);
Neale Ranns097fa662018-05-01 05:17:55 -070011960 vat_json_object_add_uint (node, "sw_if_index",
11961 ntohl (mp->mt_tunnel.mt_sw_if_index));
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011962
Neale Ranns097fa662018-05-01 05:17:55 -070011963 vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011964
Neale Ranns097fa662018-05-01 05:17:55 -070011965 fp = mp->mt_tunnel.mt_paths;
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011966 for (i = 0; i < count; i++)
Damjan Marion7cd468a2016-12-19 23:05:39 +010011967 {
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011968 vl_api_mpls_fib_path_json_print (node, fp);
11969 fp++;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011970 }
11971}
11972
11973static int
11974api_mpls_tunnel_dump (vat_main_t * vam)
11975{
11976 vl_api_mpls_tunnel_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011977 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011978 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011979
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011980 M (MPLS_TUNNEL_DUMP, mp);
Neale Ranns097fa662018-05-01 05:17:55 -070011981
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011982 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011983
11984 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040011985 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011986 S (mp_ping);
11987
Jon Loeliger56c7b012017-02-01 12:31:41 -060011988 W (ret);
11989 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011990}
11991
Neale Ranns097fa662018-05-01 05:17:55 -070011992#define vl_api_mpls_table_details_t_endian vl_noop_handler
11993#define vl_api_mpls_table_details_t_print vl_noop_handler
Damjan Marion7cd468a2016-12-19 23:05:39 +010011994
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011995
Damjan Marion7cd468a2016-12-19 23:05:39 +010011996static void
Neale Ranns097fa662018-05-01 05:17:55 -070011997vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010011998{
11999 vat_main_t *vam = &vat_main;
Neale Ranns097fa662018-05-01 05:17:55 -070012000
12001 print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
12002}
12003
12004static void vl_api_mpls_table_details_t_handler_json
12005 (vl_api_mpls_table_details_t * mp)
12006{
12007 vat_main_t *vam = &vat_main;
12008 vat_json_node_t *node = NULL;
12009
12010 if (VAT_JSON_ARRAY != vam->json_tree.type)
12011 {
12012 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12013 vat_json_init_array (&vam->json_tree);
12014 }
12015 node = vat_json_array_add (&vam->json_tree);
12016
12017 vat_json_init_object (node);
12018 vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
12019}
12020
12021static int
12022api_mpls_table_dump (vat_main_t * vam)
12023{
12024 vl_api_mpls_table_dump_t *mp;
12025 vl_api_control_ping_t *mp_ping;
12026 int ret;
12027
12028 M (MPLS_TABLE_DUMP, mp);
12029 S (mp);
12030
12031 /* Use a control ping for synchronization */
12032 MPING (CONTROL_PING, mp_ping);
12033 S (mp_ping);
12034
12035 W (ret);
12036 return ret;
12037}
12038
12039#define vl_api_mpls_route_details_t_endian vl_noop_handler
12040#define vl_api_mpls_route_details_t_print vl_noop_handler
12041
12042static void
12043vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
12044{
12045 vat_main_t *vam = &vat_main;
Dave Barach4bda2d92019-07-03 15:21:50 -040012046 int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
Neale Ranns31ed7442018-02-23 05:29:09 -080012047 vl_api_fib_path_t *fp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012048 int i;
12049
12050 print (vam->ofp,
12051 "table-id %d, label %u, ess_bit %u",
Neale Ranns097fa662018-05-01 05:17:55 -070012052 ntohl (mp->mr_route.mr_table_id),
12053 ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
12054 fp = mp->mr_route.mr_paths;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012055 for (i = 0; i < count; i++)
12056 {
Neale Ranns097fa662018-05-01 05:17:55 -070012057 vl_api_fib_path_print (vam, fp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012058 fp++;
12059 }
12060}
12061
Neale Ranns097fa662018-05-01 05:17:55 -070012062static void vl_api_mpls_route_details_t_handler_json
12063 (vl_api_mpls_route_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012064{
12065 vat_main_t *vam = &vat_main;
Dave Barach4bda2d92019-07-03 15:21:50 -040012066 int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012067 vat_json_node_t *node = NULL;
Neale Ranns31ed7442018-02-23 05:29:09 -080012068 vl_api_fib_path_t *fp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012069 int i;
12070
12071 if (VAT_JSON_ARRAY != vam->json_tree.type)
12072 {
12073 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12074 vat_json_init_array (&vam->json_tree);
12075 }
12076 node = vat_json_array_add (&vam->json_tree);
12077
12078 vat_json_init_object (node);
Neale Ranns097fa662018-05-01 05:17:55 -070012079 vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
12080 vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
12081 vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
Damjan Marion7cd468a2016-12-19 23:05:39 +010012082 vat_json_object_add_uint (node, "path_count", count);
Neale Ranns097fa662018-05-01 05:17:55 -070012083 fp = mp->mr_route.mr_paths;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012084 for (i = 0; i < count; i++)
12085 {
Neale Ranns0f26c5a2017-03-01 15:12:11 -080012086 vl_api_mpls_fib_path_json_print (node, fp);
12087 fp++;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012088 }
12089}
12090
12091static int
Neale Ranns097fa662018-05-01 05:17:55 -070012092api_mpls_route_dump (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012093{
Neale Ranns097fa662018-05-01 05:17:55 -070012094 unformat_input_t *input = vam->input;
12095 vl_api_mpls_route_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012096 vl_api_control_ping_t *mp_ping;
Neale Ranns097fa662018-05-01 05:17:55 -070012097 u32 table_id;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012098 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012099
Neale Ranns097fa662018-05-01 05:17:55 -070012100 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12101 {
12102 if (unformat (input, "table_id %d", &table_id))
12103 ;
12104 else
12105 break;
12106 }
12107 if (table_id == ~0)
12108 {
12109 errmsg ("missing table id");
12110 return -99;
12111 }
12112
12113 M (MPLS_ROUTE_DUMP, mp);
12114
12115 mp->table.mt_table_id = ntohl (table_id);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012116 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012117
12118 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040012119 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012120 S (mp_ping);
12121
Jon Loeliger56c7b012017-02-01 12:31:41 -060012122 W (ret);
12123 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012124}
12125
Neale Ranns097fa662018-05-01 05:17:55 -070012126#define vl_api_ip_table_details_t_endian vl_noop_handler
12127#define vl_api_ip_table_details_t_print vl_noop_handler
Damjan Marion7cd468a2016-12-19 23:05:39 +010012128
12129static void
Neale Ranns097fa662018-05-01 05:17:55 -070012130vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012131{
12132 vat_main_t *vam = &vat_main;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012133
12134 print (vam->ofp,
Neale Ranns097fa662018-05-01 05:17:55 -070012135 "%s; table-id %d, prefix %U/%d",
12136 mp->table.name, ntohl (mp->table.table_id));
Damjan Marion7cd468a2016-12-19 23:05:39 +010012137}
12138
Neale Ranns097fa662018-05-01 05:17:55 -070012139
12140static void vl_api_ip_table_details_t_handler_json
12141 (vl_api_ip_table_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012142{
12143 vat_main_t *vam = &vat_main;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012144 vat_json_node_t *node = NULL;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012145
12146 if (VAT_JSON_ARRAY != vam->json_tree.type)
12147 {
12148 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12149 vat_json_init_array (&vam->json_tree);
12150 }
12151 node = vat_json_array_add (&vam->json_tree);
12152
12153 vat_json_init_object (node);
Neale Ranns097fa662018-05-01 05:17:55 -070012154 vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
Damjan Marion7cd468a2016-12-19 23:05:39 +010012155}
12156
12157static int
Neale Ranns097fa662018-05-01 05:17:55 -070012158api_ip_table_dump (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012159{
Neale Ranns097fa662018-05-01 05:17:55 -070012160 vl_api_ip_table_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012161 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012162 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012163
Neale Ranns097fa662018-05-01 05:17:55 -070012164 M (IP_TABLE_DUMP, mp);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012165 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012166
12167 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040012168 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012169 S (mp_ping);
12170
Jon Loeliger56c7b012017-02-01 12:31:41 -060012171 W (ret);
12172 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012173}
12174
Neale Ranns5a8123b2017-01-26 01:18:23 -080012175static int
Neale Ranns097fa662018-05-01 05:17:55 -070012176api_ip_mtable_dump (vat_main_t * vam)
Neale Ranns5a8123b2017-01-26 01:18:23 -080012177{
Neale Ranns097fa662018-05-01 05:17:55 -070012178 vl_api_ip_mtable_dump_t *mp;
Neale Ranns5a8123b2017-01-26 01:18:23 -080012179 vl_api_control_ping_t *mp_ping;
12180 int ret;
12181
Neale Ranns097fa662018-05-01 05:17:55 -070012182 M (IP_MTABLE_DUMP, mp);
12183 S (mp);
12184
12185 /* Use a control ping for synchronization */
12186 MPING (CONTROL_PING, mp_ping);
12187 S (mp_ping);
12188
12189 W (ret);
12190 return ret;
12191}
12192
12193static int
12194api_ip_mroute_dump (vat_main_t * vam)
12195{
12196 unformat_input_t *input = vam->input;
12197 vl_api_control_ping_t *mp_ping;
12198 vl_api_ip_mroute_dump_t *mp;
12199 int ret, is_ip6;
12200 u32 table_id;
12201
12202 is_ip6 = 0;
12203 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12204 {
12205 if (unformat (input, "table_id %d", &table_id))
12206 ;
12207 else if (unformat (input, "ip6"))
12208 is_ip6 = 1;
12209 else if (unformat (input, "ip4"))
12210 is_ip6 = 0;
12211 else
12212 break;
12213 }
12214 if (table_id == ~0)
12215 {
12216 errmsg ("missing table id");
12217 return -99;
12218 }
12219
12220 M (IP_MROUTE_DUMP, mp);
12221 mp->table.table_id = table_id;
12222 mp->table.is_ip6 = is_ip6;
Neale Ranns5a8123b2017-01-26 01:18:23 -080012223 S (mp);
12224
12225 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040012226 MPING (CONTROL_PING, mp_ping);
Neale Ranns5a8123b2017-01-26 01:18:23 -080012227 S (mp_ping);
12228
12229 W (ret);
12230 return ret;
12231}
12232
Neale Ranns097fa662018-05-01 05:17:55 -070012233#define vl_api_ip_route_details_t_endian vl_noop_handler
12234#define vl_api_ip_route_details_t_print vl_noop_handler
Damjan Marion7cd468a2016-12-19 23:05:39 +010012235
12236static void
Neale Ranns097fa662018-05-01 05:17:55 -070012237vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012238{
12239 vat_main_t *vam = &vat_main;
Neale Ranns097fa662018-05-01 05:17:55 -070012240 u8 count = mp->route.n_paths;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012241 vl_api_fib_path_t *fp;
12242 int i;
12243
12244 print (vam->ofp,
Neale Ranns097fa662018-05-01 05:17:55 -070012245 "table-id %d, prefix %U/%d",
12246 ntohl (mp->route.table_id),
Paul Vinciguerraab055082019-06-06 14:07:55 -040012247 format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012248 for (i = 0; i < count; i++)
12249 {
Neale Ranns097fa662018-05-01 05:17:55 -070012250 fp = &mp->route.paths[i];
12251
12252 vl_api_fib_path_print (vam, fp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012253 fp++;
12254 }
12255}
12256
Neale Ranns097fa662018-05-01 05:17:55 -070012257static void vl_api_ip_route_details_t_handler_json
12258 (vl_api_ip_route_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012259{
12260 vat_main_t *vam = &vat_main;
Neale Ranns097fa662018-05-01 05:17:55 -070012261 u8 count = mp->route.n_paths;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012262 vat_json_node_t *node = NULL;
12263 struct in_addr ip4;
12264 struct in6_addr ip6;
12265 vl_api_fib_path_t *fp;
12266 int i;
12267
12268 if (VAT_JSON_ARRAY != vam->json_tree.type)
12269 {
12270 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12271 vat_json_init_array (&vam->json_tree);
12272 }
12273 node = vat_json_array_add (&vam->json_tree);
12274
12275 vat_json_init_object (node);
Neale Ranns097fa662018-05-01 05:17:55 -070012276 vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
12277 if (ADDRESS_IP6 == mp->route.prefix.address.af)
12278 {
12279 clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
12280 vat_json_object_add_ip6 (node, "prefix", ip6);
12281 }
12282 else
12283 {
12284 clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
12285 vat_json_object_add_ip4 (node, "prefix", ip4);
12286 }
Paul Vinciguerraab055082019-06-06 14:07:55 -040012287 vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012288 vat_json_object_add_uint (node, "path_count", count);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012289 for (i = 0; i < count; i++)
12290 {
Neale Ranns097fa662018-05-01 05:17:55 -070012291 fp = &mp->route.paths[i];
12292 vl_api_mpls_fib_path_json_print (node, fp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012293 }
12294}
12295
12296static int
Neale Ranns097fa662018-05-01 05:17:55 -070012297api_ip_route_dump (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012298{
Neale Ranns097fa662018-05-01 05:17:55 -070012299 unformat_input_t *input = vam->input;
12300 vl_api_ip_route_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012301 vl_api_control_ping_t *mp_ping;
Neale Ranns097fa662018-05-01 05:17:55 -070012302 u32 table_id;
12303 u8 is_ip6;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012304 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012305
Neale Ranns097fa662018-05-01 05:17:55 -070012306 is_ip6 = 0;
12307 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12308 {
12309 if (unformat (input, "table_id %d", &table_id))
12310 ;
12311 else if (unformat (input, "ip6"))
12312 is_ip6 = 1;
12313 else if (unformat (input, "ip4"))
12314 is_ip6 = 0;
12315 else
12316 break;
12317 }
12318 if (table_id == ~0)
12319 {
12320 errmsg ("missing table id");
12321 return -99;
12322 }
Damjan Marion7cd468a2016-12-19 23:05:39 +010012323
Neale Ranns097fa662018-05-01 05:17:55 -070012324 M (IP_ROUTE_DUMP, mp);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012325
Neale Ranns097fa662018-05-01 05:17:55 -070012326 mp->table.table_id = table_id;
12327 mp->table.is_ip6 = is_ip6;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012328
Neale Ranns5a8123b2017-01-26 01:18:23 -080012329 S (mp);
12330
12331 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040012332 MPING (CONTROL_PING, mp_ping);
Neale Ranns5a8123b2017-01-26 01:18:23 -080012333 S (mp_ping);
12334
12335 W (ret);
12336 return ret;
12337}
12338
Damjan Marion7cd468a2016-12-19 23:05:39 +010012339int
12340api_classify_table_ids (vat_main_t * vam)
12341{
12342 vl_api_classify_table_ids_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012343 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012344
12345 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012346 M (CLASSIFY_TABLE_IDS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012347 mp->context = 0;
12348
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012349 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012350 W (ret);
12351 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012352}
12353
12354int
12355api_classify_table_by_interface (vat_main_t * vam)
12356{
12357 unformat_input_t *input = vam->input;
12358 vl_api_classify_table_by_interface_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012359
12360 u32 sw_if_index = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012361 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012362 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12363 {
12364 if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12365 ;
12366 else if (unformat (input, "sw_if_index %d", &sw_if_index))
12367 ;
12368 else
12369 break;
12370 }
12371 if (sw_if_index == ~0)
12372 {
12373 errmsg ("missing interface name or sw_if_index");
12374 return -99;
12375 }
12376
12377 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012378 M (CLASSIFY_TABLE_BY_INTERFACE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012379 mp->context = 0;
12380 mp->sw_if_index = ntohl (sw_if_index);
12381
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012382 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012383 W (ret);
12384 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012385}
12386
12387int
12388api_classify_table_info (vat_main_t * vam)
12389{
12390 unformat_input_t *input = vam->input;
12391 vl_api_classify_table_info_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012392
12393 u32 table_id = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012394 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012395 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12396 {
12397 if (unformat (input, "table_id %d", &table_id))
12398 ;
12399 else
12400 break;
12401 }
12402 if (table_id == ~0)
12403 {
12404 errmsg ("missing table id");
12405 return -99;
12406 }
12407
12408 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012409 M (CLASSIFY_TABLE_INFO, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012410 mp->context = 0;
12411 mp->table_id = ntohl (table_id);
12412
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012413 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012414 W (ret);
12415 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012416}
12417
12418int
12419api_classify_session_dump (vat_main_t * vam)
12420{
12421 unformat_input_t *input = vam->input;
12422 vl_api_classify_session_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012423 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012424
12425 u32 table_id = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012426 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012427 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12428 {
12429 if (unformat (input, "table_id %d", &table_id))
12430 ;
12431 else
12432 break;
12433 }
12434 if (table_id == ~0)
12435 {
12436 errmsg ("missing table id");
12437 return -99;
12438 }
12439
12440 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012441 M (CLASSIFY_SESSION_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012442 mp->context = 0;
12443 mp->table_id = ntohl (table_id);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012444 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012445
12446 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040012447 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012448 S (mp_ping);
12449
Jon Loeliger56c7b012017-02-01 12:31:41 -060012450 W (ret);
12451 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012452}
12453
12454static void
12455vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
12456{
12457 vat_main_t *vam = &vat_main;
12458
12459 print (vam->ofp, "collector_address %U, collector_port %d, "
12460 "src_address %U, vrf_id %d, path_mtu %u, "
12461 "template_interval %u, udp_checksum %d",
12462 format_ip4_address, mp->collector_address,
12463 ntohs (mp->collector_port),
12464 format_ip4_address, mp->src_address,
12465 ntohl (mp->vrf_id), ntohl (mp->path_mtu),
12466 ntohl (mp->template_interval), mp->udp_checksum);
12467
12468 vam->retval = 0;
12469 vam->result_ready = 1;
12470}
12471
12472static void
12473 vl_api_ipfix_exporter_details_t_handler_json
12474 (vl_api_ipfix_exporter_details_t * mp)
12475{
12476 vat_main_t *vam = &vat_main;
12477 vat_json_node_t node;
12478 struct in_addr collector_address;
12479 struct in_addr src_address;
12480
12481 vat_json_init_object (&node);
12482 clib_memcpy (&collector_address, &mp->collector_address,
12483 sizeof (collector_address));
12484 vat_json_object_add_ip4 (&node, "collector_address", collector_address);
12485 vat_json_object_add_uint (&node, "collector_port",
12486 ntohs (mp->collector_port));
12487 clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
12488 vat_json_object_add_ip4 (&node, "src_address", src_address);
12489 vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
12490 vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
12491 vat_json_object_add_uint (&node, "template_interval",
12492 ntohl (mp->template_interval));
12493 vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
12494
12495 vat_json_print (vam->ofp, &node);
12496 vat_json_free (&node);
12497 vam->retval = 0;
12498 vam->result_ready = 1;
12499}
12500
12501int
12502api_ipfix_exporter_dump (vat_main_t * vam)
12503{
12504 vl_api_ipfix_exporter_dump_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012505 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012506
12507 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012508 M (IPFIX_EXPORTER_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012509 mp->context = 0;
12510
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012511 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012512 W (ret);
12513 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012514}
12515
12516static int
12517api_ipfix_classify_stream_dump (vat_main_t * vam)
12518{
12519 vl_api_ipfix_classify_stream_dump_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012520 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012521
12522 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012523 M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012524 mp->context = 0;
12525
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012526 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012527 W (ret);
12528 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012529 /* NOTREACHED */
12530 return 0;
12531}
12532
12533static void
12534 vl_api_ipfix_classify_stream_details_t_handler
12535 (vl_api_ipfix_classify_stream_details_t * mp)
12536{
12537 vat_main_t *vam = &vat_main;
12538 print (vam->ofp, "domain_id %d, src_port %d",
12539 ntohl (mp->domain_id), ntohs (mp->src_port));
12540 vam->retval = 0;
12541 vam->result_ready = 1;
12542}
12543
12544static void
12545 vl_api_ipfix_classify_stream_details_t_handler_json
12546 (vl_api_ipfix_classify_stream_details_t * mp)
12547{
12548 vat_main_t *vam = &vat_main;
12549 vat_json_node_t node;
12550
12551 vat_json_init_object (&node);
12552 vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
12553 vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
12554
12555 vat_json_print (vam->ofp, &node);
12556 vat_json_free (&node);
12557 vam->retval = 0;
12558 vam->result_ready = 1;
12559}
12560
12561static int
12562api_ipfix_classify_table_dump (vat_main_t * vam)
12563{
12564 vl_api_ipfix_classify_table_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012565 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012566 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012567
12568 if (!vam->json_output)
12569 {
12570 print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
12571 "transport_protocol");
12572 }
12573
12574 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012575 M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012576
12577 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012578 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012579
12580 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040012581 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012582 S (mp_ping);
12583
Jon Loeliger56c7b012017-02-01 12:31:41 -060012584 W (ret);
12585 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012586}
12587
12588static void
12589 vl_api_ipfix_classify_table_details_t_handler
12590 (vl_api_ipfix_classify_table_details_t * mp)
12591{
12592 vat_main_t *vam = &vat_main;
12593 print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
12594 mp->transport_protocol);
12595}
12596
12597static void
12598 vl_api_ipfix_classify_table_details_t_handler_json
12599 (vl_api_ipfix_classify_table_details_t * mp)
12600{
12601 vat_json_node_t *node = NULL;
12602 vat_main_t *vam = &vat_main;
12603
12604 if (VAT_JSON_ARRAY != vam->json_tree.type)
12605 {
12606 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12607 vat_json_init_array (&vam->json_tree);
12608 }
12609
12610 node = vat_json_array_add (&vam->json_tree);
12611 vat_json_init_object (node);
12612
12613 vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
12614 vat_json_object_add_uint (node, "ip_version", mp->ip_version);
12615 vat_json_object_add_uint (node, "transport_protocol",
12616 mp->transport_protocol);
12617}
12618
12619static int
12620api_sw_interface_span_enable_disable (vat_main_t * vam)
12621{
12622 unformat_input_t *i = vam->input;
12623 vl_api_sw_interface_span_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012624 u32 src_sw_if_index = ~0;
12625 u32 dst_sw_if_index = ~0;
12626 u8 state = 3;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012627 int ret;
Eyal Bari001fd402017-07-16 09:34:53 +030012628 u8 is_l2 = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012629
12630 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12631 {
12632 if (unformat
12633 (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
12634 ;
12635 else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
12636 ;
12637 else
12638 if (unformat
12639 (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
12640 ;
12641 else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
12642 ;
12643 else if (unformat (i, "disable"))
12644 state = 0;
12645 else if (unformat (i, "rx"))
12646 state = 1;
12647 else if (unformat (i, "tx"))
12648 state = 2;
12649 else if (unformat (i, "both"))
12650 state = 3;
Eyal Bari001fd402017-07-16 09:34:53 +030012651 else if (unformat (i, "l2"))
12652 is_l2 = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012653 else
12654 break;
12655 }
12656
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012657 M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012658
12659 mp->sw_if_index_from = htonl (src_sw_if_index);
12660 mp->sw_if_index_to = htonl (dst_sw_if_index);
12661 mp->state = state;
Eyal Bari001fd402017-07-16 09:34:53 +030012662 mp->is_l2 = is_l2;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012663
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012664 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012665 W (ret);
12666 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012667}
12668
12669static void
12670vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
12671 * mp)
12672{
12673 vat_main_t *vam = &vat_main;
12674 u8 *sw_if_from_name = 0;
12675 u8 *sw_if_to_name = 0;
12676 u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
12677 u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
12678 char *states[] = { "none", "rx", "tx", "both" };
12679 hash_pair_t *p;
12680
12681 /* *INDENT-OFF* */
12682 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
12683 ({
12684 if ((u32) p->value[0] == sw_if_index_from)
12685 {
12686 sw_if_from_name = (u8 *)(p->key);
12687 if (sw_if_to_name)
12688 break;
12689 }
12690 if ((u32) p->value[0] == sw_if_index_to)
12691 {
12692 sw_if_to_name = (u8 *)(p->key);
12693 if (sw_if_from_name)
12694 break;
12695 }
12696 }));
12697 /* *INDENT-ON* */
Jon Loeliger179ab362018-03-12 14:50:08 -050012698 print (vam->ofp, "%20s => %20s (%s) %s",
12699 sw_if_from_name, sw_if_to_name, states[mp->state],
12700 mp->is_l2 ? "l2" : "device");
Damjan Marion7cd468a2016-12-19 23:05:39 +010012701}
12702
12703static void
12704 vl_api_sw_interface_span_details_t_handler_json
12705 (vl_api_sw_interface_span_details_t * mp)
12706{
12707 vat_main_t *vam = &vat_main;
12708 vat_json_node_t *node = NULL;
12709 u8 *sw_if_from_name = 0;
12710 u8 *sw_if_to_name = 0;
12711 u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
12712 u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
12713 hash_pair_t *p;
12714
12715 /* *INDENT-OFF* */
12716 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
12717 ({
12718 if ((u32) p->value[0] == sw_if_index_from)
12719 {
12720 sw_if_from_name = (u8 *)(p->key);
12721 if (sw_if_to_name)
12722 break;
12723 }
12724 if ((u32) p->value[0] == sw_if_index_to)
12725 {
12726 sw_if_to_name = (u8 *)(p->key);
12727 if (sw_if_from_name)
12728 break;
12729 }
12730 }));
12731 /* *INDENT-ON* */
12732
12733 if (VAT_JSON_ARRAY != vam->json_tree.type)
12734 {
12735 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12736 vat_json_init_array (&vam->json_tree);
12737 }
12738 node = vat_json_array_add (&vam->json_tree);
12739
12740 vat_json_init_object (node);
12741 vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
12742 vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
12743 vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
Neale Ranns05b2bf22017-01-30 06:44:58 -080012744 if (0 != sw_if_to_name)
12745 {
12746 vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
12747 }
Damjan Marion7cd468a2016-12-19 23:05:39 +010012748 vat_json_object_add_uint (node, "state", mp->state);
Jon Loeliger179ab362018-03-12 14:50:08 -050012749 vat_json_object_add_uint (node, "is-l2", mp->is_l2);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012750}
12751
12752static int
12753api_sw_interface_span_dump (vat_main_t * vam)
12754{
Eyal Bari5b311202017-07-31 13:12:30 +030012755 unformat_input_t *input = vam->input;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012756 vl_api_sw_interface_span_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012757 vl_api_control_ping_t *mp_ping;
Eyal Bari5b311202017-07-31 13:12:30 +030012758 u8 is_l2 = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012759 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012760
Eyal Bari5b311202017-07-31 13:12:30 +030012761 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12762 {
12763 if (unformat (input, "l2"))
12764 is_l2 = 1;
12765 else
12766 break;
12767 }
12768
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012769 M (SW_INTERFACE_SPAN_DUMP, mp);
Eyal Bari5b311202017-07-31 13:12:30 +030012770 mp->is_l2 = is_l2;
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012771 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012772
12773 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040012774 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012775 S (mp_ping);
12776
Jon Loeliger56c7b012017-02-01 12:31:41 -060012777 W (ret);
12778 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012779}
12780
12781int
12782api_pg_create_interface (vat_main_t * vam)
12783{
12784 unformat_input_t *input = vam->input;
12785 vl_api_pg_create_interface_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012786
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +020012787 u32 if_id = ~0, gso_size = 0;
12788 u8 gso_enabled = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012789 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012790 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12791 {
12792 if (unformat (input, "if_id %d", &if_id))
12793 ;
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +020012794 else if (unformat (input, "gso-enabled"))
12795 {
12796 gso_enabled = 1;
12797 if (unformat (input, "gso-size %u", &gso_size))
12798 ;
12799 else
12800 {
12801 errmsg ("missing gso-size");
12802 return -99;
12803 }
12804 }
Damjan Marion7cd468a2016-12-19 23:05:39 +010012805 else
12806 break;
12807 }
12808 if (if_id == ~0)
12809 {
12810 errmsg ("missing pg interface index");
12811 return -99;
12812 }
12813
12814 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012815 M (PG_CREATE_INTERFACE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012816 mp->context = 0;
12817 mp->interface_id = ntohl (if_id);
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +020012818 mp->gso_enabled = gso_enabled;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012819
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012820 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012821 W (ret);
12822 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012823}
12824
12825int
12826api_pg_capture (vat_main_t * vam)
12827{
12828 unformat_input_t *input = vam->input;
12829 vl_api_pg_capture_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012830
12831 u32 if_id = ~0;
12832 u8 enable = 1;
12833 u32 count = 1;
12834 u8 pcap_file_set = 0;
12835 u8 *pcap_file = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012836 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012837 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12838 {
12839 if (unformat (input, "if_id %d", &if_id))
12840 ;
12841 else if (unformat (input, "pcap %s", &pcap_file))
12842 pcap_file_set = 1;
12843 else if (unformat (input, "count %d", &count))
12844 ;
12845 else if (unformat (input, "disable"))
12846 enable = 0;
12847 else
12848 break;
12849 }
12850 if (if_id == ~0)
12851 {
12852 errmsg ("missing pg interface index");
12853 return -99;
12854 }
12855 if (pcap_file_set > 0)
12856 {
12857 if (vec_len (pcap_file) > 255)
12858 {
12859 errmsg ("pcap file name is too long");
12860 return -99;
12861 }
12862 }
12863
Damjan Marion7cd468a2016-12-19 23:05:39 +010012864 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012865 M (PG_CAPTURE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012866 mp->context = 0;
12867 mp->interface_id = ntohl (if_id);
12868 mp->is_enabled = enable;
12869 mp->count = ntohl (count);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012870 if (pcap_file_set != 0)
12871 {
Jakub Grajciardb863292020-01-30 14:14:15 +010012872 vl_api_vec_to_api_string (pcap_file, &mp->pcap_file_name);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012873 }
12874 vec_free (pcap_file);
12875
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012876 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012877 W (ret);
12878 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012879}
12880
12881int
12882api_pg_enable_disable (vat_main_t * vam)
12883{
12884 unformat_input_t *input = vam->input;
12885 vl_api_pg_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012886
12887 u8 enable = 1;
12888 u8 stream_name_set = 0;
12889 u8 *stream_name = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012890 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012891 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12892 {
12893 if (unformat (input, "stream %s", &stream_name))
12894 stream_name_set = 1;
12895 else if (unformat (input, "disable"))
12896 enable = 0;
12897 else
12898 break;
12899 }
12900
12901 if (stream_name_set > 0)
12902 {
12903 if (vec_len (stream_name) > 255)
12904 {
12905 errmsg ("stream name too long");
12906 return -99;
12907 }
12908 }
12909
Damjan Marion7cd468a2016-12-19 23:05:39 +010012910 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012911 M (PG_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012912 mp->context = 0;
12913 mp->is_enabled = enable;
12914 if (stream_name_set != 0)
12915 {
Jakub Grajciardb863292020-01-30 14:14:15 +010012916 vl_api_vec_to_api_string (stream_name, &mp->stream_name);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012917 }
12918 vec_free (stream_name);
12919
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012920 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012921 W (ret);
12922 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012923}
12924
12925int
Mohsin Kazmif382b062020-08-11 15:00:44 +020012926api_pg_interface_enable_disable_coalesce (vat_main_t * vam)
12927{
12928 unformat_input_t *input = vam->input;
12929 vl_api_pg_interface_enable_disable_coalesce_t *mp;
12930
12931 u32 sw_if_index = ~0;
12932 u8 enable = 1;
12933 int ret;
12934 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12935 {
12936 if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12937 ;
12938 else if (unformat (input, "sw_if_index %d", &sw_if_index))
12939 ;
12940 else if (unformat (input, "disable"))
12941 enable = 0;
12942 else
12943 break;
12944 }
12945
12946 if (sw_if_index == ~0)
12947 {
12948 errmsg ("Interface required but not specified");
12949 return -99;
12950 }
12951
12952 /* Construct the API message */
12953 M (PG_INTERFACE_ENABLE_DISABLE_COALESCE, mp);
12954 mp->context = 0;
12955 mp->coalesce_enabled = enable;
12956 mp->sw_if_index = htonl (sw_if_index);
12957
12958 S (mp);
12959 W (ret);
12960 return ret;
12961}
12962
12963int
Damjan Marion7cd468a2016-12-19 23:05:39 +010012964api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
12965{
12966 unformat_input_t *input = vam->input;
12967 vl_api_ip_source_and_port_range_check_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012968
12969 u16 *low_ports = 0;
12970 u16 *high_ports = 0;
12971 u16 this_low;
12972 u16 this_hi;
Neale Ranns37029302018-08-10 05:30:06 -070012973 vl_api_prefix_t prefix;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012974 u32 tmp, tmp2;
12975 u8 prefix_set = 0;
12976 u32 vrf_id = ~0;
12977 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012978 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012979
12980 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12981 {
Neale Ranns37029302018-08-10 05:30:06 -070012982 if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
12983 prefix_set = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012984 else if (unformat (input, "vrf %d", &vrf_id))
12985 ;
12986 else if (unformat (input, "del"))
12987 is_add = 0;
12988 else if (unformat (input, "port %d", &tmp))
12989 {
12990 if (tmp == 0 || tmp > 65535)
12991 {
12992 errmsg ("port %d out of range", tmp);
12993 return -99;
12994 }
12995 this_low = tmp;
12996 this_hi = this_low + 1;
12997 vec_add1 (low_ports, this_low);
12998 vec_add1 (high_ports, this_hi);
12999 }
13000 else if (unformat (input, "range %d - %d", &tmp, &tmp2))
13001 {
13002 if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
13003 {
13004 errmsg ("incorrect range parameters");
13005 return -99;
13006 }
13007 this_low = tmp;
13008 /* Note: in debug CLI +1 is added to high before
13009 passing to real fn that does "the work"
13010 (ip_source_and_port_range_check_add_del).
13011 This fn is a wrapper around the binary API fn a
13012 control plane will call, which expects this increment
13013 to have occurred. Hence letting the binary API control
13014 plane fn do the increment for consistency between VAT
13015 and other control planes.
13016 */
13017 this_hi = tmp2;
13018 vec_add1 (low_ports, this_low);
13019 vec_add1 (high_ports, this_hi);
13020 }
13021 else
13022 break;
13023 }
13024
13025 if (prefix_set == 0)
13026 {
13027 errmsg ("<address>/<mask> not specified");
13028 return -99;
13029 }
13030
13031 if (vrf_id == ~0)
13032 {
13033 errmsg ("VRF ID required, not specified");
13034 return -99;
13035 }
13036
13037 if (vrf_id == 0)
13038 {
13039 errmsg
13040 ("VRF ID should not be default. Should be distinct VRF for this purpose.");
13041 return -99;
13042 }
13043
13044 if (vec_len (low_ports) == 0)
13045 {
13046 errmsg ("At least one port or port range required");
13047 return -99;
13048 }
13049
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013050 M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013051
13052 mp->is_add = is_add;
13053
Neale Ranns37029302018-08-10 05:30:06 -070013054 clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
Damjan Marion7cd468a2016-12-19 23:05:39 +010013055
Damjan Marion7cd468a2016-12-19 23:05:39 +010013056 mp->number_of_ranges = vec_len (low_ports);
13057
13058 clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
13059 vec_free (low_ports);
13060
13061 clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
13062 vec_free (high_ports);
13063
13064 mp->vrf_id = ntohl (vrf_id);
13065
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013066 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013067 W (ret);
13068 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013069}
13070
13071int
13072api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
13073{
13074 unformat_input_t *input = vam->input;
13075 vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013076 u32 sw_if_index = ~0;
13077 int vrf_set = 0;
13078 u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
13079 u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
13080 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013081 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013082
13083 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13084 {
13085 if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13086 ;
13087 else if (unformat (input, "sw_if_index %d", &sw_if_index))
13088 ;
13089 else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
13090 vrf_set = 1;
13091 else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
13092 vrf_set = 1;
13093 else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
13094 vrf_set = 1;
13095 else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
13096 vrf_set = 1;
13097 else if (unformat (input, "del"))
13098 is_add = 0;
13099 else
13100 break;
13101 }
13102
13103 if (sw_if_index == ~0)
13104 {
13105 errmsg ("Interface required but not specified");
13106 return -99;
13107 }
13108
13109 if (vrf_set == 0)
13110 {
13111 errmsg ("VRF ID required but not specified");
13112 return -99;
13113 }
13114
13115 if (tcp_out_vrf_id == 0
13116 || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
13117 {
13118 errmsg
13119 ("VRF ID should not be default. Should be distinct VRF for this purpose.");
13120 return -99;
13121 }
13122
13123 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013124 M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013125
13126 mp->sw_if_index = ntohl (sw_if_index);
13127 mp->is_add = is_add;
13128 mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
13129 mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
13130 mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
13131 mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
13132
13133 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013134 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013135
13136 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060013137 W (ret);
13138 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013139}
13140
13141static int
Pavel Kotuceke88865d2018-11-28 07:42:11 +010013142api_set_punt (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010013143{
13144 unformat_input_t *i = vam->input;
Neale Ranns50f0ac02019-05-15 02:13:37 -070013145 vl_api_address_family_t af;
Pavel Kotuceke88865d2018-11-28 07:42:11 +010013146 vl_api_set_punt_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013147 u32 protocol = ~0;
13148 u32 port = ~0;
13149 int is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013150 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013151
13152 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13153 {
Neale Ranns50f0ac02019-05-15 02:13:37 -070013154 if (unformat (i, "%U", unformat_vl_api_address_family, &af))
Damjan Marion7cd468a2016-12-19 23:05:39 +010013155 ;
13156 else if (unformat (i, "protocol %d", &protocol))
13157 ;
13158 else if (unformat (i, "port %d", &port))
13159 ;
13160 else if (unformat (i, "del"))
13161 is_add = 0;
13162 else
13163 {
13164 clib_warning ("parse error '%U'", format_unformat_error, i);
13165 return -99;
13166 }
13167 }
13168
Pavel Kotuceke88865d2018-11-28 07:42:11 +010013169 M (SET_PUNT, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013170
13171 mp->is_add = (u8) is_add;
Neale Ranns50f0ac02019-05-15 02:13:37 -070013172 mp->punt.type = PUNT_API_TYPE_L4;
13173 mp->punt.punt.l4.af = af;
13174 mp->punt.punt.l4.protocol = (u8) protocol;
13175 mp->punt.punt.l4.port = htons ((u16) port);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013176
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013177 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013178 W (ret);
13179 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013180}
13181
Damjan Marion7cd468a2016-12-19 23:05:39 +010013182static int
13183api_delete_subif (vat_main_t * vam)
13184{
13185 unformat_input_t *i = vam->input;
13186 vl_api_delete_subif_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013187 u32 sw_if_index = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013188 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013189
13190 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13191 {
13192 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13193 ;
13194 if (unformat (i, "sw_if_index %d", &sw_if_index))
13195 ;
13196 else
13197 break;
13198 }
13199
13200 if (sw_if_index == ~0)
13201 {
13202 errmsg ("missing sw_if_index");
13203 return -99;
13204 }
13205
13206 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013207 M (DELETE_SUBIF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013208 mp->sw_if_index = ntohl (sw_if_index);
13209
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013210 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013211 W (ret);
13212 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013213}
13214
13215#define foreach_pbb_vtr_op \
13216_("disable", L2_VTR_DISABLED) \
13217_("pop", L2_VTR_POP_2) \
13218_("push", L2_VTR_PUSH_2)
13219
13220static int
13221api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
13222{
13223 unformat_input_t *i = vam->input;
13224 vl_api_l2_interface_pbb_tag_rewrite_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013225 u32 sw_if_index = ~0, vtr_op = ~0;
13226 u16 outer_tag = ~0;
13227 u8 dmac[6], smac[6];
13228 u8 dmac_set = 0, smac_set = 0;
13229 u16 vlanid = 0;
13230 u32 sid = ~0;
13231 u32 tmp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013232 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013233
13234 /* Shut up coverity */
Dave Barachb7b92992018-10-17 10:38:51 -040013235 clib_memset (dmac, 0, sizeof (dmac));
13236 clib_memset (smac, 0, sizeof (smac));
Damjan Marion7cd468a2016-12-19 23:05:39 +010013237
13238 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13239 {
13240 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13241 ;
13242 else if (unformat (i, "sw_if_index %d", &sw_if_index))
13243 ;
13244 else if (unformat (i, "vtr_op %d", &vtr_op))
13245 ;
13246#define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
13247 foreach_pbb_vtr_op
13248#undef _
13249 else if (unformat (i, "translate_pbb_stag"))
13250 {
13251 if (unformat (i, "%d", &tmp))
13252 {
13253 vtr_op = L2_VTR_TRANSLATE_2_1;
13254 outer_tag = tmp;
13255 }
13256 else
13257 {
13258 errmsg
13259 ("translate_pbb_stag operation requires outer tag definition");
13260 return -99;
13261 }
13262 }
13263 else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
13264 dmac_set++;
13265 else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
13266 smac_set++;
13267 else if (unformat (i, "sid %d", &sid))
13268 ;
13269 else if (unformat (i, "vlanid %d", &tmp))
13270 vlanid = tmp;
13271 else
13272 {
13273 clib_warning ("parse error '%U'", format_unformat_error, i);
13274 return -99;
13275 }
13276 }
13277
13278 if ((sw_if_index == ~0) || (vtr_op == ~0))
13279 {
13280 errmsg ("missing sw_if_index or vtr operation");
13281 return -99;
13282 }
13283 if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
13284 && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
13285 {
13286 errmsg
13287 ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
13288 return -99;
13289 }
13290
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013291 M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013292 mp->sw_if_index = ntohl (sw_if_index);
13293 mp->vtr_op = ntohl (vtr_op);
13294 mp->outer_tag = ntohs (outer_tag);
13295 clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
13296 clib_memcpy (mp->b_smac, smac, sizeof (smac));
13297 mp->b_vlanid = ntohs (vlanid);
13298 mp->i_sid = ntohl (sid);
13299
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013300 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013301 W (ret);
13302 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013303}
13304
13305static int
13306api_flow_classify_set_interface (vat_main_t * vam)
13307{
13308 unformat_input_t *i = vam->input;
13309 vl_api_flow_classify_set_interface_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013310 u32 sw_if_index;
13311 int sw_if_index_set;
13312 u32 ip4_table_index = ~0;
13313 u32 ip6_table_index = ~0;
13314 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013315 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013316
13317 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13318 {
13319 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13320 sw_if_index_set = 1;
13321 else if (unformat (i, "sw_if_index %d", &sw_if_index))
13322 sw_if_index_set = 1;
13323 else if (unformat (i, "del"))
13324 is_add = 0;
13325 else if (unformat (i, "ip4-table %d", &ip4_table_index))
13326 ;
13327 else if (unformat (i, "ip6-table %d", &ip6_table_index))
13328 ;
13329 else
13330 {
13331 clib_warning ("parse error '%U'", format_unformat_error, i);
13332 return -99;
13333 }
13334 }
13335
13336 if (sw_if_index_set == 0)
13337 {
13338 errmsg ("missing interface name or sw_if_index");
13339 return -99;
13340 }
13341
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013342 M (FLOW_CLASSIFY_SET_INTERFACE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013343
13344 mp->sw_if_index = ntohl (sw_if_index);
13345 mp->ip4_table_index = ntohl (ip4_table_index);
13346 mp->ip6_table_index = ntohl (ip6_table_index);
13347 mp->is_add = is_add;
13348
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013349 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013350 W (ret);
13351 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013352}
13353
13354static int
13355api_flow_classify_dump (vat_main_t * vam)
13356{
13357 unformat_input_t *i = vam->input;
13358 vl_api_flow_classify_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060013359 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013360 u8 type = FLOW_CLASSIFY_N_TABLES;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013361 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013362
13363 if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
13364 ;
13365 else
13366 {
13367 errmsg ("classify table type must be specified");
13368 return -99;
13369 }
13370
13371 if (!vam->json_output)
13372 {
13373 print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
13374 }
13375
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013376 M (FLOW_CLASSIFY_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013377 mp->type = type;
13378 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013379 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013380
13381 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040013382 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060013383 S (mp_ping);
13384
Damjan Marion7cd468a2016-12-19 23:05:39 +010013385 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060013386 W (ret);
13387 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013388}
13389
13390static int
13391api_feature_enable_disable (vat_main_t * vam)
13392{
13393 unformat_input_t *i = vam->input;
13394 vl_api_feature_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013395 u8 *arc_name = 0;
13396 u8 *feature_name = 0;
13397 u32 sw_if_index = ~0;
13398 u8 enable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013399 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013400
13401 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13402 {
13403 if (unformat (i, "arc_name %s", &arc_name))
13404 ;
13405 else if (unformat (i, "feature_name %s", &feature_name))
13406 ;
13407 else
13408 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13409 ;
13410 else if (unformat (i, "sw_if_index %d", &sw_if_index))
13411 ;
13412 else if (unformat (i, "disable"))
13413 enable = 0;
13414 else
13415 break;
13416 }
13417
13418 if (arc_name == 0)
13419 {
13420 errmsg ("missing arc name");
13421 return -99;
13422 }
13423 if (vec_len (arc_name) > 63)
13424 {
13425 errmsg ("arc name too long");
13426 }
13427
13428 if (feature_name == 0)
13429 {
13430 errmsg ("missing feature name");
13431 return -99;
13432 }
13433 if (vec_len (feature_name) > 63)
13434 {
13435 errmsg ("feature name too long");
13436 }
13437
13438 if (sw_if_index == ~0)
13439 {
13440 errmsg ("missing interface name or sw_if_index");
13441 return -99;
13442 }
13443
13444 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013445 M (FEATURE_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013446 mp->sw_if_index = ntohl (sw_if_index);
13447 mp->enable = enable;
13448 clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
13449 clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
13450 vec_free (arc_name);
13451 vec_free (feature_name);
13452
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013453 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013454 W (ret);
13455 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013456}
13457
13458static int
Mohsin Kazmi29467b52019-10-08 19:42:38 +020013459api_feature_gso_enable_disable (vat_main_t * vam)
13460{
13461 unformat_input_t *i = vam->input;
13462 vl_api_feature_gso_enable_disable_t *mp;
13463 u32 sw_if_index = ~0;
13464 u8 enable = 1;
13465 int ret;
13466
13467 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13468 {
13469 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13470 ;
13471 else if (unformat (i, "sw_if_index %d", &sw_if_index))
13472 ;
13473 else if (unformat (i, "enable"))
13474 enable = 1;
13475 else if (unformat (i, "disable"))
13476 enable = 0;
13477 else
13478 break;
13479 }
13480
13481 if (sw_if_index == ~0)
13482 {
13483 errmsg ("missing interface name or sw_if_index");
13484 return -99;
13485 }
13486
13487 /* Construct the API message */
13488 M (FEATURE_GSO_ENABLE_DISABLE, mp);
13489 mp->sw_if_index = ntohl (sw_if_index);
13490 mp->enable_disable = enable;
13491
13492 S (mp);
13493 W (ret);
13494 return ret;
13495}
13496
13497static int
Damjan Marion7cd468a2016-12-19 23:05:39 +010013498api_sw_interface_tag_add_del (vat_main_t * vam)
13499{
13500 unformat_input_t *i = vam->input;
13501 vl_api_sw_interface_tag_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013502 u32 sw_if_index = ~0;
13503 u8 *tag = 0;
13504 u8 enable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013505 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013506
13507 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13508 {
13509 if (unformat (i, "tag %s", &tag))
13510 ;
13511 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13512 ;
13513 else if (unformat (i, "sw_if_index %d", &sw_if_index))
13514 ;
13515 else if (unformat (i, "del"))
13516 enable = 0;
13517 else
13518 break;
13519 }
13520
13521 if (sw_if_index == ~0)
13522 {
13523 errmsg ("missing interface name or sw_if_index");
13524 return -99;
13525 }
13526
13527 if (enable && (tag == 0))
13528 {
13529 errmsg ("no tag specified");
13530 return -99;
13531 }
13532
13533 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013534 M (SW_INTERFACE_TAG_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013535 mp->sw_if_index = ntohl (sw_if_index);
13536 mp->is_add = enable;
13537 if (enable)
Ole Troane5ff5a32019-08-23 22:55:18 +020013538 strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013539 vec_free (tag);
13540
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013541 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013542 W (ret);
13543 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013544}
13545
Matthew Smithe0792fd2019-07-12 11:48:24 -050013546static int
13547api_sw_interface_add_del_mac_address (vat_main_t * vam)
13548{
13549 unformat_input_t *i = vam->input;
13550 vl_api_mac_address_t mac = { 0 };
13551 vl_api_sw_interface_add_del_mac_address_t *mp;
13552 u32 sw_if_index = ~0;
13553 u8 is_add = 1;
13554 u8 mac_set = 0;
13555 int ret;
13556
13557 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13558 {
13559 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13560 ;
13561 else if (unformat (i, "sw_if_index %d", &sw_if_index))
13562 ;
13563 else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
13564 mac_set++;
13565 else if (unformat (i, "del"))
13566 is_add = 0;
13567 else
13568 break;
13569 }
13570
13571 if (sw_if_index == ~0)
13572 {
13573 errmsg ("missing interface name or sw_if_index");
13574 return -99;
13575 }
13576
13577 if (!mac_set)
13578 {
13579 errmsg ("missing MAC address");
13580 return -99;
13581 }
13582
13583 /* Construct the API message */
13584 M (SW_INTERFACE_ADD_DEL_MAC_ADDRESS, mp);
13585 mp->sw_if_index = ntohl (sw_if_index);
13586 mp->is_add = is_add;
13587 clib_memcpy (&mp->addr, &mac, sizeof (mac));
13588
13589 S (mp);
13590 W (ret);
13591 return ret;
13592}
13593
Damjan Marion7cd468a2016-12-19 23:05:39 +010013594static void vl_api_l2_xconnect_details_t_handler
13595 (vl_api_l2_xconnect_details_t * mp)
13596{
13597 vat_main_t *vam = &vat_main;
13598
13599 print (vam->ofp, "%15d%15d",
13600 ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
13601}
13602
13603static void vl_api_l2_xconnect_details_t_handler_json
13604 (vl_api_l2_xconnect_details_t * mp)
13605{
13606 vat_main_t *vam = &vat_main;
13607 vat_json_node_t *node = NULL;
13608
13609 if (VAT_JSON_ARRAY != vam->json_tree.type)
13610 {
13611 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13612 vat_json_init_array (&vam->json_tree);
13613 }
13614 node = vat_json_array_add (&vam->json_tree);
13615
13616 vat_json_init_object (node);
13617 vat_json_object_add_uint (node, "rx_sw_if_index",
13618 ntohl (mp->rx_sw_if_index));
13619 vat_json_object_add_uint (node, "tx_sw_if_index",
13620 ntohl (mp->tx_sw_if_index));
13621}
13622
13623static int
13624api_l2_xconnect_dump (vat_main_t * vam)
13625{
13626 vl_api_l2_xconnect_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060013627 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013628 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013629
13630 if (!vam->json_output)
13631 {
13632 print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
13633 }
13634
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013635 M (L2_XCONNECT_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013636
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013637 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013638
13639 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040013640 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060013641 S (mp_ping);
13642
Jon Loeliger56c7b012017-02-01 12:31:41 -060013643 W (ret);
13644 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013645}
13646
13647static int
Ole Troand7231612018-06-07 10:17:57 +020013648api_hw_interface_set_mtu (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010013649{
13650 unformat_input_t *i = vam->input;
Ole Troand7231612018-06-07 10:17:57 +020013651 vl_api_hw_interface_set_mtu_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013652 u32 sw_if_index = ~0;
13653 u32 mtu = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013654 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013655
13656 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13657 {
13658 if (unformat (i, "mtu %d", &mtu))
13659 ;
13660 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13661 ;
13662 else if (unformat (i, "sw_if_index %d", &sw_if_index))
13663 ;
13664 else
13665 break;
13666 }
13667
13668 if (sw_if_index == ~0)
13669 {
13670 errmsg ("missing interface name or sw_if_index");
13671 return -99;
13672 }
13673
13674 if (mtu == 0)
13675 {
13676 errmsg ("no mtu specified");
13677 return -99;
13678 }
13679
13680 /* Construct the API message */
Ole Troand7231612018-06-07 10:17:57 +020013681 M (HW_INTERFACE_SET_MTU, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013682 mp->sw_if_index = ntohl (sw_if_index);
13683 mp->mtu = ntohs ((u16) mtu);
13684
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013685 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013686 W (ret);
13687 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013688}
13689
Pavel Kotucek6899a302017-06-08 08:46:10 +020013690static int
13691api_p2p_ethernet_add (vat_main_t * vam)
13692{
13693 unformat_input_t *i = vam->input;
13694 vl_api_p2p_ethernet_add_t *mp;
13695 u32 parent_if_index = ~0;
Pavel Kotucek15ac81c2017-06-20 14:00:26 +020013696 u32 sub_id = ~0;
Pavel Kotucek6899a302017-06-08 08:46:10 +020013697 u8 remote_mac[6];
13698 u8 mac_set = 0;
13699 int ret;
13700
Dave Barachb7b92992018-10-17 10:38:51 -040013701 clib_memset (remote_mac, 0, sizeof (remote_mac));
Pavel Kotucek6899a302017-06-08 08:46:10 +020013702 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13703 {
13704 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
13705 ;
13706 else if (unformat (i, "sw_if_index %d", &parent_if_index))
13707 ;
13708 else
13709 if (unformat
13710 (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
13711 mac_set++;
Pavel Kotucek15ac81c2017-06-20 14:00:26 +020013712 else if (unformat (i, "sub_id %d", &sub_id))
13713 ;
Pavel Kotucek6899a302017-06-08 08:46:10 +020013714 else
13715 {
13716 clib_warning ("parse error '%U'", format_unformat_error, i);
13717 return -99;
13718 }
13719 }
13720
13721 if (parent_if_index == ~0)
13722 {
13723 errmsg ("missing interface name or sw_if_index");
13724 return -99;
13725 }
13726 if (mac_set == 0)
13727 {
13728 errmsg ("missing remote mac address");
13729 return -99;
13730 }
Pavel Kotucek15ac81c2017-06-20 14:00:26 +020013731 if (sub_id == ~0)
13732 {
13733 errmsg ("missing sub-interface id");
13734 return -99;
13735 }
Pavel Kotucek6899a302017-06-08 08:46:10 +020013736
13737 M (P2P_ETHERNET_ADD, mp);
13738 mp->parent_if_index = ntohl (parent_if_index);
Pavel Kotucek15ac81c2017-06-20 14:00:26 +020013739 mp->subif_id = ntohl (sub_id);
Pavel Kotucek6899a302017-06-08 08:46:10 +020013740 clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
13741
13742 S (mp);
13743 W (ret);
13744 return ret;
13745}
13746
13747static int
13748api_p2p_ethernet_del (vat_main_t * vam)
13749{
13750 unformat_input_t *i = vam->input;
13751 vl_api_p2p_ethernet_del_t *mp;
13752 u32 parent_if_index = ~0;
13753 u8 remote_mac[6];
13754 u8 mac_set = 0;
13755 int ret;
13756
Dave Barachb7b92992018-10-17 10:38:51 -040013757 clib_memset (remote_mac, 0, sizeof (remote_mac));
Pavel Kotucek6899a302017-06-08 08:46:10 +020013758 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13759 {
13760 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
13761 ;
13762 else if (unformat (i, "sw_if_index %d", &parent_if_index))
13763 ;
13764 else
13765 if (unformat
13766 (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
13767 mac_set++;
13768 else
13769 {
13770 clib_warning ("parse error '%U'", format_unformat_error, i);
13771 return -99;
13772 }
13773 }
13774
13775 if (parent_if_index == ~0)
13776 {
13777 errmsg ("missing interface name or sw_if_index");
13778 return -99;
13779 }
13780 if (mac_set == 0)
13781 {
13782 errmsg ("missing remote mac address");
13783 return -99;
13784 }
13785
13786 M (P2P_ETHERNET_DEL, mp);
13787 mp->parent_if_index = ntohl (parent_if_index);
13788 clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
13789
13790 S (mp);
13791 W (ret);
13792 return ret;
13793}
Damjan Marion7cd468a2016-12-19 23:05:39 +010013794
13795static int
Dave Barach3bbcfab2017-08-15 19:03:44 -040013796api_tcp_configure_src_addresses (vat_main_t * vam)
13797{
13798 vl_api_tcp_configure_src_addresses_t *mp;
13799 unformat_input_t *i = vam->input;
Neale Rannscbe25aa2019-09-30 10:53:31 +000013800 vl_api_address_t first, last;
Dave Barach3bbcfab2017-08-15 19:03:44 -040013801 u8 range_set = 0;
13802 u32 vrf_id = 0;
13803 int ret;
13804
13805 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13806 {
13807 if (unformat (i, "%U - %U",
Neale Rannscbe25aa2019-09-30 10:53:31 +000013808 unformat_vl_api_address, &first,
13809 unformat_vl_api_address, &last))
Dave Barach3bbcfab2017-08-15 19:03:44 -040013810 {
13811 if (range_set)
13812 {
13813 errmsg ("one range per message (range already set)");
13814 return -99;
13815 }
13816 range_set = 1;
13817 }
Dave Barach3bbcfab2017-08-15 19:03:44 -040013818 else if (unformat (i, "vrf %d", &vrf_id))
13819 ;
13820 else
13821 break;
13822 }
13823
13824 if (range_set == 0)
13825 {
13826 errmsg ("address range not set");
13827 return -99;
13828 }
13829
13830 M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
Neale Rannscbe25aa2019-09-30 10:53:31 +000013831
Dave Barach3bbcfab2017-08-15 19:03:44 -040013832 mp->vrf_id = ntohl (vrf_id);
Neale Rannscbe25aa2019-09-30 10:53:31 +000013833 clib_memcpy (&mp->first_address, &first, sizeof (first));
13834 clib_memcpy (&mp->last_address, &last, sizeof (last));
13835
Dave Barach3bbcfab2017-08-15 19:03:44 -040013836 S (mp);
13837 W (ret);
13838 return ret;
13839}
13840
Florin Coras6e8c6672017-11-10 09:03:54 -080013841static void vl_api_app_namespace_add_del_reply_t_handler
13842 (vl_api_app_namespace_add_del_reply_t * mp)
13843{
13844 vat_main_t *vam = &vat_main;
13845 i32 retval = ntohl (mp->retval);
13846 if (vam->async_mode)
13847 {
13848 vam->async_errors += (retval < 0);
13849 }
13850 else
13851 {
13852 vam->retval = retval;
13853 if (retval == 0)
13854 errmsg ("app ns index %d\n", ntohl (mp->appns_index));
13855 vam->result_ready = 1;
13856 }
13857}
13858
13859static void vl_api_app_namespace_add_del_reply_t_handler_json
13860 (vl_api_app_namespace_add_del_reply_t * mp)
13861{
13862 vat_main_t *vam = &vat_main;
13863 vat_json_node_t node;
13864
13865 vat_json_init_object (&node);
13866 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
13867 vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
13868
13869 vat_json_print (vam->ofp, &node);
13870 vat_json_free (&node);
13871
13872 vam->retval = ntohl (mp->retval);
13873 vam->result_ready = 1;
13874}
13875
Dave Barach3bbcfab2017-08-15 19:03:44 -040013876static int
Florin Corascea194d2017-10-02 00:18:51 -070013877api_app_namespace_add_del (vat_main_t * vam)
13878{
13879 vl_api_app_namespace_add_del_t *mp;
13880 unformat_input_t *i = vam->input;
13881 u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
13882 u32 sw_if_index, ip4_fib_id, ip6_fib_id;
13883 u64 secret;
13884 int ret;
13885
13886 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13887 {
13888 if (unformat (i, "id %_%v%_", &ns_id))
13889 ;
13890 else if (unformat (i, "secret %lu", &secret))
13891 secret_set = 1;
13892 else if (unformat (i, "sw_if_index %d", &sw_if_index))
13893 sw_if_index_set = 1;
13894 else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
13895 ;
13896 else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
13897 ;
13898 else
13899 break;
13900 }
13901 if (!ns_id || !secret_set || !sw_if_index_set)
13902 {
13903 errmsg ("namespace id, secret and sw_if_index must be set");
13904 return -99;
13905 }
13906 if (vec_len (ns_id) > 64)
13907 {
13908 errmsg ("namespace id too long");
13909 return -99;
13910 }
13911 M (APP_NAMESPACE_ADD_DEL, mp);
13912
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010013913 vl_api_vec_to_api_string (ns_id, &mp->namespace_id);
Florin Coras9a9adb22017-10-26 08:16:59 -070013914 mp->secret = clib_host_to_net_u64 (secret);
Florin Corascea194d2017-10-02 00:18:51 -070013915 mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
13916 mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
13917 mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
13918 vec_free (ns_id);
13919 S (mp);
13920 W (ret);
13921 return ret;
13922}
13923
13924static int
Florin Coras90a63982017-12-19 04:50:01 -080013925api_sock_init_shm (vat_main_t * vam)
13926{
13927#if VPP_API_TEST_BUILTIN == 0
13928 unformat_input_t *i = vam->input;
13929 vl_api_shm_elem_config_t *config = 0;
13930 u64 size = 64 << 20;
13931 int rv;
13932
13933 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13934 {
13935 if (unformat (i, "size %U", unformat_memory_size, &size))
13936 ;
13937 else
13938 break;
13939 }
13940
Dave Barach78958722018-05-10 16:44:27 -040013941 /*
13942 * Canned custom ring allocator config.
13943 * Should probably parse all of this
13944 */
13945 vec_validate (config, 6);
Florin Coras90a63982017-12-19 04:50:01 -080013946 config[0].type = VL_API_VLIB_RING;
Florin Coras90a63982017-12-19 04:50:01 -080013947 config[0].size = 256;
Dave Barach78958722018-05-10 16:44:27 -040013948 config[0].count = 32;
13949
13950 config[1].type = VL_API_VLIB_RING;
Florin Coras90a63982017-12-19 04:50:01 -080013951 config[1].size = 1024;
Dave Barach78958722018-05-10 16:44:27 -040013952 config[1].count = 16;
13953
13954 config[2].type = VL_API_VLIB_RING;
Florin Coras90a63982017-12-19 04:50:01 -080013955 config[2].size = 4096;
Dave Barach78958722018-05-10 16:44:27 -040013956 config[2].count = 2;
13957
13958 config[3].type = VL_API_CLIENT_RING;
13959 config[3].size = 256;
13960 config[3].count = 32;
13961
13962 config[4].type = VL_API_CLIENT_RING;
13963 config[4].size = 1024;
13964 config[4].count = 16;
13965
13966 config[5].type = VL_API_CLIENT_RING;
13967 config[5].size = 4096;
13968 config[5].count = 2;
13969
13970 config[6].type = VL_API_QUEUE;
13971 config[6].count = 128;
13972 config[6].size = sizeof (uword);
13973
Tomasz Kulasek97dcf5b2019-01-31 18:26:32 +010013974 rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
Florin Coras90a63982017-12-19 04:50:01 -080013975 if (!rv)
13976 vam->client_index_invalid = 1;
13977 return rv;
13978#else
13979 return -99;
13980#endif
13981}
13982
Florin Coras6c36f532017-11-03 18:32:34 -070013983static void
13984vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
13985{
13986 vat_main_t *vam = &vat_main;
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010013987 fib_prefix_t lcl, rmt;
Florin Coras6c36f532017-11-03 18:32:34 -070013988
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010013989 ip_prefix_decode (&mp->lcl, &lcl);
13990 ip_prefix_decode (&mp->rmt, &rmt);
13991
13992 if (lcl.fp_proto == FIB_PROTOCOL_IP4)
Florin Coras6c36f532017-11-03 18:32:34 -070013993 {
Florin Corasc97a7392017-11-05 23:07:07 -080013994 print (vam->ofp,
13995 "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
Steven85dbac02017-11-07 16:29:53 -080013996 clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010013997 mp->scope, format_ip4_address, &lcl.fp_addr.ip4, lcl.fp_len,
Steven85dbac02017-11-07 16:29:53 -080013998 clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010013999 &rmt.fp_addr.ip4, rmt.fp_len,
14000 clib_net_to_host_u16 (mp->rmt_port),
Steven85dbac02017-11-07 16:29:53 -080014001 clib_net_to_host_u32 (mp->action_index), mp->tag);
Florin Coras6c36f532017-11-03 18:32:34 -070014002 }
14003 else
14004 {
Florin Corasc97a7392017-11-05 23:07:07 -080014005 print (vam->ofp,
14006 "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
Steven85dbac02017-11-07 16:29:53 -080014007 clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014008 mp->scope, format_ip6_address, &lcl.fp_addr.ip6, lcl.fp_len,
Steven85dbac02017-11-07 16:29:53 -080014009 clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014010 &rmt.fp_addr.ip6, rmt.fp_len,
14011 clib_net_to_host_u16 (mp->rmt_port),
Steven85dbac02017-11-07 16:29:53 -080014012 clib_net_to_host_u32 (mp->action_index), mp->tag);
Florin Coras6c36f532017-11-03 18:32:34 -070014013 }
14014}
14015
14016static void
14017vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
14018 mp)
14019{
14020 vat_main_t *vam = &vat_main;
14021 vat_json_node_t *node = NULL;
14022 struct in6_addr ip6;
14023 struct in_addr ip4;
14024
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014025 fib_prefix_t lcl, rmt;
14026
14027 ip_prefix_decode (&mp->lcl, &lcl);
14028 ip_prefix_decode (&mp->rmt, &rmt);
14029
Florin Coras6c36f532017-11-03 18:32:34 -070014030 if (VAT_JSON_ARRAY != vam->json_tree.type)
14031 {
14032 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14033 vat_json_init_array (&vam->json_tree);
14034 }
14035 node = vat_json_array_add (&vam->json_tree);
14036 vat_json_init_object (node);
14037
Florin Coras6c36f532017-11-03 18:32:34 -070014038 vat_json_object_add_uint (node, "appns_index",
14039 clib_net_to_host_u32 (mp->appns_index));
14040 vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
14041 vat_json_object_add_uint (node, "scope", mp->scope);
14042 vat_json_object_add_uint (node, "action_index",
14043 clib_net_to_host_u32 (mp->action_index));
14044 vat_json_object_add_uint (node, "lcl_port",
14045 clib_net_to_host_u16 (mp->lcl_port));
14046 vat_json_object_add_uint (node, "rmt_port",
14047 clib_net_to_host_u16 (mp->rmt_port));
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014048 vat_json_object_add_uint (node, "lcl_plen", lcl.fp_len);
14049 vat_json_object_add_uint (node, "rmt_plen", rmt.fp_len);
Florin Corasc97a7392017-11-05 23:07:07 -080014050 vat_json_object_add_string_copy (node, "tag", mp->tag);
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014051 if (lcl.fp_proto == FIB_PROTOCOL_IP4)
Florin Coras6c36f532017-11-03 18:32:34 -070014052 {
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014053 clib_memcpy (&ip4, &lcl.fp_addr.ip4, sizeof (ip4));
Florin Coras6c36f532017-11-03 18:32:34 -070014054 vat_json_object_add_ip4 (node, "lcl_ip", ip4);
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014055 clib_memcpy (&ip4, &rmt.fp_addr.ip4, sizeof (ip4));
Florin Coras6c36f532017-11-03 18:32:34 -070014056 vat_json_object_add_ip4 (node, "rmt_ip", ip4);
14057 }
14058 else
14059 {
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014060 clib_memcpy (&ip6, &lcl.fp_addr.ip6, sizeof (ip6));
Florin Coras6c36f532017-11-03 18:32:34 -070014061 vat_json_object_add_ip6 (node, "lcl_ip", ip6);
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014062 clib_memcpy (&ip6, &rmt.fp_addr.ip6, sizeof (ip6));
Florin Coras6c36f532017-11-03 18:32:34 -070014063 vat_json_object_add_ip6 (node, "rmt_ip", ip6);
14064 }
14065}
14066
Florin Coras1c710452017-10-17 00:03:13 -070014067static int
14068api_session_rule_add_del (vat_main_t * vam)
14069{
14070 vl_api_session_rule_add_del_t *mp;
14071 unformat_input_t *i = vam->input;
14072 u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
14073 u32 appns_index = 0, scope = 0;
14074 ip4_address_t lcl_ip4, rmt_ip4;
14075 ip6_address_t lcl_ip6, rmt_ip6;
14076 u8 is_ip4 = 1, conn_set = 0;
Florin Corasc97a7392017-11-05 23:07:07 -080014077 u8 is_add = 1, *tag = 0;
Florin Coras1c710452017-10-17 00:03:13 -070014078 int ret;
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014079 fib_prefix_t lcl, rmt;
Florin Coras1c710452017-10-17 00:03:13 -070014080
14081 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14082 {
14083 if (unformat (i, "del"))
14084 is_add = 0;
14085 else if (unformat (i, "add"))
14086 ;
14087 else if (unformat (i, "proto tcp"))
14088 proto = 0;
14089 else if (unformat (i, "proto udp"))
14090 proto = 1;
14091 else if (unformat (i, "appns %d", &appns_index))
14092 ;
14093 else if (unformat (i, "scope %d", &scope))
14094 ;
Florin Corasc97a7392017-11-05 23:07:07 -080014095 else if (unformat (i, "tag %_%v%_", &tag))
14096 ;
Florin Coras1c710452017-10-17 00:03:13 -070014097 else
14098 if (unformat
14099 (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
14100 &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
14101 &rmt_port))
14102 {
14103 is_ip4 = 1;
14104 conn_set = 1;
14105 }
14106 else
14107 if (unformat
14108 (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
14109 &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
14110 &rmt_port))
14111 {
14112 is_ip4 = 0;
14113 conn_set = 1;
14114 }
14115 else if (unformat (i, "action %d", &action))
14116 ;
14117 else
14118 break;
14119 }
14120 if (proto == ~0 || !conn_set || action == ~0)
14121 {
14122 errmsg ("transport proto, connection and action must be set");
14123 return -99;
14124 }
14125
14126 if (scope > 3)
14127 {
14128 errmsg ("scope should be 0-3");
14129 return -99;
14130 }
14131
14132 M (SESSION_RULE_ADD_DEL, mp);
14133
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014134 clib_memset (&lcl, 0, sizeof (lcl));
14135 clib_memset (&rmt, 0, sizeof (rmt));
14136 if (is_ip4)
14137 {
14138 ip_set (&lcl.fp_addr, &lcl_ip4, 1);
14139 ip_set (&rmt.fp_addr, &rmt_ip4, 1);
14140 lcl.fp_len = lcl_plen;
14141 rmt.fp_len = rmt_plen;
14142 }
14143 else
14144 {
14145 ip_set (&lcl.fp_addr, &lcl_ip6, 0);
14146 ip_set (&rmt.fp_addr, &rmt_ip6, 0);
14147 lcl.fp_len = lcl_plen;
14148 rmt.fp_len = rmt_plen;
14149 }
14150
14151
14152 ip_prefix_encode (&lcl, &mp->lcl);
14153 ip_prefix_encode (&rmt, &mp->rmt);
Florin Corasc97a7392017-11-05 23:07:07 -080014154 mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
14155 mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014156 mp->transport_proto =
14157 proto ? TRANSPORT_PROTO_API_UDP : TRANSPORT_PROTO_API_TCP;
Florin Coras1c710452017-10-17 00:03:13 -070014158 mp->action_index = clib_host_to_net_u32 (action);
14159 mp->appns_index = clib_host_to_net_u32 (appns_index);
14160 mp->scope = scope;
14161 mp->is_add = is_add;
Florin Corasc97a7392017-11-05 23:07:07 -080014162 if (tag)
14163 {
14164 clib_memcpy (mp->tag, tag, vec_len (tag));
14165 vec_free (tag);
14166 }
Florin Coras1c710452017-10-17 00:03:13 -070014167
14168 S (mp);
14169 W (ret);
14170 return ret;
14171}
Dave Barach65457162017-10-10 17:53:14 -040014172
14173static int
Florin Coras6c36f532017-11-03 18:32:34 -070014174api_session_rules_dump (vat_main_t * vam)
14175{
14176 vl_api_session_rules_dump_t *mp;
14177 vl_api_control_ping_t *mp_ping;
14178 int ret;
14179
14180 if (!vam->json_output)
14181 {
14182 print (vam->ofp, "%=20s", "Session Rules");
14183 }
14184
14185 M (SESSION_RULES_DUMP, mp);
14186 /* send it... */
14187 S (mp);
14188
14189 /* Use a control ping for synchronization */
14190 MPING (CONTROL_PING, mp_ping);
14191 S (mp_ping);
14192
14193 /* Wait for a reply... */
14194 W (ret);
14195 return ret;
14196}
14197
14198static int
Florin Coras595992c2017-11-06 17:17:08 -080014199api_ip_container_proxy_add_del (vat_main_t * vam)
14200{
14201 vl_api_ip_container_proxy_add_del_t *mp;
14202 unformat_input_t *i = vam->input;
Neale Ranns37029302018-08-10 05:30:06 -070014203 u32 sw_if_index = ~0;
14204 vl_api_prefix_t pfx = { };
Florin Coras595992c2017-11-06 17:17:08 -080014205 u8 is_add = 1;
14206 int ret;
14207
14208 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14209 {
14210 if (unformat (i, "del"))
14211 is_add = 0;
14212 else if (unformat (i, "add"))
14213 ;
Neale Ranns37029302018-08-10 05:30:06 -070014214 if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
14215 ;
Florin Coras595992c2017-11-06 17:17:08 -080014216 else if (unformat (i, "sw_if_index %u", &sw_if_index))
14217 ;
14218 else
14219 break;
14220 }
Paul Vinciguerraab055082019-06-06 14:07:55 -040014221 if (sw_if_index == ~0 || pfx.len == 0)
Florin Coras595992c2017-11-06 17:17:08 -080014222 {
14223 errmsg ("address and sw_if_index must be set");
14224 return -99;
14225 }
14226
14227 M (IP_CONTAINER_PROXY_ADD_DEL, mp);
14228
Florin Coras595992c2017-11-06 17:17:08 -080014229 mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
Florin Coras595992c2017-11-06 17:17:08 -080014230 mp->is_add = is_add;
Neale Ranns37029302018-08-10 05:30:06 -070014231 clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
Florin Coras595992c2017-11-06 17:17:08 -080014232
14233 S (mp);
14234 W (ret);
14235 return ret;
14236}
14237
14238static int
Igor Mikhailov (imichail)582caa32018-04-26 21:33:02 -070014239api_qos_record_enable_disable (vat_main_t * vam)
14240{
14241 unformat_input_t *i = vam->input;
14242 vl_api_qos_record_enable_disable_t *mp;
14243 u32 sw_if_index, qs = 0xff;
14244 u8 sw_if_index_set = 0;
14245 u8 enable = 1;
14246 int ret;
14247
14248 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14249 {
14250 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14251 sw_if_index_set = 1;
14252 else if (unformat (i, "sw_if_index %d", &sw_if_index))
14253 sw_if_index_set = 1;
14254 else if (unformat (i, "%U", unformat_qos_source, &qs))
14255 ;
14256 else if (unformat (i, "disable"))
14257 enable = 0;
14258 else
14259 {
14260 clib_warning ("parse error '%U'", format_unformat_error, i);
14261 return -99;
14262 }
14263 }
14264
14265 if (sw_if_index_set == 0)
14266 {
14267 errmsg ("missing interface name or sw_if_index");
14268 return -99;
14269 }
14270 if (qs == 0xff)
14271 {
14272 errmsg ("input location must be specified");
14273 return -99;
14274 }
14275
14276 M (QOS_RECORD_ENABLE_DISABLE, mp);
14277
Neale Ranns5281a902019-07-23 08:16:19 -070014278 mp->record.sw_if_index = ntohl (sw_if_index);
14279 mp->record.input_source = qs;
Igor Mikhailov (imichail)582caa32018-04-26 21:33:02 -070014280 mp->enable = enable;
14281
14282 S (mp);
14283 W (ret);
14284 return ret;
14285}
14286
Dave Barach048a4e52018-06-01 18:52:25 -040014287
Igor Mikhailov (imichail)582caa32018-04-26 21:33:02 -070014288static int
Damjan Marion7cd468a2016-12-19 23:05:39 +010014289q_or_quit (vat_main_t * vam)
14290{
Dave Barachdef19da2017-02-22 17:29:20 -050014291#if VPP_API_TEST_BUILTIN == 0
Damjan Marion7cd468a2016-12-19 23:05:39 +010014292 longjmp (vam->jump_buf, 1);
Dave Barachdef19da2017-02-22 17:29:20 -050014293#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +010014294 return 0; /* not so much */
14295}
14296
14297static int
14298q (vat_main_t * vam)
14299{
14300 return q_or_quit (vam);
14301}
14302
14303static int
14304quit (vat_main_t * vam)
14305{
14306 return q_or_quit (vam);
14307}
14308
14309static int
14310comment (vat_main_t * vam)
14311{
14312 return 0;
14313}
14314
14315static int
Dave Barachb09f4d02019-07-15 16:00:03 -040014316elog_save (vat_main_t * vam)
14317{
14318#if VPP_API_TEST_BUILTIN == 0
14319 elog_main_t *em = &vam->elog_main;
14320 unformat_input_t *i = vam->input;
14321 char *file, *chroot_file;
14322 clib_error_t *error;
14323
14324 if (!unformat (i, "%s", &file))
14325 {
14326 errmsg ("expected file name, got `%U'", format_unformat_error, i);
14327 return 0;
14328 }
14329
14330 /* It's fairly hard to get "../oopsie" through unformat; just in case */
14331 if (strstr (file, "..") || index (file, '/'))
14332 {
14333 errmsg ("illegal characters in filename '%s'", file);
14334 return 0;
14335 }
14336
14337 chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
14338
14339 vec_free (file);
14340
14341 errmsg ("Saving %wd of %wd events to %s",
14342 elog_n_events_in_buffer (em),
14343 elog_buffer_capacity (em), chroot_file);
14344
14345 error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
14346 vec_free (chroot_file);
14347
14348 if (error)
14349 clib_error_report (error);
14350#else
14351 errmsg ("Use the vpp event loger...");
14352#endif
14353
14354 return 0;
14355}
14356
14357static int
14358elog_setup (vat_main_t * vam)
14359{
14360#if VPP_API_TEST_BUILTIN == 0
14361 elog_main_t *em = &vam->elog_main;
14362 unformat_input_t *i = vam->input;
14363 u32 nevents = 128 << 10;
14364
14365 (void) unformat (i, "nevents %d", &nevents);
14366
14367 elog_init (em, nevents);
14368 vl_api_set_elog_main (em);
14369 vl_api_set_elog_trace_api_messages (1);
14370 errmsg ("Event logger initialized with %u events", nevents);
14371#else
14372 errmsg ("Use the vpp event loger...");
14373#endif
14374 return 0;
14375}
14376
14377static int
14378elog_enable (vat_main_t * vam)
14379{
14380#if VPP_API_TEST_BUILTIN == 0
14381 elog_main_t *em = &vam->elog_main;
14382
14383 elog_enable_disable (em, 1 /* enable */ );
14384 vl_api_set_elog_trace_api_messages (1);
14385 errmsg ("Event logger enabled...");
14386#else
14387 errmsg ("Use the vpp event loger...");
14388#endif
14389 return 0;
14390}
14391
14392static int
14393elog_disable (vat_main_t * vam)
14394{
14395#if VPP_API_TEST_BUILTIN == 0
14396 elog_main_t *em = &vam->elog_main;
14397
14398 elog_enable_disable (em, 0 /* enable */ );
14399 vl_api_set_elog_trace_api_messages (1);
14400 errmsg ("Event logger disabled...");
14401#else
14402 errmsg ("Use the vpp event loger...");
14403#endif
14404 return 0;
14405}
14406
14407static int
Dave Barach048a4e52018-06-01 18:52:25 -040014408statseg (vat_main_t * vam)
14409{
14410 ssvm_private_t *ssvmp = &vam->stat_segment;
14411 ssvm_shared_header_t *shared_header = ssvmp->sh;
14412 vlib_counter_t **counters;
14413 u64 thread0_index1_packets;
14414 u64 thread0_index1_bytes;
14415 f64 vector_rate, input_rate;
14416 uword *p;
14417
14418 uword *counter_vector_by_name;
14419 if (vam->stat_segment_lockp == 0)
14420 {
14421 errmsg ("Stat segment not mapped...");
14422 return -99;
14423 }
14424
14425 /* look up "/if/rx for sw_if_index 1 as a test */
14426
14427 clib_spinlock_lock (vam->stat_segment_lockp);
14428
14429 counter_vector_by_name = (uword *) shared_header->opaque[1];
14430
14431 p = hash_get_mem (counter_vector_by_name, "/if/rx");
14432 if (p == 0)
14433 {
14434 clib_spinlock_unlock (vam->stat_segment_lockp);
14435 errmsg ("/if/tx not found?");
14436 return -99;
14437 }
14438
14439 /* Fish per-thread vector of combined counters from shared memory */
14440 counters = (vlib_counter_t **) p[0];
14441
14442 if (vec_len (counters[0]) < 2)
14443 {
14444 clib_spinlock_unlock (vam->stat_segment_lockp);
14445 errmsg ("/if/tx vector length %d", vec_len (counters[0]));
14446 return -99;
14447 }
14448
14449 /* Read thread 0 sw_if_index 1 counter */
14450 thread0_index1_packets = counters[0][1].packets;
14451 thread0_index1_bytes = counters[0][1].bytes;
14452
14453 p = hash_get_mem (counter_vector_by_name, "vector_rate");
14454 if (p == 0)
14455 {
14456 clib_spinlock_unlock (vam->stat_segment_lockp);
14457 errmsg ("vector_rate not found?");
14458 return -99;
14459 }
14460
14461 vector_rate = *(f64 *) (p[0]);
14462 p = hash_get_mem (counter_vector_by_name, "input_rate");
14463 if (p == 0)
14464 {
14465 clib_spinlock_unlock (vam->stat_segment_lockp);
14466 errmsg ("input_rate not found?");
14467 return -99;
14468 }
14469 input_rate = *(f64 *) (p[0]);
14470
14471 clib_spinlock_unlock (vam->stat_segment_lockp);
14472
14473 print (vam->ofp, "vector_rate %.2f input_rate %.2f",
14474 vector_rate, input_rate);
14475 print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
14476 thread0_index1_packets, thread0_index1_bytes);
14477
14478 return 0;
14479}
14480
14481static int
Damjan Marion7cd468a2016-12-19 23:05:39 +010014482cmd_cmp (void *a1, void *a2)
14483{
14484 u8 **c1 = a1;
14485 u8 **c2 = a2;
14486
14487 return strcmp ((char *) (c1[0]), (char *) (c2[0]));
14488}
14489
14490static int
14491help (vat_main_t * vam)
14492{
14493 u8 **cmds = 0;
14494 u8 *name = 0;
14495 hash_pair_t *p;
14496 unformat_input_t *i = vam->input;
14497 int j;
14498
14499 if (unformat (i, "%s", &name))
14500 {
14501 uword *hs;
14502
14503 vec_add1 (name, 0);
14504
14505 hs = hash_get_mem (vam->help_by_name, name);
14506 if (hs)
14507 print (vam->ofp, "usage: %s %s", name, hs[0]);
14508 else
14509 print (vam->ofp, "No such msg / command '%s'", name);
14510 vec_free (name);
14511 return 0;
14512 }
14513
14514 print (vam->ofp, "Help is available for the following:");
14515
14516 /* *INDENT-OFF* */
14517 hash_foreach_pair (p, vam->function_by_name,
14518 ({
14519 vec_add1 (cmds, (u8 *)(p->key));
14520 }));
14521 /* *INDENT-ON* */
14522
14523 vec_sort_with_function (cmds, cmd_cmp);
14524
14525 for (j = 0; j < vec_len (cmds); j++)
14526 print (vam->ofp, "%s", cmds[j]);
14527
14528 vec_free (cmds);
14529 return 0;
14530}
14531
14532static int
14533set (vat_main_t * vam)
14534{
14535 u8 *name = 0, *value = 0;
14536 unformat_input_t *i = vam->input;
14537
14538 if (unformat (i, "%s", &name))
14539 {
14540 /* The input buffer is a vector, not a string. */
14541 value = vec_dup (i->buffer);
14542 vec_delete (value, i->index, 0);
14543 /* Almost certainly has a trailing newline */
14544 if (value[vec_len (value) - 1] == '\n')
14545 value[vec_len (value) - 1] = 0;
14546 /* Make sure it's a proper string, one way or the other */
14547 vec_add1 (value, 0);
14548 (void) clib_macro_set_value (&vam->macro_main,
14549 (char *) name, (char *) value);
14550 }
14551 else
14552 errmsg ("usage: set <name> <value>");
14553
14554 vec_free (name);
14555 vec_free (value);
14556 return 0;
14557}
14558
14559static int
14560unset (vat_main_t * vam)
14561{
14562 u8 *name = 0;
14563
14564 if (unformat (vam->input, "%s", &name))
14565 if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
14566 errmsg ("unset: %s wasn't set", name);
14567 vec_free (name);
14568 return 0;
14569}
14570
14571typedef struct
14572{
14573 u8 *name;
14574 u8 *value;
14575} macro_sort_t;
14576
14577
14578static int
14579macro_sort_cmp (void *a1, void *a2)
14580{
14581 macro_sort_t *s1 = a1;
14582 macro_sort_t *s2 = a2;
14583
14584 return strcmp ((char *) (s1->name), (char *) (s2->name));
14585}
14586
14587static int
14588dump_macro_table (vat_main_t * vam)
14589{
14590 macro_sort_t *sort_me = 0, *sm;
14591 int i;
14592 hash_pair_t *p;
14593
14594 /* *INDENT-OFF* */
14595 hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
14596 ({
14597 vec_add2 (sort_me, sm, 1);
14598 sm->name = (u8 *)(p->key);
14599 sm->value = (u8 *) (p->value[0]);
14600 }));
14601 /* *INDENT-ON* */
14602
14603 vec_sort_with_function (sort_me, macro_sort_cmp);
14604
14605 if (vec_len (sort_me))
14606 print (vam->ofp, "%-15s%s", "Name", "Value");
14607 else
14608 print (vam->ofp, "The macro table is empty...");
14609
14610 for (i = 0; i < vec_len (sort_me); i++)
14611 print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
14612 return 0;
14613}
14614
14615static int
14616dump_node_table (vat_main_t * vam)
14617{
14618 int i, j;
14619 vlib_node_t *node, *next_node;
14620
14621 if (vec_len (vam->graph_nodes) == 0)
14622 {
14623 print (vam->ofp, "Node table empty, issue get_node_graph...");
14624 return 0;
14625 }
14626
Dave Barach1ddbc012018-06-13 09:26:05 -040014627 for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
Damjan Marion7cd468a2016-12-19 23:05:39 +010014628 {
Dave Barach1ddbc012018-06-13 09:26:05 -040014629 node = vam->graph_nodes[0][i];
Damjan Marion7cd468a2016-12-19 23:05:39 +010014630 print (vam->ofp, "[%d] %s", i, node->name);
14631 for (j = 0; j < vec_len (node->next_nodes); j++)
14632 {
14633 if (node->next_nodes[j] != ~0)
14634 {
Dave Barach1ddbc012018-06-13 09:26:05 -040014635 next_node = vam->graph_nodes[0][node->next_nodes[j]];
Damjan Marion7cd468a2016-12-19 23:05:39 +010014636 print (vam->ofp, " [%d] %s", j, next_node->name);
14637 }
14638 }
14639 }
14640 return 0;
14641}
14642
14643static int
14644value_sort_cmp (void *a1, void *a2)
14645{
14646 name_sort_t *n1 = a1;
14647 name_sort_t *n2 = a2;
14648
14649 if (n1->value < n2->value)
14650 return -1;
14651 if (n1->value > n2->value)
14652 return 1;
14653 return 0;
14654}
14655
14656
14657static int
14658dump_msg_api_table (vat_main_t * vam)
14659{
Dave Barach39d69112019-11-27 11:42:13 -050014660 api_main_t *am = vlibapi_get_main ();
Damjan Marion7cd468a2016-12-19 23:05:39 +010014661 name_sort_t *nses = 0, *ns;
14662 hash_pair_t *hp;
14663 int i;
14664
14665 /* *INDENT-OFF* */
14666 hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
14667 ({
14668 vec_add2 (nses, ns, 1);
14669 ns->name = (u8 *)(hp->key);
14670 ns->value = (u32) hp->value[0];
14671 }));
14672 /* *INDENT-ON* */
14673
14674 vec_sort_with_function (nses, value_sort_cmp);
14675
14676 for (i = 0; i < vec_len (nses); i++)
14677 print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
14678 vec_free (nses);
14679 return 0;
14680}
14681
14682static int
14683get_msg_id (vat_main_t * vam)
14684{
14685 u8 *name_and_crc;
14686 u32 message_index;
14687
14688 if (unformat (vam->input, "%s", &name_and_crc))
14689 {
Florin Corase86a8ed2018-01-05 03:20:25 -080014690 message_index = vl_msg_api_get_msg_index (name_and_crc);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014691 if (message_index == ~0)
14692 {
14693 print (vam->ofp, " '%s' not found", name_and_crc);
14694 return 0;
14695 }
14696 print (vam->ofp, " '%s' has message index %d",
14697 name_and_crc, message_index);
14698 return 0;
14699 }
14700 errmsg ("name_and_crc required...");
14701 return 0;
14702}
14703
14704static int
14705search_node_table (vat_main_t * vam)
14706{
14707 unformat_input_t *line_input = vam->input;
14708 u8 *node_to_find;
14709 int j;
14710 vlib_node_t *node, *next_node;
14711 uword *p;
14712
14713 if (vam->graph_node_index_by_name == 0)
14714 {
14715 print (vam->ofp, "Node table empty, issue get_node_graph...");
14716 return 0;
14717 }
14718
14719 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14720 {
14721 if (unformat (line_input, "%s", &node_to_find))
14722 {
14723 vec_add1 (node_to_find, 0);
14724 p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
14725 if (p == 0)
14726 {
14727 print (vam->ofp, "%s not found...", node_to_find);
14728 goto out;
14729 }
Dave Barach1ddbc012018-06-13 09:26:05 -040014730 node = vam->graph_nodes[0][p[0]];
Damjan Marion7cd468a2016-12-19 23:05:39 +010014731 print (vam->ofp, "[%d] %s", p[0], node->name);
14732 for (j = 0; j < vec_len (node->next_nodes); j++)
14733 {
14734 if (node->next_nodes[j] != ~0)
14735 {
Dave Barach1ddbc012018-06-13 09:26:05 -040014736 next_node = vam->graph_nodes[0][node->next_nodes[j]];
Damjan Marion7cd468a2016-12-19 23:05:39 +010014737 print (vam->ofp, " [%d] %s", j, next_node->name);
14738 }
14739 }
14740 }
14741
14742 else
14743 {
14744 clib_warning ("parse error '%U'", format_unformat_error,
14745 line_input);
14746 return -99;
14747 }
14748
14749 out:
14750 vec_free (node_to_find);
14751
14752 }
14753
14754 return 0;
14755}
14756
14757
14758static int
14759script (vat_main_t * vam)
14760{
14761#if (VPP_API_TEST_BUILTIN==0)
14762 u8 *s = 0;
14763 char *save_current_file;
14764 unformat_input_t save_input;
14765 jmp_buf save_jump_buf;
14766 u32 save_line_number;
14767
14768 FILE *new_fp, *save_ifp;
14769
14770 if (unformat (vam->input, "%s", &s))
14771 {
14772 new_fp = fopen ((char *) s, "r");
14773 if (new_fp == 0)
14774 {
14775 errmsg ("Couldn't open script file %s", s);
14776 vec_free (s);
14777 return -99;
14778 }
14779 }
14780 else
14781 {
14782 errmsg ("Missing script name");
14783 return -99;
14784 }
14785
14786 clib_memcpy (&save_input, &vam->input, sizeof (save_input));
14787 clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
14788 save_ifp = vam->ifp;
14789 save_line_number = vam->input_line_number;
14790 save_current_file = (char *) vam->current_file;
14791
14792 vam->input_line_number = 0;
14793 vam->ifp = new_fp;
14794 vam->current_file = s;
14795 do_one_file (vam);
14796
Sirshak Dasb0861822018-05-29 21:13:21 -050014797 clib_memcpy (&vam->input, &save_input, sizeof (save_input));
Damjan Marion7cd468a2016-12-19 23:05:39 +010014798 clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
14799 vam->ifp = save_ifp;
14800 vam->input_line_number = save_line_number;
14801 vam->current_file = (u8 *) save_current_file;
14802 vec_free (s);
14803
14804 return 0;
14805#else
14806 clib_warning ("use the exec command...");
14807 return -99;
14808#endif
14809}
14810
14811static int
14812echo (vat_main_t * vam)
14813{
14814 print (vam->ofp, "%v", vam->input->buffer);
14815 return 0;
14816}
14817
14818/* List of API message constructors, CLI names map to api_xxx */
14819#define foreach_vpe_api_msg \
Jon Loeligerc83c3b72017-02-23 13:57:35 -060014820_(create_loopback,"[mac <mac-addr>] [instance <instance>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014821_(sw_interface_dump,"") \
14822_(sw_interface_set_flags, \
14823 "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
14824_(sw_interface_add_del_address, \
14825 "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
Stevenad8015b2017-10-29 22:10:46 -070014826_(sw_interface_set_rx_mode, \
14827 "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
Mohsin Kazmi54f7c512018-08-23 18:28:11 +020014828_(sw_interface_set_rx_placement, \
14829 "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]") \
Mohsin Kazmif0b42f42018-09-10 18:11:00 +020014830_(sw_interface_rx_placement_dump, \
14831 "[<intfc> | sw_if_index <id>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014832_(sw_interface_set_table, \
14833 "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]") \
14834_(sw_interface_set_mpls_enable, \
14835 "<intfc> | sw_if_index [disable | dis]") \
14836_(sw_interface_set_vpath, \
14837 "<intfc> | sw_if_index <id> enable | disable") \
14838_(sw_interface_set_vxlan_bypass, \
John Lo2b81eb82017-01-30 13:12:10 -050014839 "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014840_(sw_interface_set_l2_xconnect, \
14841 "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
14842 "enable | disable") \
14843_(sw_interface_set_l2_bridge, \
Eyal Barif24991c2017-04-05 05:33:21 +030014844 "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n" \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014845 "[shg <split-horizon-group>] [bvi]\n" \
14846 "enable | disable") \
Eyal Barif24991c2017-04-05 05:33:21 +030014847_(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014848_(bridge_domain_add_del, \
John Lo70bfcaf2017-11-14 13:19:26 -050014849 "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 +010014850_(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n") \
14851_(l2fib_add_del, \
14852 "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 +030014853_(l2fib_flush_bd, "bd_id <bridge-domain-id>") \
14854_(l2fib_flush_int, "<intfc> | sw_if_index <id>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014855_(l2_flags, \
John Lo8d00fff2017-08-03 00:35:36 -040014856 "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014857_(bridge_flags, \
14858 "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
Damjan Marion8389fb92017-10-13 18:29:53 +020014859_(tap_create_v2, \
Mohsin Kazmi50bd1652020-08-26 11:07:48 +020014860 "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 +020014861_(tap_delete_v2, \
14862 "<vpp-if-name> | sw_if_index <id>") \
14863_(sw_interface_tap_v2_dump, "") \
Mohsin Kazmi518251b2020-09-01 17:17:44 +000014864_(virtio_pci_create_v2, \
Mohsin Kazmie347acb2020-09-28 10:26:33 +000014865 "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 +010014866_(virtio_pci_delete, \
14867 "<vpp-if-name> | sw_if_index <id>") \
14868_(sw_interface_virtio_pci_dump, "") \
Steven9cd2d7a2017-12-20 12:43:01 -080014869_(bond_create, \
14870 "[hw-addr <mac-addr>] {round-robin | active-backup | " \
Alexander Chernavinad9d5282018-12-13 09:08:09 -050014871 "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} " \
Steven Luonga1876b82019-08-20 16:58:00 -070014872 "[id <if-id>]") \
Steven Luongea717862020-07-30 07:31:40 -070014873_(bond_create2, \
14874 "[hw-addr <mac-addr>] {mode round-robin | active-backup | " \
14875 "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} " \
14876 "[id <if-id>] [gso]") \
Steven9cd2d7a2017-12-20 12:43:01 -080014877_(bond_delete, \
14878 "<vpp-if-name> | sw_if_index <id>") \
Steven Luong4c4223e2020-07-15 08:44:54 -070014879_(bond_add_member, \
Steven Luonga1876b82019-08-20 16:58:00 -070014880 "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]") \
Steven Luong4c4223e2020-07-15 08:44:54 -070014881_(bond_detach_member, \
Steven9cd2d7a2017-12-20 12:43:01 -080014882 "sw_if_index <n>") \
Steven Luonga1876b82019-08-20 16:58:00 -070014883 _(sw_interface_set_bond_weight, "<intfc> | sw_if_index <nn> weight <value>") \
Steven Luong4c4223e2020-07-15 08:44:54 -070014884 _(sw_bond_interface_dump, "<intfc> | sw_if_index <nn>") \
14885 _(sw_member_interface_dump, \
Steven9cd2d7a2017-12-20 12:43:01 -080014886 "<vpp-if-name> | sw_if_index <id>") \
Neale Ranns28ab9cc2017-08-14 07:18:42 -070014887_(ip_table_add_del, \
John Loe166fd92018-09-13 14:08:59 -040014888 "table <n> [ipv6] [add | del]\n") \
Neale Ranns097fa662018-05-01 05:17:55 -070014889_(ip_route_add_del, \
John Lo22030432018-09-20 16:07:00 -040014890 "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
14891 "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
John Lo06fda9c2018-10-03 16:32:44 -040014892 "[weight <n>] [drop] [local] [classify <n>] [out-label <n>]\n" \
14893 "[multipath] [count <n>] [del]") \
Neale Ranns32e1c012016-11-22 17:07:28 +000014894_(ip_mroute_add_del, \
14895 "<src> <grp>/<mask> [table-id <n>]\n" \
14896 "[<intfc> | sw_if_index <id>] [local] [del]") \
Neale Ranns28ab9cc2017-08-14 07:18:42 -070014897_(mpls_table_add_del, \
John Loe166fd92018-09-13 14:08:59 -040014898 "table <n> [add | del]\n") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014899_(mpls_route_add_del, \
John Loe166fd92018-09-13 14:08:59 -040014900 "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n" \
14901 "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n" \
14902 "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n" \
14903 "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n" \
John Lo06fda9c2018-10-03 16:32:44 -040014904 "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n" \
14905 "[count <n>] [del]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014906_(mpls_ip_bind_unbind, \
14907 "<label> <addr/len>") \
14908_(mpls_tunnel_add_del, \
John Lo06fda9c2018-10-03 16:32:44 -040014909 "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
14910 "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n" \
14911 "[l2-only] [out-label <n>]") \
John Loe166fd92018-09-13 14:08:59 -040014912_(sr_mpls_policy_add, \
14913 "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]") \
14914_(sr_mpls_policy_del, \
14915 "bsid <id>") \
Neale Rannsd792d9c2017-10-21 10:53:20 -070014916_(bier_table_add_del, \
14917 "<label> <sub-domain> <set> <bsl> [del]") \
14918_(bier_route_add_del, \
14919 "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
14920 "[<intfc> | sw_if_index <id>]" \
14921 "[weight <n>] [del] [multipath]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014922_(sw_interface_set_unnumbered, \
14923 "<intfc> | sw_if_index <id> unnum_if_index <id> [del]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014924_(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>") \
14925_(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n" \
14926 "[outer_vlan_id <n>][inner_vlan_id <n>]\n" \
14927 "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n" \
14928 "[outer_vlan_id_any][inner_vlan_id_any]") \
Neale Ranns9db6ada2019-11-08 12:42:31 +000014929_(ip_table_replace_begin, "table <n> [ipv6]") \
14930_(ip_table_flush, "table <n> [ipv6]") \
14931_(ip_table_replace_end, "table <n> [ipv6]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014932_(set_ip_flow_hash, \
14933 "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]") \
14934_(sw_interface_ip6_enable_disable, \
14935 "<intfc> | sw_if_index <id> enable | disable") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014936_(l2_patch_add_del, \
14937 "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
14938 "enable | disable") \
Pablo Camarillofb380952016-12-07 18:34:18 +010014939_(sr_localsid_add_del, \
14940 "(del) address <addr> next_hop <addr> behavior <beh>\n" \
14941 "fib-table <num> (end.psp) sw_if_index <num>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014942_(classify_add_del_table, \
14943 "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n" \
14944 " [del] [del-chain] mask <mask-value>\n" \
14945 " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n" \
14946 " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]") \
14947_(classify_add_del_session, \
14948 "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n" \
14949 " table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n" \
14950 " [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n" \
14951 " [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]") \
14952_(classify_set_interface_ip_table, \
14953 "<intfc> | sw_if_index <nn> table <nn>") \
14954_(classify_set_interface_l2_tables, \
14955 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
14956 " [other-table <nn>]") \
14957_(get_node_index, "node <node-name") \
14958_(add_node_next, "node <node-name> next <next-node-name>") \
eyal bariaf86a482018-04-17 11:20:27 +030014959_(vxlan_offload_rx, \
14960 "hw { <interface name> | hw_if_index <nn>} " \
14961 "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014962_(vxlan_add_del_tunnel, \
14963 "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n" \
Jon Loeliger3d460bd2018-02-01 16:36:12 -060014964 "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n" \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014965 "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]") \
14966_(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014967_(l2_fib_clear_table, "") \
14968_(l2_interface_efp_filter, "sw_if_index <nn> enable | disable") \
14969_(l2_interface_vlan_tag_rewrite, \
14970 "<intfc> | sw_if_index <nn> \n" \
14971 "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n" \
14972 "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>") \
14973_(create_vhost_user_if, \
14974 "socket <filename> [server] [renumber <dev_instance>] " \
Steven Luong4208a4c2019-05-06 08:51:56 -070014975 "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] " \
Steven Luongbc0d9ff2020-03-23 09:34:59 -070014976 "[mac <mac_address>] [packed]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014977_(modify_vhost_user_if, \
14978 "<intfc> | sw_if_index <nn> socket <filename>\n" \
Steven Luongbc0d9ff2020-03-23 09:34:59 -070014979 "[server] [renumber <dev_instance>] [gso] [packed]") \
Steven Luong27ba5002020-11-17 13:30:44 -080014980_(create_vhost_user_if_v2, \
14981 "socket <filename> [server] [renumber <dev_instance>] " \
14982 "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] " \
14983 "[mac <mac_address>] [packed] [event-idx]") \
14984_(modify_vhost_user_if_v2, \
14985 "<intfc> | sw_if_index <nn> socket <filename>\n" \
14986 "[server] [renumber <dev_instance>] [gso] [packed] [event-idx]")\
Damjan Marion7cd468a2016-12-19 23:05:39 +010014987_(delete_vhost_user_if, "<intfc> | sw_if_index <nn>") \
Steven Luonga0e8d962020-05-18 17:12:56 -070014988_(sw_interface_vhost_user_dump, "<intfc> | sw_if_index <nn>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014989_(show_version, "") \
Mohsin Kazmi5d64c782018-09-11 20:27:09 +020014990_(show_threads, "") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014991_(vxlan_gpe_add_del_tunnel, \
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080014992 "local <addr> remote <addr> | group <mcast-ip-addr>\n" \
14993 "{ <intfc> | mcast_sw_if_index <nn> } }\n" \
14994 "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n" \
14995 "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014996_(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]") \
14997_(l2_fib_table_dump, "bd_id <bridge-domain-id>") \
14998_(interface_name_renumber, \
14999 "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>") \
15000_(input_acl_set_interface, \
15001 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
15002 " [l2-table <nn>] [del]") \
John Lo8d00fff2017-08-03 00:35:36 -040015003_(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015004_(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)") \
15005_(ip_dump, "ipv4 | ipv6") \
15006_(ipsec_spd_add_del, "spd_id <n> [del]") \
15007_(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n" \
15008 " spid_id <n> ") \
Neale Ranns17dcec02019-01-09 21:22:20 -080015009_(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n" \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015010 " crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n" \
15011 " integ_alg <alg> integ_key <hex>") \
Neale Ranns17dcec02019-01-09 21:22:20 -080015012_(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n" \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015013 " (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n" \
15014 " laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
15015 " [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
Matthew Smith28029532017-09-26 13:33:44 -050015016_(ipsec_sa_dump, "[sa_id <n>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015017_(delete_loopback,"sw_if_index <nn>") \
15018_(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
John Loe26c81f2019-01-07 15:16:33 -050015019_(bd_ip_mac_flush, "bd_id <bridge-domain-id>") \
15020_(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015021_(want_interface_events, "enable|disable") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015022_(get_first_msg_id, "client <name>") \
15023_(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
15024_(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n" \
15025 "fib-id <nn> [ip4][ip6][default]") \
15026_(get_node_graph, " ") \
15027_(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>") \
15028_(ioam_enable, "[trace] [pow] [ppc <encap|decap>]") \
15029_(ioam_disable, "") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015030_(af_packet_create, "name <host interface name> [hw_addr <mac>]") \
15031_(af_packet_delete, "name <host interface name>") \
Mohsin Kazmi04e0bb22018-05-28 18:55:37 +020015032_(af_packet_dump, "") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015033_(policer_add_del, "name <policer name> <params> [del]") \
15034_(policer_dump, "[name <policer name>]") \
15035_(policer_classify_set_interface, \
15036 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
15037 " [l2-table <nn>] [del]") \
15038_(policer_classify_dump, "type [ip4|ip6|l2]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015039_(mpls_tunnel_dump, "tunnel_index <tunnel-id>") \
Neale Ranns097fa662018-05-01 05:17:55 -070015040_(mpls_table_dump, "") \
15041_(mpls_route_dump, "table-id <ID>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015042_(classify_table_ids, "") \
15043_(classify_table_by_interface, "sw_if_index <sw_if_index>") \
15044_(classify_table_info, "table_id <nn>") \
15045_(classify_session_dump, "table_id <nn>") \
15046_(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] " \
15047 "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] " \
15048 "[template_interval <nn>] [udp_checksum]") \
15049_(ipfix_exporter_dump, "") \
15050_(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
15051_(ipfix_classify_stream_dump, "") \
15052_(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
15053_(ipfix_classify_table_dump, "") \
Eyal Bari001fd402017-07-16 09:34:53 +030015054_(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 +030015055_(sw_interface_span_dump, "[l2]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015056_(get_next_index, "node-name <node-name> next-node-name <node-name>") \
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +020015057_(pg_create_interface, "if_id <nn> [gso-enabled gso-size <size>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015058_(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]") \
15059_(pg_enable_disable, "[stream <id>] disable") \
Mohsin Kazmif382b062020-08-11 15:00:44 +020015060_(pg_interface_enable_disable_coalesce, "<intf> | sw_if_index <nn> enable | disable") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015061_(ip_source_and_port_range_check_add_del, \
15062 "<ip-addr>/<mask> range <nn>-<nn> vrf <id>") \
15063_(ip_source_and_port_range_check_interface_add_del, \
15064 "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]" \
15065 "[udp-in-vrf <id>] [udp-out-vrf <id>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015066_(delete_subif,"<intfc> | sw_if_index <nn>") \
15067_(l2_interface_pbb_tag_rewrite, \
15068 "<intfc> | sw_if_index <nn> \n" \
15069 "[disable | push | pop | translate_pbb_stag <outer_tag>] \n" \
15070 "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]") \
Pavel Kotuceke88865d2018-11-28 07:42:11 +010015071_(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015072_(flow_classify_set_interface, \
15073 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
15074_(flow_classify_dump, "type [ip4|ip6]") \
Neale Ranns097fa662018-05-01 05:17:55 -070015075_(ip_table_dump, "") \
15076_(ip_route_dump, "table-id [ip4|ip6]") \
15077_(ip_mtable_dump, "") \
15078_(ip_mroute_dump, "table-id [ip4|ip6]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015079_(feature_enable_disable, "arc_name <arc_name> " \
15080 "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]") \
Mohsin Kazmi29467b52019-10-08 19:42:38 +020015081_(feature_gso_enable_disable, "<intfc> | sw_if_index <nn> " \
15082 "[enable | disable] ") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015083_(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>" \
15084"[disable]") \
Matthew Smithe0792fd2019-07-12 11:48:24 -050015085_(sw_interface_add_del_mac_address, "<intfc> | sw_if_index <nn> " \
15086 "mac <mac-address> [del]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015087_(l2_xconnect_dump, "") \
Ole Troand7231612018-06-07 10:17:57 +020015088_(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>") \
Pavel Kotucek6899a302017-06-08 08:46:10 +020015089_(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]") \
Pavel Kotucek15ac81c2017-06-20 14:00:26 +020015090_(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
Steve Shin99a0e602017-07-01 04:16:20 +000015091_(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
Dave Barach59b25652017-09-10 15:04:27 -040015092_(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]") \
Florin Coras90a63982017-12-19 04:50:01 -080015093_(sock_init_shm, "size <nnn>") \
Florin Corascea194d2017-10-02 00:18:51 -070015094_(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
Florin Coras1c710452017-10-17 00:03:13 -070015095_(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> " \
15096 "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>") \
Florin Coras6c36f532017-11-03 18:32:34 -070015097_(session_rules_dump, "") \
Florin Coras595992c2017-11-06 17:17:08 -080015098_(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>") \
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +010015099_(output_acl_set_interface, \
15100 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
15101 " [l2-table <nn>] [del]") \
Ole Troane906aac2018-06-14 14:42:14 +020015102_(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
Damjan Marion7cd468a2016-12-19 23:05:39 +010015103
15104/* List of command functions, CLI names map directly to functions */
15105#define foreach_cli_function \
15106_(comment, "usage: comment <ignore-rest-of-line>") \
15107_(dump_interface_table, "usage: dump_interface_table") \
15108_(dump_sub_interface_table, "usage: dump_sub_interface_table") \
15109_(dump_ipv4_table, "usage: dump_ipv4_table") \
15110_(dump_ipv6_table, "usage: dump_ipv6_table") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015111_(dump_macro_table, "usage: dump_macro_table ") \
15112_(dump_node_table, "usage: dump_node_table") \
15113_(dump_msg_api_table, "usage: dump_msg_api_table") \
Dave Barachb09f4d02019-07-15 16:00:03 -040015114_(elog_setup, "usage: elog_setup [nevents, default 128K]") \
15115_(elog_disable, "usage: elog_disable") \
15116_(elog_enable, "usage: elog_enable") \
15117_(elog_save, "usage: elog_save <filename>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015118_(get_msg_id, "usage: get_msg_id name_and_crc") \
15119_(echo, "usage: echo <message>") \
15120_(exec, "usage: exec <vpe-debug-CLI-command>") \
15121_(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>") \
15122_(help, "usage: help") \
15123_(q, "usage: quit") \
15124_(quit, "usage: quit") \
15125_(search_node_table, "usage: search_node_table <name>...") \
15126_(set, "usage: set <variable-name> <value>") \
15127_(script, "usage: script <file-name>") \
Neale Ranns097fa662018-05-01 05:17:55 -070015128_(statseg, "usage: statseg") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015129_(unset, "usage: unset <variable-name>")
Dave Barach048a4e52018-06-01 18:52:25 -040015130
Damjan Marion7cd468a2016-12-19 23:05:39 +010015131#define _(N,n) \
15132 static void vl_api_##n##_t_handler_uni \
15133 (vl_api_##n##_t * mp) \
15134 { \
15135 vat_main_t * vam = &vat_main; \
15136 if (vam->json_output) { \
15137 vl_api_##n##_t_handler_json(mp); \
15138 } else { \
15139 vl_api_##n##_t_handler(mp); \
15140 } \
15141 }
15142foreach_vpe_api_reply_msg;
Dave Baracha1a093d2017-03-02 13:13:23 -050015143#if VPP_API_TEST_BUILTIN == 0
15144foreach_standalone_reply_msg;
15145#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +010015146#undef _
15147
15148void
15149vat_api_hookup (vat_main_t * vam)
15150{
15151#define _(N,n) \
15152 vl_msg_api_set_handlers(VL_API_##N, #n, \
15153 vl_api_##n##_t_handler_uni, \
15154 vl_noop_handler, \
15155 vl_api_##n##_t_endian, \
15156 vl_api_##n##_t_print, \
15157 sizeof(vl_api_##n##_t), 1);
15158 foreach_vpe_api_reply_msg;
Dave Baracha1a093d2017-03-02 13:13:23 -050015159#if VPP_API_TEST_BUILTIN == 0
15160 foreach_standalone_reply_msg;
15161#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +010015162#undef _
15163
15164#if (VPP_API_TEST_BUILTIN==0)
15165 vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015166
15167 vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
15168
15169 vam->function_by_name = hash_create_string (0, sizeof (uword));
15170
15171 vam->help_by_name = hash_create_string (0, sizeof (uword));
Dave Barach45e4f362017-03-07 12:52:31 -050015172#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +010015173
15174 /* API messages we can send */
15175#define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
15176 foreach_vpe_api_msg;
15177#undef _
15178
15179 /* Help strings */
15180#define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
15181 foreach_vpe_api_msg;
15182#undef _
Damjan Marion7cd468a2016-12-19 23:05:39 +010015183
15184 /* CLI functions */
15185#define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
15186 foreach_cli_function;
15187#undef _
15188
15189 /* Help strings */
15190#define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
15191 foreach_cli_function;
15192#undef _
15193}
15194
Dave Baracha1a093d2017-03-02 13:13:23 -050015195#if VPP_API_TEST_BUILTIN
15196static clib_error_t *
15197vat_api_hookup_shim (vlib_main_t * vm)
15198{
15199 vat_api_hookup (&vat_main);
15200 return 0;
15201}
15202
15203VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
15204#endif
15205
Damjan Marion7cd468a2016-12-19 23:05:39 +010015206/*
15207 * fd.io coding-style-patch-verification: ON
15208 *
15209 * Local Variables:
15210 * eval: (c-set-style "gnu")
15211 * End:
15212 */