blob: cf9c7742d466b991cfe48fb80ea81195f9ed7bf3 [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);
533#define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
534 foreach_vnet_dscp
535#undef _
536 else
537 return 0;
538 return 1;
539}
540
541static uword
542unformat_policer_action_type (unformat_input_t * input, va_list * va)
543{
544 sse2_qos_pol_action_params_st *a
545 = va_arg (*va, sse2_qos_pol_action_params_st *);
546
547 if (unformat (input, "drop"))
548 a->action_type = SSE2_QOS_ACTION_DROP;
549 else if (unformat (input, "transmit"))
550 a->action_type = SSE2_QOS_ACTION_TRANSMIT;
551 else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
552 a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
553 else
554 return 0;
555 return 1;
556}
557
558static uword
559unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
560{
561 u32 *r = va_arg (*va, u32 *);
562 u32 tid;
563
564 if (unformat (input, "ip4"))
565 tid = POLICER_CLASSIFY_TABLE_IP4;
566 else if (unformat (input, "ip6"))
567 tid = POLICER_CLASSIFY_TABLE_IP6;
568 else if (unformat (input, "l2"))
569 tid = POLICER_CLASSIFY_TABLE_L2;
570 else
571 return 0;
572
573 *r = tid;
574 return 1;
575}
576
577static uword
578unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
579{
580 u32 *r = va_arg (*va, u32 *);
581 u32 tid;
582
583 if (unformat (input, "ip4"))
584 tid = FLOW_CLASSIFY_TABLE_IP4;
585 else if (unformat (input, "ip6"))
586 tid = FLOW_CLASSIFY_TABLE_IP6;
587 else
588 return 0;
589
590 *r = tid;
591 return 1;
592}
593
Benoît Ganne49ee6842019-04-30 11:50:46 +0200594#if (VPP_API_TEST_BUILTIN==0)
595
Neale Ranns32e1c012016-11-22 17:07:28 +0000596static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
597static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
598static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
599static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
600
601uword
602unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
603{
604 mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
605 mfib_itf_attribute_t attr;
606
607 old = *iflags;
608 FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
609 {
610 if (unformat (input, mfib_itf_flag_long_names[attr]))
611 *iflags |= (1 << attr);
612 }
613 FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
614 {
615 if (unformat (input, mfib_itf_flag_names[attr]))
616 *iflags |= (1 << attr);
617 }
618
619 return (old == *iflags ? 0 : 1);
620}
621
622uword
623unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
624{
625 mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
626 mfib_entry_attribute_t attr;
627
628 old = *eflags;
629 FOR_EACH_MFIB_ATTRIBUTE (attr)
630 {
631 if (unformat (input, mfib_flag_long_names[attr]))
632 *eflags |= (1 << attr);
633 }
634 FOR_EACH_MFIB_ATTRIBUTE (attr)
635 {
636 if (unformat (input, mfib_flag_names[attr]))
637 *eflags |= (1 << attr);
638 }
639
640 return (old == *eflags ? 0 : 1);
641}
642
Damjan Marion7cd468a2016-12-19 23:05:39 +0100643u8 *
644format_ip4_address (u8 * s, va_list * args)
645{
646 u8 *a = va_arg (*args, u8 *);
647 return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
648}
649
650u8 *
651format_ip6_address (u8 * s, va_list * args)
652{
653 ip6_address_t *a = va_arg (*args, ip6_address_t *);
654 u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
655
656 i_max_n_zero = ARRAY_LEN (a->as_u16);
657 max_n_zeros = 0;
658 i_first_zero = i_max_n_zero;
659 n_zeros = 0;
660 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
661 {
662 u32 is_zero = a->as_u16[i] == 0;
663 if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
664 {
665 i_first_zero = i;
666 n_zeros = 0;
667 }
668 n_zeros += is_zero;
669 if ((!is_zero && n_zeros > max_n_zeros)
670 || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
671 {
672 i_max_n_zero = i_first_zero;
673 max_n_zeros = n_zeros;
674 i_first_zero = ARRAY_LEN (a->as_u16);
675 n_zeros = 0;
676 }
677 }
678
679 last_double_colon = 0;
680 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
681 {
682 if (i == i_max_n_zero && max_n_zeros > 1)
683 {
684 s = format (s, "::");
685 i += max_n_zeros - 1;
686 last_double_colon = 1;
687 }
688 else
689 {
690 s = format (s, "%s%x",
691 (last_double_colon || i == 0) ? "" : ":",
692 clib_net_to_host_u16 (a->as_u16[i]));
693 last_double_colon = 0;
694 }
695 }
696
697 return s;
698}
699
700/* Format an IP46 address. */
701u8 *
702format_ip46_address (u8 * s, va_list * args)
703{
704 ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
705 ip46_type_t type = va_arg (*args, ip46_type_t);
706 int is_ip4 = 1;
707
708 switch (type)
709 {
710 case IP46_TYPE_ANY:
711 is_ip4 = ip46_address_is_ip4 (ip46);
712 break;
713 case IP46_TYPE_IP4:
714 is_ip4 = 1;
715 break;
716 case IP46_TYPE_IP6:
717 is_ip4 = 0;
718 break;
719 }
720
721 return is_ip4 ?
722 format (s, "%U", format_ip4_address, &ip46->ip4) :
723 format (s, "%U", format_ip6_address, &ip46->ip6);
724}
725
726u8 *
727format_ethernet_address (u8 * s, va_list * args)
728{
729 u8 *a = va_arg (*args, u8 *);
730
731 return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
732 a[0], a[1], a[2], a[3], a[4], a[5]);
733}
734#endif
735
736static void
Neale Ranns097fa662018-05-01 05:17:55 -0700737increment_v4_address (vl_api_ip4_address_t * i)
Damjan Marion7cd468a2016-12-19 23:05:39 +0100738{
Neale Ranns097fa662018-05-01 05:17:55 -0700739 ip4_address_t *a = (ip4_address_t *) i;
Damjan Marion7cd468a2016-12-19 23:05:39 +0100740 u32 v;
741
742 v = ntohl (a->as_u32) + 1;
743 a->as_u32 = ntohl (v);
744}
745
746static void
Neale Ranns097fa662018-05-01 05:17:55 -0700747increment_v6_address (vl_api_ip6_address_t * i)
Neale Ranns2b5ba952019-04-02 10:15:40 +0000748{
Neale Ranns097fa662018-05-01 05:17:55 -0700749 ip6_address_t *a = (ip6_address_t *) i;
Damjan Marion7cd468a2016-12-19 23:05:39 +0100750 u64 v0, v1;
751
752 v0 = clib_net_to_host_u64 (a->as_u64[0]);
753 v1 = clib_net_to_host_u64 (a->as_u64[1]);
754
755 v1 += 1;
756 if (v1 == 0)
757 v0 += 1;
758 a->as_u64[0] = clib_net_to_host_u64 (v0);
759 a->as_u64[1] = clib_net_to_host_u64 (v1);
760}
761
762static void
Neale Ranns097fa662018-05-01 05:17:55 -0700763increment_address (vl_api_address_t * a)
764{
Dave Barach54582662020-04-21 08:01:16 -0400765 if (a->af == ADDRESS_IP4)
Neale Ranns097fa662018-05-01 05:17:55 -0700766 increment_v4_address (&a->un.ip4);
Dave Barach54582662020-04-21 08:01:16 -0400767 else if (a->af == ADDRESS_IP6)
Neale Ranns097fa662018-05-01 05:17:55 -0700768 increment_v6_address (&a->un.ip6);
769}
770
771static void
772set_ip4_address (vl_api_address_t * a, u32 v)
773{
774 if (a->af == ADDRESS_IP4)
775 {
776 ip4_address_t *i = (ip4_address_t *) & a->un.ip4;
777 i->as_u32 = v;
778 }
779}
780
Jakub Grajciar23a386b2020-02-26 11:01:43 +0100781void
782ip_set (ip46_address_t * dst, void *src, u8 is_ip4)
783{
784 if (is_ip4)
785 dst->ip4.as_u32 = ((ip4_address_t *) src)->as_u32;
786 else
787 clib_memcpy_fast (&dst->ip6, (ip6_address_t *) src,
788 sizeof (ip6_address_t));
789}
790
Neale Ranns097fa662018-05-01 05:17:55 -0700791static void
Mohsin Kazmi57938f62017-10-27 21:28:07 +0200792increment_mac_address (u8 * mac)
Damjan Marion7cd468a2016-12-19 23:05:39 +0100793{
Mohsin Kazmi57938f62017-10-27 21:28:07 +0200794 u64 tmp = *((u64 *) mac);
Damjan Marion7cd468a2016-12-19 23:05:39 +0100795 tmp = clib_net_to_host_u64 (tmp);
796 tmp += 1 << 16; /* skip unused (least significant) octets */
797 tmp = clib_host_to_net_u64 (tmp);
Mohsin Kazmi57938f62017-10-27 21:28:07 +0200798
799 clib_memcpy (mac, &tmp, 6);
Damjan Marion7cd468a2016-12-19 23:05:39 +0100800}
801
Neale Ranns097fa662018-05-01 05:17:55 -0700802static void
803vat_json_object_add_address (vat_json_node_t * node,
804 const char *str, const vl_api_address_t * addr)
805{
806 if (ADDRESS_IP6 == addr->af)
807 {
808 struct in6_addr ip6;
809
810 clib_memcpy (&ip6, &addr->un.ip6, sizeof (ip6));
811 vat_json_object_add_ip6 (node, str, ip6);
812 }
813 else
814 {
815 struct in_addr ip4;
816
817 clib_memcpy (&ip4, &addr->un.ip4, sizeof (ip4));
818 vat_json_object_add_ip4 (node, str, ip4);
819 }
820}
821
822static void
823vat_json_object_add_prefix (vat_json_node_t * node,
824 const vl_api_prefix_t * prefix)
825{
Paul Vinciguerraab055082019-06-06 14:07:55 -0400826 vat_json_object_add_uint (node, "len", prefix->len);
827 vat_json_object_add_address (node, "address", &prefix->address);
Neale Ranns097fa662018-05-01 05:17:55 -0700828}
829
Damjan Marion7cd468a2016-12-19 23:05:39 +0100830static void vl_api_create_loopback_reply_t_handler
831 (vl_api_create_loopback_reply_t * mp)
832{
833 vat_main_t *vam = &vat_main;
834 i32 retval = ntohl (mp->retval);
835
836 vam->retval = retval;
837 vam->regenerate_interface_table = 1;
838 vam->sw_if_index = ntohl (mp->sw_if_index);
839 vam->result_ready = 1;
840}
841
842static void vl_api_create_loopback_reply_t_handler_json
843 (vl_api_create_loopback_reply_t * mp)
844{
845 vat_main_t *vam = &vat_main;
846 vat_json_node_t node;
847
848 vat_json_init_object (&node);
849 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
850 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
851
852 vat_json_print (vam->ofp, &node);
853 vat_json_free (&node);
854 vam->retval = ntohl (mp->retval);
855 vam->result_ready = 1;
856}
857
Jon Loeligerc83c3b72017-02-23 13:57:35 -0600858static void vl_api_create_loopback_instance_reply_t_handler
859 (vl_api_create_loopback_instance_reply_t * mp)
860{
861 vat_main_t *vam = &vat_main;
862 i32 retval = ntohl (mp->retval);
863
864 vam->retval = retval;
865 vam->regenerate_interface_table = 1;
866 vam->sw_if_index = ntohl (mp->sw_if_index);
867 vam->result_ready = 1;
868}
869
870static void vl_api_create_loopback_instance_reply_t_handler_json
871 (vl_api_create_loopback_instance_reply_t * mp)
872{
873 vat_main_t *vam = &vat_main;
874 vat_json_node_t node;
875
876 vat_json_init_object (&node);
877 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
878 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
879
880 vat_json_print (vam->ofp, &node);
881 vat_json_free (&node);
882 vam->retval = ntohl (mp->retval);
883 vam->result_ready = 1;
884}
885
Damjan Marion7cd468a2016-12-19 23:05:39 +0100886static void vl_api_af_packet_create_reply_t_handler
887 (vl_api_af_packet_create_reply_t * mp)
888{
889 vat_main_t *vam = &vat_main;
890 i32 retval = ntohl (mp->retval);
891
892 vam->retval = retval;
893 vam->regenerate_interface_table = 1;
894 vam->sw_if_index = ntohl (mp->sw_if_index);
895 vam->result_ready = 1;
896}
897
898static void vl_api_af_packet_create_reply_t_handler_json
899 (vl_api_af_packet_create_reply_t * mp)
900{
901 vat_main_t *vam = &vat_main;
902 vat_json_node_t node;
903
904 vat_json_init_object (&node);
905 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
906 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
907
908 vat_json_print (vam->ofp, &node);
909 vat_json_free (&node);
910
911 vam->retval = ntohl (mp->retval);
912 vam->result_ready = 1;
913}
914
915static void vl_api_create_vlan_subif_reply_t_handler
916 (vl_api_create_vlan_subif_reply_t * mp)
917{
918 vat_main_t *vam = &vat_main;
919 i32 retval = ntohl (mp->retval);
920
921 vam->retval = retval;
922 vam->regenerate_interface_table = 1;
923 vam->sw_if_index = ntohl (mp->sw_if_index);
924 vam->result_ready = 1;
925}
926
927static void vl_api_create_vlan_subif_reply_t_handler_json
928 (vl_api_create_vlan_subif_reply_t * mp)
929{
930 vat_main_t *vam = &vat_main;
931 vat_json_node_t node;
932
933 vat_json_init_object (&node);
934 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
935 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
936
937 vat_json_print (vam->ofp, &node);
938 vat_json_free (&node);
939
940 vam->retval = ntohl (mp->retval);
941 vam->result_ready = 1;
942}
943
944static void vl_api_create_subif_reply_t_handler
945 (vl_api_create_subif_reply_t * mp)
946{
947 vat_main_t *vam = &vat_main;
948 i32 retval = ntohl (mp->retval);
949
950 vam->retval = retval;
951 vam->regenerate_interface_table = 1;
952 vam->sw_if_index = ntohl (mp->sw_if_index);
953 vam->result_ready = 1;
954}
955
956static void vl_api_create_subif_reply_t_handler_json
957 (vl_api_create_subif_reply_t * mp)
958{
959 vat_main_t *vam = &vat_main;
960 vat_json_node_t node;
961
962 vat_json_init_object (&node);
963 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
964 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
965
966 vat_json_print (vam->ofp, &node);
967 vat_json_free (&node);
968
969 vam->retval = ntohl (mp->retval);
970 vam->result_ready = 1;
971}
972
973static void vl_api_interface_name_renumber_reply_t_handler
974 (vl_api_interface_name_renumber_reply_t * mp)
975{
976 vat_main_t *vam = &vat_main;
977 i32 retval = ntohl (mp->retval);
978
979 vam->retval = retval;
980 vam->regenerate_interface_table = 1;
981 vam->result_ready = 1;
982}
983
984static void vl_api_interface_name_renumber_reply_t_handler_json
985 (vl_api_interface_name_renumber_reply_t * mp)
986{
987 vat_main_t *vam = &vat_main;
988 vat_json_node_t node;
989
990 vat_json_init_object (&node);
991 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
992
993 vat_json_print (vam->ofp, &node);
994 vat_json_free (&node);
995
996 vam->retval = ntohl (mp->retval);
997 vam->result_ready = 1;
998}
999
1000/*
1001 * Special-case: build the interface table, maintain
1002 * the next loopback sw_if_index vbl.
1003 */
1004static void vl_api_sw_interface_details_t_handler
1005 (vl_api_sw_interface_details_t * mp)
1006{
1007 vat_main_t *vam = &vat_main;
Ole Troane5ff5a32019-08-23 22:55:18 +02001008 u8 *s = format (0, "%s%c", mp->interface_name, 0);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001009
1010 hash_set_mem (vam->sw_if_index_by_interface_name, s,
1011 ntohl (mp->sw_if_index));
1012
1013 /* In sub interface case, fill the sub interface table entry */
1014 if (mp->sw_if_index != mp->sup_sw_if_index)
1015 {
1016 sw_interface_subif_t *sub = NULL;
1017
1018 vec_add2 (vam->sw_if_subif_table, sub, 1);
1019
1020 vec_validate (sub->interface_name, strlen ((char *) s) + 1);
1021 strncpy ((char *) sub->interface_name, (char *) s,
1022 vec_len (sub->interface_name));
1023 sub->sw_if_index = ntohl (mp->sw_if_index);
1024 sub->sub_id = ntohl (mp->sub_id);
1025
Jakub Grajciar053204a2019-03-18 13:17:53 +01001026 sub->raw_flags = ntohl (mp->sub_if_flags & SUB_IF_API_FLAG_MASK_VNET);
1027
Damjan Marion7cd468a2016-12-19 23:05:39 +01001028 sub->sub_number_of_tags = mp->sub_number_of_tags;
1029 sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
1030 sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001031
1032 /* vlan tag rewrite */
1033 sub->vtr_op = ntohl (mp->vtr_op);
1034 sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
1035 sub->vtr_tag1 = ntohl (mp->vtr_tag1);
1036 sub->vtr_tag2 = ntohl (mp->vtr_tag2);
1037 }
1038}
1039
1040static void vl_api_sw_interface_details_t_handler_json
1041 (vl_api_sw_interface_details_t * mp)
1042{
1043 vat_main_t *vam = &vat_main;
1044 vat_json_node_t *node = NULL;
1045
1046 if (VAT_JSON_ARRAY != vam->json_tree.type)
1047 {
1048 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1049 vat_json_init_array (&vam->json_tree);
1050 }
1051 node = vat_json_array_add (&vam->json_tree);
1052
1053 vat_json_init_object (node);
1054 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1055 vat_json_object_add_uint (node, "sup_sw_if_index",
1056 ntohl (mp->sup_sw_if_index));
Damjan Marion7cd468a2016-12-19 23:05:39 +01001057 vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
1058 sizeof (mp->l2_address));
1059 vat_json_object_add_string_copy (node, "interface_name",
Ole Troane5ff5a32019-08-23 22:55:18 +02001060 mp->interface_name);
Mohsin Kazmide312c22019-09-27 13:44:28 +02001061 vat_json_object_add_string_copy (node, "interface_dev_type",
1062 mp->interface_dev_type);
Jakub Grajciar053204a2019-03-18 13:17:53 +01001063 vat_json_object_add_uint (node, "flags", mp->flags);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001064 vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
1065 vat_json_object_add_uint (node, "link_speed", mp->link_speed);
Damjan Marionfe7d4a22018-04-13 19:43:39 +02001066 vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
Damjan Marion7cd468a2016-12-19 23:05:39 +01001067 vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
Damjan Marion7cd468a2016-12-19 23:05:39 +01001068 vat_json_object_add_uint (node, "sub_number_of_tags",
1069 mp->sub_number_of_tags);
1070 vat_json_object_add_uint (node, "sub_outer_vlan_id",
1071 ntohs (mp->sub_outer_vlan_id));
1072 vat_json_object_add_uint (node, "sub_inner_vlan_id",
1073 ntohs (mp->sub_inner_vlan_id));
Jakub Grajciar053204a2019-03-18 13:17:53 +01001074 vat_json_object_add_uint (node, "sub_if_flags", ntohl (mp->sub_if_flags));
Damjan Marion7cd468a2016-12-19 23:05:39 +01001075 vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1076 vat_json_object_add_uint (node, "vtr_push_dot1q",
1077 ntohl (mp->vtr_push_dot1q));
1078 vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1079 vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
Jakub Grajciar053204a2019-03-18 13:17:53 +01001080 if (ntohl (mp->sub_if_flags) & SUB_IF_API_FLAG_DOT1AH)
Pavel Kotucek65e84572017-01-16 17:01:56 +01001081 {
1082 vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1083 format (0, "%U",
1084 format_ethernet_address,
1085 &mp->b_dmac));
1086 vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1087 format (0, "%U",
1088 format_ethernet_address,
1089 &mp->b_smac));
1090 vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1091 vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1092 }
Damjan Marion7cd468a2016-12-19 23:05:39 +01001093}
1094
Dave Baracha1a093d2017-03-02 13:13:23 -05001095#if VPP_API_TEST_BUILTIN == 0
Neale Rannsa07bd702017-08-07 07:53:49 -07001096static void vl_api_sw_interface_event_t_handler
1097 (vl_api_sw_interface_event_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01001098{
1099 vat_main_t *vam = &vat_main;
1100 if (vam->interface_event_display)
1101 errmsg ("interface flags: sw_if_index %d %s %s",
1102 ntohl (mp->sw_if_index),
Jakub Grajciar053204a2019-03-18 13:17:53 +01001103 ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_ADMIN_UP) ?
1104 "admin-up" : "admin-down",
1105 ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_LINK_UP) ?
1106 "link-up" : "link-down");
Damjan Marion7cd468a2016-12-19 23:05:39 +01001107}
Dave Baracha1a093d2017-03-02 13:13:23 -05001108#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +01001109
Benoît Ganne49ee6842019-04-30 11:50:46 +02001110__clib_unused static void
1111vl_api_sw_interface_event_t_handler_json (vl_api_sw_interface_event_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01001112{
1113 /* JSON output not supported */
1114}
1115
1116static void
1117vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1118{
1119 vat_main_t *vam = &vat_main;
1120 i32 retval = ntohl (mp->retval);
1121
1122 vam->retval = retval;
Damjan Marion7bee80c2017-04-26 15:32:12 +02001123 vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001124 vam->result_ready = 1;
1125}
1126
1127static void
1128vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1129{
1130 vat_main_t *vam = &vat_main;
1131 vat_json_node_t node;
Damjan Marion7cd468a2016-12-19 23:05:39 +01001132 void *oldheap;
1133 u8 *reply;
1134
1135 vat_json_init_object (&node);
1136 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1137 vat_json_object_add_uint (&node, "reply_in_shmem",
1138 ntohl (mp->reply_in_shmem));
1139 /* Toss the shared-memory original... */
Nathan Skrzypczak0aa40132019-11-25 16:29:38 +01001140 oldheap = vl_msg_push_heap ();
Damjan Marion7cd468a2016-12-19 23:05:39 +01001141
Damjan Marion7bee80c2017-04-26 15:32:12 +02001142 reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001143 vec_free (reply);
1144
Nathan Skrzypczak0aa40132019-11-25 16:29:38 +01001145 vl_msg_pop_heap (oldheap);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001146
1147 vat_json_print (vam->ofp, &node);
1148 vat_json_free (&node);
1149
1150 vam->retval = ntohl (mp->retval);
1151 vam->result_ready = 1;
1152}
1153
1154static void
1155vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1156{
1157 vat_main_t *vam = &vat_main;
1158 i32 retval = ntohl (mp->retval);
Dave Barach59b25652017-09-10 15:04:27 -04001159
1160 vec_reset_length (vam->cmd_reply);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001161
1162 vam->retval = retval;
Dave Barach59b25652017-09-10 15:04:27 -04001163 if (retval == 0)
Dave Barach77841402020-04-29 17:04:10 -04001164 vam->cmd_reply = vl_api_from_api_to_new_vec (mp, &mp->reply);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001165 vam->result_ready = 1;
1166}
1167
1168static void
1169vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1170{
1171 vat_main_t *vam = &vat_main;
1172 vat_json_node_t node;
Jakub Grajciar2dbee932020-02-07 11:30:26 +01001173 u8 *reply = 0; /* reply vector */
Damjan Marion7cd468a2016-12-19 23:05:39 +01001174
Dave Barach77841402020-04-29 17:04:10 -04001175 reply = vl_api_from_api_to_new_vec (mp, &mp->reply);
Dave Barach59b25652017-09-10 15:04:27 -04001176 vec_reset_length (vam->cmd_reply);
1177
Damjan Marion7cd468a2016-12-19 23:05:39 +01001178 vat_json_init_object (&node);
1179 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
Jakub Grajciar2dbee932020-02-07 11:30:26 +01001180 vat_json_object_add_string_copy (&node, "reply", reply);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001181
1182 vat_json_print (vam->ofp, &node);
1183 vat_json_free (&node);
Jakub Grajciar2dbee932020-02-07 11:30:26 +01001184 vec_free (reply);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001185
1186 vam->retval = ntohl (mp->retval);
1187 vam->result_ready = 1;
1188}
1189
1190static void vl_api_classify_add_del_table_reply_t_handler
1191 (vl_api_classify_add_del_table_reply_t * mp)
1192{
1193 vat_main_t *vam = &vat_main;
1194 i32 retval = ntohl (mp->retval);
1195 if (vam->async_mode)
1196 {
1197 vam->async_errors += (retval < 0);
1198 }
1199 else
1200 {
1201 vam->retval = retval;
1202 if (retval == 0 &&
1203 ((mp->new_table_index != 0xFFFFFFFF) ||
1204 (mp->skip_n_vectors != 0xFFFFFFFF) ||
1205 (mp->match_n_vectors != 0xFFFFFFFF)))
1206 /*
1207 * Note: this is just barely thread-safe, depends on
1208 * the main thread spinning waiting for an answer...
1209 */
1210 errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1211 ntohl (mp->new_table_index),
1212 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1213 vam->result_ready = 1;
1214 }
1215}
1216
1217static void vl_api_classify_add_del_table_reply_t_handler_json
1218 (vl_api_classify_add_del_table_reply_t * mp)
1219{
1220 vat_main_t *vam = &vat_main;
1221 vat_json_node_t node;
1222
1223 vat_json_init_object (&node);
1224 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1225 vat_json_object_add_uint (&node, "new_table_index",
1226 ntohl (mp->new_table_index));
1227 vat_json_object_add_uint (&node, "skip_n_vectors",
1228 ntohl (mp->skip_n_vectors));
1229 vat_json_object_add_uint (&node, "match_n_vectors",
1230 ntohl (mp->match_n_vectors));
1231
1232 vat_json_print (vam->ofp, &node);
1233 vat_json_free (&node);
1234
1235 vam->retval = ntohl (mp->retval);
1236 vam->result_ready = 1;
1237}
1238
1239static void vl_api_get_node_index_reply_t_handler
1240 (vl_api_get_node_index_reply_t * mp)
1241{
1242 vat_main_t *vam = &vat_main;
1243 i32 retval = ntohl (mp->retval);
1244 if (vam->async_mode)
1245 {
1246 vam->async_errors += (retval < 0);
1247 }
1248 else
1249 {
1250 vam->retval = retval;
1251 if (retval == 0)
1252 errmsg ("node index %d", ntohl (mp->node_index));
1253 vam->result_ready = 1;
1254 }
1255}
1256
1257static void vl_api_get_node_index_reply_t_handler_json
1258 (vl_api_get_node_index_reply_t * mp)
1259{
1260 vat_main_t *vam = &vat_main;
1261 vat_json_node_t node;
1262
1263 vat_json_init_object (&node);
1264 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1265 vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1266
1267 vat_json_print (vam->ofp, &node);
1268 vat_json_free (&node);
1269
1270 vam->retval = ntohl (mp->retval);
1271 vam->result_ready = 1;
1272}
1273
1274static void vl_api_get_next_index_reply_t_handler
1275 (vl_api_get_next_index_reply_t * mp)
1276{
1277 vat_main_t *vam = &vat_main;
1278 i32 retval = ntohl (mp->retval);
1279 if (vam->async_mode)
1280 {
1281 vam->async_errors += (retval < 0);
1282 }
1283 else
1284 {
1285 vam->retval = retval;
1286 if (retval == 0)
1287 errmsg ("next node index %d", ntohl (mp->next_index));
1288 vam->result_ready = 1;
1289 }
1290}
1291
1292static void vl_api_get_next_index_reply_t_handler_json
1293 (vl_api_get_next_index_reply_t * mp)
1294{
1295 vat_main_t *vam = &vat_main;
1296 vat_json_node_t node;
1297
1298 vat_json_init_object (&node);
1299 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1300 vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1301
1302 vat_json_print (vam->ofp, &node);
1303 vat_json_free (&node);
1304
1305 vam->retval = ntohl (mp->retval);
1306 vam->result_ready = 1;
1307}
1308
1309static void vl_api_add_node_next_reply_t_handler
1310 (vl_api_add_node_next_reply_t * mp)
1311{
1312 vat_main_t *vam = &vat_main;
1313 i32 retval = ntohl (mp->retval);
1314 if (vam->async_mode)
1315 {
1316 vam->async_errors += (retval < 0);
1317 }
1318 else
1319 {
1320 vam->retval = retval;
1321 if (retval == 0)
1322 errmsg ("next index %d", ntohl (mp->next_index));
1323 vam->result_ready = 1;
1324 }
1325}
1326
1327static void vl_api_add_node_next_reply_t_handler_json
1328 (vl_api_add_node_next_reply_t * mp)
1329{
1330 vat_main_t *vam = &vat_main;
1331 vat_json_node_t node;
1332
1333 vat_json_init_object (&node);
1334 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1335 vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1336
1337 vat_json_print (vam->ofp, &node);
1338 vat_json_free (&node);
1339
1340 vam->retval = ntohl (mp->retval);
1341 vam->result_ready = 1;
1342}
1343
1344static void vl_api_show_version_reply_t_handler
1345 (vl_api_show_version_reply_t * mp)
1346{
1347 vat_main_t *vam = &vat_main;
1348 i32 retval = ntohl (mp->retval);
1349
1350 if (retval >= 0)
1351 {
Ole Troane5ff5a32019-08-23 22:55:18 +02001352 errmsg (" program: %s", mp->program);
1353 errmsg (" version: %s", mp->version);
1354 errmsg (" build date: %s", mp->build_date);
1355 errmsg ("build directory: %s", mp->build_directory);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001356 }
1357 vam->retval = retval;
1358 vam->result_ready = 1;
1359}
1360
1361static void vl_api_show_version_reply_t_handler_json
1362 (vl_api_show_version_reply_t * mp)
1363{
1364 vat_main_t *vam = &vat_main;
1365 vat_json_node_t node;
1366
1367 vat_json_init_object (&node);
1368 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
Ole Troane5ff5a32019-08-23 22:55:18 +02001369 vat_json_object_add_string_copy (&node, "program", mp->program);
1370 vat_json_object_add_string_copy (&node, "version", mp->version);
1371 vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001372 vat_json_object_add_string_copy (&node, "build_directory",
Ole Troane5ff5a32019-08-23 22:55:18 +02001373 mp->build_directory);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001374
1375 vat_json_print (vam->ofp, &node);
1376 vat_json_free (&node);
1377
1378 vam->retval = ntohl (mp->retval);
1379 vam->result_ready = 1;
1380}
1381
Mohsin Kazmi5d64c782018-09-11 20:27:09 +02001382static void vl_api_show_threads_reply_t_handler
1383 (vl_api_show_threads_reply_t * mp)
1384{
1385 vat_main_t *vam = &vat_main;
1386 i32 retval = ntohl (mp->retval);
1387 int i, count = 0;
1388
1389 if (retval >= 0)
1390 count = ntohl (mp->count);
1391
1392 for (i = 0; i < count; i++)
1393 print (vam->ofp,
1394 "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1395 ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1396 mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1397 ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1398 ntohl (mp->thread_data[i].cpu_socket));
1399
1400 vam->retval = retval;
1401 vam->result_ready = 1;
1402}
1403
1404static void vl_api_show_threads_reply_t_handler_json
1405 (vl_api_show_threads_reply_t * mp)
1406{
1407 vat_main_t *vam = &vat_main;
1408 vat_json_node_t node;
1409 vl_api_thread_data_t *td;
Mohsin Kazmi5df628b2018-10-01 17:41:08 +02001410 i32 retval = ntohl (mp->retval);
1411 int i, count = 0;
1412
1413 if (retval >= 0)
1414 count = ntohl (mp->count);
Mohsin Kazmi5d64c782018-09-11 20:27:09 +02001415
1416 vat_json_init_object (&node);
Mohsin Kazmi5df628b2018-10-01 17:41:08 +02001417 vat_json_object_add_int (&node, "retval", retval);
Mohsin Kazmi5d64c782018-09-11 20:27:09 +02001418 vat_json_object_add_uint (&node, "count", count);
1419
1420 for (i = 0; i < count; i++)
1421 {
1422 td = &mp->thread_data[i];
1423 vat_json_object_add_uint (&node, "id", ntohl (td->id));
1424 vat_json_object_add_string_copy (&node, "name", td->name);
1425 vat_json_object_add_string_copy (&node, "type", td->type);
1426 vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1427 vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1428 vat_json_object_add_int (&node, "core", ntohl (td->id));
1429 vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1430 }
1431
1432 vat_json_print (vam->ofp, &node);
1433 vat_json_free (&node);
1434
Mohsin Kazmi5df628b2018-10-01 17:41:08 +02001435 vam->retval = retval;
Mohsin Kazmi5d64c782018-09-11 20:27:09 +02001436 vam->result_ready = 1;
1437}
1438
1439static int
1440api_show_threads (vat_main_t * vam)
1441{
1442 vl_api_show_threads_t *mp;
1443 int ret;
1444
1445 print (vam->ofp,
1446 "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1447 "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1448
1449 M (SHOW_THREADS, mp);
1450
1451 S (mp);
1452 W (ret);
1453 return ret;
1454}
1455
Damjan Marion7cd468a2016-12-19 23:05:39 +01001456static void
John Lo8d00fff2017-08-03 00:35:36 -04001457vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1458{
1459 u32 n_macs = ntohl (mp->n_macs);
Paul Vinciguerraec11b132018-09-24 05:25:00 -07001460 errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
John Lo8d00fff2017-08-03 00:35:36 -04001461 ntohl (mp->pid), mp->client_index, n_macs);
1462 int i;
1463 for (i = 0; i < n_macs; i++)
1464 {
1465 vl_api_mac_entry_t *mac = &mp->mac[i];
John Loe23c99e2018-03-13 21:53:18 -04001466 errmsg (" [%d] sw_if_index %d mac_addr %U action %d \n",
John Lo8d00fff2017-08-03 00:35:36 -04001467 i + 1, ntohl (mac->sw_if_index),
John Loe23c99e2018-03-13 21:53:18 -04001468 format_ethernet_address, mac->mac_addr, mac->action);
John Lo8d00fff2017-08-03 00:35:36 -04001469 if (i == 1000)
1470 break;
1471 }
1472}
1473
1474static void
1475vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1476{
1477 /* JSON output not supported */
1478}
1479
Ole Troan01384fe2017-05-12 11:55:35 +02001480#define vl_api_bridge_domain_details_t_endian vl_noop_handler
1481#define vl_api_bridge_domain_details_t_print vl_noop_handler
1482
Damjan Marion7cd468a2016-12-19 23:05:39 +01001483/*
1484 * Special-case: build the bridge domain table, maintain
1485 * the next bd id vbl.
1486 */
1487static void vl_api_bridge_domain_details_t_handler
1488 (vl_api_bridge_domain_details_t * mp)
1489{
1490 vat_main_t *vam = &vat_main;
1491 u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
Ole Troan01384fe2017-05-12 11:55:35 +02001492 int i;
Damjan Marion7cd468a2016-12-19 23:05:39 +01001493
Mohsin Kazmi762d83c2018-09-27 15:00:32 +02001494 print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1495 " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
Damjan Marion7cd468a2016-12-19 23:05:39 +01001496
Mohsin Kazmi762d83c2018-09-27 15:00:32 +02001497 print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
Damjan Marion7cd468a2016-12-19 23:05:39 +01001498 ntohl (mp->bd_id), mp->learn, mp->forward,
Mohsin Kazmi762d83c2018-09-27 15:00:32 +02001499 mp->flood, ntohl (mp->bvi_sw_if_index),
1500 ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001501
1502 if (n_sw_ifs)
Ole Troan01384fe2017-05-12 11:55:35 +02001503 {
1504 vl_api_bridge_domain_sw_if_t *sw_ifs;
1505 print (vam->ofp, "\n\n%s %s %s", "sw_if_index", "SHG",
1506 "Interface Name");
1507
1508 sw_ifs = mp->sw_if_details;
1509 for (i = 0; i < n_sw_ifs; i++)
1510 {
1511 u8 *sw_if_name = 0;
1512 u32 sw_if_index;
1513 hash_pair_t *p;
1514
1515 sw_if_index = ntohl (sw_ifs->sw_if_index);
1516
1517 /* *INDENT-OFF* */
1518 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1519 ({
1520 if ((u32) p->value[0] == sw_if_index)
1521 {
1522 sw_if_name = (u8 *)(p->key);
1523 break;
1524 }
1525 }));
1526 /* *INDENT-ON* */
1527 print (vam->ofp, "%7d %3d %s", sw_if_index,
1528 sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1529 "sw_if_index not found!");
1530
1531 sw_ifs++;
1532 }
1533 }
Damjan Marion7cd468a2016-12-19 23:05:39 +01001534}
1535
1536static void vl_api_bridge_domain_details_t_handler_json
1537 (vl_api_bridge_domain_details_t * mp)
1538{
1539 vat_main_t *vam = &vat_main;
1540 vat_json_node_t *node, *array = NULL;
Ole Troan01384fe2017-05-12 11:55:35 +02001541 u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001542
1543 if (VAT_JSON_ARRAY != vam->json_tree.type)
1544 {
1545 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1546 vat_json_init_array (&vam->json_tree);
1547 }
1548 node = vat_json_array_add (&vam->json_tree);
1549
1550 vat_json_init_object (node);
1551 vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1552 vat_json_object_add_uint (node, "flood", mp->flood);
1553 vat_json_object_add_uint (node, "forward", mp->forward);
1554 vat_json_object_add_uint (node, "learn", mp->learn);
1555 vat_json_object_add_uint (node, "bvi_sw_if_index",
1556 ntohl (mp->bvi_sw_if_index));
Ole Troan01384fe2017-05-12 11:55:35 +02001557 vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001558 array = vat_json_object_add (node, "sw_if");
1559 vat_json_init_array (array);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001560
Damjan Marion7cd468a2016-12-19 23:05:39 +01001561
Damjan Marion7cd468a2016-12-19 23:05:39 +01001562
Ole Troan01384fe2017-05-12 11:55:35 +02001563 if (n_sw_ifs)
1564 {
1565 vl_api_bridge_domain_sw_if_t *sw_ifs;
1566 int i;
Damjan Marion7cd468a2016-12-19 23:05:39 +01001567
Ole Troan01384fe2017-05-12 11:55:35 +02001568 sw_ifs = mp->sw_if_details;
1569 for (i = 0; i < n_sw_ifs; i++)
1570 {
1571 node = vat_json_array_add (array);
1572 vat_json_init_object (node);
1573 vat_json_object_add_uint (node, "sw_if_index",
1574 ntohl (sw_ifs->sw_if_index));
1575 vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1576 sw_ifs++;
1577 }
1578 }
Damjan Marion7cd468a2016-12-19 23:05:39 +01001579}
1580
1581static void vl_api_control_ping_reply_t_handler
1582 (vl_api_control_ping_reply_t * mp)
1583{
1584 vat_main_t *vam = &vat_main;
1585 i32 retval = ntohl (mp->retval);
1586 if (vam->async_mode)
1587 {
1588 vam->async_errors += (retval < 0);
1589 }
1590 else
1591 {
1592 vam->retval = retval;
1593 vam->result_ready = 1;
1594 }
Florin Coras90a63982017-12-19 04:50:01 -08001595 if (vam->socket_client_main)
1596 vam->socket_client_main->control_pings_outstanding--;
Damjan Marion7cd468a2016-12-19 23:05:39 +01001597}
1598
1599static void vl_api_control_ping_reply_t_handler_json
1600 (vl_api_control_ping_reply_t * mp)
1601{
1602 vat_main_t *vam = &vat_main;
1603 i32 retval = ntohl (mp->retval);
1604
1605 if (VAT_JSON_NONE != vam->json_tree.type)
1606 {
1607 vat_json_print (vam->ofp, &vam->json_tree);
1608 vat_json_free (&vam->json_tree);
1609 vam->json_tree.type = VAT_JSON_NONE;
1610 }
1611 else
1612 {
1613 /* just print [] */
1614 vat_json_init_array (&vam->json_tree);
1615 vat_json_print (vam->ofp, &vam->json_tree);
1616 vam->json_tree.type = VAT_JSON_NONE;
1617 }
1618
1619 vam->retval = retval;
1620 vam->result_ready = 1;
1621}
1622
1623static void
Eyal Barifead6702017-04-04 04:46:32 +03001624 vl_api_bridge_domain_set_mac_age_reply_t_handler
1625 (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1626{
1627 vat_main_t *vam = &vat_main;
1628 i32 retval = ntohl (mp->retval);
1629 if (vam->async_mode)
1630 {
1631 vam->async_errors += (retval < 0);
1632 }
1633 else
1634 {
1635 vam->retval = retval;
1636 vam->result_ready = 1;
1637 }
1638}
1639
1640static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1641 (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1642{
1643 vat_main_t *vam = &vat_main;
1644 vat_json_node_t node;
1645
1646 vat_json_init_object (&node);
1647 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1648
1649 vat_json_print (vam->ofp, &node);
1650 vat_json_free (&node);
1651
1652 vam->retval = ntohl (mp->retval);
1653 vam->result_ready = 1;
1654}
1655
1656static void
Damjan Marion7cd468a2016-12-19 23:05:39 +01001657vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1658{
1659 vat_main_t *vam = &vat_main;
1660 i32 retval = ntohl (mp->retval);
1661 if (vam->async_mode)
1662 {
1663 vam->async_errors += (retval < 0);
1664 }
1665 else
1666 {
1667 vam->retval = retval;
1668 vam->result_ready = 1;
1669 }
1670}
1671
1672static void vl_api_l2_flags_reply_t_handler_json
1673 (vl_api_l2_flags_reply_t * mp)
1674{
1675 vat_main_t *vam = &vat_main;
1676 vat_json_node_t node;
1677
1678 vat_json_init_object (&node);
1679 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1680 vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1681 ntohl (mp->resulting_feature_bitmap));
1682
1683 vat_json_print (vam->ofp, &node);
1684 vat_json_free (&node);
1685
1686 vam->retval = ntohl (mp->retval);
1687 vam->result_ready = 1;
1688}
1689
1690static void vl_api_bridge_flags_reply_t_handler
1691 (vl_api_bridge_flags_reply_t * mp)
1692{
1693 vat_main_t *vam = &vat_main;
1694 i32 retval = ntohl (mp->retval);
1695 if (vam->async_mode)
1696 {
1697 vam->async_errors += (retval < 0);
1698 }
1699 else
1700 {
1701 vam->retval = retval;
1702 vam->result_ready = 1;
1703 }
1704}
1705
1706static void vl_api_bridge_flags_reply_t_handler_json
1707 (vl_api_bridge_flags_reply_t * mp)
1708{
1709 vat_main_t *vam = &vat_main;
1710 vat_json_node_t node;
1711
1712 vat_json_init_object (&node);
1713 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1714 vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1715 ntohl (mp->resulting_feature_bitmap));
1716
1717 vat_json_print (vam->ofp, &node);
1718 vat_json_free (&node);
1719
1720 vam->retval = ntohl (mp->retval);
1721 vam->result_ready = 1;
1722}
1723
Damjan Marion8389fb92017-10-13 18:29:53 +02001724static void
1725vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1726{
1727 vat_main_t *vam = &vat_main;
1728 i32 retval = ntohl (mp->retval);
1729 if (vam->async_mode)
1730 {
1731 vam->async_errors += (retval < 0);
1732 }
1733 else
1734 {
1735 vam->retval = retval;
1736 vam->sw_if_index = ntohl (mp->sw_if_index);
1737 vam->result_ready = 1;
1738 }
1739
1740}
1741
1742static void vl_api_tap_create_v2_reply_t_handler_json
1743 (vl_api_tap_create_v2_reply_t * mp)
1744{
1745 vat_main_t *vam = &vat_main;
1746 vat_json_node_t node;
1747
1748 vat_json_init_object (&node);
1749 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1750 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1751
1752 vat_json_print (vam->ofp, &node);
1753 vat_json_free (&node);
1754
1755 vam->retval = ntohl (mp->retval);
1756 vam->result_ready = 1;
1757
1758}
1759
1760static void
1761vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1762{
1763 vat_main_t *vam = &vat_main;
1764 i32 retval = ntohl (mp->retval);
1765 if (vam->async_mode)
1766 {
1767 vam->async_errors += (retval < 0);
1768 }
1769 else
1770 {
1771 vam->retval = retval;
1772 vam->result_ready = 1;
1773 }
1774}
1775
1776static void vl_api_tap_delete_v2_reply_t_handler_json
1777 (vl_api_tap_delete_v2_reply_t * mp)
1778{
1779 vat_main_t *vam = &vat_main;
1780 vat_json_node_t node;
1781
1782 vat_json_init_object (&node);
1783 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1784
1785 vat_json_print (vam->ofp, &node);
1786 vat_json_free (&node);
1787
1788 vam->retval = ntohl (mp->retval);
1789 vam->result_ready = 1;
1790}
1791
Steven9cd2d7a2017-12-20 12:43:01 -08001792static void
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01001793vl_api_virtio_pci_create_reply_t_handler (vl_api_virtio_pci_create_reply_t *
1794 mp)
1795{
1796 vat_main_t *vam = &vat_main;
1797 i32 retval = ntohl (mp->retval);
1798 if (vam->async_mode)
1799 {
1800 vam->async_errors += (retval < 0);
1801 }
1802 else
1803 {
1804 vam->retval = retval;
1805 vam->sw_if_index = ntohl (mp->sw_if_index);
1806 vam->result_ready = 1;
1807 }
1808}
1809
1810static void vl_api_virtio_pci_create_reply_t_handler_json
1811 (vl_api_virtio_pci_create_reply_t * mp)
1812{
1813 vat_main_t *vam = &vat_main;
1814 vat_json_node_t node;
1815
1816 vat_json_init_object (&node);
1817 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1818 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1819
1820 vat_json_print (vam->ofp, &node);
1821 vat_json_free (&node);
1822
1823 vam->retval = ntohl (mp->retval);
1824 vam->result_ready = 1;
1825
1826}
1827
1828static void
Mohsin Kazmi518251b2020-09-01 17:17:44 +00001829 vl_api_virtio_pci_create_v2_reply_t_handler
1830 (vl_api_virtio_pci_create_v2_reply_t * mp)
1831{
1832 vat_main_t *vam = &vat_main;
1833 i32 retval = ntohl (mp->retval);
1834 if (vam->async_mode)
1835 {
1836 vam->async_errors += (retval < 0);
1837 }
1838 else
1839 {
1840 vam->retval = retval;
1841 vam->sw_if_index = ntohl (mp->sw_if_index);
1842 vam->result_ready = 1;
1843 }
1844}
1845
1846static void vl_api_virtio_pci_create_v2_reply_t_handler_json
1847 (vl_api_virtio_pci_create_v2_reply_t * mp)
1848{
1849 vat_main_t *vam = &vat_main;
1850 vat_json_node_t node;
1851
1852 vat_json_init_object (&node);
1853 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1854 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1855
1856 vat_json_print (vam->ofp, &node);
1857 vat_json_free (&node);
1858
1859 vam->retval = ntohl (mp->retval);
1860 vam->result_ready = 1;
1861}
1862
1863static void
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01001864vl_api_virtio_pci_delete_reply_t_handler (vl_api_virtio_pci_delete_reply_t *
1865 mp)
1866{
1867 vat_main_t *vam = &vat_main;
1868 i32 retval = ntohl (mp->retval);
1869 if (vam->async_mode)
1870 {
1871 vam->async_errors += (retval < 0);
1872 }
1873 else
1874 {
1875 vam->retval = retval;
1876 vam->result_ready = 1;
1877 }
1878}
1879
1880static void vl_api_virtio_pci_delete_reply_t_handler_json
1881 (vl_api_virtio_pci_delete_reply_t * mp)
1882{
1883 vat_main_t *vam = &vat_main;
1884 vat_json_node_t node;
1885
1886 vat_json_init_object (&node);
1887 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1888
1889 vat_json_print (vam->ofp, &node);
1890 vat_json_free (&node);
1891
1892 vam->retval = ntohl (mp->retval);
1893 vam->result_ready = 1;
1894}
1895
1896static void
Steven9cd2d7a2017-12-20 12:43:01 -08001897vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1898{
1899 vat_main_t *vam = &vat_main;
1900 i32 retval = ntohl (mp->retval);
1901
1902 if (vam->async_mode)
1903 {
1904 vam->async_errors += (retval < 0);
1905 }
1906 else
1907 {
1908 vam->retval = retval;
1909 vam->sw_if_index = ntohl (mp->sw_if_index);
1910 vam->result_ready = 1;
1911 }
1912}
1913
1914static void vl_api_bond_create_reply_t_handler_json
1915 (vl_api_bond_create_reply_t * mp)
1916{
1917 vat_main_t *vam = &vat_main;
1918 vat_json_node_t node;
1919
1920 vat_json_init_object (&node);
1921 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1922 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1923
1924 vat_json_print (vam->ofp, &node);
1925 vat_json_free (&node);
1926
1927 vam->retval = ntohl (mp->retval);
1928 vam->result_ready = 1;
1929}
1930
1931static void
Steven Luongea717862020-07-30 07:31:40 -07001932vl_api_bond_create2_reply_t_handler (vl_api_bond_create2_reply_t * mp)
1933{
1934 vat_main_t *vam = &vat_main;
1935 i32 retval = ntohl (mp->retval);
1936
1937 if (vam->async_mode)
1938 {
1939 vam->async_errors += (retval < 0);
1940 }
1941 else
1942 {
1943 vam->retval = retval;
1944 vam->sw_if_index = ntohl (mp->sw_if_index);
1945 vam->result_ready = 1;
1946 }
1947}
1948
1949static void vl_api_bond_create2_reply_t_handler_json
1950 (vl_api_bond_create2_reply_t * mp)
1951{
1952 vat_main_t *vam = &vat_main;
1953 vat_json_node_t node;
1954
1955 vat_json_init_object (&node);
1956 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1957 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1958
1959 vat_json_print (vam->ofp, &node);
1960 vat_json_free (&node);
1961
1962 vam->retval = ntohl (mp->retval);
1963 vam->result_ready = 1;
1964}
1965
1966static void
Steven9cd2d7a2017-12-20 12:43:01 -08001967vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1968{
1969 vat_main_t *vam = &vat_main;
1970 i32 retval = ntohl (mp->retval);
1971
1972 if (vam->async_mode)
1973 {
1974 vam->async_errors += (retval < 0);
1975 }
1976 else
1977 {
1978 vam->retval = retval;
1979 vam->result_ready = 1;
1980 }
1981}
1982
1983static void vl_api_bond_delete_reply_t_handler_json
1984 (vl_api_bond_delete_reply_t * mp)
1985{
1986 vat_main_t *vam = &vat_main;
1987 vat_json_node_t node;
1988
1989 vat_json_init_object (&node);
1990 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1991
1992 vat_json_print (vam->ofp, &node);
1993 vat_json_free (&node);
1994
1995 vam->retval = ntohl (mp->retval);
1996 vam->result_ready = 1;
1997}
1998
1999static void
Steven Luong4c4223e2020-07-15 08:44:54 -07002000vl_api_bond_add_member_reply_t_handler (vl_api_bond_add_member_reply_t * mp)
Steven9cd2d7a2017-12-20 12:43:01 -08002001{
2002 vat_main_t *vam = &vat_main;
2003 i32 retval = ntohl (mp->retval);
2004
2005 if (vam->async_mode)
2006 {
2007 vam->async_errors += (retval < 0);
2008 }
2009 else
2010 {
2011 vam->retval = retval;
2012 vam->result_ready = 1;
2013 }
2014}
2015
Steven Luong4c4223e2020-07-15 08:44:54 -07002016static void vl_api_bond_add_member_reply_t_handler_json
2017 (vl_api_bond_add_member_reply_t * mp)
Steven9cd2d7a2017-12-20 12:43:01 -08002018{
2019 vat_main_t *vam = &vat_main;
2020 vat_json_node_t node;
2021
2022 vat_json_init_object (&node);
2023 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2024
2025 vat_json_print (vam->ofp, &node);
2026 vat_json_free (&node);
2027
2028 vam->retval = ntohl (mp->retval);
2029 vam->result_ready = 1;
2030}
2031
2032static void
Steven Luong4c4223e2020-07-15 08:44:54 -07002033vl_api_bond_detach_member_reply_t_handler (vl_api_bond_detach_member_reply_t *
2034 mp)
Steven9cd2d7a2017-12-20 12:43:01 -08002035{
2036 vat_main_t *vam = &vat_main;
2037 i32 retval = ntohl (mp->retval);
2038
2039 if (vam->async_mode)
2040 {
2041 vam->async_errors += (retval < 0);
2042 }
2043 else
2044 {
2045 vam->retval = retval;
2046 vam->result_ready = 1;
2047 }
2048}
2049
Steven Luong4c4223e2020-07-15 08:44:54 -07002050static void vl_api_bond_detach_member_reply_t_handler_json
2051 (vl_api_bond_detach_member_reply_t * mp)
Steven9cd2d7a2017-12-20 12:43:01 -08002052{
2053 vat_main_t *vam = &vat_main;
2054 vat_json_node_t node;
2055
2056 vat_json_init_object (&node);
2057 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2058
2059 vat_json_print (vam->ofp, &node);
2060 vat_json_free (&node);
2061
2062 vam->retval = ntohl (mp->retval);
2063 vam->result_ready = 1;
2064}
2065
Steven Luonga1876b82019-08-20 16:58:00 -07002066static int
2067api_sw_interface_set_bond_weight (vat_main_t * vam)
2068{
2069 unformat_input_t *i = vam->input;
2070 vl_api_sw_interface_set_bond_weight_t *mp;
2071 u32 sw_if_index = ~0;
2072 u32 weight = 0;
2073 u8 weight_enter = 0;
2074 int ret;
2075
2076 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2077 {
2078 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2079 ;
2080 else if (unformat (i, "sw_if_index %d", &sw_if_index))
2081 ;
2082 else if (unformat (i, "weight %u", &weight))
2083 weight_enter = 1;
2084 else
2085 break;
2086 }
2087
2088 if (sw_if_index == ~0)
2089 {
2090 errmsg ("missing interface name or sw_if_index");
2091 return -99;
2092 }
2093 if (weight_enter == 0)
2094 {
2095 errmsg ("missing valid weight");
2096 return -99;
2097 }
2098
2099 /* Construct the API message */
2100 M (SW_INTERFACE_SET_BOND_WEIGHT, mp);
2101 mp->sw_if_index = ntohl (sw_if_index);
2102 mp->weight = ntohl (weight);
2103
2104 S (mp);
2105 W (ret);
2106 return ret;
2107}
2108
Steven Luong4c4223e2020-07-15 08:44:54 -07002109static void vl_api_sw_bond_interface_details_t_handler
2110 (vl_api_sw_bond_interface_details_t * mp)
Steven9cd2d7a2017-12-20 12:43:01 -08002111{
2112 vat_main_t *vam = &vat_main;
2113
2114 print (vam->ofp,
2115 "%-16s %-12d %-12U %-13U %-14u %-14u",
2116 mp->interface_name, ntohl (mp->sw_if_index),
Jakub Grajciar3d1ef872019-08-26 12:55:15 +02002117 format_bond_mode, ntohl (mp->mode), format_bond_load_balance,
Steven Luong4c4223e2020-07-15 08:44:54 -07002118 ntohl (mp->lb), ntohl (mp->active_members), ntohl (mp->members));
Steven9cd2d7a2017-12-20 12:43:01 -08002119}
2120
Steven Luong4c4223e2020-07-15 08:44:54 -07002121static void vl_api_sw_bond_interface_details_t_handler_json
2122 (vl_api_sw_bond_interface_details_t * mp)
Steven9cd2d7a2017-12-20 12:43:01 -08002123{
2124 vat_main_t *vam = &vat_main;
2125 vat_json_node_t *node = NULL;
2126
2127 if (VAT_JSON_ARRAY != vam->json_tree.type)
2128 {
2129 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2130 vat_json_init_array (&vam->json_tree);
2131 }
2132 node = vat_json_array_add (&vam->json_tree);
2133
2134 vat_json_init_object (node);
2135 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2136 vat_json_object_add_string_copy (node, "interface_name",
2137 mp->interface_name);
Jakub Grajciar3d1ef872019-08-26 12:55:15 +02002138 vat_json_object_add_uint (node, "mode", ntohl (mp->mode));
2139 vat_json_object_add_uint (node, "load_balance", ntohl (mp->lb));
Steven Luong4c4223e2020-07-15 08:44:54 -07002140 vat_json_object_add_uint (node, "active_members",
2141 ntohl (mp->active_members));
2142 vat_json_object_add_uint (node, "members", ntohl (mp->members));
Steven9cd2d7a2017-12-20 12:43:01 -08002143}
2144
2145static int
Steven Luong4c4223e2020-07-15 08:44:54 -07002146api_sw_bond_interface_dump (vat_main_t * vam)
Steven9cd2d7a2017-12-20 12:43:01 -08002147{
Steven Luong4c4223e2020-07-15 08:44:54 -07002148 unformat_input_t *i = vam->input;
2149 vl_api_sw_bond_interface_dump_t *mp;
Steven9cd2d7a2017-12-20 12:43:01 -08002150 vl_api_control_ping_t *mp_ping;
2151 int ret;
Steven Luong4c4223e2020-07-15 08:44:54 -07002152 u32 sw_if_index = ~0;
2153
2154 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2155 {
2156 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2157 ;
2158 else if (unformat (i, "sw_if_index %d", &sw_if_index))
2159 ;
2160 else
2161 break;
2162 }
Steven9cd2d7a2017-12-20 12:43:01 -08002163
2164 print (vam->ofp,
2165 "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2166 "interface name", "sw_if_index", "mode", "load balance",
Steven Luong4c4223e2020-07-15 08:44:54 -07002167 "active members", "members");
Steven9cd2d7a2017-12-20 12:43:01 -08002168
2169 /* Get list of bond interfaces */
Steven Luong4c4223e2020-07-15 08:44:54 -07002170 M (SW_BOND_INTERFACE_DUMP, mp);
2171 mp->sw_if_index = ntohl (sw_if_index);
Steven9cd2d7a2017-12-20 12:43:01 -08002172 S (mp);
2173
2174 /* Use a control ping for synchronization */
2175 MPING (CONTROL_PING, mp_ping);
2176 S (mp_ping);
2177
2178 W (ret);
2179 return ret;
2180}
2181
Steven Luong4c4223e2020-07-15 08:44:54 -07002182static void vl_api_sw_member_interface_details_t_handler
2183 (vl_api_sw_member_interface_details_t * mp)
Steven9cd2d7a2017-12-20 12:43:01 -08002184{
2185 vat_main_t *vam = &vat_main;
2186
2187 print (vam->ofp,
Steven Luonga1876b82019-08-20 16:58:00 -07002188 "%-25s %-12d %-7d %-12d %-10d %-10d", mp->interface_name,
2189 ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout,
2190 ntohl (mp->weight), mp->is_local_numa);
Steven9cd2d7a2017-12-20 12:43:01 -08002191}
2192
Steven Luong4c4223e2020-07-15 08:44:54 -07002193static void vl_api_sw_member_interface_details_t_handler_json
2194 (vl_api_sw_member_interface_details_t * mp)
Steven9cd2d7a2017-12-20 12:43:01 -08002195{
2196 vat_main_t *vam = &vat_main;
2197 vat_json_node_t *node = NULL;
2198
2199 if (VAT_JSON_ARRAY != vam->json_tree.type)
2200 {
2201 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2202 vat_json_init_array (&vam->json_tree);
2203 }
2204 node = vat_json_array_add (&vam->json_tree);
2205
2206 vat_json_init_object (node);
2207 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2208 vat_json_object_add_string_copy (node, "interface_name",
2209 mp->interface_name);
2210 vat_json_object_add_uint (node, "passive", mp->is_passive);
2211 vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
Steven Luonga1876b82019-08-20 16:58:00 -07002212 vat_json_object_add_uint (node, "weight", ntohl (mp->weight));
2213 vat_json_object_add_uint (node, "is_local_numa", mp->is_local_numa);
Steven9cd2d7a2017-12-20 12:43:01 -08002214}
2215
2216static int
Steven Luong4c4223e2020-07-15 08:44:54 -07002217api_sw_member_interface_dump (vat_main_t * vam)
Steven9cd2d7a2017-12-20 12:43:01 -08002218{
2219 unformat_input_t *i = vam->input;
Steven Luong4c4223e2020-07-15 08:44:54 -07002220 vl_api_sw_member_interface_dump_t *mp;
Steven9cd2d7a2017-12-20 12:43:01 -08002221 vl_api_control_ping_t *mp_ping;
2222 u32 sw_if_index = ~0;
2223 u8 sw_if_index_set = 0;
2224 int ret;
2225
2226 /* Parse args required to build the message */
2227 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2228 {
2229 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2230 sw_if_index_set = 1;
2231 else if (unformat (i, "sw_if_index %d", &sw_if_index))
2232 sw_if_index_set = 1;
2233 else
2234 break;
2235 }
2236
2237 if (sw_if_index_set == 0)
2238 {
2239 errmsg ("missing vpp interface name. ");
2240 return -99;
2241 }
2242
2243 print (vam->ofp,
Steven Luonga1876b82019-08-20 16:58:00 -07002244 "\n%-25s %-12s %-7s %-12s %-10s %-10s",
Steven Luong4c4223e2020-07-15 08:44:54 -07002245 "member interface name", "sw_if_index", "passive", "long_timeout",
Steven Luonga1876b82019-08-20 16:58:00 -07002246 "weight", "local numa");
Steven9cd2d7a2017-12-20 12:43:01 -08002247
2248 /* Get list of bond interfaces */
Steven Luong4c4223e2020-07-15 08:44:54 -07002249 M (SW_MEMBER_INTERFACE_DUMP, mp);
Steven9cd2d7a2017-12-20 12:43:01 -08002250 mp->sw_if_index = ntohl (sw_if_index);
2251 S (mp);
2252
2253 /* Use a control ping for synchronization */
2254 MPING (CONTROL_PING, mp_ping);
2255 S (mp_ping);
2256
2257 W (ret);
2258 return ret;
2259}
2260
Damjan Marion7cd468a2016-12-19 23:05:39 +01002261static void vl_api_mpls_tunnel_add_del_reply_t_handler
2262 (vl_api_mpls_tunnel_add_del_reply_t * mp)
2263{
2264 vat_main_t *vam = &vat_main;
2265 i32 retval = ntohl (mp->retval);
2266 if (vam->async_mode)
2267 {
2268 vam->async_errors += (retval < 0);
2269 }
2270 else
2271 {
2272 vam->retval = retval;
John Lo06fda9c2018-10-03 16:32:44 -04002273 vam->sw_if_index = ntohl (mp->sw_if_index);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002274 vam->result_ready = 1;
2275 }
John Lo06fda9c2018-10-03 16:32:44 -04002276 vam->regenerate_interface_table = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002277}
2278
2279static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2280 (vl_api_mpls_tunnel_add_del_reply_t * mp)
2281{
2282 vat_main_t *vam = &vat_main;
2283 vat_json_node_t node;
2284
2285 vat_json_init_object (&node);
2286 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2287 vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2288 ntohl (mp->sw_if_index));
2289
2290 vat_json_print (vam->ofp, &node);
2291 vat_json_free (&node);
2292
2293 vam->retval = ntohl (mp->retval);
2294 vam->result_ready = 1;
2295}
2296
Damjan Marion7cd468a2016-12-19 23:05:39 +01002297static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2298 (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2299{
2300 vat_main_t *vam = &vat_main;
2301 i32 retval = ntohl (mp->retval);
2302 if (vam->async_mode)
2303 {
2304 vam->async_errors += (retval < 0);
2305 }
2306 else
2307 {
2308 vam->retval = retval;
2309 vam->sw_if_index = ntohl (mp->sw_if_index);
2310 vam->result_ready = 1;
2311 }
Dave Barachf72212e2018-01-11 10:25:07 -05002312 vam->regenerate_interface_table = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002313}
2314
2315static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2316 (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2317{
2318 vat_main_t *vam = &vat_main;
2319 vat_json_node_t node;
2320
2321 vat_json_init_object (&node);
2322 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2323 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2324
2325 vat_json_print (vam->ofp, &node);
2326 vat_json_free (&node);
2327
2328 vam->retval = ntohl (mp->retval);
2329 vam->result_ready = 1;
2330}
2331
eyal bariaf86a482018-04-17 11:20:27 +03002332static void vl_api_vxlan_offload_rx_reply_t_handler
2333 (vl_api_vxlan_offload_rx_reply_t * mp)
2334{
2335 vat_main_t *vam = &vat_main;
2336 i32 retval = ntohl (mp->retval);
2337 if (vam->async_mode)
2338 {
2339 vam->async_errors += (retval < 0);
2340 }
2341 else
2342 {
2343 vam->retval = retval;
2344 vam->result_ready = 1;
2345 }
2346}
2347
2348static void vl_api_vxlan_offload_rx_reply_t_handler_json
2349 (vl_api_vxlan_offload_rx_reply_t * mp)
2350{
2351 vat_main_t *vam = &vat_main;
2352 vat_json_node_t node;
2353
2354 vat_json_init_object (&node);
2355 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2356
2357 vat_json_print (vam->ofp, &node);
2358 vat_json_free (&node);
2359
2360 vam->retval = ntohl (mp->retval);
2361 vam->result_ready = 1;
2362}
2363
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +08002364static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2365 (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2366{
2367 vat_main_t *vam = &vat_main;
2368 i32 retval = ntohl (mp->retval);
2369 if (vam->async_mode)
2370 {
2371 vam->async_errors += (retval < 0);
2372 }
2373 else
2374 {
2375 vam->retval = retval;
2376 vam->sw_if_index = ntohl (mp->sw_if_index);
2377 vam->result_ready = 1;
2378 }
Dave Barachf72212e2018-01-11 10:25:07 -05002379 vam->regenerate_interface_table = 1;
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +08002380}
2381
2382static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2383 (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2384{
2385 vat_main_t *vam = &vat_main;
2386 vat_json_node_t node;
2387
2388 vat_json_init_object (&node);
2389 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2390 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2391
2392 vat_json_print (vam->ofp, &node);
2393 vat_json_free (&node);
2394
2395 vam->retval = ntohl (mp->retval);
2396 vam->result_ready = 1;
2397}
2398
Damjan Marion7cd468a2016-12-19 23:05:39 +01002399static void vl_api_create_vhost_user_if_reply_t_handler
2400 (vl_api_create_vhost_user_if_reply_t * mp)
2401{
2402 vat_main_t *vam = &vat_main;
2403 i32 retval = ntohl (mp->retval);
2404 if (vam->async_mode)
2405 {
2406 vam->async_errors += (retval < 0);
2407 }
2408 else
2409 {
2410 vam->retval = retval;
2411 vam->sw_if_index = ntohl (mp->sw_if_index);
2412 vam->result_ready = 1;
2413 }
Dave Barachf72212e2018-01-11 10:25:07 -05002414 vam->regenerate_interface_table = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002415}
2416
2417static void vl_api_create_vhost_user_if_reply_t_handler_json
2418 (vl_api_create_vhost_user_if_reply_t * mp)
2419{
2420 vat_main_t *vam = &vat_main;
2421 vat_json_node_t node;
2422
2423 vat_json_init_object (&node);
2424 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2425 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2426
2427 vat_json_print (vam->ofp, &node);
2428 vat_json_free (&node);
2429
2430 vam->retval = ntohl (mp->retval);
2431 vam->result_ready = 1;
2432}
2433
Steven Luong27ba5002020-11-17 13:30:44 -08002434static void vl_api_create_vhost_user_if_v2_reply_t_handler
2435 (vl_api_create_vhost_user_if_v2_reply_t * mp)
2436{
2437 vat_main_t *vam = &vat_main;
2438 i32 retval = ntohl (mp->retval);
2439 if (vam->async_mode)
2440 {
2441 vam->async_errors += (retval < 0);
2442 }
2443 else
2444 {
2445 vam->retval = retval;
2446 vam->sw_if_index = ntohl (mp->sw_if_index);
2447 vam->result_ready = 1;
2448 }
2449 vam->regenerate_interface_table = 1;
2450}
2451
2452static void vl_api_create_vhost_user_if_v2_reply_t_handler_json
2453 (vl_api_create_vhost_user_if_v2_reply_t * mp)
2454{
2455 vat_main_t *vam = &vat_main;
2456 vat_json_node_t node;
2457
2458 vat_json_init_object (&node);
2459 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2460 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2461
2462 vat_json_print (vam->ofp, &node);
2463 vat_json_free (&node);
2464
2465 vam->retval = ntohl (mp->retval);
2466 vam->result_ready = 1;
2467}
2468
Damjan Marion7cd468a2016-12-19 23:05:39 +01002469static void vl_api_ip_address_details_t_handler
2470 (vl_api_ip_address_details_t * mp)
2471{
2472 vat_main_t *vam = &vat_main;
2473 static ip_address_details_t empty_ip_address_details = { {0} };
2474 ip_address_details_t *address = NULL;
2475 ip_details_t *current_ip_details = NULL;
2476 ip_details_t *details = NULL;
2477
2478 details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2479
2480 if (!details || vam->current_sw_if_index >= vec_len (details)
2481 || !details[vam->current_sw_if_index].present)
2482 {
2483 errmsg ("ip address details arrived but not stored");
2484 errmsg ("ip_dump should be called first");
2485 return;
2486 }
2487
2488 current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2489
2490#define addresses (current_ip_details->addr)
2491
2492 vec_validate_init_empty (addresses, vec_len (addresses),
2493 empty_ip_address_details);
2494
2495 address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2496
Neale Ranns097fa662018-05-01 05:17:55 -07002497 clib_memcpy (&address->ip, &mp->prefix.address.un, sizeof (address->ip));
Paul Vinciguerraab055082019-06-06 14:07:55 -04002498 address->prefix_length = mp->prefix.len;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002499#undef addresses
2500}
2501
2502static void vl_api_ip_address_details_t_handler_json
2503 (vl_api_ip_address_details_t * mp)
2504{
2505 vat_main_t *vam = &vat_main;
2506 vat_json_node_t *node = NULL;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002507
2508 if (VAT_JSON_ARRAY != vam->json_tree.type)
2509 {
2510 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2511 vat_json_init_array (&vam->json_tree);
2512 }
2513 node = vat_json_array_add (&vam->json_tree);
2514
2515 vat_json_init_object (node);
Neale Ranns097fa662018-05-01 05:17:55 -07002516 vat_json_object_add_prefix (node, &mp->prefix);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002517}
2518
2519static void
2520vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2521{
2522 vat_main_t *vam = &vat_main;
2523 static ip_details_t empty_ip_details = { 0 };
2524 ip_details_t *ip = NULL;
2525 u32 sw_if_index = ~0;
2526
2527 sw_if_index = ntohl (mp->sw_if_index);
2528
2529 vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2530 sw_if_index, empty_ip_details);
2531
2532 ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2533 sw_if_index);
2534
2535 ip->present = 1;
2536}
2537
2538static void
2539vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2540{
2541 vat_main_t *vam = &vat_main;
2542
2543 if (VAT_JSON_ARRAY != vam->json_tree.type)
2544 {
2545 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2546 vat_json_init_array (&vam->json_tree);
2547 }
2548 vat_json_array_add_uint (&vam->json_tree,
2549 clib_net_to_host_u32 (mp->sw_if_index));
2550}
2551
Damjan Marion7cd468a2016-12-19 23:05:39 +01002552static void vl_api_get_first_msg_id_reply_t_handler
2553 (vl_api_get_first_msg_id_reply_t * mp)
2554{
2555 vat_main_t *vam = &vat_main;
2556 i32 retval = ntohl (mp->retval);
2557
2558 if (vam->async_mode)
2559 {
2560 vam->async_errors += (retval < 0);
2561 }
2562 else
2563 {
2564 vam->retval = retval;
2565 vam->result_ready = 1;
2566 }
2567 if (retval >= 0)
2568 {
2569 errmsg ("first message id %d", ntohs (mp->first_msg_id));
2570 }
2571}
2572
2573static void vl_api_get_first_msg_id_reply_t_handler_json
2574 (vl_api_get_first_msg_id_reply_t * mp)
2575{
2576 vat_main_t *vam = &vat_main;
2577 vat_json_node_t node;
2578
2579 vat_json_init_object (&node);
2580 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2581 vat_json_object_add_uint (&node, "first_msg_id",
2582 (uint) ntohs (mp->first_msg_id));
2583
2584 vat_json_print (vam->ofp, &node);
2585 vat_json_free (&node);
2586
2587 vam->retval = ntohl (mp->retval);
2588 vam->result_ready = 1;
2589}
2590
2591static void vl_api_get_node_graph_reply_t_handler
2592 (vl_api_get_node_graph_reply_t * mp)
2593{
2594 vat_main_t *vam = &vat_main;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002595 i32 retval = ntohl (mp->retval);
2596 u8 *pvt_copy, *reply;
2597 void *oldheap;
2598 vlib_node_t *node;
2599 int i;
2600
2601 if (vam->async_mode)
2602 {
2603 vam->async_errors += (retval < 0);
2604 }
2605 else
2606 {
2607 vam->retval = retval;
2608 vam->result_ready = 1;
2609 }
2610
2611 /* "Should never happen..." */
2612 if (retval != 0)
2613 return;
2614
Damjan Marion7bee80c2017-04-26 15:32:12 +02002615 reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002616 pvt_copy = vec_dup (reply);
2617
2618 /* Toss the shared-memory original... */
Nathan Skrzypczak0aa40132019-11-25 16:29:38 +01002619 oldheap = vl_msg_push_heap ();
Damjan Marion7cd468a2016-12-19 23:05:39 +01002620
2621 vec_free (reply);
2622
Nathan Skrzypczak0aa40132019-11-25 16:29:38 +01002623 vl_msg_pop_heap (oldheap);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002624
2625 if (vam->graph_nodes)
2626 {
2627 hash_free (vam->graph_node_index_by_name);
2628
Dave Barach1ddbc012018-06-13 09:26:05 -04002629 for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002630 {
Dave Barach1ddbc012018-06-13 09:26:05 -04002631 node = vam->graph_nodes[0][i];
Damjan Marion7cd468a2016-12-19 23:05:39 +01002632 vec_free (node->name);
2633 vec_free (node->next_nodes);
2634 vec_free (node);
2635 }
Dave Barach1ddbc012018-06-13 09:26:05 -04002636 vec_free (vam->graph_nodes[0]);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002637 vec_free (vam->graph_nodes);
2638 }
2639
2640 vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2641 vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2642 vec_free (pvt_copy);
2643
Dave Barach1ddbc012018-06-13 09:26:05 -04002644 for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002645 {
Dave Barach1ddbc012018-06-13 09:26:05 -04002646 node = vam->graph_nodes[0][i];
Damjan Marion7cd468a2016-12-19 23:05:39 +01002647 hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2648 }
2649}
2650
2651static void vl_api_get_node_graph_reply_t_handler_json
2652 (vl_api_get_node_graph_reply_t * mp)
2653{
2654 vat_main_t *vam = &vat_main;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002655 void *oldheap;
2656 vat_json_node_t node;
2657 u8 *reply;
2658
2659 /* $$$$ make this real? */
2660 vat_json_init_object (&node);
2661 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2662 vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2663
Damjan Marion7bee80c2017-04-26 15:32:12 +02002664 reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002665
2666 /* Toss the shared-memory original... */
Nathan Skrzypczak0aa40132019-11-25 16:29:38 +01002667 oldheap = vl_msg_push_heap ();
Damjan Marion7cd468a2016-12-19 23:05:39 +01002668
2669 vec_free (reply);
2670
Nathan Skrzypczak0aa40132019-11-25 16:29:38 +01002671 vl_msg_pop_heap (oldheap);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002672
2673 vat_json_print (vam->ofp, &node);
2674 vat_json_free (&node);
2675
2676 vam->retval = ntohl (mp->retval);
2677 vam->result_ready = 1;
2678}
2679
Damjan Marion7cd468a2016-12-19 23:05:39 +01002680static u8 *
2681format_policer_type (u8 * s, va_list * va)
2682{
2683 u32 i = va_arg (*va, u32);
2684
2685 if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2686 s = format (s, "1r2c");
2687 else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2688 s = format (s, "1r3c");
2689 else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2690 s = format (s, "2r3c-2698");
2691 else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2692 s = format (s, "2r3c-4115");
2693 else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2694 s = format (s, "2r3c-mef5cf1");
2695 else
2696 s = format (s, "ILLEGAL");
2697 return s;
2698}
2699
2700static u8 *
2701format_policer_rate_type (u8 * s, va_list * va)
2702{
2703 u32 i = va_arg (*va, u32);
2704
2705 if (i == SSE2_QOS_RATE_KBPS)
2706 s = format (s, "kbps");
2707 else if (i == SSE2_QOS_RATE_PPS)
2708 s = format (s, "pps");
2709 else
2710 s = format (s, "ILLEGAL");
2711 return s;
2712}
2713
2714static u8 *
2715format_policer_round_type (u8 * s, va_list * va)
2716{
2717 u32 i = va_arg (*va, u32);
2718
2719 if (i == SSE2_QOS_ROUND_TO_CLOSEST)
2720 s = format (s, "closest");
2721 else if (i == SSE2_QOS_ROUND_TO_UP)
2722 s = format (s, "up");
2723 else if (i == SSE2_QOS_ROUND_TO_DOWN)
2724 s = format (s, "down");
2725 else
2726 s = format (s, "ILLEGAL");
2727 return s;
2728}
2729
2730static u8 *
2731format_policer_action_type (u8 * s, va_list * va)
2732{
2733 u32 i = va_arg (*va, u32);
2734
2735 if (i == SSE2_QOS_ACTION_DROP)
2736 s = format (s, "drop");
2737 else if (i == SSE2_QOS_ACTION_TRANSMIT)
2738 s = format (s, "transmit");
2739 else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2740 s = format (s, "mark-and-transmit");
2741 else
2742 s = format (s, "ILLEGAL");
2743 return s;
2744}
2745
2746static u8 *
2747format_dscp (u8 * s, va_list * va)
2748{
2749 u32 i = va_arg (*va, u32);
2750 char *t = 0;
2751
2752 switch (i)
2753 {
2754#define _(v,f,str) case VNET_DSCP_##f: t = str; break;
2755 foreach_vnet_dscp
2756#undef _
2757 default:
2758 return format (s, "ILLEGAL");
2759 }
2760 s = format (s, "%s", t);
2761 return s;
2762}
2763
2764static void
2765vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
2766{
2767 vat_main_t *vam = &vat_main;
2768 u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
2769
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002770 if (mp->conform_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
2771 conform_dscp_str = format (0, "%U", format_dscp, mp->conform_action.dscp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002772 else
2773 conform_dscp_str = format (0, "");
2774
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002775 if (mp->exceed_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
2776 exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_action.dscp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002777 else
2778 exceed_dscp_str = format (0, "");
2779
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002780 if (mp->violate_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
2781 violate_dscp_str = format (0, "%U", format_dscp, mp->violate_action.dscp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002782 else
2783 violate_dscp_str = format (0, "");
2784
2785 print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
2786 "rate type %U, round type %U, %s rate, %s color-aware, "
2787 "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
2788 "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
2789 "conform action %U%s, exceed action %U%s, violate action %U%s",
2790 mp->name,
2791 format_policer_type, mp->type,
2792 ntohl (mp->cir),
2793 ntohl (mp->eir),
2794 clib_net_to_host_u64 (mp->cb),
2795 clib_net_to_host_u64 (mp->eb),
2796 format_policer_rate_type, mp->rate_type,
2797 format_policer_round_type, mp->round_type,
2798 mp->single_rate ? "single" : "dual",
2799 mp->color_aware ? "is" : "not",
2800 ntohl (mp->cir_tokens_per_period),
2801 ntohl (mp->pir_tokens_per_period),
2802 ntohl (mp->scale),
2803 ntohl (mp->current_limit),
2804 ntohl (mp->current_bucket),
2805 ntohl (mp->extended_limit),
2806 ntohl (mp->extended_bucket),
2807 clib_net_to_host_u64 (mp->last_update_time),
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002808 format_policer_action_type, mp->conform_action.type,
Damjan Marion7cd468a2016-12-19 23:05:39 +01002809 conform_dscp_str,
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002810 format_policer_action_type, mp->exceed_action.type,
Damjan Marion7cd468a2016-12-19 23:05:39 +01002811 exceed_dscp_str,
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002812 format_policer_action_type, mp->violate_action.type,
Damjan Marion7cd468a2016-12-19 23:05:39 +01002813 violate_dscp_str);
2814
2815 vec_free (conform_dscp_str);
2816 vec_free (exceed_dscp_str);
2817 vec_free (violate_dscp_str);
2818}
2819
2820static void vl_api_policer_details_t_handler_json
2821 (vl_api_policer_details_t * mp)
2822{
2823 vat_main_t *vam = &vat_main;
2824 vat_json_node_t *node;
2825 u8 *rate_type_str, *round_type_str, *type_str;
2826 u8 *conform_action_str, *exceed_action_str, *violate_action_str;
2827
2828 rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
2829 round_type_str =
2830 format (0, "%U", format_policer_round_type, mp->round_type);
2831 type_str = format (0, "%U", format_policer_type, mp->type);
2832 conform_action_str = format (0, "%U", format_policer_action_type,
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002833 mp->conform_action.type);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002834 exceed_action_str = format (0, "%U", format_policer_action_type,
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002835 mp->exceed_action.type);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002836 violate_action_str = format (0, "%U", format_policer_action_type,
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002837 mp->violate_action.type);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002838
2839 if (VAT_JSON_ARRAY != vam->json_tree.type)
2840 {
2841 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2842 vat_json_init_array (&vam->json_tree);
2843 }
2844 node = vat_json_array_add (&vam->json_tree);
2845
2846 vat_json_init_object (node);
2847 vat_json_object_add_string_copy (node, "name", mp->name);
2848 vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
2849 vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
Marek Gradzki59ed4902017-03-21 11:51:54 +01002850 vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
2851 vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
Damjan Marion7cd468a2016-12-19 23:05:39 +01002852 vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
2853 vat_json_object_add_string_copy (node, "round_type", round_type_str);
2854 vat_json_object_add_string_copy (node, "type", type_str);
2855 vat_json_object_add_uint (node, "single_rate", mp->single_rate);
2856 vat_json_object_add_uint (node, "color_aware", mp->color_aware);
2857 vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
2858 vat_json_object_add_uint (node, "cir_tokens_per_period",
2859 ntohl (mp->cir_tokens_per_period));
2860 vat_json_object_add_uint (node, "eir_tokens_per_period",
2861 ntohl (mp->pir_tokens_per_period));
2862 vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
2863 vat_json_object_add_uint (node, "current_bucket",
2864 ntohl (mp->current_bucket));
2865 vat_json_object_add_uint (node, "extended_limit",
2866 ntohl (mp->extended_limit));
2867 vat_json_object_add_uint (node, "extended_bucket",
2868 ntohl (mp->extended_bucket));
2869 vat_json_object_add_uint (node, "last_update_time",
2870 ntohl (mp->last_update_time));
2871 vat_json_object_add_string_copy (node, "conform_action",
2872 conform_action_str);
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002873 if (mp->conform_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002874 {
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002875 u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_action.dscp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002876 vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
2877 vec_free (dscp_str);
2878 }
2879 vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002880 if (mp->exceed_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002881 {
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002882 u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_action.dscp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002883 vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
2884 vec_free (dscp_str);
2885 }
2886 vat_json_object_add_string_copy (node, "violate_action",
2887 violate_action_str);
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002888 if (mp->violate_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002889 {
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002890 u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_action.dscp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002891 vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
2892 vec_free (dscp_str);
2893 }
2894
2895 vec_free (rate_type_str);
2896 vec_free (round_type_str);
2897 vec_free (type_str);
2898 vec_free (conform_action_str);
2899 vec_free (exceed_action_str);
2900 vec_free (violate_action_str);
2901}
2902
2903static void
2904vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
2905 mp)
2906{
2907 vat_main_t *vam = &vat_main;
2908 int i, count = ntohl (mp->count);
2909
2910 if (count > 0)
2911 print (vam->ofp, "classify table ids (%d) : ", count);
2912 for (i = 0; i < count; i++)
2913 {
2914 print (vam->ofp, "%d", ntohl (mp->ids[i]));
2915 print (vam->ofp, (i < count - 1) ? "," : "");
2916 }
2917 vam->retval = ntohl (mp->retval);
2918 vam->result_ready = 1;
2919}
2920
2921static void
2922 vl_api_classify_table_ids_reply_t_handler_json
2923 (vl_api_classify_table_ids_reply_t * mp)
2924{
2925 vat_main_t *vam = &vat_main;
2926 int i, count = ntohl (mp->count);
2927
2928 if (count > 0)
2929 {
2930 vat_json_node_t node;
2931
2932 vat_json_init_object (&node);
2933 for (i = 0; i < count; i++)
2934 {
2935 vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
2936 }
2937 vat_json_print (vam->ofp, &node);
2938 vat_json_free (&node);
2939 }
2940 vam->retval = ntohl (mp->retval);
2941 vam->result_ready = 1;
2942}
2943
2944static void
2945 vl_api_classify_table_by_interface_reply_t_handler
2946 (vl_api_classify_table_by_interface_reply_t * mp)
2947{
2948 vat_main_t *vam = &vat_main;
2949 u32 table_id;
2950
2951 table_id = ntohl (mp->l2_table_id);
2952 if (table_id != ~0)
2953 print (vam->ofp, "l2 table id : %d", table_id);
2954 else
2955 print (vam->ofp, "l2 table id : No input ACL tables configured");
2956 table_id = ntohl (mp->ip4_table_id);
2957 if (table_id != ~0)
2958 print (vam->ofp, "ip4 table id : %d", table_id);
2959 else
2960 print (vam->ofp, "ip4 table id : No input ACL tables configured");
2961 table_id = ntohl (mp->ip6_table_id);
2962 if (table_id != ~0)
2963 print (vam->ofp, "ip6 table id : %d", table_id);
2964 else
2965 print (vam->ofp, "ip6 table id : No input ACL tables configured");
2966 vam->retval = ntohl (mp->retval);
2967 vam->result_ready = 1;
2968}
2969
2970static void
2971 vl_api_classify_table_by_interface_reply_t_handler_json
2972 (vl_api_classify_table_by_interface_reply_t * mp)
2973{
2974 vat_main_t *vam = &vat_main;
2975 vat_json_node_t node;
2976
2977 vat_json_init_object (&node);
2978
2979 vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
2980 vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
2981 vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
2982
2983 vat_json_print (vam->ofp, &node);
2984 vat_json_free (&node);
2985
2986 vam->retval = ntohl (mp->retval);
2987 vam->result_ready = 1;
2988}
2989
2990static void vl_api_policer_add_del_reply_t_handler
2991 (vl_api_policer_add_del_reply_t * mp)
2992{
2993 vat_main_t *vam = &vat_main;
2994 i32 retval = ntohl (mp->retval);
2995 if (vam->async_mode)
2996 {
2997 vam->async_errors += (retval < 0);
2998 }
2999 else
3000 {
3001 vam->retval = retval;
3002 vam->result_ready = 1;
3003 if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3004 /*
3005 * Note: this is just barely thread-safe, depends on
3006 * the main thread spinning waiting for an answer...
3007 */
3008 errmsg ("policer index %d", ntohl (mp->policer_index));
3009 }
3010}
3011
3012static void vl_api_policer_add_del_reply_t_handler_json
3013 (vl_api_policer_add_del_reply_t * mp)
3014{
3015 vat_main_t *vam = &vat_main;
3016 vat_json_node_t node;
3017
3018 vat_json_init_object (&node);
3019 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3020 vat_json_object_add_uint (&node, "policer_index",
3021 ntohl (mp->policer_index));
3022
3023 vat_json_print (vam->ofp, &node);
3024 vat_json_free (&node);
3025
3026 vam->retval = ntohl (mp->retval);
3027 vam->result_ready = 1;
3028}
3029
3030/* Format hex dump. */
3031u8 *
3032format_hex_bytes (u8 * s, va_list * va)
3033{
3034 u8 *bytes = va_arg (*va, u8 *);
3035 int n_bytes = va_arg (*va, int);
3036 uword i;
3037
3038 /* Print short or long form depending on byte count. */
3039 uword short_form = n_bytes <= 32;
Christophe Fontained3c008d2017-10-02 18:10:54 +02003040 u32 indent = format_get_indent (s);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003041
3042 if (n_bytes == 0)
3043 return s;
3044
3045 for (i = 0; i < n_bytes; i++)
3046 {
3047 if (!short_form && (i % 32) == 0)
3048 s = format (s, "%08x: ", i);
3049 s = format (s, "%02x", bytes[i]);
3050 if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3051 s = format (s, "\n%U", format_white_space, indent);
3052 }
3053
3054 return s;
3055}
3056
3057static void
3058vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3059 * mp)
3060{
3061 vat_main_t *vam = &vat_main;
3062 i32 retval = ntohl (mp->retval);
3063 if (retval == 0)
3064 {
3065 print (vam->ofp, "classify table info :");
3066 print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
3067 ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3068 ntohl (mp->miss_next_index));
3069 print (vam->ofp, "nbuckets: %d skip: %d match: %d",
3070 ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3071 ntohl (mp->match_n_vectors));
3072 print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
3073 ntohl (mp->mask_length));
3074 }
3075 vam->retval = retval;
3076 vam->result_ready = 1;
3077}
3078
3079static void
3080 vl_api_classify_table_info_reply_t_handler_json
3081 (vl_api_classify_table_info_reply_t * mp)
3082{
3083 vat_main_t *vam = &vat_main;
3084 vat_json_node_t node;
3085
3086 i32 retval = ntohl (mp->retval);
3087 if (retval == 0)
3088 {
3089 vat_json_init_object (&node);
3090
3091 vat_json_object_add_int (&node, "sessions",
3092 ntohl (mp->active_sessions));
3093 vat_json_object_add_int (&node, "nexttbl",
3094 ntohl (mp->next_table_index));
3095 vat_json_object_add_int (&node, "nextnode",
3096 ntohl (mp->miss_next_index));
3097 vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3098 vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3099 vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3100 u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3101 ntohl (mp->mask_length), 0);
3102 vat_json_object_add_string_copy (&node, "mask", s);
3103
3104 vat_json_print (vam->ofp, &node);
3105 vat_json_free (&node);
3106 }
3107 vam->retval = ntohl (mp->retval);
3108 vam->result_ready = 1;
3109}
3110
3111static void
3112vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3113 mp)
3114{
3115 vat_main_t *vam = &vat_main;
3116
3117 print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3118 ntohl (mp->hit_next_index), ntohl (mp->advance),
3119 ntohl (mp->opaque_index));
3120 print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
3121 ntohl (mp->match_length));
3122}
3123
3124static void
3125 vl_api_classify_session_details_t_handler_json
3126 (vl_api_classify_session_details_t * mp)
3127{
3128 vat_main_t *vam = &vat_main;
3129 vat_json_node_t *node = NULL;
3130
3131 if (VAT_JSON_ARRAY != vam->json_tree.type)
3132 {
3133 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3134 vat_json_init_array (&vam->json_tree);
3135 }
3136 node = vat_json_array_add (&vam->json_tree);
3137
3138 vat_json_init_object (node);
3139 vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3140 vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3141 vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3142 u8 *s =
3143 format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3144 0);
3145 vat_json_object_add_string_copy (node, "match", s);
3146}
3147
3148static void vl_api_pg_create_interface_reply_t_handler
3149 (vl_api_pg_create_interface_reply_t * mp)
3150{
3151 vat_main_t *vam = &vat_main;
3152
3153 vam->retval = ntohl (mp->retval);
3154 vam->result_ready = 1;
3155}
3156
3157static void vl_api_pg_create_interface_reply_t_handler_json
3158 (vl_api_pg_create_interface_reply_t * mp)
3159{
3160 vat_main_t *vam = &vat_main;
3161 vat_json_node_t node;
3162
3163 i32 retval = ntohl (mp->retval);
3164 if (retval == 0)
3165 {
3166 vat_json_init_object (&node);
3167
3168 vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3169
3170 vat_json_print (vam->ofp, &node);
3171 vat_json_free (&node);
3172 }
3173 vam->retval = ntohl (mp->retval);
3174 vam->result_ready = 1;
3175}
3176
3177static void vl_api_policer_classify_details_t_handler
3178 (vl_api_policer_classify_details_t * mp)
3179{
3180 vat_main_t *vam = &vat_main;
3181
3182 print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3183 ntohl (mp->table_index));
3184}
3185
3186static void vl_api_policer_classify_details_t_handler_json
3187 (vl_api_policer_classify_details_t * mp)
3188{
3189 vat_main_t *vam = &vat_main;
3190 vat_json_node_t *node;
3191
3192 if (VAT_JSON_ARRAY != vam->json_tree.type)
3193 {
3194 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3195 vat_json_init_array (&vam->json_tree);
3196 }
3197 node = vat_json_array_add (&vam->json_tree);
3198
3199 vat_json_init_object (node);
3200 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3201 vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3202}
3203
Damjan Marion7cd468a2016-12-19 23:05:39 +01003204static void vl_api_flow_classify_details_t_handler
3205 (vl_api_flow_classify_details_t * mp)
3206{
3207 vat_main_t *vam = &vat_main;
3208
3209 print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3210 ntohl (mp->table_index));
3211}
3212
3213static void vl_api_flow_classify_details_t_handler_json
3214 (vl_api_flow_classify_details_t * mp)
3215{
3216 vat_main_t *vam = &vat_main;
3217 vat_json_node_t *node;
3218
3219 if (VAT_JSON_ARRAY != vam->json_tree.type)
3220 {
3221 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3222 vat_json_init_array (&vam->json_tree);
3223 }
3224 node = vat_json_array_add (&vam->json_tree);
3225
3226 vat_json_init_object (node);
3227 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3228 vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3229}
3230
Damjan Marion7cd468a2016-12-19 23:05:39 +01003231/*
3232 * Generate boilerplate reply handlers, which
3233 * dig the return value out of the xxx_reply_t API message,
3234 * stick it into vam->retval, and set vam->result_ready
3235 *
3236 * Could also do this by pointing N message decode slots at
3237 * a single function, but that could break in subtle ways.
3238 */
3239
3240#define foreach_standard_reply_retval_handler \
3241_(sw_interface_set_flags_reply) \
3242_(sw_interface_add_del_address_reply) \
Stevenad8015b2017-10-29 22:10:46 -07003243_(sw_interface_set_rx_mode_reply) \
Mohsin Kazmi54f7c512018-08-23 18:28:11 +02003244_(sw_interface_set_rx_placement_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003245_(sw_interface_set_table_reply) \
3246_(sw_interface_set_mpls_enable_reply) \
3247_(sw_interface_set_vpath_reply) \
3248_(sw_interface_set_vxlan_bypass_reply) \
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +08003249_(sw_interface_set_vxlan_gpe_bypass_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003250_(sw_interface_set_l2_bridge_reply) \
Steven Luonga1876b82019-08-20 16:58:00 -07003251_(sw_interface_set_bond_weight_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003252_(bridge_domain_add_del_reply) \
3253_(sw_interface_set_l2_xconnect_reply) \
3254_(l2fib_add_del_reply) \
Eyal Barif24991c2017-04-05 05:33:21 +03003255_(l2fib_flush_int_reply) \
3256_(l2fib_flush_bd_reply) \
Neale Ranns097fa662018-05-01 05:17:55 -07003257_(ip_route_add_del_reply) \
Neale Ranns28ab9cc2017-08-14 07:18:42 -07003258_(ip_table_add_del_reply) \
Neale Ranns9db6ada2019-11-08 12:42:31 +00003259_(ip_table_replace_begin_reply) \
3260_(ip_table_flush_reply) \
3261_(ip_table_replace_end_reply) \
Neale Ranns32e1c012016-11-22 17:07:28 +00003262_(ip_mroute_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003263_(mpls_route_add_del_reply) \
Neale Ranns28ab9cc2017-08-14 07:18:42 -07003264_(mpls_table_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003265_(mpls_ip_bind_unbind_reply) \
Neale Rannsd792d9c2017-10-21 10:53:20 -07003266_(bier_route_add_del_reply) \
3267_(bier_table_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003268_(sw_interface_set_unnumbered_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003269_(set_ip_flow_hash_reply) \
3270_(sw_interface_ip6_enable_disable_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003271_(l2_patch_add_del_reply) \
John Loe166fd92018-09-13 14:08:59 -04003272_(sr_mpls_policy_add_reply) \
3273_(sr_mpls_policy_mod_reply) \
3274_(sr_mpls_policy_del_reply) \
Pablo Camarillofb380952016-12-07 18:34:18 +01003275_(sr_policy_add_reply) \
3276_(sr_policy_mod_reply) \
3277_(sr_policy_del_reply) \
3278_(sr_localsid_add_del_reply) \
3279_(sr_steering_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003280_(classify_add_del_session_reply) \
3281_(classify_set_interface_ip_table_reply) \
3282_(classify_set_interface_l2_tables_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003283_(l2_fib_clear_table_reply) \
3284_(l2_interface_efp_filter_reply) \
3285_(l2_interface_vlan_tag_rewrite_reply) \
3286_(modify_vhost_user_if_reply) \
Steven Luong27ba5002020-11-17 13:30:44 -08003287_(modify_vhost_user_if_v2_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003288_(delete_vhost_user_if_reply) \
John Lo8d00fff2017-08-03 00:35:36 -04003289_(want_l2_macs_events_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003290_(input_acl_set_interface_reply) \
3291_(ipsec_spd_add_del_reply) \
3292_(ipsec_interface_add_del_spd_reply) \
Neale Ranns17dcec02019-01-09 21:22:20 -08003293_(ipsec_spd_entry_add_del_reply) \
3294_(ipsec_sad_entry_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003295_(delete_loopback_reply) \
3296_(bd_ip_mac_add_del_reply) \
John Loe26c81f2019-01-07 15:16:33 -05003297_(bd_ip_mac_flush_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003298_(want_interface_events_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003299_(cop_interface_enable_disable_reply) \
3300_(cop_whitelist_enable_disable_reply) \
3301_(sw_interface_clear_stats_reply) \
Dave Barach65457162017-10-10 17:53:14 -04003302_(ioam_enable_reply) \
3303_(ioam_disable_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003304_(af_packet_delete_reply) \
3305_(policer_classify_set_interface_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003306_(set_ipfix_exporter_reply) \
3307_(set_ipfix_classify_stream_reply) \
3308_(ipfix_classify_table_add_del_reply) \
3309_(flow_classify_set_interface_reply) \
3310_(sw_interface_span_enable_disable_reply) \
3311_(pg_capture_reply) \
3312_(pg_enable_disable_reply) \
Mohsin Kazmif382b062020-08-11 15:00:44 +02003313_(pg_interface_enable_disable_coalesce_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003314_(ip_source_and_port_range_check_add_del_reply) \
3315_(ip_source_and_port_range_check_interface_add_del_reply)\
3316_(delete_subif_reply) \
3317_(l2_interface_pbb_tag_rewrite_reply) \
Pavel Kotuceke88865d2018-11-28 07:42:11 +01003318_(set_punt_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003319_(feature_enable_disable_reply) \
Mohsin Kazmi29467b52019-10-08 19:42:38 +02003320_(feature_gso_enable_disable_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003321_(sw_interface_tag_add_del_reply) \
Matthew Smithe0792fd2019-07-12 11:48:24 -05003322_(sw_interface_add_del_mac_address_reply) \
Ole Troand7231612018-06-07 10:17:57 +02003323_(hw_interface_set_mtu_reply) \
Pavel Kotucek6899a302017-06-08 08:46:10 +02003324_(p2p_ethernet_add_reply) \
Steve Shin99a0e602017-07-01 04:16:20 +00003325_(p2p_ethernet_del_reply) \
Florin Corascea194d2017-10-02 00:18:51 -07003326_(tcp_configure_src_addresses_reply) \
Florin Coras595992c2017-11-06 17:17:08 -08003327_(session_rule_add_del_reply) \
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +01003328_(ip_container_proxy_add_del_reply) \
Igor Mikhailov (imichail)582caa32018-04-26 21:33:02 -07003329_(output_acl_set_interface_reply) \
Chenmin Sund0236f72020-07-27 17:54:40 +08003330_(qos_record_enable_disable_reply) \
3331_(flow_add_reply)
Damjan Marion7cd468a2016-12-19 23:05:39 +01003332
3333#define _(n) \
3334 static void vl_api_##n##_t_handler \
3335 (vl_api_##n##_t * mp) \
3336 { \
3337 vat_main_t * vam = &vat_main; \
3338 i32 retval = ntohl(mp->retval); \
3339 if (vam->async_mode) { \
3340 vam->async_errors += (retval < 0); \
3341 } else { \
3342 vam->retval = retval; \
3343 vam->result_ready = 1; \
3344 } \
3345 }
3346foreach_standard_reply_retval_handler;
3347#undef _
3348
3349#define _(n) \
3350 static void vl_api_##n##_t_handler_json \
3351 (vl_api_##n##_t * mp) \
3352 { \
3353 vat_main_t * vam = &vat_main; \
3354 vat_json_node_t node; \
3355 vat_json_init_object(&node); \
3356 vat_json_object_add_int(&node, "retval", ntohl(mp->retval)); \
3357 vat_json_print(vam->ofp, &node); \
3358 vam->retval = ntohl(mp->retval); \
3359 vam->result_ready = 1; \
3360 }
3361foreach_standard_reply_retval_handler;
3362#undef _
3363
3364/*
3365 * Table of message reply handlers, must include boilerplate handlers
3366 * we just generated
3367 */
3368
3369#define foreach_vpe_api_reply_msg \
3370_(CREATE_LOOPBACK_REPLY, create_loopback_reply) \
Jon Loeligerc83c3b72017-02-23 13:57:35 -06003371_(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003372_(SW_INTERFACE_DETAILS, sw_interface_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003373_(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply) \
3374_(CONTROL_PING_REPLY, control_ping_reply) \
3375_(CLI_REPLY, cli_reply) \
3376_(CLI_INBAND_REPLY, cli_inband_reply) \
3377_(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY, \
3378 sw_interface_add_del_address_reply) \
Stevenad8015b2017-10-29 22:10:46 -07003379_(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply) \
Mohsin Kazmi54f7c512018-08-23 18:28:11 +02003380_(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply) \
Mohsin Kazmif0b42f42018-09-10 18:11:00 +02003381_(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003382_(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply) \
3383_(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
3384_(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply) \
3385_(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +08003386_(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003387_(SW_INTERFACE_SET_L2_XCONNECT_REPLY, \
3388 sw_interface_set_l2_xconnect_reply) \
3389_(SW_INTERFACE_SET_L2_BRIDGE_REPLY, \
3390 sw_interface_set_l2_bridge_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003391_(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply) \
3392_(BRIDGE_DOMAIN_DETAILS, bridge_domain_details) \
Eyal Barifead6702017-04-04 04:46:32 +03003393_(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003394_(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply) \
Eyal Barif24991c2017-04-05 05:33:21 +03003395_(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply) \
3396_(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003397_(L2_FLAGS_REPLY, l2_flags_reply) \
3398_(BRIDGE_FLAGS_REPLY, bridge_flags_reply) \
Damjan Marion8389fb92017-10-13 18:29:53 +02003399_(TAP_CREATE_V2_REPLY, tap_create_v2_reply) \
3400_(TAP_DELETE_V2_REPLY, tap_delete_v2_reply) \
3401_(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details) \
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01003402_(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply) \
Mohsin Kazmi518251b2020-09-01 17:17:44 +00003403_(VIRTIO_PCI_CREATE_V2_REPLY, virtio_pci_create_v2_reply) \
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01003404_(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply) \
3405_(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details) \
Steven9cd2d7a2017-12-20 12:43:01 -08003406_(BOND_CREATE_REPLY, bond_create_reply) \
Steven Luongea717862020-07-30 07:31:40 -07003407_(BOND_CREATE2_REPLY, bond_create2_reply) \
Steven9cd2d7a2017-12-20 12:43:01 -08003408_(BOND_DELETE_REPLY, bond_delete_reply) \
Steven Luong4c4223e2020-07-15 08:44:54 -07003409_(BOND_ADD_MEMBER_REPLY, bond_add_member_reply) \
3410_(BOND_DETACH_MEMBER_REPLY, bond_detach_member_reply) \
Steven Luonga1876b82019-08-20 16:58:00 -07003411_(SW_INTERFACE_SET_BOND_WEIGHT_REPLY, sw_interface_set_bond_weight_reply) \
Steven Luong4c4223e2020-07-15 08:44:54 -07003412_(SW_BOND_INTERFACE_DETAILS, sw_bond_interface_details) \
3413_(SW_MEMBER_INTERFACE_DETAILS, sw_member_interface_details) \
Neale Ranns097fa662018-05-01 05:17:55 -07003414_(IP_ROUTE_ADD_DEL_REPLY, ip_route_add_del_reply) \
Neale Ranns28ab9cc2017-08-14 07:18:42 -07003415_(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply) \
Neale Ranns9db6ada2019-11-08 12:42:31 +00003416_(IP_TABLE_REPLACE_BEGIN_REPLY, ip_table_replace_begin_reply) \
3417_(IP_TABLE_FLUSH_REPLY, ip_table_flush_reply) \
3418_(IP_TABLE_REPLACE_END_REPLY, ip_table_replace_end_reply) \
Neale Ranns32e1c012016-11-22 17:07:28 +00003419_(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply) \
Neale Ranns28ab9cc2017-08-14 07:18:42 -07003420_(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003421_(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply) \
3422_(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply) \
Neale Rannsd792d9c2017-10-21 10:53:20 -07003423_(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply) \
3424_(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003425_(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply) \
3426_(SW_INTERFACE_SET_UNNUMBERED_REPLY, \
3427 sw_interface_set_unnumbered_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003428_(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply) \
3429_(CREATE_SUBIF_REPLY, create_subif_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003430_(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply) \
3431_(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY, \
3432 sw_interface_ip6_enable_disable_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003433_(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply) \
John Loe166fd92018-09-13 14:08:59 -04003434_(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply) \
3435_(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply) \
3436_(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply) \
Pablo Camarillofb380952016-12-07 18:34:18 +01003437_(SR_POLICY_ADD_REPLY, sr_policy_add_reply) \
3438_(SR_POLICY_MOD_REPLY, sr_policy_mod_reply) \
3439_(SR_POLICY_DEL_REPLY, sr_policy_del_reply) \
3440_(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply) \
3441_(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003442_(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply) \
3443_(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply) \
3444_(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY, \
3445classify_set_interface_ip_table_reply) \
3446_(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY, \
3447 classify_set_interface_l2_tables_reply) \
3448_(GET_NODE_INDEX_REPLY, get_node_index_reply) \
3449_(ADD_NODE_NEXT_REPLY, add_node_next_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003450_(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply) \
eyal bariaf86a482018-04-17 11:20:27 +03003451_(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003452_(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003453_(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply) \
3454_(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply) \
3455_(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3456_(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details) \
3457_(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply) \
3458_(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply) \
Steven Luong27ba5002020-11-17 13:30:44 -08003459_(CREATE_VHOST_USER_IF_V2_REPLY, create_vhost_user_if_v2_reply) \
3460_(MODIFY_VHOST_USER_IF_V2_REPLY, modify_vhost_user_if_v2_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003461_(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply) \
3462_(SHOW_VERSION_REPLY, show_version_reply) \
Mohsin Kazmi5d64c782018-09-11 20:27:09 +02003463_(SHOW_THREADS_REPLY, show_threads_reply) \
Ole Troan01384fe2017-05-12 11:55:35 +02003464_(L2_FIB_TABLE_DETAILS, l2_fib_table_details) \
John Loc7b43042018-04-13 16:46:22 -04003465_(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003466_(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details) \
3467_(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply) \
John Lo8d00fff2017-08-03 00:35:36 -04003468_(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply) \
3469_(L2_MACS_EVENT, l2_macs_event) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003470_(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply) \
3471_(IP_ADDRESS_DETAILS, ip_address_details) \
3472_(IP_DETAILS, ip_details) \
3473_(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply) \
3474_(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
Neale Ranns17dcec02019-01-09 21:22:20 -08003475_(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply) \
3476_(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply) \
Matthew Smith28029532017-09-26 13:33:44 -05003477_(IPSEC_SA_DETAILS, ipsec_sa_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003478_(DELETE_LOOPBACK_REPLY, delete_loopback_reply) \
3479_(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply) \
John Loe26c81f2019-01-07 15:16:33 -05003480_(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply) \
Mohsin Kazmi5d82d2f2018-08-13 19:17:54 +02003481_(BD_IP_MAC_DETAILS, bd_ip_mac_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003482_(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003483_(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply) \
3484_(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
3485_(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
3486_(GET_NODE_GRAPH_REPLY, get_node_graph_reply) \
3487_(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply) \
3488_(IOAM_ENABLE_REPLY, ioam_enable_reply) \
3489_(IOAM_DISABLE_REPLY, ioam_disable_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003490_(AF_PACKET_CREATE_REPLY, af_packet_create_reply) \
3491_(AF_PACKET_DELETE_REPLY, af_packet_delete_reply) \
Mohsin Kazmi04e0bb22018-05-28 18:55:37 +02003492_(AF_PACKET_DETAILS, af_packet_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003493_(POLICER_ADD_DEL_REPLY, policer_add_del_reply) \
3494_(POLICER_DETAILS, policer_details) \
3495_(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3496_(POLICER_CLASSIFY_DETAILS, policer_classify_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003497_(MPLS_TUNNEL_DETAILS, mpls_tunnel_details) \
Neale Ranns097fa662018-05-01 05:17:55 -07003498_(MPLS_TABLE_DETAILS, mpls_table_details) \
3499_(MPLS_ROUTE_DETAILS, mpls_route_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003500_(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply) \
3501_(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3502_(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply) \
3503_(CLASSIFY_SESSION_DETAILS, classify_session_details) \
3504_(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply) \
3505_(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details) \
3506_(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply) \
3507_(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details) \
3508_(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
3509_(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details) \
3510_(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
3511_(FLOW_CLASSIFY_DETAILS, flow_classify_details) \
3512_(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
3513_(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details) \
3514_(GET_NEXT_INDEX_REPLY, get_next_index_reply) \
3515_(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply) \
3516_(PG_CAPTURE_REPLY, pg_capture_reply) \
3517_(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply) \
Mohsin Kazmif382b062020-08-11 15:00:44 +02003518_(PG_INTERFACE_ENABLE_DISABLE_COALESCE_REPLY, pg_interface_enable_disable_coalesce_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003519_(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY, \
3520 ip_source_and_port_range_check_add_del_reply) \
3521_(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY, \
3522 ip_source_and_port_range_check_interface_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003523_(DELETE_SUBIF_REPLY, delete_subif_reply) \
3524_(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
Pavel Kotuceke88865d2018-11-28 07:42:11 +01003525_(SET_PUNT_REPLY, set_punt_reply) \
Neale Ranns097fa662018-05-01 05:17:55 -07003526_(IP_TABLE_DETAILS, ip_table_details) \
3527_(IP_ROUTE_DETAILS, ip_route_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003528_(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply) \
Mohsin Kazmi29467b52019-10-08 19:42:38 +02003529_(FEATURE_GSO_ENABLE_DISABLE_REPLY, feature_gso_enable_disable_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003530_(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply) \
Matthew Smithe0792fd2019-07-12 11:48:24 -05003531_(SW_INTERFACE_ADD_DEL_MAC_ADDRESS_REPLY, sw_interface_add_del_mac_address_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003532_(L2_XCONNECT_DETAILS, l2_xconnect_details) \
Ole Troand7231612018-06-07 10:17:57 +02003533_(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply) \
Pavel Kotucek6899a302017-06-08 08:46:10 +02003534_(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply) \
3535_(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply) \
Steve Shin99a0e602017-07-01 04:16:20 +00003536_(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply) \
Florin Corascea194d2017-10-02 00:18:51 -07003537_(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
Dave Barach65457162017-10-10 17:53:14 -04003538_(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply) \
Florin Coras6c36f532017-11-03 18:32:34 -07003539_(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply) \
Florin Coras595992c2017-11-06 17:17:08 -08003540_(SESSION_RULES_DETAILS, session_rules_details) \
3541_(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply) \
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +01003542_(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply) \
Chenmin Sund0236f72020-07-27 17:54:40 +08003543_(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply) \
3544_(FLOW_ADD_REPLY, flow_add_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003545
Dave Baracha1a093d2017-03-02 13:13:23 -05003546#define foreach_standalone_reply_msg \
Ole Troanf49ba0e2018-11-13 14:04:50 +01003547_(SW_INTERFACE_EVENT, sw_interface_event)
Dave Baracha1a093d2017-03-02 13:13:23 -05003548
Damjan Marion7cd468a2016-12-19 23:05:39 +01003549typedef struct
3550{
3551 u8 *name;
3552 u32 value;
3553} name_sort_t;
3554
Damjan Marion7cd468a2016-12-19 23:05:39 +01003555#define STR_VTR_OP_CASE(op) \
3556 case L2_VTR_ ## op: \
3557 return "" # op;
3558
3559static const char *
3560str_vtr_op (u32 vtr_op)
3561{
3562 switch (vtr_op)
3563 {
3564 STR_VTR_OP_CASE (DISABLED);
3565 STR_VTR_OP_CASE (PUSH_1);
3566 STR_VTR_OP_CASE (PUSH_2);
3567 STR_VTR_OP_CASE (POP_1);
3568 STR_VTR_OP_CASE (POP_2);
3569 STR_VTR_OP_CASE (TRANSLATE_1_1);
3570 STR_VTR_OP_CASE (TRANSLATE_1_2);
3571 STR_VTR_OP_CASE (TRANSLATE_2_1);
3572 STR_VTR_OP_CASE (TRANSLATE_2_2);
3573 }
3574
3575 return "UNKNOWN";
3576}
3577
3578static int
3579dump_sub_interface_table (vat_main_t * vam)
3580{
3581 const sw_interface_subif_t *sub = NULL;
3582
3583 if (vam->json_output)
3584 {
3585 clib_warning
3586 ("JSON output supported only for VPE API calls and dump_stats_table");
3587 return -99;
3588 }
3589
3590 print (vam->ofp,
3591 "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
3592 "Interface", "sw_if_index",
3593 "sub id", "dot1ad", "tags", "outer id",
3594 "inner id", "exact", "default", "outer any", "inner any");
3595
3596 vec_foreach (sub, vam->sw_if_subif_table)
3597 {
3598 print (vam->ofp,
3599 "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
3600 sub->interface_name,
3601 sub->sw_if_index,
3602 sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
3603 sub->sub_number_of_tags, sub->sub_outer_vlan_id,
3604 sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
3605 sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
3606 if (sub->vtr_op != L2_VTR_DISABLED)
3607 {
3608 print (vam->ofp,
3609 " vlan-tag-rewrite - op: %-14s [ dot1q: %d "
3610 "tag1: %d tag2: %d ]",
3611 str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
3612 sub->vtr_tag1, sub->vtr_tag2);
3613 }
3614 }
3615
3616 return 0;
3617}
3618
3619static int
3620name_sort_cmp (void *a1, void *a2)
3621{
3622 name_sort_t *n1 = a1;
3623 name_sort_t *n2 = a2;
3624
3625 return strcmp ((char *) n1->name, (char *) n2->name);
3626}
3627
3628static int
3629dump_interface_table (vat_main_t * vam)
3630{
3631 hash_pair_t *p;
3632 name_sort_t *nses = 0, *ns;
3633
3634 if (vam->json_output)
3635 {
3636 clib_warning
3637 ("JSON output supported only for VPE API calls and dump_stats_table");
3638 return -99;
3639 }
3640
3641 /* *INDENT-OFF* */
3642 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3643 ({
3644 vec_add2 (nses, ns, 1);
3645 ns->name = (u8 *)(p->key);
3646 ns->value = (u32) p->value[0];
3647 }));
3648 /* *INDENT-ON* */
3649
3650 vec_sort_with_function (nses, name_sort_cmp);
3651
3652 print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
3653 vec_foreach (ns, nses)
3654 {
3655 print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
3656 }
3657 vec_free (nses);
3658 return 0;
3659}
3660
3661static int
3662dump_ip_table (vat_main_t * vam, int is_ipv6)
3663{
3664 const ip_details_t *det = NULL;
3665 const ip_address_details_t *address = NULL;
3666 u32 i = ~0;
3667
3668 print (vam->ofp, "%-12s", "sw_if_index");
3669
3670 vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
3671 {
3672 i++;
3673 if (!det->present)
3674 {
3675 continue;
3676 }
3677 print (vam->ofp, "%-12d", i);
3678 print (vam->ofp, " %-30s%-13s", "Address", "Prefix length");
3679 if (!det->addr)
3680 {
3681 continue;
3682 }
3683 vec_foreach (address, det->addr)
3684 {
3685 print (vam->ofp,
3686 " %-30U%-13d",
3687 is_ipv6 ? format_ip6_address : format_ip4_address,
3688 address->ip, address->prefix_length);
3689 }
3690 }
3691
3692 return 0;
3693}
3694
3695static int
3696dump_ipv4_table (vat_main_t * vam)
3697{
3698 if (vam->json_output)
3699 {
3700 clib_warning
3701 ("JSON output supported only for VPE API calls and dump_stats_table");
3702 return -99;
3703 }
3704
3705 return dump_ip_table (vam, 0);
3706}
3707
3708static int
3709dump_ipv6_table (vat_main_t * vam)
3710{
3711 if (vam->json_output)
3712 {
3713 clib_warning
3714 ("JSON output supported only for VPE API calls and dump_stats_table");
3715 return -99;
3716 }
3717
3718 return dump_ip_table (vam, 1);
3719}
3720
Damjan Marion7cd468a2016-12-19 23:05:39 +01003721/*
Dave Barach59b25652017-09-10 15:04:27 -04003722 * Pass CLI buffers directly in the CLI_INBAND API message,
3723 * instead of an additional shared memory area.
Damjan Marion7cd468a2016-12-19 23:05:39 +01003724 */
3725static int
3726exec_inband (vat_main_t * vam)
3727{
3728 vl_api_cli_inband_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003729 unformat_input_t *i = vam->input;
Jon Loeliger56c7b012017-02-01 12:31:41 -06003730 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003731
3732 if (vec_len (i->buffer) == 0)
3733 return -1;
3734
3735 if (vam->exec_mode == 0 && unformat (i, "mode"))
3736 {
3737 vam->exec_mode = 1;
3738 return 0;
3739 }
3740 if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
3741 {
3742 vam->exec_mode = 0;
3743 return 0;
3744 }
3745
3746 /*
3747 * In order for the CLI command to work, it
3748 * must be a vector ending in \n, not a C-string ending
3749 * in \n\0.
3750 */
Jakub Grajciar2dbee932020-02-07 11:30:26 +01003751 M2 (CLI_INBAND, mp, vec_len (vam->input->buffer));
3752 vl_api_vec_to_api_string (vam->input->buffer, &mp->cmd);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003753
Jon Loeliger7bc770c2017-01-31 14:03:33 -06003754 S (mp);
Dave Barach59b25652017-09-10 15:04:27 -04003755 W (ret);
3756 /* json responses may or may not include a useful reply... */
3757 if (vec_len (vam->cmd_reply))
Dave Barachcf5e8482017-10-17 11:48:29 -04003758 print (vam->ofp, "%v", (char *) (vam->cmd_reply));
Jon Loeliger56c7b012017-02-01 12:31:41 -06003759 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003760}
3761
Dave Barach59b25652017-09-10 15:04:27 -04003762int
3763exec (vat_main_t * vam)
3764{
3765 return exec_inband (vam);
3766}
3767
Damjan Marion7cd468a2016-12-19 23:05:39 +01003768static int
3769api_create_loopback (vat_main_t * vam)
3770{
3771 unformat_input_t *i = vam->input;
3772 vl_api_create_loopback_t *mp;
Jon Loeligerc83c3b72017-02-23 13:57:35 -06003773 vl_api_create_loopback_instance_t *mp_lbi;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003774 u8 mac_address[6];
3775 u8 mac_set = 0;
Jon Loeligerc83c3b72017-02-23 13:57:35 -06003776 u8 is_specified = 0;
3777 u32 user_instance = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06003778 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003779
Dave Barachb7b92992018-10-17 10:38:51 -04003780 clib_memset (mac_address, 0, sizeof (mac_address));
Damjan Marion7cd468a2016-12-19 23:05:39 +01003781
3782 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3783 {
3784 if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
3785 mac_set = 1;
Jon Loeligerc83c3b72017-02-23 13:57:35 -06003786 if (unformat (i, "instance %d", &user_instance))
3787 is_specified = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003788 else
3789 break;
3790 }
3791
Jon Loeligerc83c3b72017-02-23 13:57:35 -06003792 if (is_specified)
3793 {
3794 M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
3795 mp_lbi->is_specified = is_specified;
3796 if (is_specified)
3797 mp_lbi->user_instance = htonl (user_instance);
3798 if (mac_set)
3799 clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
3800 S (mp_lbi);
3801 }
3802 else
3803 {
3804 /* Construct the API message */
3805 M (CREATE_LOOPBACK, mp);
3806 if (mac_set)
3807 clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
3808 S (mp);
3809 }
Damjan Marion7cd468a2016-12-19 23:05:39 +01003810
Jon Loeliger56c7b012017-02-01 12:31:41 -06003811 W (ret);
3812 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003813}
3814
3815static int
3816api_delete_loopback (vat_main_t * vam)
3817{
3818 unformat_input_t *i = vam->input;
3819 vl_api_delete_loopback_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003820 u32 sw_if_index = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06003821 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003822
3823 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3824 {
3825 if (unformat (i, "sw_if_index %d", &sw_if_index))
3826 ;
3827 else
3828 break;
3829 }
3830
3831 if (sw_if_index == ~0)
3832 {
3833 errmsg ("missing sw_if_index");
3834 return -99;
3835 }
3836
3837 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06003838 M (DELETE_LOOPBACK, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003839 mp->sw_if_index = ntohl (sw_if_index);
3840
Jon Loeliger7bc770c2017-01-31 14:03:33 -06003841 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06003842 W (ret);
3843 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003844}
3845
3846static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01003847api_want_interface_events (vat_main_t * vam)
3848{
3849 unformat_input_t *i = vam->input;
3850 vl_api_want_interface_events_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003851 int enable = -1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06003852 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003853
3854 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3855 {
3856 if (unformat (i, "enable"))
3857 enable = 1;
3858 else if (unformat (i, "disable"))
3859 enable = 0;
3860 else
3861 break;
3862 }
3863
3864 if (enable == -1)
3865 {
3866 errmsg ("missing enable|disable");
3867 return -99;
3868 }
3869
Jon Loeliger8a2aea32017-01-31 13:19:40 -06003870 M (WANT_INTERFACE_EVENTS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003871 mp->enable_disable = enable;
3872
3873 vam->interface_event_display = enable;
3874
Jon Loeliger7bc770c2017-01-31 14:03:33 -06003875 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06003876 W (ret);
3877 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003878}
3879
3880
3881/* Note: non-static, called once to set up the initial intfc table */
3882int
3883api_sw_interface_dump (vat_main_t * vam)
3884{
3885 vl_api_sw_interface_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -06003886 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003887 hash_pair_t *p;
3888 name_sort_t *nses = 0, *ns;
3889 sw_interface_subif_t *sub = NULL;
Jon Loeliger56c7b012017-02-01 12:31:41 -06003890 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003891
3892 /* Toss the old name table */
3893 /* *INDENT-OFF* */
3894 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3895 ({
3896 vec_add2 (nses, ns, 1);
3897 ns->name = (u8 *)(p->key);
3898 ns->value = (u32) p->value[0];
3899 }));
3900 /* *INDENT-ON* */
3901
3902 hash_free (vam->sw_if_index_by_interface_name);
3903
3904 vec_foreach (ns, nses) vec_free (ns->name);
3905
3906 vec_free (nses);
3907
3908 vec_foreach (sub, vam->sw_if_subif_table)
3909 {
3910 vec_free (sub->interface_name);
3911 }
3912 vec_free (vam->sw_if_subif_table);
3913
3914 /* recreate the interface name hash table */
3915 vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
3916
Dave Barachf72212e2018-01-11 10:25:07 -05003917 /*
3918 * Ask for all interface names. Otherwise, the epic catalog of
3919 * name filters becomes ridiculously long, and vat ends up needing
3920 * to be taught about new interface types.
3921 */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06003922 M (SW_INTERFACE_DUMP, mp);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06003923 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003924
3925 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -04003926 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06003927 S (mp_ping);
3928
Jon Loeliger56c7b012017-02-01 12:31:41 -06003929 W (ret);
3930 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003931}
3932
3933static int
3934api_sw_interface_set_flags (vat_main_t * vam)
3935{
3936 unformat_input_t *i = vam->input;
3937 vl_api_sw_interface_set_flags_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003938 u32 sw_if_index;
3939 u8 sw_if_index_set = 0;
Neale Rannsa07bd702017-08-07 07:53:49 -07003940 u8 admin_up = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06003941 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003942
3943 /* Parse args required to build the message */
3944 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3945 {
3946 if (unformat (i, "admin-up"))
3947 admin_up = 1;
3948 else if (unformat (i, "admin-down"))
3949 admin_up = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003950 else
3951 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
3952 sw_if_index_set = 1;
3953 else if (unformat (i, "sw_if_index %d", &sw_if_index))
3954 sw_if_index_set = 1;
3955 else
3956 break;
3957 }
3958
3959 if (sw_if_index_set == 0)
3960 {
3961 errmsg ("missing interface name or sw_if_index");
3962 return -99;
3963 }
3964
3965 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06003966 M (SW_INTERFACE_SET_FLAGS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003967 mp->sw_if_index = ntohl (sw_if_index);
Jakub Grajciar053204a2019-03-18 13:17:53 +01003968 mp->flags = ntohl ((admin_up) ? IF_STATUS_API_FLAG_ADMIN_UP : 0);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003969
3970 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06003971 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003972
3973 /* Wait for a reply, return the good/bad news... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06003974 W (ret);
3975 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003976}
3977
3978static int
Stevenad8015b2017-10-29 22:10:46 -07003979api_sw_interface_set_rx_mode (vat_main_t * vam)
3980{
3981 unformat_input_t *i = vam->input;
3982 vl_api_sw_interface_set_rx_mode_t *mp;
3983 u32 sw_if_index;
3984 u8 sw_if_index_set = 0;
3985 int ret;
3986 u8 queue_id_valid = 0;
3987 u32 queue_id;
Damjan Marioneabd4242020-10-07 20:59:07 +02003988 vnet_hw_if_rx_mode mode = VNET_HW_IF_RX_MODE_UNKNOWN;
Stevenad8015b2017-10-29 22:10:46 -07003989
3990 /* Parse args required to build the message */
3991 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3992 {
3993 if (unformat (i, "queue %d", &queue_id))
3994 queue_id_valid = 1;
3995 else if (unformat (i, "polling"))
Damjan Marioneabd4242020-10-07 20:59:07 +02003996 mode = VNET_HW_IF_RX_MODE_POLLING;
Stevenad8015b2017-10-29 22:10:46 -07003997 else if (unformat (i, "interrupt"))
Damjan Marioneabd4242020-10-07 20:59:07 +02003998 mode = VNET_HW_IF_RX_MODE_INTERRUPT;
Stevenad8015b2017-10-29 22:10:46 -07003999 else if (unformat (i, "adaptive"))
Damjan Marioneabd4242020-10-07 20:59:07 +02004000 mode = VNET_HW_IF_RX_MODE_ADAPTIVE;
Stevenad8015b2017-10-29 22:10:46 -07004001 else
4002 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4003 sw_if_index_set = 1;
4004 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4005 sw_if_index_set = 1;
4006 else
4007 break;
4008 }
4009
4010 if (sw_if_index_set == 0)
4011 {
4012 errmsg ("missing interface name or sw_if_index");
4013 return -99;
4014 }
Damjan Marioneabd4242020-10-07 20:59:07 +02004015 if (mode == VNET_HW_IF_RX_MODE_UNKNOWN)
Stevenad8015b2017-10-29 22:10:46 -07004016 {
4017 errmsg ("missing rx-mode");
4018 return -99;
4019 }
4020
4021 /* Construct the API message */
4022 M (SW_INTERFACE_SET_RX_MODE, mp);
4023 mp->sw_if_index = ntohl (sw_if_index);
Jakub Grajciar053204a2019-03-18 13:17:53 +01004024 mp->mode = (vl_api_rx_mode_t) mode;
Stevenad8015b2017-10-29 22:10:46 -07004025 mp->queue_id_valid = queue_id_valid;
4026 mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
4027
4028 /* send it... */
4029 S (mp);
4030
4031 /* Wait for a reply, return the good/bad news... */
4032 W (ret);
4033 return ret;
4034}
4035
4036static int
Mohsin Kazmi54f7c512018-08-23 18:28:11 +02004037api_sw_interface_set_rx_placement (vat_main_t * vam)
4038{
4039 unformat_input_t *i = vam->input;
4040 vl_api_sw_interface_set_rx_placement_t *mp;
4041 u32 sw_if_index;
4042 u8 sw_if_index_set = 0;
4043 int ret;
4044 u8 is_main = 0;
4045 u32 queue_id, thread_index;
4046
4047 /* Parse args required to build the message */
4048 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4049 {
4050 if (unformat (i, "queue %d", &queue_id))
4051 ;
4052 else if (unformat (i, "main"))
4053 is_main = 1;
4054 else if (unformat (i, "worker %d", &thread_index))
4055 ;
4056 else
4057 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4058 sw_if_index_set = 1;
4059 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4060 sw_if_index_set = 1;
4061 else
4062 break;
4063 }
4064
4065 if (sw_if_index_set == 0)
4066 {
4067 errmsg ("missing interface name or sw_if_index");
4068 return -99;
4069 }
4070
4071 if (is_main)
4072 thread_index = 0;
4073 /* Construct the API message */
4074 M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
4075 mp->sw_if_index = ntohl (sw_if_index);
4076 mp->worker_id = ntohl (thread_index);
4077 mp->queue_id = ntohl (queue_id);
4078 mp->is_main = is_main;
4079
4080 /* send it... */
4081 S (mp);
4082 /* Wait for a reply, return the good/bad news... */
4083 W (ret);
4084 return ret;
4085}
4086
Mohsin Kazmif0b42f42018-09-10 18:11:00 +02004087static void vl_api_sw_interface_rx_placement_details_t_handler
4088 (vl_api_sw_interface_rx_placement_details_t * mp)
4089{
4090 vat_main_t *vam = &vat_main;
4091 u32 worker_id = ntohl (mp->worker_id);
4092
4093 print (vam->ofp,
4094 "\n%-11d %-11s %-6d %-5d %-9s",
4095 ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
4096 worker_id, ntohl (mp->queue_id),
4097 (mp->mode ==
4098 1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
4099}
4100
4101static void vl_api_sw_interface_rx_placement_details_t_handler_json
4102 (vl_api_sw_interface_rx_placement_details_t * mp)
4103{
4104 vat_main_t *vam = &vat_main;
4105 vat_json_node_t *node = NULL;
4106
4107 if (VAT_JSON_ARRAY != vam->json_tree.type)
4108 {
4109 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4110 vat_json_init_array (&vam->json_tree);
4111 }
4112 node = vat_json_array_add (&vam->json_tree);
4113
4114 vat_json_init_object (node);
4115 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4116 vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
4117 vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
4118 vat_json_object_add_uint (node, "mode", mp->mode);
4119}
4120
4121static int
4122api_sw_interface_rx_placement_dump (vat_main_t * vam)
4123{
4124 unformat_input_t *i = vam->input;
4125 vl_api_sw_interface_rx_placement_dump_t *mp;
4126 vl_api_control_ping_t *mp_ping;
4127 int ret;
4128 u32 sw_if_index;
4129 u8 sw_if_index_set = 0;
4130
4131 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4132 {
4133 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4134 sw_if_index_set++;
4135 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4136 sw_if_index_set++;
4137 else
4138 break;
4139 }
4140
4141 print (vam->ofp,
4142 "\n%-11s %-11s %-6s %-5s %-4s",
4143 "sw_if_index", "main/worker", "thread", "queue", "mode");
4144
4145 /* Dump Interface rx placement */
4146 M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
4147
4148 if (sw_if_index_set)
4149 mp->sw_if_index = htonl (sw_if_index);
4150 else
4151 mp->sw_if_index = ~0;
4152
4153 S (mp);
4154
4155 /* Use a control ping for synchronization */
4156 MPING (CONTROL_PING, mp_ping);
4157 S (mp_ping);
4158
4159 W (ret);
4160 return ret;
4161}
4162
Mohsin Kazmi54f7c512018-08-23 18:28:11 +02004163static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01004164api_sw_interface_clear_stats (vat_main_t * vam)
4165{
4166 unformat_input_t *i = vam->input;
4167 vl_api_sw_interface_clear_stats_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004168 u32 sw_if_index;
4169 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004170 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004171
4172 /* Parse args required to build the message */
4173 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4174 {
4175 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4176 sw_if_index_set = 1;
4177 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4178 sw_if_index_set = 1;
4179 else
4180 break;
4181 }
4182
4183 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004184 M (SW_INTERFACE_CLEAR_STATS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004185
4186 if (sw_if_index_set == 1)
4187 mp->sw_if_index = ntohl (sw_if_index);
4188 else
4189 mp->sw_if_index = ~0;
4190
4191 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004192 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004193
4194 /* Wait for a reply, return the good/bad news... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06004195 W (ret);
4196 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004197}
4198
Damjan Marion7cd468a2016-12-19 23:05:39 +01004199static int
4200api_sw_interface_add_del_address (vat_main_t * vam)
4201{
4202 unformat_input_t *i = vam->input;
4203 vl_api_sw_interface_add_del_address_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004204 u32 sw_if_index;
4205 u8 sw_if_index_set = 0;
4206 u8 is_add = 1, del_all = 0;
4207 u32 address_length = 0;
4208 u8 v4_address_set = 0;
4209 u8 v6_address_set = 0;
4210 ip4_address_t v4address;
4211 ip6_address_t v6address;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004212 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004213
4214 /* Parse args required to build the message */
4215 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4216 {
4217 if (unformat (i, "del-all"))
4218 del_all = 1;
4219 else if (unformat (i, "del"))
4220 is_add = 0;
4221 else
4222 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4223 sw_if_index_set = 1;
4224 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4225 sw_if_index_set = 1;
4226 else if (unformat (i, "%U/%d",
4227 unformat_ip4_address, &v4address, &address_length))
4228 v4_address_set = 1;
4229 else if (unformat (i, "%U/%d",
4230 unformat_ip6_address, &v6address, &address_length))
4231 v6_address_set = 1;
4232 else
4233 break;
4234 }
4235
4236 if (sw_if_index_set == 0)
4237 {
4238 errmsg ("missing interface name or sw_if_index");
4239 return -99;
4240 }
4241 if (v4_address_set && v6_address_set)
4242 {
4243 errmsg ("both v4 and v6 addresses set");
4244 return -99;
4245 }
4246 if (!v4_address_set && !v6_address_set && !del_all)
4247 {
4248 errmsg ("no addresses set");
4249 return -99;
4250 }
4251
4252 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004253 M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004254
4255 mp->sw_if_index = ntohl (sw_if_index);
4256 mp->is_add = is_add;
4257 mp->del_all = del_all;
4258 if (v6_address_set)
4259 {
Jakub Grajciar053204a2019-03-18 13:17:53 +01004260 mp->prefix.address.af = ADDRESS_IP6;
4261 clib_memcpy (mp->prefix.address.un.ip6, &v6address, sizeof (v6address));
Damjan Marion7cd468a2016-12-19 23:05:39 +01004262 }
4263 else
4264 {
Jakub Grajciar053204a2019-03-18 13:17:53 +01004265 mp->prefix.address.af = ADDRESS_IP4;
4266 clib_memcpy (mp->prefix.address.un.ip4, &v4address, sizeof (v4address));
Damjan Marion7cd468a2016-12-19 23:05:39 +01004267 }
Jakub Grajciar053204a2019-03-18 13:17:53 +01004268 mp->prefix.len = address_length;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004269
4270 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004271 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004272
4273 /* Wait for a reply, return good/bad news */
Jon Loeliger56c7b012017-02-01 12:31:41 -06004274 W (ret);
4275 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004276}
4277
4278static int
4279api_sw_interface_set_mpls_enable (vat_main_t * vam)
4280{
4281 unformat_input_t *i = vam->input;
4282 vl_api_sw_interface_set_mpls_enable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004283 u32 sw_if_index;
4284 u8 sw_if_index_set = 0;
4285 u8 enable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004286 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004287
4288 /* Parse args required to build the message */
4289 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4290 {
4291 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4292 sw_if_index_set = 1;
4293 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4294 sw_if_index_set = 1;
4295 else if (unformat (i, "disable"))
4296 enable = 0;
4297 else if (unformat (i, "dis"))
4298 enable = 0;
4299 else
4300 break;
4301 }
4302
4303 if (sw_if_index_set == 0)
4304 {
4305 errmsg ("missing interface name or sw_if_index");
4306 return -99;
4307 }
4308
4309 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004310 M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004311
4312 mp->sw_if_index = ntohl (sw_if_index);
4313 mp->enable = enable;
4314
4315 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004316 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004317
4318 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06004319 W (ret);
4320 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004321}
4322
4323static int
4324api_sw_interface_set_table (vat_main_t * vam)
4325{
4326 unformat_input_t *i = vam->input;
4327 vl_api_sw_interface_set_table_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004328 u32 sw_if_index, vrf_id = 0;
4329 u8 sw_if_index_set = 0;
4330 u8 is_ipv6 = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004331 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004332
4333 /* Parse args required to build the message */
4334 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4335 {
4336 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4337 sw_if_index_set = 1;
4338 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4339 sw_if_index_set = 1;
4340 else if (unformat (i, "vrf %d", &vrf_id))
4341 ;
4342 else if (unformat (i, "ipv6"))
4343 is_ipv6 = 1;
4344 else
4345 break;
4346 }
4347
4348 if (sw_if_index_set == 0)
4349 {
4350 errmsg ("missing interface name or sw_if_index");
4351 return -99;
4352 }
4353
4354 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004355 M (SW_INTERFACE_SET_TABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004356
4357 mp->sw_if_index = ntohl (sw_if_index);
4358 mp->is_ipv6 = is_ipv6;
4359 mp->vrf_id = ntohl (vrf_id);
4360
4361 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004362 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004363
4364 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06004365 W (ret);
4366 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004367}
4368
4369static void vl_api_sw_interface_get_table_reply_t_handler
4370 (vl_api_sw_interface_get_table_reply_t * mp)
4371{
4372 vat_main_t *vam = &vat_main;
4373
4374 print (vam->ofp, "%d", ntohl (mp->vrf_id));
4375
4376 vam->retval = ntohl (mp->retval);
4377 vam->result_ready = 1;
4378
4379}
4380
4381static void vl_api_sw_interface_get_table_reply_t_handler_json
4382 (vl_api_sw_interface_get_table_reply_t * mp)
4383{
4384 vat_main_t *vam = &vat_main;
4385 vat_json_node_t node;
4386
4387 vat_json_init_object (&node);
4388 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4389 vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
4390
4391 vat_json_print (vam->ofp, &node);
4392 vat_json_free (&node);
4393
4394 vam->retval = ntohl (mp->retval);
4395 vam->result_ready = 1;
4396}
4397
4398static int
4399api_sw_interface_get_table (vat_main_t * vam)
4400{
4401 unformat_input_t *i = vam->input;
4402 vl_api_sw_interface_get_table_t *mp;
4403 u32 sw_if_index;
4404 u8 sw_if_index_set = 0;
4405 u8 is_ipv6 = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004406 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004407
4408 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4409 {
4410 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4411 sw_if_index_set = 1;
4412 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4413 sw_if_index_set = 1;
4414 else if (unformat (i, "ipv6"))
4415 is_ipv6 = 1;
4416 else
4417 break;
4418 }
4419
4420 if (sw_if_index_set == 0)
4421 {
4422 errmsg ("missing interface name or sw_if_index");
4423 return -99;
4424 }
4425
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004426 M (SW_INTERFACE_GET_TABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004427 mp->sw_if_index = htonl (sw_if_index);
4428 mp->is_ipv6 = is_ipv6;
4429
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004430 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06004431 W (ret);
4432 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004433}
4434
4435static int
4436api_sw_interface_set_vpath (vat_main_t * vam)
4437{
4438 unformat_input_t *i = vam->input;
4439 vl_api_sw_interface_set_vpath_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004440 u32 sw_if_index = 0;
4441 u8 sw_if_index_set = 0;
4442 u8 is_enable = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004443 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004444
4445 /* Parse args required to build the message */
4446 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4447 {
4448 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4449 sw_if_index_set = 1;
4450 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4451 sw_if_index_set = 1;
4452 else if (unformat (i, "enable"))
4453 is_enable = 1;
4454 else if (unformat (i, "disable"))
4455 is_enable = 0;
4456 else
4457 break;
4458 }
4459
4460 if (sw_if_index_set == 0)
4461 {
4462 errmsg ("missing interface name or sw_if_index");
4463 return -99;
4464 }
4465
4466 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004467 M (SW_INTERFACE_SET_VPATH, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004468
4469 mp->sw_if_index = ntohl (sw_if_index);
4470 mp->enable = is_enable;
4471
4472 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004473 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004474
4475 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06004476 W (ret);
4477 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004478}
4479
4480static int
4481api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
4482{
4483 unformat_input_t *i = vam->input;
4484 vl_api_sw_interface_set_vxlan_bypass_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004485 u32 sw_if_index = 0;
4486 u8 sw_if_index_set = 0;
John Lo2b81eb82017-01-30 13:12:10 -05004487 u8 is_enable = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004488 u8 is_ipv6 = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004489 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004490
4491 /* Parse args required to build the message */
4492 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4493 {
4494 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4495 sw_if_index_set = 1;
4496 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4497 sw_if_index_set = 1;
4498 else if (unformat (i, "enable"))
4499 is_enable = 1;
4500 else if (unformat (i, "disable"))
4501 is_enable = 0;
4502 else if (unformat (i, "ip4"))
4503 is_ipv6 = 0;
4504 else if (unformat (i, "ip6"))
4505 is_ipv6 = 1;
4506 else
4507 break;
4508 }
4509
4510 if (sw_if_index_set == 0)
4511 {
4512 errmsg ("missing interface name or sw_if_index");
4513 return -99;
4514 }
4515
4516 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004517 M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004518
4519 mp->sw_if_index = ntohl (sw_if_index);
4520 mp->enable = is_enable;
4521 mp->is_ipv6 = is_ipv6;
4522
4523 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004524 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004525
4526 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06004527 W (ret);
4528 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004529}
4530
Marco Varleseb598f1d2017-09-19 14:25:28 +02004531static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01004532api_sw_interface_set_l2_xconnect (vat_main_t * vam)
4533{
4534 unformat_input_t *i = vam->input;
4535 vl_api_sw_interface_set_l2_xconnect_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004536 u32 rx_sw_if_index;
4537 u8 rx_sw_if_index_set = 0;
4538 u32 tx_sw_if_index;
4539 u8 tx_sw_if_index_set = 0;
4540 u8 enable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004541 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004542
4543 /* Parse args required to build the message */
4544 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4545 {
4546 if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
4547 rx_sw_if_index_set = 1;
4548 else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
4549 tx_sw_if_index_set = 1;
4550 else if (unformat (i, "rx"))
4551 {
4552 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4553 {
4554 if (unformat (i, "%U", api_unformat_sw_if_index, vam,
4555 &rx_sw_if_index))
4556 rx_sw_if_index_set = 1;
4557 }
4558 else
4559 break;
4560 }
4561 else if (unformat (i, "tx"))
4562 {
4563 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4564 {
4565 if (unformat (i, "%U", api_unformat_sw_if_index, vam,
4566 &tx_sw_if_index))
4567 tx_sw_if_index_set = 1;
4568 }
4569 else
4570 break;
4571 }
4572 else if (unformat (i, "enable"))
4573 enable = 1;
4574 else if (unformat (i, "disable"))
4575 enable = 0;
4576 else
4577 break;
4578 }
4579
4580 if (rx_sw_if_index_set == 0)
4581 {
4582 errmsg ("missing rx interface name or rx_sw_if_index");
4583 return -99;
4584 }
4585
4586 if (enable && (tx_sw_if_index_set == 0))
4587 {
4588 errmsg ("missing tx interface name or tx_sw_if_index");
4589 return -99;
4590 }
4591
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004592 M (SW_INTERFACE_SET_L2_XCONNECT, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004593
4594 mp->rx_sw_if_index = ntohl (rx_sw_if_index);
4595 mp->tx_sw_if_index = ntohl (tx_sw_if_index);
4596 mp->enable = enable;
4597
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004598 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06004599 W (ret);
4600 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004601}
4602
4603static int
4604api_sw_interface_set_l2_bridge (vat_main_t * vam)
4605{
4606 unformat_input_t *i = vam->input;
4607 vl_api_sw_interface_set_l2_bridge_t *mp;
Neale Rannsb4743802018-09-05 09:13:57 -07004608 vl_api_l2_port_type_t port_type;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004609 u32 rx_sw_if_index;
4610 u8 rx_sw_if_index_set = 0;
4611 u32 bd_id;
4612 u8 bd_id_set = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004613 u32 shg = 0;
4614 u8 enable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004615 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004616
Neale Rannsb4743802018-09-05 09:13:57 -07004617 port_type = L2_API_PORT_TYPE_NORMAL;
4618
Damjan Marion7cd468a2016-12-19 23:05:39 +01004619 /* Parse args required to build the message */
4620 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4621 {
4622 if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
4623 rx_sw_if_index_set = 1;
4624 else if (unformat (i, "bd_id %d", &bd_id))
4625 bd_id_set = 1;
4626 else
4627 if (unformat
4628 (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
4629 rx_sw_if_index_set = 1;
4630 else if (unformat (i, "shg %d", &shg))
4631 ;
4632 else if (unformat (i, "bvi"))
Neale Rannsb4743802018-09-05 09:13:57 -07004633 port_type = L2_API_PORT_TYPE_BVI;
4634 else if (unformat (i, "uu-fwd"))
4635 port_type = L2_API_PORT_TYPE_UU_FWD;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004636 else if (unformat (i, "enable"))
4637 enable = 1;
4638 else if (unformat (i, "disable"))
4639 enable = 0;
4640 else
4641 break;
4642 }
4643
4644 if (rx_sw_if_index_set == 0)
4645 {
4646 errmsg ("missing rx interface name or sw_if_index");
4647 return -99;
4648 }
4649
4650 if (enable && (bd_id_set == 0))
4651 {
4652 errmsg ("missing bridge domain");
4653 return -99;
4654 }
4655
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004656 M (SW_INTERFACE_SET_L2_BRIDGE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004657
4658 mp->rx_sw_if_index = ntohl (rx_sw_if_index);
4659 mp->bd_id = ntohl (bd_id);
4660 mp->shg = (u8) shg;
Neale Rannsb4743802018-09-05 09:13:57 -07004661 mp->port_type = ntohl (port_type);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004662 mp->enable = enable;
4663
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004664 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06004665 W (ret);
4666 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004667}
4668
4669static int
4670api_bridge_domain_dump (vat_main_t * vam)
4671{
4672 unformat_input_t *i = vam->input;
4673 vl_api_bridge_domain_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -06004674 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004675 u32 bd_id = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004676 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004677
4678 /* Parse args required to build the message */
4679 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4680 {
4681 if (unformat (i, "bd_id %d", &bd_id))
4682 ;
4683 else
4684 break;
4685 }
4686
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004687 M (BRIDGE_DOMAIN_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004688 mp->bd_id = ntohl (bd_id);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004689 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004690
4691 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -04004692 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06004693 S (mp_ping);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004694
Jon Loeliger56c7b012017-02-01 12:31:41 -06004695 W (ret);
4696 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004697}
4698
4699static int
4700api_bridge_domain_add_del (vat_main_t * vam)
4701{
4702 unformat_input_t *i = vam->input;
4703 vl_api_bridge_domain_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004704 u32 bd_id = ~0;
4705 u8 is_add = 1;
4706 u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
Jerome Tollet50570ec2017-09-14 12:53:56 +01004707 u8 *bd_tag = NULL;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004708 u32 mac_age = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004709 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004710
4711 /* Parse args required to build the message */
4712 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4713 {
4714 if (unformat (i, "bd_id %d", &bd_id))
4715 ;
4716 else if (unformat (i, "flood %d", &flood))
4717 ;
4718 else if (unformat (i, "uu-flood %d", &uu_flood))
4719 ;
4720 else if (unformat (i, "forward %d", &forward))
4721 ;
4722 else if (unformat (i, "learn %d", &learn))
4723 ;
4724 else if (unformat (i, "arp-term %d", &arp_term))
4725 ;
4726 else if (unformat (i, "mac-age %d", &mac_age))
4727 ;
Jerome Tollet50570ec2017-09-14 12:53:56 +01004728 else if (unformat (i, "bd-tag %s", &bd_tag))
4729 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004730 else if (unformat (i, "del"))
4731 {
4732 is_add = 0;
4733 flood = uu_flood = forward = learn = 0;
4734 }
4735 else
4736 break;
4737 }
4738
4739 if (bd_id == ~0)
4740 {
4741 errmsg ("missing bridge domain");
Jerome Tollet50570ec2017-09-14 12:53:56 +01004742 ret = -99;
4743 goto done;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004744 }
4745
4746 if (mac_age > 255)
4747 {
4748 errmsg ("mac age must be less than 256 ");
Jerome Tollet50570ec2017-09-14 12:53:56 +01004749 ret = -99;
4750 goto done;
4751 }
4752
John Lo70bfcaf2017-11-14 13:19:26 -05004753 if ((bd_tag) && (vec_len (bd_tag) > 63))
Jerome Tollet50570ec2017-09-14 12:53:56 +01004754 {
4755 errmsg ("bd-tag cannot be longer than 63");
4756 ret = -99;
4757 goto done;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004758 }
4759
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004760 M (BRIDGE_DOMAIN_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004761
4762 mp->bd_id = ntohl (bd_id);
4763 mp->flood = flood;
4764 mp->uu_flood = uu_flood;
4765 mp->forward = forward;
4766 mp->learn = learn;
4767 mp->arp_term = arp_term;
4768 mp->is_add = is_add;
4769 mp->mac_age = (u8) mac_age;
Jerome Tollet50570ec2017-09-14 12:53:56 +01004770 if (bd_tag)
John Lo70bfcaf2017-11-14 13:19:26 -05004771 {
4772 clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
4773 mp->bd_tag[vec_len (bd_tag)] = 0;
4774 }
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004775 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06004776 W (ret);
Jerome Tollet50570ec2017-09-14 12:53:56 +01004777
4778done:
4779 vec_free (bd_tag);
Jon Loeliger56c7b012017-02-01 12:31:41 -06004780 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004781}
4782
4783static int
Eyal Barif24991c2017-04-05 05:33:21 +03004784api_l2fib_flush_bd (vat_main_t * vam)
4785{
4786 unformat_input_t *i = vam->input;
4787 vl_api_l2fib_flush_bd_t *mp;
4788 u32 bd_id = ~0;
4789 int ret;
4790
4791 /* Parse args required to build the message */
4792 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4793 {
4794 if (unformat (i, "bd_id %d", &bd_id));
4795 else
4796 break;
4797 }
4798
4799 if (bd_id == ~0)
4800 {
4801 errmsg ("missing bridge domain");
4802 return -99;
4803 }
4804
4805 M (L2FIB_FLUSH_BD, mp);
4806
4807 mp->bd_id = htonl (bd_id);
4808
4809 S (mp);
4810 W (ret);
4811 return ret;
4812}
4813
4814static int
4815api_l2fib_flush_int (vat_main_t * vam)
4816{
4817 unformat_input_t *i = vam->input;
4818 vl_api_l2fib_flush_int_t *mp;
4819 u32 sw_if_index = ~0;
4820 int ret;
4821
4822 /* Parse args required to build the message */
4823 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4824 {
4825 if (unformat (i, "sw_if_index %d", &sw_if_index));
4826 else
4827 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
4828 else
4829 break;
4830 }
4831
4832 if (sw_if_index == ~0)
4833 {
4834 errmsg ("missing interface name or sw_if_index");
4835 return -99;
4836 }
4837
4838 M (L2FIB_FLUSH_INT, mp);
4839
4840 mp->sw_if_index = ntohl (sw_if_index);
4841
4842 S (mp);
4843 W (ret);
4844 return ret;
4845}
4846
4847static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01004848api_l2fib_add_del (vat_main_t * vam)
4849{
4850 unformat_input_t *i = vam->input;
4851 vl_api_l2fib_add_del_t *mp;
4852 f64 timeout;
Mohsin Kazmi57938f62017-10-27 21:28:07 +02004853 u8 mac[6] = { 0 };
Damjan Marion7cd468a2016-12-19 23:05:39 +01004854 u8 mac_set = 0;
4855 u32 bd_id;
4856 u8 bd_id_set = 0;
John Lo7dbd7262018-05-31 10:25:18 -04004857 u32 sw_if_index = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004858 u8 sw_if_index_set = 0;
4859 u8 is_add = 1;
4860 u8 static_mac = 0;
4861 u8 filter_mac = 0;
4862 u8 bvi_mac = 0;
4863 int count = 1;
4864 f64 before = 0;
4865 int j;
4866
4867 /* Parse args required to build the message */
4868 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4869 {
Mohsin Kazmi57938f62017-10-27 21:28:07 +02004870 if (unformat (i, "mac %U", unformat_ethernet_address, mac))
Damjan Marion7cd468a2016-12-19 23:05:39 +01004871 mac_set = 1;
4872 else if (unformat (i, "bd_id %d", &bd_id))
4873 bd_id_set = 1;
4874 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4875 sw_if_index_set = 1;
4876 else if (unformat (i, "sw_if"))
4877 {
4878 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4879 {
4880 if (unformat
4881 (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4882 sw_if_index_set = 1;
4883 }
4884 else
4885 break;
4886 }
4887 else if (unformat (i, "static"))
4888 static_mac = 1;
4889 else if (unformat (i, "filter"))
4890 {
4891 filter_mac = 1;
4892 static_mac = 1;
4893 }
4894 else if (unformat (i, "bvi"))
4895 {
4896 bvi_mac = 1;
4897 static_mac = 1;
4898 }
4899 else if (unformat (i, "del"))
4900 is_add = 0;
4901 else if (unformat (i, "count %d", &count))
4902 ;
4903 else
4904 break;
4905 }
4906
4907 if (mac_set == 0)
4908 {
4909 errmsg ("missing mac address");
4910 return -99;
4911 }
4912
4913 if (bd_id_set == 0)
4914 {
4915 errmsg ("missing bridge domain");
4916 return -99;
4917 }
4918
4919 if (is_add && sw_if_index_set == 0 && filter_mac == 0)
4920 {
4921 errmsg ("missing interface name or sw_if_index");
4922 return -99;
4923 }
4924
4925 if (count > 1)
4926 {
4927 /* Turn on async mode */
4928 vam->async_mode = 1;
4929 vam->async_errors = 0;
4930 before = vat_time_now (vam);
4931 }
4932
4933 for (j = 0; j < count; j++)
4934 {
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004935 M (L2FIB_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004936
Mohsin Kazmi57938f62017-10-27 21:28:07 +02004937 clib_memcpy (mp->mac, mac, 6);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004938 mp->bd_id = ntohl (bd_id);
4939 mp->is_add = is_add;
John Lo7dbd7262018-05-31 10:25:18 -04004940 mp->sw_if_index = ntohl (sw_if_index);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004941
4942 if (is_add)
4943 {
Damjan Marion7cd468a2016-12-19 23:05:39 +01004944 mp->static_mac = static_mac;
4945 mp->filter_mac = filter_mac;
4946 mp->bvi_mac = bvi_mac;
4947 }
Mohsin Kazmi57938f62017-10-27 21:28:07 +02004948 increment_mac_address (mac);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004949 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004950 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004951 }
4952
4953 if (count > 1)
4954 {
Jon Loeliger2d23eca2017-02-01 13:09:58 -06004955 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004956 f64 after;
4957
4958 /* Shut off async mode */
4959 vam->async_mode = 0;
4960
Dave Barach59b25652017-09-10 15:04:27 -04004961 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06004962 S (mp_ping);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004963
4964 timeout = vat_time_now (vam) + 1.0;
4965 while (vat_time_now (vam) < timeout)
4966 if (vam->result_ready == 1)
4967 goto out;
4968 vam->retval = -99;
4969
4970 out:
4971 if (vam->retval == -99)
4972 errmsg ("timeout");
4973
4974 if (vam->async_errors > 0)
4975 {
4976 errmsg ("%d asynchronous errors", vam->async_errors);
4977 vam->retval = -98;
4978 }
4979 vam->async_errors = 0;
4980 after = vat_time_now (vam);
4981
4982 print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
4983 count, after - before, count / (after - before));
4984 }
4985 else
4986 {
Jon Loeliger56c7b012017-02-01 12:31:41 -06004987 int ret;
4988
Damjan Marion7cd468a2016-12-19 23:05:39 +01004989 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06004990 W (ret);
4991 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004992 }
4993 /* Return the good/bad news */
4994 return (vam->retval);
4995}
4996
4997static int
Eyal Barifead6702017-04-04 04:46:32 +03004998api_bridge_domain_set_mac_age (vat_main_t * vam)
4999{
5000 unformat_input_t *i = vam->input;
5001 vl_api_bridge_domain_set_mac_age_t *mp;
5002 u32 bd_id = ~0;
5003 u32 mac_age = 0;
5004 int ret;
5005
5006 /* Parse args required to build the message */
5007 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5008 {
5009 if (unformat (i, "bd_id %d", &bd_id));
5010 else if (unformat (i, "mac-age %d", &mac_age));
5011 else
5012 break;
5013 }
5014
5015 if (bd_id == ~0)
5016 {
5017 errmsg ("missing bridge domain");
5018 return -99;
5019 }
5020
5021 if (mac_age > 255)
5022 {
5023 errmsg ("mac age must be less than 256 ");
5024 return -99;
5025 }
5026
5027 M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
5028
5029 mp->bd_id = htonl (bd_id);
5030 mp->mac_age = (u8) mac_age;
5031
5032 S (mp);
5033 W (ret);
5034 return ret;
5035}
5036
5037static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01005038api_l2_flags (vat_main_t * vam)
5039{
5040 unformat_input_t *i = vam->input;
5041 vl_api_l2_flags_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005042 u32 sw_if_index;
John Lo8d00fff2017-08-03 00:35:36 -04005043 u32 flags = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005044 u8 sw_if_index_set = 0;
John Lo8d00fff2017-08-03 00:35:36 -04005045 u8 is_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005046 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005047
5048 /* Parse args required to build the message */
5049 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5050 {
5051 if (unformat (i, "sw_if_index %d", &sw_if_index))
5052 sw_if_index_set = 1;
5053 else if (unformat (i, "sw_if"))
5054 {
5055 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5056 {
5057 if (unformat
5058 (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5059 sw_if_index_set = 1;
5060 }
5061 else
5062 break;
5063 }
5064 else if (unformat (i, "learn"))
John Lo8d00fff2017-08-03 00:35:36 -04005065 flags |= L2_LEARN;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005066 else if (unformat (i, "forward"))
John Lo8d00fff2017-08-03 00:35:36 -04005067 flags |= L2_FWD;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005068 else if (unformat (i, "flood"))
John Lo8d00fff2017-08-03 00:35:36 -04005069 flags |= L2_FLOOD;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005070 else if (unformat (i, "uu-flood"))
John Lo8d00fff2017-08-03 00:35:36 -04005071 flags |= L2_UU_FLOOD;
5072 else if (unformat (i, "arp-term"))
5073 flags |= L2_ARP_TERM;
5074 else if (unformat (i, "off"))
5075 is_set = 0;
5076 else if (unformat (i, "disable"))
5077 is_set = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005078 else
5079 break;
5080 }
5081
5082 if (sw_if_index_set == 0)
5083 {
5084 errmsg ("missing interface name or sw_if_index");
5085 return -99;
5086 }
5087
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005088 M (L2_FLAGS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005089
5090 mp->sw_if_index = ntohl (sw_if_index);
John Lo8d00fff2017-08-03 00:35:36 -04005091 mp->feature_bitmap = ntohl (flags);
5092 mp->is_set = is_set;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005093
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005094 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06005095 W (ret);
5096 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005097}
5098
5099static int
5100api_bridge_flags (vat_main_t * vam)
5101{
5102 unformat_input_t *i = vam->input;
5103 vl_api_bridge_flags_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005104 u32 bd_id;
5105 u8 bd_id_set = 0;
5106 u8 is_set = 1;
Neale Rannsb4743802018-09-05 09:13:57 -07005107 bd_flags_t flags = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005108 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005109
5110 /* Parse args required to build the message */
5111 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5112 {
5113 if (unformat (i, "bd_id %d", &bd_id))
5114 bd_id_set = 1;
5115 else if (unformat (i, "learn"))
Neale Rannsb4743802018-09-05 09:13:57 -07005116 flags |= BRIDGE_API_FLAG_LEARN;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005117 else if (unformat (i, "forward"))
Neale Rannsb4743802018-09-05 09:13:57 -07005118 flags |= BRIDGE_API_FLAG_FWD;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005119 else if (unformat (i, "flood"))
Neale Rannsb4743802018-09-05 09:13:57 -07005120 flags |= BRIDGE_API_FLAG_FLOOD;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005121 else if (unformat (i, "uu-flood"))
Neale Rannsb4743802018-09-05 09:13:57 -07005122 flags |= BRIDGE_API_FLAG_UU_FLOOD;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005123 else if (unformat (i, "arp-term"))
Neale Rannsb4743802018-09-05 09:13:57 -07005124 flags |= BRIDGE_API_FLAG_ARP_TERM;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005125 else if (unformat (i, "off"))
5126 is_set = 0;
5127 else if (unformat (i, "disable"))
5128 is_set = 0;
5129 else
5130 break;
5131 }
5132
5133 if (bd_id_set == 0)
5134 {
5135 errmsg ("missing bridge domain");
5136 return -99;
5137 }
5138
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005139 M (BRIDGE_FLAGS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005140
5141 mp->bd_id = ntohl (bd_id);
Neale Rannsb4743802018-09-05 09:13:57 -07005142 mp->flags = ntohl (flags);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005143 mp->is_set = is_set;
5144
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005145 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06005146 W (ret);
5147 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005148}
5149
5150static int
5151api_bd_ip_mac_add_del (vat_main_t * vam)
5152{
Neale Ranns4d5b9172018-10-24 02:57:49 -07005153 vl_api_address_t ip = VL_API_ZERO_ADDRESS;
Ole Troan8006c6a2018-12-17 12:02:26 +01005154 vl_api_mac_address_t mac = { 0 };
Damjan Marion7cd468a2016-12-19 23:05:39 +01005155 unformat_input_t *i = vam->input;
5156 vl_api_bd_ip_mac_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005157 u32 bd_id;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005158 u8 is_add = 1;
5159 u8 bd_id_set = 0;
5160 u8 ip_set = 0;
5161 u8 mac_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005162 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005163
5164
5165 /* Parse args required to build the message */
5166 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5167 {
5168 if (unformat (i, "bd_id %d", &bd_id))
5169 {
5170 bd_id_set++;
5171 }
Neale Ranns4d5b9172018-10-24 02:57:49 -07005172 else if (unformat (i, "%U", unformat_vl_api_address, &ip))
Damjan Marion7cd468a2016-12-19 23:05:39 +01005173 {
5174 ip_set++;
5175 }
Neale Ranns4d5b9172018-10-24 02:57:49 -07005176 else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
Damjan Marion7cd468a2016-12-19 23:05:39 +01005177 {
5178 mac_set++;
5179 }
5180 else if (unformat (i, "del"))
5181 is_add = 0;
5182 else
5183 break;
5184 }
5185
5186 if (bd_id_set == 0)
5187 {
5188 errmsg ("missing bridge domain");
5189 return -99;
5190 }
5191 else if (ip_set == 0)
5192 {
5193 errmsg ("missing IP address");
5194 return -99;
5195 }
5196 else if (mac_set == 0)
5197 {
5198 errmsg ("missing MAC address");
5199 return -99;
5200 }
5201
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005202 M (BD_IP_MAC_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005203
Neale Rannsbc764c82019-06-19 07:07:13 -07005204 mp->entry.bd_id = ntohl (bd_id);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005205 mp->is_add = is_add;
Neale Ranns4d5b9172018-10-24 02:57:49 -07005206
Neale Rannsbc764c82019-06-19 07:07:13 -07005207 clib_memcpy (&mp->entry.ip, &ip, sizeof (ip));
5208 clib_memcpy (&mp->entry.mac, &mac, sizeof (mac));
Neale Ranns4d5b9172018-10-24 02:57:49 -07005209
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005210 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06005211 W (ret);
5212 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005213}
5214
John Loe26c81f2019-01-07 15:16:33 -05005215static int
5216api_bd_ip_mac_flush (vat_main_t * vam)
5217{
5218 unformat_input_t *i = vam->input;
5219 vl_api_bd_ip_mac_flush_t *mp;
5220 u32 bd_id;
5221 u8 bd_id_set = 0;
5222 int ret;
5223
5224 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5225 {
5226 if (unformat (i, "bd_id %d", &bd_id))
5227 {
5228 bd_id_set++;
5229 }
5230 else
5231 break;
5232 }
5233
5234 if (bd_id_set == 0)
5235 {
5236 errmsg ("missing bridge domain");
5237 return -99;
5238 }
5239
5240 M (BD_IP_MAC_FLUSH, mp);
5241
5242 mp->bd_id = ntohl (bd_id);
5243
5244 S (mp);
5245 W (ret);
5246 return ret;
5247}
5248
Mohsin Kazmi5d82d2f2018-08-13 19:17:54 +02005249static void vl_api_bd_ip_mac_details_t_handler
5250 (vl_api_bd_ip_mac_details_t * mp)
5251{
5252 vat_main_t *vam = &vat_main;
Mohsin Kazmi5d82d2f2018-08-13 19:17:54 +02005253
5254 print (vam->ofp,
Neale Rannsbc764c82019-06-19 07:07:13 -07005255 "\n%-5d %U %U",
5256 ntohl (mp->entry.bd_id),
5257 format_vl_api_mac_address, mp->entry.mac,
5258 format_vl_api_address, &mp->entry.ip);
Mohsin Kazmi5d82d2f2018-08-13 19:17:54 +02005259}
5260
5261static void vl_api_bd_ip_mac_details_t_handler_json
5262 (vl_api_bd_ip_mac_details_t * mp)
5263{
5264 vat_main_t *vam = &vat_main;
5265 vat_json_node_t *node = NULL;
5266
5267 if (VAT_JSON_ARRAY != vam->json_tree.type)
5268 {
5269 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5270 vat_json_init_array (&vam->json_tree);
5271 }
5272 node = vat_json_array_add (&vam->json_tree);
5273
5274 vat_json_init_object (node);
Neale Rannsbc764c82019-06-19 07:07:13 -07005275 vat_json_object_add_uint (node, "bd_id", ntohl (mp->entry.bd_id));
Mohsin Kazmi5d82d2f2018-08-13 19:17:54 +02005276 vat_json_object_add_string_copy (node, "mac_address",
Neale Rannsbc764c82019-06-19 07:07:13 -07005277 format (0, "%U", format_vl_api_mac_address,
5278 &mp->entry.mac));
Mohsin Kazmi5d82d2f2018-08-13 19:17:54 +02005279 u8 *ip = 0;
5280
Neale Rannsbc764c82019-06-19 07:07:13 -07005281 ip = format (0, "%U", format_vl_api_address, &mp->entry.ip);
Mohsin Kazmi5d82d2f2018-08-13 19:17:54 +02005282 vat_json_object_add_string_copy (node, "ip_address", ip);
5283 vec_free (ip);
5284}
5285
5286static int
5287api_bd_ip_mac_dump (vat_main_t * vam)
5288{
5289 unformat_input_t *i = vam->input;
5290 vl_api_bd_ip_mac_dump_t *mp;
5291 vl_api_control_ping_t *mp_ping;
5292 int ret;
5293 u32 bd_id;
5294 u8 bd_id_set = 0;
5295
5296 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5297 {
5298 if (unformat (i, "bd_id %d", &bd_id))
5299 {
5300 bd_id_set++;
5301 }
5302 else
5303 break;
5304 }
5305
5306 print (vam->ofp,
5307 "\n%-5s %-7s %-20s %-30s",
5308 "bd_id", "is_ipv6", "mac_address", "ip_address");
5309
5310 /* Dump Bridge Domain Ip to Mac entries */
5311 M (BD_IP_MAC_DUMP, mp);
5312
5313 if (bd_id_set)
5314 mp->bd_id = htonl (bd_id);
5315 else
5316 mp->bd_id = ~0;
5317
5318 S (mp);
5319
5320 /* Use a control ping for synchronization */
5321 MPING (CONTROL_PING, mp_ping);
5322 S (mp_ping);
5323
5324 W (ret);
5325 return ret;
5326}
5327
Damjan Marion7cd468a2016-12-19 23:05:39 +01005328static int
Damjan Marion8389fb92017-10-13 18:29:53 +02005329api_tap_create_v2 (vat_main_t * vam)
5330{
5331 unformat_input_t *i = vam->input;
5332 vl_api_tap_create_v2_t *mp;
5333 u8 mac_address[6];
5334 u8 random_mac = 1;
Damjan Marion2df39092017-12-04 20:03:37 +01005335 u32 id = ~0;
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005336 u32 num_rx_queues = 0;
Damjan Marion2df39092017-12-04 20:03:37 +01005337 u8 *host_if_name = 0;
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005338 u8 host_if_name_set = 0;
Damjan Marion2df39092017-12-04 20:03:37 +01005339 u8 *host_ns = 0;
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005340 u8 host_ns_set = 0;
Damjan Marion2df39092017-12-04 20:03:37 +01005341 u8 host_mac_addr[6];
5342 u8 host_mac_addr_set = 0;
Damjan Marion91c6ef72017-12-01 13:34:24 +01005343 u8 *host_bridge = 0;
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005344 u8 host_bridge_set = 0;
5345 u8 host_ip4_prefix_set = 0;
5346 u8 host_ip6_prefix_set = 0;
Damjan Marion91c6ef72017-12-01 13:34:24 +01005347 ip4_address_t host_ip4_addr;
Damjan Marion7866c452018-01-18 13:35:11 +01005348 ip4_address_t host_ip4_gw;
5349 u8 host_ip4_gw_set = 0;
Damjan Marion91c6ef72017-12-01 13:34:24 +01005350 u32 host_ip4_prefix_len = 0;
5351 ip6_address_t host_ip6_addr;
Damjan Marion7866c452018-01-18 13:35:11 +01005352 ip6_address_t host_ip6_gw;
5353 u8 host_ip6_gw_set = 0;
Damjan Marion91c6ef72017-12-01 13:34:24 +01005354 u32 host_ip6_prefix_len = 0;
Mohsin Kazmi97d54ed2019-06-10 11:20:15 +02005355 u32 host_mtu_size = 0;
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005356 u8 host_mtu_set = 0;
Mohsin Kazmi97d54ed2019-06-10 11:20:15 +02005357 u32 tap_flags = 0;
Damjan Marion8389fb92017-10-13 18:29:53 +02005358 int ret;
Steven9e635692018-03-01 09:36:01 -08005359 u32 rx_ring_sz = 0, tx_ring_sz = 0;
Damjan Marion8389fb92017-10-13 18:29:53 +02005360
Dave Barachb7b92992018-10-17 10:38:51 -04005361 clib_memset (mac_address, 0, sizeof (mac_address));
Damjan Marion8389fb92017-10-13 18:29:53 +02005362
5363 /* Parse args required to build the message */
5364 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5365 {
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005366 if (unformat (i, "id %u", &id))
Damjan Marion91c6ef72017-12-01 13:34:24 +01005367 ;
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005368 else
5369 if (unformat
5370 (i, "hw-addr %U", unformat_ethernet_address, mac_address))
5371 random_mac = 0;
Damjan Marion2df39092017-12-04 20:03:37 +01005372 else if (unformat (i, "host-if-name %s", &host_if_name))
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005373 host_if_name_set = 1;
5374 else if (unformat (i, "num-rx-queues %u", &num_rx_queues))
Damjan Marion91c6ef72017-12-01 13:34:24 +01005375 ;
Damjan Marion2df39092017-12-04 20:03:37 +01005376 else if (unformat (i, "host-ns %s", &host_ns))
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005377 host_ns_set = 1;
Damjan Marion2df39092017-12-04 20:03:37 +01005378 else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
5379 host_mac_addr))
5380 host_mac_addr_set = 1;
Damjan Marion91c6ef72017-12-01 13:34:24 +01005381 else if (unformat (i, "host-bridge %s", &host_bridge))
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005382 host_bridge_set = 1;
5383 else if (unformat (i, "host-ip4-addr %U/%u", unformat_ip4_address,
Damjan Marion91c6ef72017-12-01 13:34:24 +01005384 &host_ip4_addr, &host_ip4_prefix_len))
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005385 host_ip4_prefix_set = 1;
5386 else if (unformat (i, "host-ip6-addr %U/%u", unformat_ip6_address,
Damjan Marion91c6ef72017-12-01 13:34:24 +01005387 &host_ip6_addr, &host_ip6_prefix_len))
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005388 host_ip6_prefix_set = 1;
Damjan Marion7866c452018-01-18 13:35:11 +01005389 else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
5390 &host_ip4_gw))
5391 host_ip4_gw_set = 1;
5392 else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
5393 &host_ip6_gw))
5394 host_ip6_gw_set = 1;
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005395 else if (unformat (i, "rx-ring-size %u", &rx_ring_sz))
Damjan Marion8389fb92017-10-13 18:29:53 +02005396 ;
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005397 else if (unformat (i, "tx-ring-size %u", &tx_ring_sz))
Damjan Marion8389fb92017-10-13 18:29:53 +02005398 ;
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005399 else if (unformat (i, "host-mtu-size %u", &host_mtu_size))
Mohsin Kazmi97d54ed2019-06-10 11:20:15 +02005400 host_mtu_set = 1;
5401 else if (unformat (i, "no-gso"))
Mohsin Kazmid88fc0f2020-04-30 19:05:56 +02005402 tap_flags &= ~TAP_API_FLAG_GSO;
Mohsin Kazmi97d54ed2019-06-10 11:20:15 +02005403 else if (unformat (i, "gso"))
Mohsin Kazmid88fc0f2020-04-30 19:05:56 +02005404 tap_flags |= TAP_API_FLAG_GSO;
Mohsin Kazmiba0061f2019-12-18 17:08:54 +01005405 else if (unformat (i, "csum-offload"))
Mohsin Kazmid88fc0f2020-04-30 19:05:56 +02005406 tap_flags |= TAP_API_FLAG_CSUM_OFFLOAD;
Mohsin Kazmib49bc1a2020-02-14 17:51:04 +00005407 else if (unformat (i, "persist"))
Mohsin Kazmid88fc0f2020-04-30 19:05:56 +02005408 tap_flags |= TAP_API_FLAG_PERSIST;
Mohsin Kazmib49bc1a2020-02-14 17:51:04 +00005409 else if (unformat (i, "attach"))
Mohsin Kazmid88fc0f2020-04-30 19:05:56 +02005410 tap_flags |= TAP_API_FLAG_ATTACH;
5411 else if (unformat (i, "tun"))
5412 tap_flags |= TAP_API_FLAG_TUN;
5413 else if (unformat (i, "gro-coalesce"))
5414 tap_flags |= TAP_API_FLAG_GRO_COALESCE;
Mohsin Kazmi50bd1652020-08-26 11:07:48 +02005415 else if (unformat (i, "packed"))
5416 tap_flags |= TAP_API_FLAG_PACKED;
5417 else if (unformat (i, "in-order"))
5418 tap_flags |= TAP_API_FLAG_IN_ORDER;
Damjan Marion8389fb92017-10-13 18:29:53 +02005419 else
5420 break;
5421 }
5422
Damjan Marion2df39092017-12-04 20:03:37 +01005423 if (vec_len (host_if_name) > 63)
Damjan Marion8389fb92017-10-13 18:29:53 +02005424 {
5425 errmsg ("tap name too long. ");
5426 return -99;
5427 }
Damjan Marion2df39092017-12-04 20:03:37 +01005428 if (vec_len (host_ns) > 63)
Damjan Marion8389fb92017-10-13 18:29:53 +02005429 {
5430 errmsg ("host name space too long. ");
5431 return -99;
5432 }
Damjan Marion91c6ef72017-12-01 13:34:24 +01005433 if (vec_len (host_bridge) > 63)
5434 {
5435 errmsg ("host bridge name too long. ");
5436 return -99;
5437 }
5438 if (host_ip4_prefix_len > 32)
5439 {
5440 errmsg ("host ip4 prefix length not valid. ");
5441 return -99;
5442 }
5443 if (host_ip6_prefix_len > 128)
5444 {
5445 errmsg ("host ip6 prefix length not valid. ");
5446 return -99;
5447 }
Damjan Marion8389fb92017-10-13 18:29:53 +02005448 if (!is_pow2 (rx_ring_sz))
5449 {
5450 errmsg ("rx ring size must be power of 2. ");
5451 return -99;
5452 }
5453 if (rx_ring_sz > 32768)
5454 {
5455 errmsg ("rx ring size must be 32768 or lower. ");
5456 return -99;
5457 }
5458 if (!is_pow2 (tx_ring_sz))
5459 {
5460 errmsg ("tx ring size must be power of 2. ");
5461 return -99;
5462 }
5463 if (tx_ring_sz > 32768)
5464 {
5465 errmsg ("tx ring size must be 32768 or lower. ");
5466 return -99;
5467 }
Mohsin Kazmi97d54ed2019-06-10 11:20:15 +02005468 if (host_mtu_set && (host_mtu_size < 64 || host_mtu_size > 65355))
5469 {
5470 errmsg ("host MTU size must be in between 64 and 65355. ");
5471 return -99;
5472 }
Damjan Marion8389fb92017-10-13 18:29:53 +02005473
Damjan Marion8389fb92017-10-13 18:29:53 +02005474 /* Construct the API message */
5475 M (TAP_CREATE_V2, mp);
5476
Steven9e635692018-03-01 09:36:01 -08005477 mp->id = ntohl (id);
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005478 mp->use_random_mac = random_mac;
5479 mp->num_rx_queues = (u8) num_rx_queues;
Steven9e635692018-03-01 09:36:01 -08005480 mp->tx_ring_sz = ntohs (tx_ring_sz);
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005481 mp->rx_ring_sz = ntohs (rx_ring_sz);
Mohsin Kazmi97d54ed2019-06-10 11:20:15 +02005482 mp->host_mtu_set = host_mtu_set;
5483 mp->host_mtu_size = ntohl (host_mtu_size);
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005484 mp->host_mac_addr_set = host_mac_addr_set;
5485 mp->host_ip4_prefix_set = host_ip4_prefix_set;
5486 mp->host_ip6_prefix_set = host_ip6_prefix_set;
5487 mp->host_ip4_gw_set = host_ip4_gw_set;
5488 mp->host_ip6_gw_set = host_ip6_gw_set;
Mohsin Kazmi97d54ed2019-06-10 11:20:15 +02005489 mp->tap_flags = ntohl (tap_flags);
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005490 mp->host_namespace_set = host_ns_set;
5491 mp->host_if_name_set = host_if_name_set;
5492 mp->host_bridge_set = host_bridge_set;
Damjan Marion2df39092017-12-04 20:03:37 +01005493
Steven9e635692018-03-01 09:36:01 -08005494 if (random_mac == 0)
Damjan Marion2df39092017-12-04 20:03:37 +01005495 clib_memcpy (mp->mac_address, mac_address, 6);
5496 if (host_mac_addr_set)
5497 clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005498 if (host_if_name_set)
Damjan Marion2df39092017-12-04 20:03:37 +01005499 clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005500 if (host_ns_set)
Damjan Marion2df39092017-12-04 20:03:37 +01005501 clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005502 if (host_bridge_set)
Damjan Marion91c6ef72017-12-01 13:34:24 +01005503 clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005504 if (host_ip4_prefix_set)
5505 {
5506 clib_memcpy (mp->host_ip4_prefix.address, &host_ip4_addr, 4);
5507 mp->host_ip4_prefix.len = (u8) host_ip4_prefix_len;
5508 }
5509 if (host_ip6_prefix_set)
5510 {
5511 clib_memcpy (mp->host_ip6_prefix.address, &host_ip6_addr, 16);
5512 mp->host_ip6_prefix.len = (u8) host_ip6_prefix_len;
5513 }
Damjan Marion7866c452018-01-18 13:35:11 +01005514 if (host_ip4_gw_set)
5515 clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
5516 if (host_ip6_gw_set)
5517 clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
Damjan Marion8389fb92017-10-13 18:29:53 +02005518
Damjan Marion2df39092017-12-04 20:03:37 +01005519 vec_free (host_ns);
5520 vec_free (host_if_name);
5521 vec_free (host_bridge);
Damjan Marion8389fb92017-10-13 18:29:53 +02005522
5523 /* send it... */
5524 S (mp);
5525
5526 /* Wait for a reply... */
5527 W (ret);
5528 return ret;
5529}
5530
5531static int
5532api_tap_delete_v2 (vat_main_t * vam)
5533{
5534 unformat_input_t *i = vam->input;
5535 vl_api_tap_delete_v2_t *mp;
5536 u32 sw_if_index = ~0;
5537 u8 sw_if_index_set = 0;
5538 int ret;
5539
5540 /* Parse args required to build the message */
5541 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5542 {
5543 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5544 sw_if_index_set = 1;
5545 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5546 sw_if_index_set = 1;
5547 else
5548 break;
5549 }
5550
5551 if (sw_if_index_set == 0)
5552 {
5553 errmsg ("missing vpp interface name. ");
5554 return -99;
5555 }
5556
5557 /* Construct the API message */
5558 M (TAP_DELETE_V2, mp);
5559
5560 mp->sw_if_index = ntohl (sw_if_index);
5561
5562 /* send it... */
5563 S (mp);
5564
5565 /* Wait for a reply... */
5566 W (ret);
5567 return ret;
5568}
5569
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005570uword
jialv01082ebeb2019-09-10 00:23:55 +08005571unformat_vlib_pci_addr (unformat_input_t * input, va_list * args)
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005572{
jialv01082ebeb2019-09-10 00:23:55 +08005573 vlib_pci_addr_t *addr = va_arg (*args, vlib_pci_addr_t *);
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005574 u32 x[4];
5575
5576 if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
5577 return 0;
5578
5579 addr->domain = x[0];
5580 addr->bus = x[1];
5581 addr->slot = x[2];
5582 addr->function = x[3];
5583
5584 return 1;
5585}
5586
5587static int
Mohsin Kazmi518251b2020-09-01 17:17:44 +00005588api_virtio_pci_create_v2 (vat_main_t * vam)
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005589{
5590 unformat_input_t *i = vam->input;
Mohsin Kazmi518251b2020-09-01 17:17:44 +00005591 vl_api_virtio_pci_create_v2_t *mp;
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005592 u8 mac_address[6];
5593 u8 random_mac = 1;
5594 u32 pci_addr = 0;
5595 u64 features = (u64) ~ (0ULL);
Mohsin Kazmi518251b2020-09-01 17:17:44 +00005596 u32 virtio_flags = 0;
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005597 int ret;
5598
5599 clib_memset (mac_address, 0, sizeof (mac_address));
5600
5601 /* Parse args required to build the message */
5602 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5603 {
5604 if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
5605 {
5606 random_mac = 0;
5607 }
jialv01082ebeb2019-09-10 00:23:55 +08005608 else if (unformat (i, "pci-addr %U", unformat_vlib_pci_addr, &pci_addr))
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005609 ;
5610 else if (unformat (i, "features 0x%llx", &features))
5611 ;
Mohsin Kazmibbd6b742019-05-02 13:54:59 +02005612 else if (unformat (i, "gso-enabled"))
Mohsin Kazmi518251b2020-09-01 17:17:44 +00005613 virtio_flags |= VIRTIO_API_FLAG_GSO;
Mohsin Kazmi6d4af892020-01-03 15:11:53 +00005614 else if (unformat (i, "csum-offload-enabled"))
Mohsin Kazmi518251b2020-09-01 17:17:44 +00005615 virtio_flags |= VIRTIO_API_FLAG_CSUM_OFFLOAD;
5616 else if (unformat (i, "gro-coalesce"))
5617 virtio_flags |= VIRTIO_API_FLAG_GRO_COALESCE;
5618 else if (unformat (i, "packed"))
5619 virtio_flags |= VIRTIO_API_FLAG_PACKED;
5620 else if (unformat (i, "in-order"))
5621 virtio_flags |= VIRTIO_API_FLAG_IN_ORDER;
Mohsin Kazmie347acb2020-09-28 10:26:33 +00005622 else if (unformat (i, "buffering"))
5623 virtio_flags |= VIRTIO_API_FLAG_BUFFERING;
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005624 else
5625 break;
5626 }
5627
5628 if (pci_addr == 0)
5629 {
5630 errmsg ("pci address must be non zero. ");
5631 return -99;
5632 }
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005633
5634 /* Construct the API message */
Mohsin Kazmi518251b2020-09-01 17:17:44 +00005635 M (VIRTIO_PCI_CREATE_V2, mp);
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005636
5637 mp->use_random_mac = random_mac;
5638
Jakub Grajciar2c504f82019-09-26 10:34:41 +02005639 mp->pci_addr.domain = htons (((vlib_pci_addr_t) pci_addr).domain);
5640 mp->pci_addr.bus = ((vlib_pci_addr_t) pci_addr).bus;
5641 mp->pci_addr.slot = ((vlib_pci_addr_t) pci_addr).slot;
5642 mp->pci_addr.function = ((vlib_pci_addr_t) pci_addr).function;
5643
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005644 mp->features = clib_host_to_net_u64 (features);
Mohsin Kazmi518251b2020-09-01 17:17:44 +00005645 mp->virtio_flags = clib_host_to_net_u32 (virtio_flags);
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005646
5647 if (random_mac == 0)
5648 clib_memcpy (mp->mac_address, mac_address, 6);
5649
5650 /* send it... */
5651 S (mp);
5652
5653 /* Wait for a reply... */
5654 W (ret);
5655 return ret;
5656}
5657
5658static int
5659api_virtio_pci_delete (vat_main_t * vam)
5660{
5661 unformat_input_t *i = vam->input;
5662 vl_api_virtio_pci_delete_t *mp;
5663 u32 sw_if_index = ~0;
5664 u8 sw_if_index_set = 0;
5665 int ret;
5666
5667 /* Parse args required to build the message */
5668 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5669 {
5670 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5671 sw_if_index_set = 1;
5672 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5673 sw_if_index_set = 1;
5674 else
5675 break;
5676 }
5677
5678 if (sw_if_index_set == 0)
5679 {
5680 errmsg ("missing vpp interface name. ");
5681 return -99;
5682 }
5683
5684 /* Construct the API message */
5685 M (VIRTIO_PCI_DELETE, mp);
5686
5687 mp->sw_if_index = htonl (sw_if_index);
5688
5689 /* send it... */
5690 S (mp);
5691
5692 /* Wait for a reply... */
5693 W (ret);
5694 return ret;
5695}
5696
Damjan Marion8389fb92017-10-13 18:29:53 +02005697static int
Steven9cd2d7a2017-12-20 12:43:01 -08005698api_bond_create (vat_main_t * vam)
5699{
5700 unformat_input_t *i = vam->input;
5701 vl_api_bond_create_t *mp;
5702 u8 mac_address[6];
5703 u8 custom_mac = 0;
5704 int ret;
5705 u8 mode;
5706 u8 lb;
5707 u8 mode_is_set = 0;
Alexander Chernavinad9d5282018-12-13 09:08:09 -05005708 u32 id = ~0;
Zhiyong Yang751e3f32019-06-26 05:49:14 -04005709 u8 numa_only = 0;
Steven9cd2d7a2017-12-20 12:43:01 -08005710
Dave Barachb7b92992018-10-17 10:38:51 -04005711 clib_memset (mac_address, 0, sizeof (mac_address));
Steven9cd2d7a2017-12-20 12:43:01 -08005712 lb = BOND_LB_L2;
5713
5714 /* Parse args required to build the message */
5715 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5716 {
5717 if (unformat (i, "mode %U", unformat_bond_mode, &mode))
5718 mode_is_set = 1;
5719 else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
5720 && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
5721 ;
5722 else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
5723 mac_address))
5724 custom_mac = 1;
Zhiyong Yang751e3f32019-06-26 05:49:14 -04005725 else if (unformat (i, "numa-only"))
5726 numa_only = 1;
Alexander Chernavinad9d5282018-12-13 09:08:09 -05005727 else if (unformat (i, "id %u", &id))
5728 ;
Steven9cd2d7a2017-12-20 12:43:01 -08005729 else
5730 break;
5731 }
5732
5733 if (mode_is_set == 0)
5734 {
5735 errmsg ("Missing bond mode. ");
5736 return -99;
5737 }
5738
5739 /* Construct the API message */
5740 M (BOND_CREATE, mp);
5741
5742 mp->use_custom_mac = custom_mac;
5743
Jakub Grajciar3d1ef872019-08-26 12:55:15 +02005744 mp->mode = htonl (mode);
5745 mp->lb = htonl (lb);
Alexander Chernavinad9d5282018-12-13 09:08:09 -05005746 mp->id = htonl (id);
Zhiyong Yang751e3f32019-06-26 05:49:14 -04005747 mp->numa_only = numa_only;
Steven9cd2d7a2017-12-20 12:43:01 -08005748
5749 if (custom_mac)
5750 clib_memcpy (mp->mac_address, mac_address, 6);
5751
5752 /* send it... */
5753 S (mp);
5754
5755 /* Wait for a reply... */
5756 W (ret);
5757 return ret;
5758}
5759
5760static int
Steven Luongea717862020-07-30 07:31:40 -07005761api_bond_create2 (vat_main_t * vam)
5762{
5763 unformat_input_t *i = vam->input;
5764 vl_api_bond_create2_t *mp;
5765 u8 mac_address[6];
5766 u8 custom_mac = 0;
5767 int ret;
5768 u8 mode;
5769 u8 lb;
5770 u8 mode_is_set = 0;
5771 u32 id = ~0;
5772 u8 numa_only = 0;
5773 u8 gso = 0;
5774
5775 clib_memset (mac_address, 0, sizeof (mac_address));
5776 lb = BOND_LB_L2;
5777
5778 /* Parse args required to build the message */
5779 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5780 {
5781 if (unformat (i, "mode %U", unformat_bond_mode, &mode))
5782 mode_is_set = 1;
5783 else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
5784 && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
5785 ;
5786 else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
5787 mac_address))
5788 custom_mac = 1;
5789 else if (unformat (i, "numa-only"))
5790 numa_only = 1;
5791 else if (unformat (i, "gso"))
5792 gso = 1;
5793 else if (unformat (i, "id %u", &id))
5794 ;
5795 else
5796 break;
5797 }
5798
5799 if (mode_is_set == 0)
5800 {
5801 errmsg ("Missing bond mode. ");
5802 return -99;
5803 }
5804
5805 /* Construct the API message */
5806 M (BOND_CREATE2, mp);
5807
5808 mp->use_custom_mac = custom_mac;
5809
5810 mp->mode = htonl (mode);
5811 mp->lb = htonl (lb);
5812 mp->id = htonl (id);
5813 mp->numa_only = numa_only;
5814 mp->enable_gso = gso;
5815
5816 if (custom_mac)
5817 clib_memcpy (mp->mac_address, mac_address, 6);
5818
5819 /* send it... */
5820 S (mp);
5821
5822 /* Wait for a reply... */
5823 W (ret);
5824 return ret;
5825}
5826
5827static int
Steven9cd2d7a2017-12-20 12:43:01 -08005828api_bond_delete (vat_main_t * vam)
5829{
5830 unformat_input_t *i = vam->input;
5831 vl_api_bond_delete_t *mp;
5832 u32 sw_if_index = ~0;
5833 u8 sw_if_index_set = 0;
5834 int ret;
5835
5836 /* Parse args required to build the message */
5837 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5838 {
5839 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5840 sw_if_index_set = 1;
5841 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5842 sw_if_index_set = 1;
5843 else
5844 break;
5845 }
5846
5847 if (sw_if_index_set == 0)
5848 {
5849 errmsg ("missing vpp interface name. ");
5850 return -99;
5851 }
5852
5853 /* Construct the API message */
5854 M (BOND_DELETE, mp);
5855
5856 mp->sw_if_index = ntohl (sw_if_index);
5857
5858 /* send it... */
5859 S (mp);
5860
5861 /* Wait for a reply... */
5862 W (ret);
5863 return ret;
5864}
5865
5866static int
Steven Luong4c4223e2020-07-15 08:44:54 -07005867api_bond_add_member (vat_main_t * vam)
Steven9cd2d7a2017-12-20 12:43:01 -08005868{
5869 unformat_input_t *i = vam->input;
Steven Luong4c4223e2020-07-15 08:44:54 -07005870 vl_api_bond_add_member_t *mp;
Steven9cd2d7a2017-12-20 12:43:01 -08005871 u32 bond_sw_if_index;
5872 int ret;
5873 u8 is_passive;
5874 u8 is_long_timeout;
5875 u32 bond_sw_if_index_is_set = 0;
5876 u32 sw_if_index;
5877 u8 sw_if_index_is_set = 0;
5878
5879 /* Parse args required to build the message */
5880 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5881 {
5882 if (unformat (i, "sw_if_index %d", &sw_if_index))
5883 sw_if_index_is_set = 1;
5884 else if (unformat (i, "bond %u", &bond_sw_if_index))
5885 bond_sw_if_index_is_set = 1;
5886 else if (unformat (i, "passive %d", &is_passive))
5887 ;
5888 else if (unformat (i, "long-timeout %d", &is_long_timeout))
5889 ;
5890 else
5891 break;
5892 }
5893
5894 if (bond_sw_if_index_is_set == 0)
5895 {
5896 errmsg ("Missing bond sw_if_index. ");
5897 return -99;
5898 }
5899 if (sw_if_index_is_set == 0)
5900 {
Steven Luong4c4223e2020-07-15 08:44:54 -07005901 errmsg ("Missing member sw_if_index. ");
Steven9cd2d7a2017-12-20 12:43:01 -08005902 return -99;
5903 }
5904
5905 /* Construct the API message */
Steven Luong4c4223e2020-07-15 08:44:54 -07005906 M (BOND_ADD_MEMBER, mp);
Steven9cd2d7a2017-12-20 12:43:01 -08005907
5908 mp->bond_sw_if_index = ntohl (bond_sw_if_index);
5909 mp->sw_if_index = ntohl (sw_if_index);
5910 mp->is_long_timeout = is_long_timeout;
5911 mp->is_passive = is_passive;
5912
5913 /* send it... */
5914 S (mp);
5915
5916 /* Wait for a reply... */
5917 W (ret);
5918 return ret;
5919}
5920
5921static int
Steven Luong4c4223e2020-07-15 08:44:54 -07005922api_bond_detach_member (vat_main_t * vam)
Steven9cd2d7a2017-12-20 12:43:01 -08005923{
5924 unformat_input_t *i = vam->input;
Steven Luong4c4223e2020-07-15 08:44:54 -07005925 vl_api_bond_detach_member_t *mp;
Steven9cd2d7a2017-12-20 12:43:01 -08005926 u32 sw_if_index = ~0;
5927 u8 sw_if_index_set = 0;
5928 int ret;
5929
5930 /* Parse args required to build the message */
5931 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5932 {
5933 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5934 sw_if_index_set = 1;
5935 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5936 sw_if_index_set = 1;
5937 else
5938 break;
5939 }
5940
5941 if (sw_if_index_set == 0)
5942 {
5943 errmsg ("missing vpp interface name. ");
5944 return -99;
5945 }
5946
5947 /* Construct the API message */
Steven Luong4c4223e2020-07-15 08:44:54 -07005948 M (BOND_DETACH_MEMBER, mp);
Steven9cd2d7a2017-12-20 12:43:01 -08005949
5950 mp->sw_if_index = ntohl (sw_if_index);
5951
5952 /* send it... */
5953 S (mp);
5954
5955 /* Wait for a reply... */
5956 W (ret);
5957 return ret;
5958}
5959
5960static int
Neale Ranns28ab9cc2017-08-14 07:18:42 -07005961api_ip_table_add_del (vat_main_t * vam)
5962{
5963 unformat_input_t *i = vam->input;
5964 vl_api_ip_table_add_del_t *mp;
5965 u32 table_id = ~0;
5966 u8 is_ipv6 = 0;
5967 u8 is_add = 1;
5968 int ret = 0;
5969
5970 /* Parse args required to build the message */
5971 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5972 {
5973 if (unformat (i, "ipv6"))
5974 is_ipv6 = 1;
5975 else if (unformat (i, "del"))
5976 is_add = 0;
5977 else if (unformat (i, "add"))
5978 is_add = 1;
5979 else if (unformat (i, "table %d", &table_id))
5980 ;
5981 else
5982 {
5983 clib_warning ("parse error '%U'", format_unformat_error, i);
5984 return -99;
5985 }
5986 }
5987
5988 if (~0 == table_id)
5989 {
5990 errmsg ("missing table-ID");
5991 return -99;
5992 }
5993
5994 /* Construct the API message */
5995 M (IP_TABLE_ADD_DEL, mp);
5996
Neale Ranns097fa662018-05-01 05:17:55 -07005997 mp->table.table_id = ntohl (table_id);
5998 mp->table.is_ip6 = is_ipv6;
Neale Ranns28ab9cc2017-08-14 07:18:42 -07005999 mp->is_add = is_add;
6000
6001 /* send it... */
6002 S (mp);
6003
6004 /* Wait for a reply... */
6005 W (ret);
6006
6007 return ret;
6008}
6009
Neale Ranns097fa662018-05-01 05:17:55 -07006010uword
6011unformat_fib_path (unformat_input_t * input, va_list * args)
6012{
6013 vat_main_t *vam = va_arg (*args, vat_main_t *);
6014 vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
6015 u32 weight, preference;
6016 mpls_label_t out_label;
6017
6018 clib_memset (path, 0, sizeof (*path));
6019 path->weight = 1;
6020 path->sw_if_index = ~0;
6021 path->rpf_id = ~0;
6022 path->n_labels = 0;
6023
6024 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
6025 {
6026 if (unformat (input, "%U %U",
6027 unformat_vl_api_ip4_address,
6028 &path->nh.address.ip4,
6029 api_unformat_sw_if_index, vam, &path->sw_if_index))
6030 {
6031 path->proto = FIB_API_PATH_NH_PROTO_IP4;
6032 }
6033 else if (unformat (input, "%U %U",
6034 unformat_vl_api_ip6_address,
6035 &path->nh.address.ip6,
6036 api_unformat_sw_if_index, vam, &path->sw_if_index))
6037 {
6038 path->proto = FIB_API_PATH_NH_PROTO_IP6;
6039 }
6040 else if (unformat (input, "weight %u", &weight))
6041 {
6042 path->weight = weight;
6043 }
6044 else if (unformat (input, "preference %u", &preference))
6045 {
6046 path->preference = preference;
6047 }
6048 else if (unformat (input, "%U next-hop-table %d",
6049 unformat_vl_api_ip4_address,
6050 &path->nh.address.ip4, &path->table_id))
6051 {
6052 path->proto = FIB_API_PATH_NH_PROTO_IP4;
6053 }
6054 else if (unformat (input, "%U next-hop-table %d",
6055 unformat_vl_api_ip6_address,
6056 &path->nh.address.ip6, &path->table_id))
6057 {
6058 path->proto = FIB_API_PATH_NH_PROTO_IP6;
6059 }
6060 else if (unformat (input, "%U",
6061 unformat_vl_api_ip4_address, &path->nh.address.ip4))
6062 {
6063 /*
6064 * the recursive next-hops are by default in the default table
6065 */
6066 path->table_id = 0;
6067 path->sw_if_index = ~0;
6068 path->proto = FIB_API_PATH_NH_PROTO_IP4;
6069 }
6070 else if (unformat (input, "%U",
6071 unformat_vl_api_ip6_address, &path->nh.address.ip6))
6072 {
6073 /*
6074 * the recursive next-hops are by default in the default table
6075 */
6076 path->table_id = 0;
6077 path->sw_if_index = ~0;
6078 path->proto = FIB_API_PATH_NH_PROTO_IP6;
6079 }
6080 else if (unformat (input, "resolve-via-host"))
6081 {
6082 path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
6083 }
6084 else if (unformat (input, "resolve-via-attached"))
6085 {
6086 path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
6087 }
6088 else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
6089 {
6090 path->type = FIB_API_PATH_TYPE_LOCAL;
6091 path->sw_if_index = ~0;
6092 path->proto = FIB_API_PATH_NH_PROTO_IP4;
6093 }
6094 else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
6095 {
6096 path->type = FIB_API_PATH_TYPE_LOCAL;
6097 path->sw_if_index = ~0;
6098 path->proto = FIB_API_PATH_NH_PROTO_IP6;
6099 }
6100 else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
6101 ;
6102 else if (unformat (input, "via-label %d", &path->nh.via_label))
6103 {
6104 path->proto = FIB_API_PATH_NH_PROTO_MPLS;
6105 path->sw_if_index = ~0;
6106 }
6107 else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
6108 {
6109 path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
6110 path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
6111 }
6112 else if (unformat (input, "local"))
6113 {
6114 path->type = FIB_API_PATH_TYPE_LOCAL;
6115 }
6116 else if (unformat (input, "out-labels"))
6117 {
6118 while (unformat (input, "%d", &out_label))
6119 {
6120 path->label_stack[path->n_labels].label = out_label;
6121 path->label_stack[path->n_labels].is_uniform = 0;
6122 path->label_stack[path->n_labels].ttl = 64;
6123 path->n_labels++;
6124 }
6125 }
6126 else if (unformat (input, "via"))
6127 {
6128 /* new path, back up and return */
6129 unformat_put_input (input);
6130 unformat_put_input (input);
6131 unformat_put_input (input);
6132 unformat_put_input (input);
6133 break;
6134 }
6135 else
6136 {
6137 return (0);
6138 }
6139 }
6140
6141 path->proto = ntohl (path->proto);
6142 path->type = ntohl (path->type);
6143 path->flags = ntohl (path->flags);
6144 path->table_id = ntohl (path->table_id);
6145 path->sw_if_index = ntohl (path->sw_if_index);
6146
6147 return (1);
6148}
6149
Neale Ranns28ab9cc2017-08-14 07:18:42 -07006150static int
Neale Ranns097fa662018-05-01 05:17:55 -07006151api_ip_route_add_del (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +01006152{
6153 unformat_input_t *i = vam->input;
Neale Ranns097fa662018-05-01 05:17:55 -07006154 vl_api_ip_route_add_del_t *mp;
6155 u32 vrf_id = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006156 u8 is_add = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006157 u8 is_multipath = 0;
Neale Ranns097fa662018-05-01 05:17:55 -07006158 u8 prefix_set = 0;
6159 u8 path_count = 0;
6160 vl_api_prefix_t pfx = { };
6161 vl_api_fib_path_t paths[8];
Damjan Marion7cd468a2016-12-19 23:05:39 +01006162 int count = 1;
6163 int j;
6164 f64 before = 0;
6165 u32 random_add_del = 0;
6166 u32 *random_vector = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006167 u32 random_seed = 0xdeaddabe;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006168
6169 /* Parse args required to build the message */
6170 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6171 {
Neale Ranns097fa662018-05-01 05:17:55 -07006172 if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
6173 prefix_set = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006174 else if (unformat (i, "del"))
6175 is_add = 0;
6176 else if (unformat (i, "add"))
6177 is_add = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006178 else if (unformat (i, "vrf %d", &vrf_id))
6179 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006180 else if (unformat (i, "count %d", &count))
6181 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006182 else if (unformat (i, "random"))
6183 random_add_del = 1;
Neale Ranns097fa662018-05-01 05:17:55 -07006184 else if (unformat (i, "multipath"))
6185 is_multipath = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006186 else if (unformat (i, "seed %d", &random_seed))
6187 ;
6188 else
Neale Ranns097fa662018-05-01 05:17:55 -07006189 if (unformat
6190 (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
6191 {
6192 path_count++;
6193 if (8 == path_count)
6194 {
6195 errmsg ("max 8 paths");
6196 return -99;
6197 }
6198 }
6199 else
Damjan Marion7cd468a2016-12-19 23:05:39 +01006200 {
6201 clib_warning ("parse error '%U'", format_unformat_error, i);
6202 return -99;
6203 }
6204 }
6205
Neale Ranns097fa662018-05-01 05:17:55 -07006206 if (!path_count)
Damjan Marion7cd468a2016-12-19 23:05:39 +01006207 {
Neale Ranns097fa662018-05-01 05:17:55 -07006208 errmsg ("specify a path; via ...");
Damjan Marion7cd468a2016-12-19 23:05:39 +01006209 return -99;
6210 }
Neale Ranns097fa662018-05-01 05:17:55 -07006211 if (prefix_set == 0)
Damjan Marion7cd468a2016-12-19 23:05:39 +01006212 {
Neale Ranns097fa662018-05-01 05:17:55 -07006213 errmsg ("missing prefix");
Damjan Marion7cd468a2016-12-19 23:05:39 +01006214 return -99;
6215 }
6216
6217 /* Generate a pile of unique, random routes */
6218 if (random_add_del)
6219 {
Neale Ranns097fa662018-05-01 05:17:55 -07006220 ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006221 u32 this_random_address;
Neale Ranns097fa662018-05-01 05:17:55 -07006222 uword *random_hash;
6223
Damjan Marion7cd468a2016-12-19 23:05:39 +01006224 random_hash = hash_create (count, sizeof (uword));
6225
Neale Ranns097fa662018-05-01 05:17:55 -07006226 hash_set (random_hash, i->as_u32, 1);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006227 for (j = 0; j <= count; j++)
6228 {
6229 do
6230 {
6231 this_random_address = random_u32 (&random_seed);
6232 this_random_address =
6233 clib_host_to_net_u32 (this_random_address);
6234 }
6235 while (hash_get (random_hash, this_random_address));
6236 vec_add1 (random_vector, this_random_address);
6237 hash_set (random_hash, this_random_address, 1);
6238 }
6239 hash_free (random_hash);
Neale Ranns097fa662018-05-01 05:17:55 -07006240 set_ip4_address (&pfx.address, random_vector[0]);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006241 }
6242
6243 if (count > 1)
6244 {
6245 /* Turn on async mode */
6246 vam->async_mode = 1;
6247 vam->async_errors = 0;
6248 before = vat_time_now (vam);
6249 }
6250
6251 for (j = 0; j < count; j++)
6252 {
6253 /* Construct the API message */
Neale Ranns097fa662018-05-01 05:17:55 -07006254 M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006255
6256 mp->is_add = is_add;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006257 mp->is_multipath = is_multipath;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006258
Neale Ranns097fa662018-05-01 05:17:55 -07006259 clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
6260 mp->route.table_id = ntohl (vrf_id);
6261 mp->route.n_paths = path_count;
6262
6263 clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
6264
6265 if (random_add_del)
6266 set_ip4_address (&pfx.address, random_vector[j + 1]);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006267 else
Neale Ranns097fa662018-05-01 05:17:55 -07006268 increment_address (&pfx.address);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006269 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006270 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006271 /* If we receive SIGTERM, stop now... */
6272 if (vam->do_exit)
6273 break;
6274 }
6275
6276 /* When testing multiple add/del ops, use a control-ping to sync */
6277 if (count > 1)
6278 {
Jon Loeliger2d23eca2017-02-01 13:09:58 -06006279 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006280 f64 after;
Jon Loeliger1f9191f2017-01-31 15:27:19 -06006281 f64 timeout;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006282
6283 /* Shut off async mode */
6284 vam->async_mode = 0;
6285
Dave Barach59b25652017-09-10 15:04:27 -04006286 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06006287 S (mp_ping);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006288
6289 timeout = vat_time_now (vam) + 1.0;
6290 while (vat_time_now (vam) < timeout)
6291 if (vam->result_ready == 1)
6292 goto out;
6293 vam->retval = -99;
6294
6295 out:
6296 if (vam->retval == -99)
6297 errmsg ("timeout");
6298
6299 if (vam->async_errors > 0)
6300 {
6301 errmsg ("%d asynchronous errors", vam->async_errors);
6302 vam->retval = -98;
6303 }
6304 vam->async_errors = 0;
6305 after = vat_time_now (vam);
6306
6307 /* slim chance, but we might have eaten SIGTERM on the first iteration */
6308 if (j > 0)
6309 count = j;
6310
6311 print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6312 count, after - before, count / (after - before));
6313 }
6314 else
6315 {
Jon Loeliger56c7b012017-02-01 12:31:41 -06006316 int ret;
6317
Damjan Marion7cd468a2016-12-19 23:05:39 +01006318 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06006319 W (ret);
6320 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006321 }
6322
6323 /* Return the good/bad news */
6324 return (vam->retval);
6325}
6326
6327static int
Neale Ranns32e1c012016-11-22 17:07:28 +00006328api_ip_mroute_add_del (vat_main_t * vam)
6329{
6330 unformat_input_t *i = vam->input;
Neale Ranns097fa662018-05-01 05:17:55 -07006331 u8 path_set = 0, prefix_set = 0, is_add = 1;
Neale Ranns32e1c012016-11-22 17:07:28 +00006332 vl_api_ip_mroute_add_del_t *mp;
Neale Ranns32e1c012016-11-22 17:07:28 +00006333 mfib_entry_flags_t eflags = 0;
Neale Ranns097fa662018-05-01 05:17:55 -07006334 vl_api_mfib_path_t path;
6335 vl_api_mprefix_t pfx = { };
6336 u32 vrf_id = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006337 int ret;
Neale Ranns32e1c012016-11-22 17:07:28 +00006338
6339 /* Parse args required to build the message */
6340 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6341 {
Neale Ranns097fa662018-05-01 05:17:55 -07006342 if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
Neale Ranns32e1c012016-11-22 17:07:28 +00006343 {
Neale Ranns097fa662018-05-01 05:17:55 -07006344 prefix_set = 1;
6345 pfx.grp_address_length = htons (pfx.grp_address_length);
Neale Ranns32e1c012016-11-22 17:07:28 +00006346 }
6347 else if (unformat (i, "del"))
6348 is_add = 0;
6349 else if (unformat (i, "add"))
6350 is_add = 1;
6351 else if (unformat (i, "vrf %d", &vrf_id))
6352 ;
Neale Ranns097fa662018-05-01 05:17:55 -07006353 else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
6354 path.itf_flags = htonl (path.itf_flags);
Neale Ranns32e1c012016-11-22 17:07:28 +00006355 else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
6356 ;
Neale Ranns097fa662018-05-01 05:17:55 -07006357 else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
6358 path_set = 1;
Neale Ranns32e1c012016-11-22 17:07:28 +00006359 else
6360 {
6361 clib_warning ("parse error '%U'", format_unformat_error, i);
6362 return -99;
6363 }
6364 }
6365
Neale Ranns097fa662018-05-01 05:17:55 -07006366 if (prefix_set == 0)
Neale Ranns32e1c012016-11-22 17:07:28 +00006367 {
6368 errmsg ("missing addresses\n");
6369 return -99;
6370 }
Neale Ranns097fa662018-05-01 05:17:55 -07006371 if (path_set == 0)
6372 {
6373 errmsg ("missing path\n");
6374 return -99;
6375 }
Neale Ranns32e1c012016-11-22 17:07:28 +00006376
6377 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006378 M (IP_MROUTE_ADD_DEL, mp);
Neale Ranns32e1c012016-11-22 17:07:28 +00006379
Neale Ranns32e1c012016-11-22 17:07:28 +00006380 mp->is_add = is_add;
Neale Ranns097fa662018-05-01 05:17:55 -07006381 mp->is_multipath = 1;
Neale Ranns32e1c012016-11-22 17:07:28 +00006382
Neale Ranns097fa662018-05-01 05:17:55 -07006383 clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
6384 mp->route.table_id = htonl (vrf_id);
6385 mp->route.n_paths = 1;
6386 mp->route.entry_flags = htonl (eflags);
Neale Ranns32e1c012016-11-22 17:07:28 +00006387
Neale Ranns097fa662018-05-01 05:17:55 -07006388 clib_memcpy (&mp->route.paths, &path, sizeof (path));
Neale Ranns32e1c012016-11-22 17:07:28 +00006389
6390 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006391 S (mp);
Neale Ranns32e1c012016-11-22 17:07:28 +00006392 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06006393 W (ret);
6394 return ret;
Neale Ranns32e1c012016-11-22 17:07:28 +00006395}
6396
6397static int
Neale Ranns28ab9cc2017-08-14 07:18:42 -07006398api_mpls_table_add_del (vat_main_t * vam)
6399{
6400 unformat_input_t *i = vam->input;
6401 vl_api_mpls_table_add_del_t *mp;
6402 u32 table_id = ~0;
6403 u8 is_add = 1;
6404 int ret = 0;
6405
6406 /* Parse args required to build the message */
6407 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6408 {
Florin Corasd0a59722017-10-15 17:41:21 +00006409 if (unformat (i, "table %d", &table_id))
6410 ;
6411 else if (unformat (i, "del"))
Neale Ranns28ab9cc2017-08-14 07:18:42 -07006412 is_add = 0;
6413 else if (unformat (i, "add"))
6414 is_add = 1;
6415 else
6416 {
6417 clib_warning ("parse error '%U'", format_unformat_error, i);
6418 return -99;
6419 }
6420 }
6421
6422 if (~0 == table_id)
6423 {
6424 errmsg ("missing table-ID");
6425 return -99;
6426 }
6427
6428 /* Construct the API message */
6429 M (MPLS_TABLE_ADD_DEL, mp);
6430
Neale Ranns097fa662018-05-01 05:17:55 -07006431 mp->mt_table.mt_table_id = ntohl (table_id);
Neale Ranns28ab9cc2017-08-14 07:18:42 -07006432 mp->mt_is_add = is_add;
6433
6434 /* send it... */
6435 S (mp);
6436
6437 /* Wait for a reply... */
6438 W (ret);
6439
6440 return ret;
6441}
6442
6443static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01006444api_mpls_route_add_del (vat_main_t * vam)
6445{
Neale Ranns097fa662018-05-01 05:17:55 -07006446 u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
6447 mpls_label_t local_label = MPLS_LABEL_INVALID;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006448 unformat_input_t *i = vam->input;
6449 vl_api_mpls_route_add_del_t *mp;
Neale Ranns097fa662018-05-01 05:17:55 -07006450 vl_api_fib_path_t paths[8];
6451 int count = 1, j;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006452 f64 before = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006453
6454 /* Parse args required to build the message */
6455 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6456 {
Neale Ranns097fa662018-05-01 05:17:55 -07006457 if (unformat (i, "%d", &local_label))
Damjan Marion7cd468a2016-12-19 23:05:39 +01006458 ;
6459 else if (unformat (i, "eos"))
6460 is_eos = 1;
6461 else if (unformat (i, "non-eos"))
6462 is_eos = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006463 else if (unformat (i, "del"))
6464 is_add = 0;
6465 else if (unformat (i, "add"))
6466 is_add = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006467 else if (unformat (i, "multipath"))
6468 is_multipath = 1;
6469 else if (unformat (i, "count %d", &count))
6470 ;
John Loe166fd92018-09-13 14:08:59 -04006471 else
6472 if (unformat
Neale Ranns097fa662018-05-01 05:17:55 -07006473 (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
John Loe166fd92018-09-13 14:08:59 -04006474 {
Neale Ranns097fa662018-05-01 05:17:55 -07006475 path_count++;
6476 if (8 == path_count)
6477 {
6478 errmsg ("max 8 paths");
6479 return -99;
6480 }
John Loe166fd92018-09-13 14:08:59 -04006481 }
Damjan Marion7cd468a2016-12-19 23:05:39 +01006482 else
6483 {
6484 clib_warning ("parse error '%U'", format_unformat_error, i);
6485 return -99;
6486 }
6487 }
6488
Neale Ranns097fa662018-05-01 05:17:55 -07006489 if (!path_count)
Damjan Marion7cd468a2016-12-19 23:05:39 +01006490 {
Neale Ranns097fa662018-05-01 05:17:55 -07006491 errmsg ("specify a path; via ...");
Damjan Marion7cd468a2016-12-19 23:05:39 +01006492 return -99;
6493 }
6494
6495 if (MPLS_LABEL_INVALID == local_label)
6496 {
6497 errmsg ("missing label");
6498 return -99;
6499 }
6500
6501 if (count > 1)
6502 {
6503 /* Turn on async mode */
6504 vam->async_mode = 1;
6505 vam->async_errors = 0;
6506 before = vat_time_now (vam);
6507 }
6508
6509 for (j = 0; j < count; j++)
6510 {
6511 /* Construct the API message */
Neale Ranns097fa662018-05-01 05:17:55 -07006512 M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006513
6514 mp->mr_is_add = is_add;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006515 mp->mr_is_multipath = is_multipath;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006516
Neale Ranns097fa662018-05-01 05:17:55 -07006517 mp->mr_route.mr_label = local_label;
6518 mp->mr_route.mr_eos = is_eos;
6519 mp->mr_route.mr_table_id = 0;
6520 mp->mr_route.mr_n_paths = path_count;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006521
Neale Ranns097fa662018-05-01 05:17:55 -07006522 clib_memcpy (&mp->mr_route.mr_paths, paths,
6523 sizeof (paths[0]) * path_count);
Neale Rannsda78f952017-05-24 09:15:43 -07006524
Damjan Marion7cd468a2016-12-19 23:05:39 +01006525 local_label++;
6526
6527 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006528 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006529 /* If we receive SIGTERM, stop now... */
6530 if (vam->do_exit)
6531 break;
6532 }
6533
6534 /* When testing multiple add/del ops, use a control-ping to sync */
6535 if (count > 1)
6536 {
Jon Loeliger2d23eca2017-02-01 13:09:58 -06006537 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006538 f64 after;
Jon Loeliger1f9191f2017-01-31 15:27:19 -06006539 f64 timeout;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006540
6541 /* Shut off async mode */
6542 vam->async_mode = 0;
6543
Dave Barach59b25652017-09-10 15:04:27 -04006544 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06006545 S (mp_ping);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006546
6547 timeout = vat_time_now (vam) + 1.0;
6548 while (vat_time_now (vam) < timeout)
6549 if (vam->result_ready == 1)
6550 goto out;
6551 vam->retval = -99;
6552
6553 out:
6554 if (vam->retval == -99)
6555 errmsg ("timeout");
6556
6557 if (vam->async_errors > 0)
6558 {
6559 errmsg ("%d asynchronous errors", vam->async_errors);
6560 vam->retval = -98;
6561 }
6562 vam->async_errors = 0;
6563 after = vat_time_now (vam);
6564
6565 /* slim chance, but we might have eaten SIGTERM on the first iteration */
6566 if (j > 0)
6567 count = j;
6568
6569 print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6570 count, after - before, count / (after - before));
6571 }
6572 else
6573 {
Jon Loeliger56c7b012017-02-01 12:31:41 -06006574 int ret;
6575
Damjan Marion7cd468a2016-12-19 23:05:39 +01006576 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06006577 W (ret);
6578 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006579 }
6580
6581 /* Return the good/bad news */
6582 return (vam->retval);
Neale Ranns097fa662018-05-01 05:17:55 -07006583 return (0);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006584}
6585
6586static int
6587api_mpls_ip_bind_unbind (vat_main_t * vam)
6588{
6589 unformat_input_t *i = vam->input;
6590 vl_api_mpls_ip_bind_unbind_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006591 u32 ip_table_id = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006592 u8 is_bind = 1;
Neale Ranns097fa662018-05-01 05:17:55 -07006593 vl_api_prefix_t pfx;
6594 u8 prefix_set = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006595 mpls_label_t local_label = MPLS_LABEL_INVALID;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006596 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006597
6598 /* Parse args required to build the message */
6599 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6600 {
Neale Ranns097fa662018-05-01 05:17:55 -07006601 if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
6602 prefix_set = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006603 else if (unformat (i, "%d", &local_label))
6604 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006605 else if (unformat (i, "table-id %d", &ip_table_id))
6606 ;
6607 else if (unformat (i, "unbind"))
6608 is_bind = 0;
6609 else if (unformat (i, "bind"))
6610 is_bind = 1;
6611 else
6612 {
6613 clib_warning ("parse error '%U'", format_unformat_error, i);
6614 return -99;
6615 }
6616 }
6617
Neale Ranns097fa662018-05-01 05:17:55 -07006618 if (!prefix_set)
Damjan Marion7cd468a2016-12-19 23:05:39 +01006619 {
Neale Ranns097fa662018-05-01 05:17:55 -07006620 errmsg ("IP prefix not set");
Damjan Marion7cd468a2016-12-19 23:05:39 +01006621 return -99;
6622 }
6623
6624 if (MPLS_LABEL_INVALID == local_label)
6625 {
6626 errmsg ("missing label");
6627 return -99;
6628 }
6629
6630 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006631 M (MPLS_IP_BIND_UNBIND, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006632
Damjan Marion7cd468a2016-12-19 23:05:39 +01006633 mp->mb_is_bind = is_bind;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006634 mp->mb_ip_table_id = ntohl (ip_table_id);
6635 mp->mb_mpls_table_id = 0;
6636 mp->mb_label = ntohl (local_label);
Neale Ranns097fa662018-05-01 05:17:55 -07006637 clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
Damjan Marion7cd468a2016-12-19 23:05:39 +01006638
6639 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006640 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006641
6642 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06006643 W (ret);
6644 return ret;
Neale Ranns097fa662018-05-01 05:17:55 -07006645 return (0);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006646}
6647
6648static int
John Loe166fd92018-09-13 14:08:59 -04006649api_sr_mpls_policy_add (vat_main_t * vam)
6650{
6651 unformat_input_t *i = vam->input;
6652 vl_api_sr_mpls_policy_add_t *mp;
6653 u32 bsid = 0;
6654 u32 weight = 1;
6655 u8 type = 0;
6656 u8 n_segments = 0;
6657 u32 sid;
6658 u32 *segments = NULL;
6659 int ret;
6660
6661 /* Parse args required to build the message */
6662 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6663 {
6664 if (unformat (i, "bsid %d", &bsid))
6665 ;
6666 else if (unformat (i, "weight %d", &weight))
6667 ;
6668 else if (unformat (i, "spray"))
6669 type = 1;
6670 else if (unformat (i, "next %d", &sid))
6671 {
6672 n_segments += 1;
6673 vec_add1 (segments, htonl (sid));
6674 }
6675 else
6676 {
6677 clib_warning ("parse error '%U'", format_unformat_error, i);
6678 return -99;
6679 }
6680 }
6681
6682 if (bsid == 0)
6683 {
6684 errmsg ("bsid not set");
6685 return -99;
6686 }
6687
6688 if (n_segments == 0)
6689 {
6690 errmsg ("no sid in segment stack");
6691 return -99;
6692 }
6693
6694 /* Construct the API message */
6695 M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
6696
6697 mp->bsid = htonl (bsid);
6698 mp->weight = htonl (weight);
Jakub Grajciar00ec4012020-01-31 10:17:29 +01006699 mp->is_spray = type;
John Loe166fd92018-09-13 14:08:59 -04006700 mp->n_segments = n_segments;
6701 memcpy (mp->segments, segments, sizeof (u32) * n_segments);
6702 vec_free (segments);
6703
6704 /* send it... */
6705 S (mp);
6706
6707 /* Wait for a reply... */
6708 W (ret);
6709 return ret;
6710}
6711
6712static int
6713api_sr_mpls_policy_del (vat_main_t * vam)
6714{
6715 unformat_input_t *i = vam->input;
6716 vl_api_sr_mpls_policy_del_t *mp;
6717 u32 bsid = 0;
6718 int ret;
6719
6720 /* Parse args required to build the message */
6721 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6722 {
6723 if (unformat (i, "bsid %d", &bsid))
6724 ;
6725 else
6726 {
6727 clib_warning ("parse error '%U'", format_unformat_error, i);
6728 return -99;
6729 }
6730 }
6731
6732 if (bsid == 0)
6733 {
6734 errmsg ("bsid not set");
6735 return -99;
6736 }
6737
6738 /* Construct the API message */
6739 M (SR_MPLS_POLICY_DEL, mp);
6740
6741 mp->bsid = htonl (bsid);
6742
6743 /* send it... */
6744 S (mp);
6745
6746 /* Wait for a reply... */
6747 W (ret);
6748 return ret;
6749}
6750
6751static int
Neale Rannsd792d9c2017-10-21 10:53:20 -07006752api_bier_table_add_del (vat_main_t * vam)
6753{
6754 unformat_input_t *i = vam->input;
6755 vl_api_bier_table_add_del_t *mp;
6756 u8 is_add = 1;
6757 u32 set = 0, sub_domain = 0, hdr_len = 3;
6758 mpls_label_t local_label = MPLS_LABEL_INVALID;
6759 int ret;
6760
6761 /* Parse args required to build the message */
6762 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6763 {
6764 if (unformat (i, "sub-domain %d", &sub_domain))
6765 ;
6766 else if (unformat (i, "set %d", &set))
6767 ;
6768 else if (unformat (i, "label %d", &local_label))
6769 ;
6770 else if (unformat (i, "hdr-len %d", &hdr_len))
6771 ;
6772 else if (unformat (i, "add"))
6773 is_add = 1;
6774 else if (unformat (i, "del"))
6775 is_add = 0;
6776 else
6777 {
6778 clib_warning ("parse error '%U'", format_unformat_error, i);
6779 return -99;
6780 }
6781 }
6782
6783 if (MPLS_LABEL_INVALID == local_label)
6784 {
6785 errmsg ("missing label\n");
6786 return -99;
6787 }
6788
6789 /* Construct the API message */
6790 M (BIER_TABLE_ADD_DEL, mp);
6791
6792 mp->bt_is_add = is_add;
6793 mp->bt_label = ntohl (local_label);
6794 mp->bt_tbl_id.bt_set = set;
6795 mp->bt_tbl_id.bt_sub_domain = sub_domain;
6796 mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
6797
6798 /* send it... */
6799 S (mp);
6800
6801 /* Wait for a reply... */
6802 W (ret);
6803
6804 return (ret);
6805}
6806
6807static int
6808api_bier_route_add_del (vat_main_t * vam)
6809{
6810 unformat_input_t *i = vam->input;
6811 vl_api_bier_route_add_del_t *mp;
6812 u8 is_add = 1;
6813 u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
6814 ip4_address_t v4_next_hop_address;
6815 ip6_address_t v6_next_hop_address;
6816 u8 next_hop_set = 0;
6817 u8 next_hop_proto_is_ip4 = 1;
6818 mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6819 int ret;
6820
6821 /* Parse args required to build the message */
6822 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6823 {
6824 if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
6825 {
6826 next_hop_proto_is_ip4 = 1;
6827 next_hop_set = 1;
6828 }
6829 else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
6830 {
6831 next_hop_proto_is_ip4 = 0;
6832 next_hop_set = 1;
6833 }
6834 if (unformat (i, "sub-domain %d", &sub_domain))
6835 ;
6836 else if (unformat (i, "set %d", &set))
6837 ;
6838 else if (unformat (i, "hdr-len %d", &hdr_len))
6839 ;
6840 else if (unformat (i, "bp %d", &bp))
6841 ;
6842 else if (unformat (i, "add"))
6843 is_add = 1;
6844 else if (unformat (i, "del"))
6845 is_add = 0;
6846 else if (unformat (i, "out-label %d", &next_hop_out_label))
6847 ;
6848 else
6849 {
6850 clib_warning ("parse error '%U'", format_unformat_error, i);
6851 return -99;
6852 }
6853 }
6854
6855 if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
6856 {
6857 errmsg ("next hop / label set\n");
6858 return -99;
6859 }
6860 if (0 == bp)
6861 {
6862 errmsg ("bit=position not set\n");
6863 return -99;
6864 }
6865
6866 /* Construct the API message */
Neale Ranns31ed7442018-02-23 05:29:09 -08006867 M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
Neale Rannsd792d9c2017-10-21 10:53:20 -07006868
6869 mp->br_is_add = is_add;
Neale Ranns097fa662018-05-01 05:17:55 -07006870 mp->br_route.br_tbl_id.bt_set = set;
6871 mp->br_route.br_tbl_id.bt_sub_domain = sub_domain;
6872 mp->br_route.br_tbl_id.bt_hdr_len_id = hdr_len;
6873 mp->br_route.br_bp = ntohs (bp);
6874 mp->br_route.br_n_paths = 1;
6875 mp->br_route.br_paths[0].n_labels = 1;
6876 mp->br_route.br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
6877 mp->br_route.br_paths[0].proto = (next_hop_proto_is_ip4 ?
6878 FIB_API_PATH_NH_PROTO_IP4 :
6879 FIB_API_PATH_NH_PROTO_IP6);
Neale Rannsd792d9c2017-10-21 10:53:20 -07006880
6881 if (next_hop_proto_is_ip4)
6882 {
Neale Ranns097fa662018-05-01 05:17:55 -07006883 clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip4,
Neale Rannsd792d9c2017-10-21 10:53:20 -07006884 &v4_next_hop_address, sizeof (v4_next_hop_address));
6885 }
6886 else
6887 {
Neale Ranns097fa662018-05-01 05:17:55 -07006888 clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip6,
Neale Rannsd792d9c2017-10-21 10:53:20 -07006889 &v6_next_hop_address, sizeof (v6_next_hop_address));
6890 }
6891
6892 /* send it... */
6893 S (mp);
6894
6895 /* Wait for a reply... */
6896 W (ret);
6897
6898 return (ret);
6899}
6900
6901static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01006902api_mpls_tunnel_add_del (vat_main_t * vam)
6903{
6904 unformat_input_t *i = vam->input;
6905 vl_api_mpls_tunnel_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006906
Neale Ranns097fa662018-05-01 05:17:55 -07006907 vl_api_fib_path_t paths[8];
Damjan Marion7cd468a2016-12-19 23:05:39 +01006908 u32 sw_if_index = ~0;
Neale Ranns097fa662018-05-01 05:17:55 -07006909 u8 path_count = 0;
6910 u8 l2_only = 0;
6911 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006912 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006913
6914 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6915 {
6916 if (unformat (i, "add"))
6917 is_add = 1;
John Lo06fda9c2018-10-03 16:32:44 -04006918 else
6919 if (unformat
6920 (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
6921 is_add = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006922 else if (unformat (i, "del sw_if_index %d", &sw_if_index))
6923 is_add = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006924 else if (unformat (i, "l2-only"))
6925 l2_only = 1;
Neale Ranns097fa662018-05-01 05:17:55 -07006926 else
6927 if (unformat
6928 (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
John Lo06fda9c2018-10-03 16:32:44 -04006929 {
Neale Ranns097fa662018-05-01 05:17:55 -07006930 path_count++;
6931 if (8 == path_count)
6932 {
6933 errmsg ("max 8 paths");
6934 return -99;
6935 }
John Lo06fda9c2018-10-03 16:32:44 -04006936 }
Damjan Marion7cd468a2016-12-19 23:05:39 +01006937 else
6938 {
6939 clib_warning ("parse error '%U'", format_unformat_error, i);
6940 return -99;
6941 }
6942 }
6943
Neale Ranns097fa662018-05-01 05:17:55 -07006944 M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006945
Damjan Marion7cd468a2016-12-19 23:05:39 +01006946 mp->mt_is_add = is_add;
Neale Ranns097fa662018-05-01 05:17:55 -07006947 mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
6948 mp->mt_tunnel.mt_l2_only = l2_only;
6949 mp->mt_tunnel.mt_is_multicast = 0;
6950 mp->mt_tunnel.mt_n_paths = path_count;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006951
Neale Ranns097fa662018-05-01 05:17:55 -07006952 clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
6953 sizeof (paths[0]) * path_count);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006954
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006955 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06006956 W (ret);
6957 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006958}
6959
6960static int
6961api_sw_interface_set_unnumbered (vat_main_t * vam)
6962{
6963 unformat_input_t *i = vam->input;
6964 vl_api_sw_interface_set_unnumbered_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006965 u32 sw_if_index;
6966 u32 unnum_sw_index = ~0;
6967 u8 is_add = 1;
6968 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006969 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006970
6971 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6972 {
6973 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6974 sw_if_index_set = 1;
6975 else if (unformat (i, "sw_if_index %d", &sw_if_index))
6976 sw_if_index_set = 1;
6977 else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
6978 ;
6979 else if (unformat (i, "del"))
6980 is_add = 0;
6981 else
6982 {
6983 clib_warning ("parse error '%U'", format_unformat_error, i);
6984 return -99;
6985 }
6986 }
6987
6988 if (sw_if_index_set == 0)
6989 {
6990 errmsg ("missing interface name or sw_if_index");
6991 return -99;
6992 }
6993
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006994 M (SW_INTERFACE_SET_UNNUMBERED, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006995
6996 mp->sw_if_index = ntohl (sw_if_index);
6997 mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
6998 mp->is_add = is_add;
6999
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007000 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007001 W (ret);
7002 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007003}
7004
Damjan Marion7cd468a2016-12-19 23:05:39 +01007005
7006static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01007007api_create_vlan_subif (vat_main_t * vam)
7008{
7009 unformat_input_t *i = vam->input;
7010 vl_api_create_vlan_subif_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007011 u32 sw_if_index;
7012 u8 sw_if_index_set = 0;
7013 u32 vlan_id;
7014 u8 vlan_id_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007015 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007016
7017 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7018 {
7019 if (unformat (i, "sw_if_index %d", &sw_if_index))
7020 sw_if_index_set = 1;
7021 else
7022 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7023 sw_if_index_set = 1;
7024 else if (unformat (i, "vlan %d", &vlan_id))
7025 vlan_id_set = 1;
7026 else
7027 {
7028 clib_warning ("parse error '%U'", format_unformat_error, i);
7029 return -99;
7030 }
7031 }
7032
7033 if (sw_if_index_set == 0)
7034 {
7035 errmsg ("missing interface name or sw_if_index");
7036 return -99;
7037 }
7038
7039 if (vlan_id_set == 0)
7040 {
7041 errmsg ("missing vlan_id");
7042 return -99;
7043 }
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007044 M (CREATE_VLAN_SUBIF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007045
7046 mp->sw_if_index = ntohl (sw_if_index);
7047 mp->vlan_id = ntohl (vlan_id);
7048
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007049 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007050 W (ret);
7051 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007052}
7053
7054#define foreach_create_subif_bit \
7055_(no_tags) \
7056_(one_tag) \
7057_(two_tags) \
7058_(dot1ad) \
7059_(exact_match) \
7060_(default_sub) \
7061_(outer_vlan_id_any) \
7062_(inner_vlan_id_any)
7063
Jakub Grajciar053204a2019-03-18 13:17:53 +01007064#define foreach_create_subif_flag \
7065_(0, "no_tags") \
7066_(1, "one_tag") \
7067_(2, "two_tags") \
7068_(3, "dot1ad") \
7069_(4, "exact_match") \
7070_(5, "default_sub") \
7071_(6, "outer_vlan_id_any") \
7072_(7, "inner_vlan_id_any")
7073
Damjan Marion7cd468a2016-12-19 23:05:39 +01007074static int
7075api_create_subif (vat_main_t * vam)
7076{
7077 unformat_input_t *i = vam->input;
7078 vl_api_create_subif_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007079 u32 sw_if_index;
7080 u8 sw_if_index_set = 0;
7081 u32 sub_id;
7082 u8 sub_id_set = 0;
Jakub Grajciar053204a2019-03-18 13:17:53 +01007083 u32 __attribute__ ((unused)) no_tags = 0;
7084 u32 __attribute__ ((unused)) one_tag = 0;
7085 u32 __attribute__ ((unused)) two_tags = 0;
7086 u32 __attribute__ ((unused)) dot1ad = 0;
7087 u32 __attribute__ ((unused)) exact_match = 0;
7088 u32 __attribute__ ((unused)) default_sub = 0;
7089 u32 __attribute__ ((unused)) outer_vlan_id_any = 0;
7090 u32 __attribute__ ((unused)) inner_vlan_id_any = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007091 u32 tmp;
7092 u16 outer_vlan_id = 0;
7093 u16 inner_vlan_id = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007094 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007095
7096 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7097 {
7098 if (unformat (i, "sw_if_index %d", &sw_if_index))
7099 sw_if_index_set = 1;
7100 else
7101 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7102 sw_if_index_set = 1;
7103 else if (unformat (i, "sub_id %d", &sub_id))
7104 sub_id_set = 1;
7105 else if (unformat (i, "outer_vlan_id %d", &tmp))
7106 outer_vlan_id = tmp;
7107 else if (unformat (i, "inner_vlan_id %d", &tmp))
7108 inner_vlan_id = tmp;
7109
7110#define _(a) else if (unformat (i, #a)) a = 1 ;
7111 foreach_create_subif_bit
7112#undef _
7113 else
7114 {
7115 clib_warning ("parse error '%U'", format_unformat_error, i);
7116 return -99;
7117 }
7118 }
7119
7120 if (sw_if_index_set == 0)
7121 {
7122 errmsg ("missing interface name or sw_if_index");
7123 return -99;
7124 }
7125
7126 if (sub_id_set == 0)
7127 {
7128 errmsg ("missing sub_id");
7129 return -99;
7130 }
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007131 M (CREATE_SUBIF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007132
7133 mp->sw_if_index = ntohl (sw_if_index);
7134 mp->sub_id = ntohl (sub_id);
7135
Jakub Grajciar053204a2019-03-18 13:17:53 +01007136#define _(a,b) mp->sub_if_flags |= (1 << a);
7137 foreach_create_subif_flag;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007138#undef _
7139
7140 mp->outer_vlan_id = ntohs (outer_vlan_id);
7141 mp->inner_vlan_id = ntohs (inner_vlan_id);
7142
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007143 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007144 W (ret);
7145 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007146}
7147
7148static int
Neale Ranns9db6ada2019-11-08 12:42:31 +00007149api_ip_table_replace_begin (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +01007150{
7151 unformat_input_t *i = vam->input;
Neale Ranns9db6ada2019-11-08 12:42:31 +00007152 vl_api_ip_table_replace_begin_t *mp;
7153 u32 table_id = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007154 u8 is_ipv6 = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007155
Jon Loeliger56c7b012017-02-01 12:31:41 -06007156 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007157 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7158 {
Neale Ranns9db6ada2019-11-08 12:42:31 +00007159 if (unformat (i, "table %d", &table_id))
7160 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007161 else if (unformat (i, "ipv6"))
7162 is_ipv6 = 1;
7163 else
7164 {
7165 clib_warning ("parse error '%U'", format_unformat_error, i);
7166 return -99;
7167 }
7168 }
7169
Neale Ranns9db6ada2019-11-08 12:42:31 +00007170 M (IP_TABLE_REPLACE_BEGIN, mp);
7171
7172 mp->table.table_id = ntohl (table_id);
7173 mp->table.is_ip6 = is_ipv6;
7174
7175 S (mp);
7176 W (ret);
7177 return ret;
7178}
7179
7180static int
7181api_ip_table_flush (vat_main_t * vam)
7182{
7183 unformat_input_t *i = vam->input;
7184 vl_api_ip_table_flush_t *mp;
7185 u32 table_id = 0;
7186 u8 is_ipv6 = 0;
7187
7188 int ret;
7189 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
Damjan Marion7cd468a2016-12-19 23:05:39 +01007190 {
Neale Ranns9db6ada2019-11-08 12:42:31 +00007191 if (unformat (i, "table %d", &table_id))
7192 ;
7193 else if (unformat (i, "ipv6"))
7194 is_ipv6 = 1;
7195 else
7196 {
7197 clib_warning ("parse error '%U'", format_unformat_error, i);
7198 return -99;
7199 }
Damjan Marion7cd468a2016-12-19 23:05:39 +01007200 }
7201
Neale Ranns9db6ada2019-11-08 12:42:31 +00007202 M (IP_TABLE_FLUSH, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007203
Neale Ranns9db6ada2019-11-08 12:42:31 +00007204 mp->table.table_id = ntohl (table_id);
7205 mp->table.is_ip6 = is_ipv6;
7206
7207 S (mp);
7208 W (ret);
7209 return ret;
7210}
7211
7212static int
7213api_ip_table_replace_end (vat_main_t * vam)
7214{
7215 unformat_input_t *i = vam->input;
7216 vl_api_ip_table_replace_end_t *mp;
7217 u32 table_id = 0;
7218 u8 is_ipv6 = 0;
7219
7220 int ret;
7221 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7222 {
7223 if (unformat (i, "table %d", &table_id))
7224 ;
7225 else if (unformat (i, "ipv6"))
7226 is_ipv6 = 1;
7227 else
7228 {
7229 clib_warning ("parse error '%U'", format_unformat_error, i);
7230 return -99;
7231 }
7232 }
7233
7234 M (IP_TABLE_REPLACE_END, mp);
7235
7236 mp->table.table_id = ntohl (table_id);
7237 mp->table.is_ip6 = is_ipv6;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007238
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007239 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007240 W (ret);
7241 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007242}
7243
7244static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01007245api_set_ip_flow_hash (vat_main_t * vam)
7246{
7247 unformat_input_t *i = vam->input;
7248 vl_api_set_ip_flow_hash_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007249 u32 vrf_id = 0;
7250 u8 is_ipv6 = 0;
7251 u8 vrf_id_set = 0;
7252 u8 src = 0;
7253 u8 dst = 0;
7254 u8 sport = 0;
7255 u8 dport = 0;
7256 u8 proto = 0;
7257 u8 reverse = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007258 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007259
7260 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7261 {
7262 if (unformat (i, "vrf %d", &vrf_id))
7263 vrf_id_set = 1;
7264 else if (unformat (i, "ipv6"))
7265 is_ipv6 = 1;
7266 else if (unformat (i, "src"))
7267 src = 1;
7268 else if (unformat (i, "dst"))
7269 dst = 1;
7270 else if (unformat (i, "sport"))
7271 sport = 1;
7272 else if (unformat (i, "dport"))
7273 dport = 1;
7274 else if (unformat (i, "proto"))
7275 proto = 1;
7276 else if (unformat (i, "reverse"))
7277 reverse = 1;
7278
7279 else
7280 {
7281 clib_warning ("parse error '%U'", format_unformat_error, i);
7282 return -99;
7283 }
7284 }
7285
7286 if (vrf_id_set == 0)
7287 {
7288 errmsg ("missing vrf id");
7289 return -99;
7290 }
7291
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007292 M (SET_IP_FLOW_HASH, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007293 mp->src = src;
7294 mp->dst = dst;
7295 mp->sport = sport;
7296 mp->dport = dport;
7297 mp->proto = proto;
7298 mp->reverse = reverse;
7299 mp->vrf_id = ntohl (vrf_id);
7300 mp->is_ipv6 = is_ipv6;
7301
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007302 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007303 W (ret);
7304 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007305}
7306
7307static int
7308api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7309{
7310 unformat_input_t *i = vam->input;
7311 vl_api_sw_interface_ip6_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007312 u32 sw_if_index;
7313 u8 sw_if_index_set = 0;
7314 u8 enable = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007315 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007316
7317 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7318 {
7319 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7320 sw_if_index_set = 1;
7321 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7322 sw_if_index_set = 1;
7323 else if (unformat (i, "enable"))
7324 enable = 1;
7325 else if (unformat (i, "disable"))
7326 enable = 0;
7327 else
7328 {
7329 clib_warning ("parse error '%U'", format_unformat_error, i);
7330 return -99;
7331 }
7332 }
7333
7334 if (sw_if_index_set == 0)
7335 {
7336 errmsg ("missing interface name or sw_if_index");
7337 return -99;
7338 }
7339
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007340 M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007341
7342 mp->sw_if_index = ntohl (sw_if_index);
7343 mp->enable = enable;
7344
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007345 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007346 W (ret);
7347 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007348}
7349
Damjan Marion7cd468a2016-12-19 23:05:39 +01007350
7351static int
7352api_l2_patch_add_del (vat_main_t * vam)
7353{
7354 unformat_input_t *i = vam->input;
7355 vl_api_l2_patch_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007356 u32 rx_sw_if_index;
7357 u8 rx_sw_if_index_set = 0;
7358 u32 tx_sw_if_index;
7359 u8 tx_sw_if_index_set = 0;
7360 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007361 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007362
7363 /* Parse args required to build the message */
7364 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7365 {
7366 if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7367 rx_sw_if_index_set = 1;
7368 else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7369 tx_sw_if_index_set = 1;
7370 else if (unformat (i, "rx"))
7371 {
7372 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7373 {
7374 if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7375 &rx_sw_if_index))
7376 rx_sw_if_index_set = 1;
7377 }
7378 else
7379 break;
7380 }
7381 else if (unformat (i, "tx"))
7382 {
7383 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7384 {
7385 if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7386 &tx_sw_if_index))
7387 tx_sw_if_index_set = 1;
7388 }
7389 else
7390 break;
7391 }
7392 else if (unformat (i, "del"))
7393 is_add = 0;
7394 else
7395 break;
7396 }
7397
7398 if (rx_sw_if_index_set == 0)
7399 {
7400 errmsg ("missing rx interface name or rx_sw_if_index");
7401 return -99;
7402 }
7403
7404 if (tx_sw_if_index_set == 0)
7405 {
7406 errmsg ("missing tx interface name or tx_sw_if_index");
7407 return -99;
7408 }
7409
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007410 M (L2_PATCH_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007411
7412 mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7413 mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7414 mp->is_add = is_add;
7415
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007416 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007417 W (ret);
7418 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007419}
7420
Pablo Camarillofb380952016-12-07 18:34:18 +01007421u8 is_del;
7422u8 localsid_addr[16];
7423u8 end_psp;
7424u8 behavior;
7425u32 sw_if_index;
7426u32 vlan_index;
7427u32 fib_table;
7428u8 nh_addr[16];
7429
7430static int
7431api_sr_localsid_add_del (vat_main_t * vam)
7432{
7433 unformat_input_t *i = vam->input;
7434 vl_api_sr_localsid_add_del_t *mp;
7435
7436 u8 is_del;
7437 ip6_address_t localsid;
7438 u8 end_psp = 0;
7439 u8 behavior = ~0;
7440 u32 sw_if_index;
7441 u32 fib_table = ~(u32) 0;
Jakub Grajciar0938eba2020-03-04 13:08:27 +01007442 ip46_address_t nh_addr;
7443 clib_memset (&nh_addr, 0, sizeof (ip46_address_t));
Pablo Camarillofb380952016-12-07 18:34:18 +01007444
7445 bool nexthop_set = 0;
7446
7447 int ret;
7448
7449 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7450 {
7451 if (unformat (i, "del"))
7452 is_del = 1;
7453 else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
Jakub Grajciar0938eba2020-03-04 13:08:27 +01007454 else if (unformat (i, "next-hop %U", unformat_ip46_address, &nh_addr))
Pablo Camarillofb380952016-12-07 18:34:18 +01007455 nexthop_set = 1;
7456 else if (unformat (i, "behavior %u", &behavior));
7457 else if (unformat (i, "sw_if_index %u", &sw_if_index));
7458 else if (unformat (i, "fib-table %u", &fib_table));
7459 else if (unformat (i, "end.psp %u", &behavior));
7460 else
7461 break;
7462 }
7463
7464 M (SR_LOCALSID_ADD_DEL, mp);
7465
Jakub Grajciar0938eba2020-03-04 13:08:27 +01007466 clib_memcpy (mp->localsid, &localsid, sizeof (mp->localsid));
Tetsuya Murakami1b81e6e2019-11-06 11:05:51 -08007467
Pablo Camarillofb380952016-12-07 18:34:18 +01007468 if (nexthop_set)
Pablo Camarillo3337bd22018-06-19 15:49:02 +02007469 {
Jakub Grajciar0938eba2020-03-04 13:08:27 +01007470 clib_memcpy (&mp->nh_addr.un, &nh_addr, sizeof (mp->nh_addr.un));
Pablo Camarillo3337bd22018-06-19 15:49:02 +02007471 }
Pablo Camarillofb380952016-12-07 18:34:18 +01007472 mp->behavior = behavior;
7473 mp->sw_if_index = ntohl (sw_if_index);
7474 mp->fib_table = ntohl (fib_table);
7475 mp->end_psp = end_psp;
7476 mp->is_del = is_del;
7477
7478 S (mp);
7479 W (ret);
7480 return ret;
7481}
7482
Damjan Marion7cd468a2016-12-19 23:05:39 +01007483static int
7484api_ioam_enable (vat_main_t * vam)
7485{
7486 unformat_input_t *input = vam->input;
7487 vl_api_ioam_enable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007488 u32 id = 0;
7489 int has_trace_option = 0;
7490 int has_pot_option = 0;
7491 int has_seqno_option = 0;
7492 int has_analyse_option = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007493 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007494
7495 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7496 {
7497 if (unformat (input, "trace"))
7498 has_trace_option = 1;
7499 else if (unformat (input, "pot"))
7500 has_pot_option = 1;
7501 else if (unformat (input, "seqno"))
7502 has_seqno_option = 1;
7503 else if (unformat (input, "analyse"))
7504 has_analyse_option = 1;
7505 else
7506 break;
7507 }
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007508 M (IOAM_ENABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007509 mp->id = htons (id);
7510 mp->seqno = has_seqno_option;
7511 mp->analyse = has_analyse_option;
7512 mp->pot_enable = has_pot_option;
7513 mp->trace_enable = has_trace_option;
7514
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007515 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007516 W (ret);
7517 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007518}
7519
7520
7521static int
7522api_ioam_disable (vat_main_t * vam)
7523{
7524 vl_api_ioam_disable_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007525 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007526
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007527 M (IOAM_DISABLE, mp);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007528 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007529 W (ret);
7530 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007531}
7532
Damjan Marion7cd468a2016-12-19 23:05:39 +01007533#define foreach_tcp_proto_field \
7534_(src_port) \
7535_(dst_port)
7536
7537#define foreach_udp_proto_field \
7538_(src_port) \
7539_(dst_port)
7540
7541#define foreach_ip4_proto_field \
7542_(src_address) \
7543_(dst_address) \
7544_(tos) \
7545_(length) \
7546_(fragment_id) \
7547_(ttl) \
7548_(protocol) \
7549_(checksum)
7550
Dave Barach4a3f69c2017-02-22 12:44:56 -05007551typedef struct
7552{
7553 u16 src_port, dst_port;
7554} tcpudp_header_t;
7555
7556#if VPP_API_TEST_BUILTIN == 0
Damjan Marion7cd468a2016-12-19 23:05:39 +01007557uword
7558unformat_tcp_mask (unformat_input_t * input, va_list * args)
7559{
7560 u8 **maskp = va_arg (*args, u8 **);
7561 u8 *mask = 0;
7562 u8 found_something = 0;
7563 tcp_header_t *tcp;
7564
7565#define _(a) u8 a=0;
7566 foreach_tcp_proto_field;
7567#undef _
7568
7569 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7570 {
7571 if (0);
7572#define _(a) else if (unformat (input, #a)) a=1;
7573 foreach_tcp_proto_field
7574#undef _
7575 else
7576 break;
7577 }
7578
7579#define _(a) found_something += a;
7580 foreach_tcp_proto_field;
7581#undef _
7582
7583 if (found_something == 0)
7584 return 0;
7585
7586 vec_validate (mask, sizeof (*tcp) - 1);
7587
7588 tcp = (tcp_header_t *) mask;
7589
Dave Barachb7b92992018-10-17 10:38:51 -04007590#define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
Damjan Marion7cd468a2016-12-19 23:05:39 +01007591 foreach_tcp_proto_field;
7592#undef _
7593
7594 *maskp = mask;
7595 return 1;
7596}
7597
7598uword
7599unformat_udp_mask (unformat_input_t * input, va_list * args)
7600{
7601 u8 **maskp = va_arg (*args, u8 **);
7602 u8 *mask = 0;
7603 u8 found_something = 0;
7604 udp_header_t *udp;
7605
7606#define _(a) u8 a=0;
7607 foreach_udp_proto_field;
7608#undef _
7609
7610 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7611 {
7612 if (0);
7613#define _(a) else if (unformat (input, #a)) a=1;
7614 foreach_udp_proto_field
7615#undef _
7616 else
7617 break;
7618 }
7619
7620#define _(a) found_something += a;
7621 foreach_udp_proto_field;
7622#undef _
7623
7624 if (found_something == 0)
7625 return 0;
7626
7627 vec_validate (mask, sizeof (*udp) - 1);
7628
7629 udp = (udp_header_t *) mask;
7630
Dave Barachb7b92992018-10-17 10:38:51 -04007631#define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
Damjan Marion7cd468a2016-12-19 23:05:39 +01007632 foreach_udp_proto_field;
7633#undef _
7634
7635 *maskp = mask;
7636 return 1;
7637}
7638
Damjan Marion7cd468a2016-12-19 23:05:39 +01007639uword
7640unformat_l4_mask (unformat_input_t * input, va_list * args)
7641{
7642 u8 **maskp = va_arg (*args, u8 **);
7643 u16 src_port = 0, dst_port = 0;
7644 tcpudp_header_t *tcpudp;
7645
7646 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7647 {
7648 if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
7649 return 1;
7650 else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
7651 return 1;
7652 else if (unformat (input, "src_port"))
7653 src_port = 0xFFFF;
7654 else if (unformat (input, "dst_port"))
7655 dst_port = 0xFFFF;
7656 else
7657 return 0;
7658 }
7659
7660 if (!src_port && !dst_port)
7661 return 0;
7662
7663 u8 *mask = 0;
7664 vec_validate (mask, sizeof (tcpudp_header_t) - 1);
7665
7666 tcpudp = (tcpudp_header_t *) mask;
7667 tcpudp->src_port = src_port;
7668 tcpudp->dst_port = dst_port;
7669
7670 *maskp = mask;
7671
7672 return 1;
7673}
7674
7675uword
7676unformat_ip4_mask (unformat_input_t * input, va_list * args)
7677{
7678 u8 **maskp = va_arg (*args, u8 **);
7679 u8 *mask = 0;
7680 u8 found_something = 0;
7681 ip4_header_t *ip;
7682
7683#define _(a) u8 a=0;
7684 foreach_ip4_proto_field;
7685#undef _
7686 u8 version = 0;
7687 u8 hdr_length = 0;
7688
7689
7690 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7691 {
7692 if (unformat (input, "version"))
7693 version = 1;
7694 else if (unformat (input, "hdr_length"))
7695 hdr_length = 1;
7696 else if (unformat (input, "src"))
7697 src_address = 1;
7698 else if (unformat (input, "dst"))
7699 dst_address = 1;
7700 else if (unformat (input, "proto"))
7701 protocol = 1;
7702
7703#define _(a) else if (unformat (input, #a)) a=1;
7704 foreach_ip4_proto_field
7705#undef _
7706 else
7707 break;
7708 }
7709
7710#define _(a) found_something += a;
7711 foreach_ip4_proto_field;
7712#undef _
7713
7714 if (found_something == 0)
7715 return 0;
7716
7717 vec_validate (mask, sizeof (*ip) - 1);
7718
7719 ip = (ip4_header_t *) mask;
7720
Dave Barachb7b92992018-10-17 10:38:51 -04007721#define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
Damjan Marion7cd468a2016-12-19 23:05:39 +01007722 foreach_ip4_proto_field;
7723#undef _
7724
7725 ip->ip_version_and_header_length = 0;
7726
7727 if (version)
7728 ip->ip_version_and_header_length |= 0xF0;
7729
7730 if (hdr_length)
7731 ip->ip_version_and_header_length |= 0x0F;
7732
7733 *maskp = mask;
7734 return 1;
7735}
7736
7737#define foreach_ip6_proto_field \
7738_(src_address) \
7739_(dst_address) \
7740_(payload_length) \
7741_(hop_limit) \
7742_(protocol)
7743
7744uword
7745unformat_ip6_mask (unformat_input_t * input, va_list * args)
7746{
7747 u8 **maskp = va_arg (*args, u8 **);
7748 u8 *mask = 0;
7749 u8 found_something = 0;
7750 ip6_header_t *ip;
7751 u32 ip_version_traffic_class_and_flow_label;
7752
7753#define _(a) u8 a=0;
7754 foreach_ip6_proto_field;
7755#undef _
7756 u8 version = 0;
7757 u8 traffic_class = 0;
7758 u8 flow_label = 0;
7759
7760 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7761 {
7762 if (unformat (input, "version"))
7763 version = 1;
7764 else if (unformat (input, "traffic-class"))
7765 traffic_class = 1;
7766 else if (unformat (input, "flow-label"))
7767 flow_label = 1;
7768 else if (unformat (input, "src"))
7769 src_address = 1;
7770 else if (unformat (input, "dst"))
7771 dst_address = 1;
7772 else if (unformat (input, "proto"))
7773 protocol = 1;
7774
7775#define _(a) else if (unformat (input, #a)) a=1;
7776 foreach_ip6_proto_field
7777#undef _
7778 else
7779 break;
7780 }
7781
7782#define _(a) found_something += a;
7783 foreach_ip6_proto_field;
7784#undef _
7785
7786 if (found_something == 0)
7787 return 0;
7788
7789 vec_validate (mask, sizeof (*ip) - 1);
7790
7791 ip = (ip6_header_t *) mask;
7792
Dave Barachb7b92992018-10-17 10:38:51 -04007793#define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
Damjan Marion7cd468a2016-12-19 23:05:39 +01007794 foreach_ip6_proto_field;
7795#undef _
7796
7797 ip_version_traffic_class_and_flow_label = 0;
7798
7799 if (version)
7800 ip_version_traffic_class_and_flow_label |= 0xF0000000;
7801
7802 if (traffic_class)
7803 ip_version_traffic_class_and_flow_label |= 0x0FF00000;
7804
7805 if (flow_label)
7806 ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
7807
7808 ip->ip_version_traffic_class_and_flow_label =
7809 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
7810
7811 *maskp = mask;
7812 return 1;
7813}
7814
7815uword
7816unformat_l3_mask (unformat_input_t * input, va_list * args)
7817{
7818 u8 **maskp = va_arg (*args, u8 **);
7819
7820 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7821 {
7822 if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
7823 return 1;
7824 else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
7825 return 1;
7826 else
7827 break;
7828 }
7829 return 0;
7830}
7831
7832uword
7833unformat_l2_mask (unformat_input_t * input, va_list * args)
7834{
7835 u8 **maskp = va_arg (*args, u8 **);
7836 u8 *mask = 0;
7837 u8 src = 0;
7838 u8 dst = 0;
7839 u8 proto = 0;
7840 u8 tag1 = 0;
7841 u8 tag2 = 0;
7842 u8 ignore_tag1 = 0;
7843 u8 ignore_tag2 = 0;
7844 u8 cos1 = 0;
7845 u8 cos2 = 0;
7846 u8 dot1q = 0;
7847 u8 dot1ad = 0;
7848 int len = 14;
7849
7850 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7851 {
7852 if (unformat (input, "src"))
7853 src = 1;
7854 else if (unformat (input, "dst"))
7855 dst = 1;
7856 else if (unformat (input, "proto"))
7857 proto = 1;
7858 else if (unformat (input, "tag1"))
7859 tag1 = 1;
7860 else if (unformat (input, "tag2"))
7861 tag2 = 1;
7862 else if (unformat (input, "ignore-tag1"))
7863 ignore_tag1 = 1;
7864 else if (unformat (input, "ignore-tag2"))
7865 ignore_tag2 = 1;
7866 else if (unformat (input, "cos1"))
7867 cos1 = 1;
7868 else if (unformat (input, "cos2"))
7869 cos2 = 1;
7870 else if (unformat (input, "dot1q"))
7871 dot1q = 1;
7872 else if (unformat (input, "dot1ad"))
7873 dot1ad = 1;
7874 else
7875 break;
7876 }
7877 if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
7878 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
7879 return 0;
7880
7881 if (tag1 || ignore_tag1 || cos1 || dot1q)
7882 len = 18;
7883 if (tag2 || ignore_tag2 || cos2 || dot1ad)
7884 len = 22;
7885
7886 vec_validate (mask, len - 1);
7887
7888 if (dst)
Dave Barachb7b92992018-10-17 10:38:51 -04007889 clib_memset (mask, 0xff, 6);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007890
7891 if (src)
Dave Barachb7b92992018-10-17 10:38:51 -04007892 clib_memset (mask + 6, 0xff, 6);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007893
7894 if (tag2 || dot1ad)
7895 {
7896 /* inner vlan tag */
7897 if (tag2)
7898 {
7899 mask[19] = 0xff;
7900 mask[18] = 0x0f;
7901 }
7902 if (cos2)
7903 mask[18] |= 0xe0;
7904 if (proto)
7905 mask[21] = mask[20] = 0xff;
7906 if (tag1)
7907 {
7908 mask[15] = 0xff;
7909 mask[14] = 0x0f;
7910 }
7911 if (cos1)
7912 mask[14] |= 0xe0;
7913 *maskp = mask;
7914 return 1;
7915 }
7916 if (tag1 | dot1q)
7917 {
7918 if (tag1)
7919 {
7920 mask[15] = 0xff;
7921 mask[14] = 0x0f;
7922 }
7923 if (cos1)
7924 mask[14] |= 0xe0;
7925 if (proto)
7926 mask[16] = mask[17] = 0xff;
7927
7928 *maskp = mask;
7929 return 1;
7930 }
7931 if (cos2)
7932 mask[18] |= 0xe0;
7933 if (cos1)
7934 mask[14] |= 0xe0;
7935 if (proto)
7936 mask[12] = mask[13] = 0xff;
7937
7938 *maskp = mask;
7939 return 1;
7940}
7941
7942uword
7943unformat_classify_mask (unformat_input_t * input, va_list * args)
7944{
7945 u8 **maskp = va_arg (*args, u8 **);
7946 u32 *skipp = va_arg (*args, u32 *);
7947 u32 *matchp = va_arg (*args, u32 *);
7948 u32 match;
7949 u8 *mask = 0;
7950 u8 *l2 = 0;
7951 u8 *l3 = 0;
7952 u8 *l4 = 0;
7953 int i;
7954
7955 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7956 {
7957 if (unformat (input, "hex %U", unformat_hex_string, &mask))
7958 ;
7959 else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
7960 ;
7961 else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
7962 ;
7963 else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
7964 ;
7965 else
7966 break;
7967 }
7968
7969 if (l4 && !l3)
7970 {
7971 vec_free (mask);
7972 vec_free (l2);
7973 vec_free (l4);
7974 return 0;
7975 }
7976
7977 if (mask || l2 || l3 || l4)
7978 {
7979 if (l2 || l3 || l4)
7980 {
7981 /* "With a free Ethernet header in every package" */
7982 if (l2 == 0)
7983 vec_validate (l2, 13);
7984 mask = l2;
7985 if (vec_len (l3))
7986 {
7987 vec_append (mask, l3);
7988 vec_free (l3);
7989 }
7990 if (vec_len (l4))
7991 {
7992 vec_append (mask, l4);
7993 vec_free (l4);
7994 }
7995 }
7996
7997 /* Scan forward looking for the first significant mask octet */
7998 for (i = 0; i < vec_len (mask); i++)
7999 if (mask[i])
8000 break;
8001
8002 /* compute (skip, match) params */
8003 *skipp = i / sizeof (u32x4);
8004 vec_delete (mask, *skipp * sizeof (u32x4), 0);
8005
8006 /* Pad mask to an even multiple of the vector size */
8007 while (vec_len (mask) % sizeof (u32x4))
8008 vec_add1 (mask, 0);
8009
8010 match = vec_len (mask) / sizeof (u32x4);
8011
8012 for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
8013 {
8014 u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
8015 if (*tmp || *(tmp + 1))
8016 break;
8017 match--;
8018 }
8019 if (match == 0)
8020 clib_warning ("BUG: match 0");
8021
8022 _vec_len (mask) = match * sizeof (u32x4);
8023
8024 *matchp = match;
8025 *maskp = mask;
8026
8027 return 1;
8028 }
8029
8030 return 0;
8031}
Dave Barach4a3f69c2017-02-22 12:44:56 -05008032#endif /* VPP_API_TEST_BUILTIN */
Damjan Marion7cd468a2016-12-19 23:05:39 +01008033
8034#define foreach_l2_next \
8035_(drop, DROP) \
8036_(ethernet, ETHERNET_INPUT) \
8037_(ip4, IP4_INPUT) \
8038_(ip6, IP6_INPUT)
8039
8040uword
8041unformat_l2_next_index (unformat_input_t * input, va_list * args)
8042{
8043 u32 *miss_next_indexp = va_arg (*args, u32 *);
8044 u32 next_index = 0;
8045 u32 tmp;
8046
8047#define _(n,N) \
8048 if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
8049 foreach_l2_next;
8050#undef _
8051
8052 if (unformat (input, "%d", &tmp))
8053 {
8054 next_index = tmp;
8055 goto out;
8056 }
8057
8058 return 0;
8059
8060out:
8061 *miss_next_indexp = next_index;
8062 return 1;
8063}
8064
8065#define foreach_ip_next \
8066_(drop, DROP) \
8067_(local, LOCAL) \
8068_(rewrite, REWRITE)
8069
8070uword
Dave Barach4a3f69c2017-02-22 12:44:56 -05008071api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
Damjan Marion7cd468a2016-12-19 23:05:39 +01008072{
8073 u32 *miss_next_indexp = va_arg (*args, u32 *);
8074 u32 next_index = 0;
8075 u32 tmp;
8076
8077#define _(n,N) \
8078 if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
8079 foreach_ip_next;
8080#undef _
8081
8082 if (unformat (input, "%d", &tmp))
8083 {
8084 next_index = tmp;
8085 goto out;
8086 }
8087
8088 return 0;
8089
8090out:
8091 *miss_next_indexp = next_index;
8092 return 1;
8093}
8094
8095#define foreach_acl_next \
8096_(deny, DENY)
8097
8098uword
Dave Barach4a3f69c2017-02-22 12:44:56 -05008099api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
Damjan Marion7cd468a2016-12-19 23:05:39 +01008100{
8101 u32 *miss_next_indexp = va_arg (*args, u32 *);
8102 u32 next_index = 0;
8103 u32 tmp;
8104
8105#define _(n,N) \
8106 if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
8107 foreach_acl_next;
8108#undef _
8109
8110 if (unformat (input, "permit"))
8111 {
8112 next_index = ~0;
8113 goto out;
8114 }
8115 else if (unformat (input, "%d", &tmp))
8116 {
8117 next_index = tmp;
8118 goto out;
8119 }
8120
8121 return 0;
8122
8123out:
8124 *miss_next_indexp = next_index;
8125 return 1;
8126}
8127
8128uword
8129unformat_policer_precolor (unformat_input_t * input, va_list * args)
8130{
8131 u32 *r = va_arg (*args, u32 *);
8132
8133 if (unformat (input, "conform-color"))
8134 *r = POLICE_CONFORM;
8135 else if (unformat (input, "exceed-color"))
8136 *r = POLICE_EXCEED;
8137 else
8138 return 0;
8139
8140 return 1;
8141}
8142
8143static int
8144api_classify_add_del_table (vat_main_t * vam)
8145{
8146 unformat_input_t *i = vam->input;
8147 vl_api_classify_add_del_table_t *mp;
8148
8149 u32 nbuckets = 2;
8150 u32 skip = ~0;
8151 u32 match = ~0;
8152 int is_add = 1;
8153 int del_chain = 0;
8154 u32 table_index = ~0;
8155 u32 next_table_index = ~0;
8156 u32 miss_next_index = ~0;
8157 u32 memory_size = 32 << 20;
8158 u8 *mask = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008159 u32 current_data_flag = 0;
8160 int current_data_offset = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008161 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008162
8163 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8164 {
8165 if (unformat (i, "del"))
8166 is_add = 0;
8167 else if (unformat (i, "del-chain"))
8168 {
8169 is_add = 0;
8170 del_chain = 1;
8171 }
8172 else if (unformat (i, "buckets %d", &nbuckets))
8173 ;
8174 else if (unformat (i, "memory_size %d", &memory_size))
8175 ;
8176 else if (unformat (i, "skip %d", &skip))
8177 ;
8178 else if (unformat (i, "match %d", &match))
8179 ;
8180 else if (unformat (i, "table %d", &table_index))
8181 ;
8182 else if (unformat (i, "mask %U", unformat_classify_mask,
8183 &mask, &skip, &match))
8184 ;
8185 else if (unformat (i, "next-table %d", &next_table_index))
8186 ;
Dave Barach4a3f69c2017-02-22 12:44:56 -05008187 else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
Damjan Marion7cd468a2016-12-19 23:05:39 +01008188 &miss_next_index))
8189 ;
8190 else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
8191 &miss_next_index))
8192 ;
Dave Barach4a3f69c2017-02-22 12:44:56 -05008193 else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
Damjan Marion7cd468a2016-12-19 23:05:39 +01008194 &miss_next_index))
8195 ;
8196 else if (unformat (i, "current-data-flag %d", &current_data_flag))
8197 ;
8198 else if (unformat (i, "current-data-offset %d", &current_data_offset))
8199 ;
8200 else
8201 break;
8202 }
8203
8204 if (is_add && mask == 0)
8205 {
8206 errmsg ("Mask required");
8207 return -99;
8208 }
8209
8210 if (is_add && skip == ~0)
8211 {
8212 errmsg ("skip count required");
8213 return -99;
8214 }
8215
8216 if (is_add && match == ~0)
8217 {
8218 errmsg ("match count required");
8219 return -99;
8220 }
8221
8222 if (!is_add && table_index == ~0)
8223 {
8224 errmsg ("table index required for delete");
8225 return -99;
8226 }
8227
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008228 M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
Damjan Marion7cd468a2016-12-19 23:05:39 +01008229
8230 mp->is_add = is_add;
8231 mp->del_chain = del_chain;
8232 mp->table_index = ntohl (table_index);
8233 mp->nbuckets = ntohl (nbuckets);
8234 mp->memory_size = ntohl (memory_size);
8235 mp->skip_n_vectors = ntohl (skip);
8236 mp->match_n_vectors = ntohl (match);
8237 mp->next_table_index = ntohl (next_table_index);
8238 mp->miss_next_index = ntohl (miss_next_index);
8239 mp->current_data_flag = ntohl (current_data_flag);
8240 mp->current_data_offset = ntohl (current_data_offset);
Juraj Sloboda75282452018-06-12 14:20:49 +02008241 mp->mask_len = ntohl (vec_len (mask));
Damjan Marion7cd468a2016-12-19 23:05:39 +01008242 clib_memcpy (mp->mask, mask, vec_len (mask));
8243
8244 vec_free (mask);
8245
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008246 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008247 W (ret);
8248 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008249}
8250
Dave Barach4a3f69c2017-02-22 12:44:56 -05008251#if VPP_API_TEST_BUILTIN == 0
Damjan Marion7cd468a2016-12-19 23:05:39 +01008252uword
8253unformat_l4_match (unformat_input_t * input, va_list * args)
8254{
8255 u8 **matchp = va_arg (*args, u8 **);
8256
8257 u8 *proto_header = 0;
8258 int src_port = 0;
8259 int dst_port = 0;
8260
8261 tcpudp_header_t h;
8262
8263 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8264 {
8265 if (unformat (input, "src_port %d", &src_port))
8266 ;
8267 else if (unformat (input, "dst_port %d", &dst_port))
8268 ;
8269 else
8270 return 0;
8271 }
8272
8273 h.src_port = clib_host_to_net_u16 (src_port);
8274 h.dst_port = clib_host_to_net_u16 (dst_port);
8275 vec_validate (proto_header, sizeof (h) - 1);
8276 memcpy (proto_header, &h, sizeof (h));
8277
8278 *matchp = proto_header;
8279
8280 return 1;
8281}
8282
8283uword
8284unformat_ip4_match (unformat_input_t * input, va_list * args)
8285{
8286 u8 **matchp = va_arg (*args, u8 **);
8287 u8 *match = 0;
8288 ip4_header_t *ip;
8289 int version = 0;
8290 u32 version_val;
8291 int hdr_length = 0;
8292 u32 hdr_length_val;
8293 int src = 0, dst = 0;
8294 ip4_address_t src_val, dst_val;
8295 int proto = 0;
8296 u32 proto_val;
8297 int tos = 0;
8298 u32 tos_val;
8299 int length = 0;
8300 u32 length_val;
8301 int fragment_id = 0;
8302 u32 fragment_id_val;
8303 int ttl = 0;
8304 int ttl_val;
8305 int checksum = 0;
8306 u32 checksum_val;
8307
8308 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8309 {
8310 if (unformat (input, "version %d", &version_val))
8311 version = 1;
8312 else if (unformat (input, "hdr_length %d", &hdr_length_val))
8313 hdr_length = 1;
8314 else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
8315 src = 1;
8316 else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
8317 dst = 1;
8318 else if (unformat (input, "proto %d", &proto_val))
8319 proto = 1;
8320 else if (unformat (input, "tos %d", &tos_val))
8321 tos = 1;
8322 else if (unformat (input, "length %d", &length_val))
8323 length = 1;
8324 else if (unformat (input, "fragment_id %d", &fragment_id_val))
8325 fragment_id = 1;
8326 else if (unformat (input, "ttl %d", &ttl_val))
8327 ttl = 1;
8328 else if (unformat (input, "checksum %d", &checksum_val))
8329 checksum = 1;
8330 else
8331 break;
8332 }
8333
8334 if (version + hdr_length + src + dst + proto + tos + length + fragment_id
8335 + ttl + checksum == 0)
8336 return 0;
8337
8338 /*
8339 * Aligned because we use the real comparison functions
8340 */
8341 vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8342
8343 ip = (ip4_header_t *) match;
8344
8345 /* These are realistically matched in practice */
8346 if (src)
8347 ip->src_address.as_u32 = src_val.as_u32;
8348
8349 if (dst)
8350 ip->dst_address.as_u32 = dst_val.as_u32;
8351
8352 if (proto)
8353 ip->protocol = proto_val;
8354
8355
8356 /* These are not, but they're included for completeness */
8357 if (version)
8358 ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
8359
8360 if (hdr_length)
8361 ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
8362
8363 if (tos)
8364 ip->tos = tos_val;
8365
8366 if (length)
8367 ip->length = clib_host_to_net_u16 (length_val);
8368
8369 if (ttl)
8370 ip->ttl = ttl_val;
8371
8372 if (checksum)
8373 ip->checksum = clib_host_to_net_u16 (checksum_val);
8374
8375 *matchp = match;
8376 return 1;
8377}
8378
8379uword
8380unformat_ip6_match (unformat_input_t * input, va_list * args)
8381{
8382 u8 **matchp = va_arg (*args, u8 **);
8383 u8 *match = 0;
8384 ip6_header_t *ip;
8385 int version = 0;
8386 u32 version_val;
8387 u8 traffic_class = 0;
8388 u32 traffic_class_val = 0;
8389 u8 flow_label = 0;
8390 u8 flow_label_val;
8391 int src = 0, dst = 0;
8392 ip6_address_t src_val, dst_val;
8393 int proto = 0;
8394 u32 proto_val;
8395 int payload_length = 0;
8396 u32 payload_length_val;
8397 int hop_limit = 0;
8398 int hop_limit_val;
8399 u32 ip_version_traffic_class_and_flow_label;
8400
8401 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8402 {
8403 if (unformat (input, "version %d", &version_val))
8404 version = 1;
8405 else if (unformat (input, "traffic_class %d", &traffic_class_val))
8406 traffic_class = 1;
8407 else if (unformat (input, "flow_label %d", &flow_label_val))
8408 flow_label = 1;
8409 else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
8410 src = 1;
8411 else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
8412 dst = 1;
8413 else if (unformat (input, "proto %d", &proto_val))
8414 proto = 1;
8415 else if (unformat (input, "payload_length %d", &payload_length_val))
8416 payload_length = 1;
8417 else if (unformat (input, "hop_limit %d", &hop_limit_val))
8418 hop_limit = 1;
8419 else
8420 break;
8421 }
8422
8423 if (version + traffic_class + flow_label + src + dst + proto +
8424 payload_length + hop_limit == 0)
8425 return 0;
8426
8427 /*
8428 * Aligned because we use the real comparison functions
8429 */
8430 vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8431
8432 ip = (ip6_header_t *) match;
8433
8434 if (src)
8435 clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
8436
8437 if (dst)
8438 clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
8439
8440 if (proto)
8441 ip->protocol = proto_val;
8442
8443 ip_version_traffic_class_and_flow_label = 0;
8444
8445 if (version)
8446 ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
8447
8448 if (traffic_class)
8449 ip_version_traffic_class_and_flow_label |=
8450 (traffic_class_val & 0xFF) << 20;
8451
8452 if (flow_label)
8453 ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
8454
8455 ip->ip_version_traffic_class_and_flow_label =
8456 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8457
8458 if (payload_length)
8459 ip->payload_length = clib_host_to_net_u16 (payload_length_val);
8460
8461 if (hop_limit)
8462 ip->hop_limit = hop_limit_val;
8463
8464 *matchp = match;
8465 return 1;
8466}
8467
8468uword
8469unformat_l3_match (unformat_input_t * input, va_list * args)
8470{
8471 u8 **matchp = va_arg (*args, u8 **);
8472
8473 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8474 {
8475 if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
8476 return 1;
8477 else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
8478 return 1;
8479 else
8480 break;
8481 }
8482 return 0;
8483}
8484
8485uword
8486unformat_vlan_tag (unformat_input_t * input, va_list * args)
8487{
8488 u8 *tagp = va_arg (*args, u8 *);
8489 u32 tag;
8490
8491 if (unformat (input, "%d", &tag))
8492 {
8493 tagp[0] = (tag >> 8) & 0x0F;
8494 tagp[1] = tag & 0xFF;
8495 return 1;
8496 }
8497
8498 return 0;
8499}
8500
8501uword
8502unformat_l2_match (unformat_input_t * input, va_list * args)
8503{
8504 u8 **matchp = va_arg (*args, u8 **);
8505 u8 *match = 0;
8506 u8 src = 0;
8507 u8 src_val[6];
8508 u8 dst = 0;
8509 u8 dst_val[6];
8510 u8 proto = 0;
8511 u16 proto_val;
8512 u8 tag1 = 0;
8513 u8 tag1_val[2];
8514 u8 tag2 = 0;
8515 u8 tag2_val[2];
8516 int len = 14;
8517 u8 ignore_tag1 = 0;
8518 u8 ignore_tag2 = 0;
8519 u8 cos1 = 0;
8520 u8 cos2 = 0;
8521 u32 cos1_val = 0;
8522 u32 cos2_val = 0;
8523
8524 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8525 {
8526 if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
8527 src = 1;
8528 else
8529 if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
8530 dst = 1;
8531 else if (unformat (input, "proto %U",
8532 unformat_ethernet_type_host_byte_order, &proto_val))
8533 proto = 1;
8534 else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
8535 tag1 = 1;
8536 else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
8537 tag2 = 1;
8538 else if (unformat (input, "ignore-tag1"))
8539 ignore_tag1 = 1;
8540 else if (unformat (input, "ignore-tag2"))
8541 ignore_tag2 = 1;
8542 else if (unformat (input, "cos1 %d", &cos1_val))
8543 cos1 = 1;
8544 else if (unformat (input, "cos2 %d", &cos2_val))
8545 cos2 = 1;
8546 else
8547 break;
8548 }
8549 if ((src + dst + proto + tag1 + tag2 +
8550 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8551 return 0;
8552
8553 if (tag1 || ignore_tag1 || cos1)
8554 len = 18;
8555 if (tag2 || ignore_tag2 || cos2)
8556 len = 22;
8557
8558 vec_validate_aligned (match, len - 1, sizeof (u32x4));
8559
8560 if (dst)
8561 clib_memcpy (match, dst_val, 6);
8562
8563 if (src)
8564 clib_memcpy (match + 6, src_val, 6);
8565
8566 if (tag2)
8567 {
8568 /* inner vlan tag */
8569 match[19] = tag2_val[1];
8570 match[18] = tag2_val[0];
8571 if (cos2)
8572 match[18] |= (cos2_val & 0x7) << 5;
8573 if (proto)
8574 {
8575 match[21] = proto_val & 0xff;
8576 match[20] = proto_val >> 8;
8577 }
8578 if (tag1)
8579 {
8580 match[15] = tag1_val[1];
8581 match[14] = tag1_val[0];
8582 }
8583 if (cos1)
8584 match[14] |= (cos1_val & 0x7) << 5;
8585 *matchp = match;
8586 return 1;
8587 }
8588 if (tag1)
8589 {
8590 match[15] = tag1_val[1];
8591 match[14] = tag1_val[0];
8592 if (proto)
8593 {
8594 match[17] = proto_val & 0xff;
8595 match[16] = proto_val >> 8;
8596 }
8597 if (cos1)
8598 match[14] |= (cos1_val & 0x7) << 5;
8599
8600 *matchp = match;
8601 return 1;
8602 }
8603 if (cos2)
8604 match[18] |= (cos2_val & 0x7) << 5;
8605 if (cos1)
8606 match[14] |= (cos1_val & 0x7) << 5;
8607 if (proto)
8608 {
8609 match[13] = proto_val & 0xff;
8610 match[12] = proto_val >> 8;
8611 }
8612
8613 *matchp = match;
8614 return 1;
8615}
Igor Mikhailov (imichail)582caa32018-04-26 21:33:02 -07008616
8617uword
8618unformat_qos_source (unformat_input_t * input, va_list * args)
8619{
8620 int *qs = va_arg (*args, int *);
8621
8622 if (unformat (input, "ip"))
8623 *qs = QOS_SOURCE_IP;
8624 else if (unformat (input, "mpls"))
8625 *qs = QOS_SOURCE_MPLS;
8626 else if (unformat (input, "ext"))
8627 *qs = QOS_SOURCE_EXT;
8628 else if (unformat (input, "vlan"))
8629 *qs = QOS_SOURCE_VLAN;
8630 else
8631 return 0;
8632
8633 return 1;
8634}
Dave Barach4a3f69c2017-02-22 12:44:56 -05008635#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +01008636
8637uword
Dave Barach4a3f69c2017-02-22 12:44:56 -05008638api_unformat_classify_match (unformat_input_t * input, va_list * args)
Damjan Marion7cd468a2016-12-19 23:05:39 +01008639{
8640 u8 **matchp = va_arg (*args, u8 **);
8641 u32 skip_n_vectors = va_arg (*args, u32);
8642 u32 match_n_vectors = va_arg (*args, u32);
8643
8644 u8 *match = 0;
8645 u8 *l2 = 0;
8646 u8 *l3 = 0;
8647 u8 *l4 = 0;
8648
8649 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8650 {
8651 if (unformat (input, "hex %U", unformat_hex_string, &match))
8652 ;
8653 else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
8654 ;
8655 else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
8656 ;
8657 else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
8658 ;
8659 else
8660 break;
8661 }
8662
8663 if (l4 && !l3)
8664 {
8665 vec_free (match);
8666 vec_free (l2);
8667 vec_free (l4);
8668 return 0;
8669 }
8670
8671 if (match || l2 || l3 || l4)
8672 {
8673 if (l2 || l3 || l4)
8674 {
8675 /* "Win a free Ethernet header in every packet" */
8676 if (l2 == 0)
8677 vec_validate_aligned (l2, 13, sizeof (u32x4));
8678 match = l2;
8679 if (vec_len (l3))
8680 {
8681 vec_append_aligned (match, l3, sizeof (u32x4));
8682 vec_free (l3);
8683 }
8684 if (vec_len (l4))
8685 {
8686 vec_append_aligned (match, l4, sizeof (u32x4));
8687 vec_free (l4);
8688 }
8689 }
8690
8691 /* Make sure the vector is big enough even if key is all 0's */
8692 vec_validate_aligned
8693 (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
8694 sizeof (u32x4));
8695
8696 /* Set size, include skipped vectors */
8697 _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
8698
8699 *matchp = match;
8700
8701 return 1;
8702 }
8703
8704 return 0;
8705}
8706
8707static int
8708api_classify_add_del_session (vat_main_t * vam)
8709{
8710 unformat_input_t *i = vam->input;
8711 vl_api_classify_add_del_session_t *mp;
8712 int is_add = 1;
8713 u32 table_index = ~0;
8714 u32 hit_next_index = ~0;
8715 u32 opaque_index = ~0;
8716 u8 *match = 0;
8717 i32 advance = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008718 u32 skip_n_vectors = 0;
8719 u32 match_n_vectors = 0;
8720 u32 action = 0;
8721 u32 metadata = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008722 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008723
8724 /*
8725 * Warning: you have to supply skip_n and match_n
8726 * because the API client cant simply look at the classify
8727 * table object.
8728 */
8729
8730 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8731 {
8732 if (unformat (i, "del"))
8733 is_add = 0;
Dave Barach4a3f69c2017-02-22 12:44:56 -05008734 else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
Damjan Marion7cd468a2016-12-19 23:05:39 +01008735 &hit_next_index))
8736 ;
8737 else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
8738 &hit_next_index))
8739 ;
Dave Barach4a3f69c2017-02-22 12:44:56 -05008740 else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
Damjan Marion7cd468a2016-12-19 23:05:39 +01008741 &hit_next_index))
8742 ;
8743 else if (unformat (i, "policer-hit-next %d", &hit_next_index))
8744 ;
8745 else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
8746 ;
8747 else if (unformat (i, "opaque-index %d", &opaque_index))
8748 ;
8749 else if (unformat (i, "skip_n %d", &skip_n_vectors))
8750 ;
8751 else if (unformat (i, "match_n %d", &match_n_vectors))
8752 ;
Dave Barach4a3f69c2017-02-22 12:44:56 -05008753 else if (unformat (i, "match %U", api_unformat_classify_match,
Damjan Marion7cd468a2016-12-19 23:05:39 +01008754 &match, skip_n_vectors, match_n_vectors))
8755 ;
8756 else if (unformat (i, "advance %d", &advance))
8757 ;
8758 else if (unformat (i, "table-index %d", &table_index))
8759 ;
8760 else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
8761 action = 1;
8762 else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
8763 action = 2;
8764 else if (unformat (i, "action %d", &action))
8765 ;
8766 else if (unformat (i, "metadata %d", &metadata))
8767 ;
8768 else
8769 break;
8770 }
8771
8772 if (table_index == ~0)
8773 {
8774 errmsg ("Table index required");
8775 return -99;
8776 }
8777
8778 if (is_add && match == 0)
8779 {
8780 errmsg ("Match value required");
8781 return -99;
8782 }
8783
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008784 M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
Damjan Marion7cd468a2016-12-19 23:05:39 +01008785
8786 mp->is_add = is_add;
8787 mp->table_index = ntohl (table_index);
8788 mp->hit_next_index = ntohl (hit_next_index);
8789 mp->opaque_index = ntohl (opaque_index);
8790 mp->advance = ntohl (advance);
8791 mp->action = action;
8792 mp->metadata = ntohl (metadata);
Juraj Sloboda75282452018-06-12 14:20:49 +02008793 mp->match_len = ntohl (vec_len (match));
Damjan Marion7cd468a2016-12-19 23:05:39 +01008794 clib_memcpy (mp->match, match, vec_len (match));
8795 vec_free (match);
8796
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008797 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008798 W (ret);
8799 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008800}
8801
8802static int
8803api_classify_set_interface_ip_table (vat_main_t * vam)
8804{
8805 unformat_input_t *i = vam->input;
8806 vl_api_classify_set_interface_ip_table_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008807 u32 sw_if_index;
8808 int sw_if_index_set;
8809 u32 table_index = ~0;
8810 u8 is_ipv6 = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008811 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008812
8813 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8814 {
8815 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8816 sw_if_index_set = 1;
8817 else if (unformat (i, "sw_if_index %d", &sw_if_index))
8818 sw_if_index_set = 1;
8819 else if (unformat (i, "table %d", &table_index))
8820 ;
8821 else
8822 {
8823 clib_warning ("parse error '%U'", format_unformat_error, i);
8824 return -99;
8825 }
8826 }
8827
8828 if (sw_if_index_set == 0)
8829 {
8830 errmsg ("missing interface name or sw_if_index");
8831 return -99;
8832 }
8833
8834
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008835 M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008836
8837 mp->sw_if_index = ntohl (sw_if_index);
8838 mp->table_index = ntohl (table_index);
8839 mp->is_ipv6 = is_ipv6;
8840
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008841 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008842 W (ret);
8843 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008844}
8845
8846static int
8847api_classify_set_interface_l2_tables (vat_main_t * vam)
8848{
8849 unformat_input_t *i = vam->input;
8850 vl_api_classify_set_interface_l2_tables_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008851 u32 sw_if_index;
8852 int sw_if_index_set;
8853 u32 ip4_table_index = ~0;
8854 u32 ip6_table_index = ~0;
8855 u32 other_table_index = ~0;
8856 u32 is_input = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008857 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008858
8859 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8860 {
8861 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8862 sw_if_index_set = 1;
8863 else if (unformat (i, "sw_if_index %d", &sw_if_index))
8864 sw_if_index_set = 1;
8865 else if (unformat (i, "ip4-table %d", &ip4_table_index))
8866 ;
8867 else if (unformat (i, "ip6-table %d", &ip6_table_index))
8868 ;
8869 else if (unformat (i, "other-table %d", &other_table_index))
8870 ;
8871 else if (unformat (i, "is-input %d", &is_input))
8872 ;
8873 else
8874 {
8875 clib_warning ("parse error '%U'", format_unformat_error, i);
8876 return -99;
8877 }
8878 }
8879
8880 if (sw_if_index_set == 0)
8881 {
8882 errmsg ("missing interface name or sw_if_index");
8883 return -99;
8884 }
8885
8886
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008887 M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008888
8889 mp->sw_if_index = ntohl (sw_if_index);
8890 mp->ip4_table_index = ntohl (ip4_table_index);
8891 mp->ip6_table_index = ntohl (ip6_table_index);
8892 mp->other_table_index = ntohl (other_table_index);
8893 mp->is_input = (u8) is_input;
8894
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008895 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008896 W (ret);
8897 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008898}
8899
8900static int
8901api_set_ipfix_exporter (vat_main_t * vam)
8902{
8903 unformat_input_t *i = vam->input;
8904 vl_api_set_ipfix_exporter_t *mp;
8905 ip4_address_t collector_address;
8906 u8 collector_address_set = 0;
8907 u32 collector_port = ~0;
8908 ip4_address_t src_address;
8909 u8 src_address_set = 0;
8910 u32 vrf_id = ~0;
8911 u32 path_mtu = ~0;
8912 u32 template_interval = ~0;
8913 u8 udp_checksum = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008914 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008915
8916 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8917 {
8918 if (unformat (i, "collector_address %U", unformat_ip4_address,
8919 &collector_address))
8920 collector_address_set = 1;
8921 else if (unformat (i, "collector_port %d", &collector_port))
8922 ;
8923 else if (unformat (i, "src_address %U", unformat_ip4_address,
8924 &src_address))
8925 src_address_set = 1;
8926 else if (unformat (i, "vrf_id %d", &vrf_id))
8927 ;
8928 else if (unformat (i, "path_mtu %d", &path_mtu))
8929 ;
8930 else if (unformat (i, "template_interval %d", &template_interval))
8931 ;
8932 else if (unformat (i, "udp_checksum"))
8933 udp_checksum = 1;
8934 else
8935 break;
8936 }
8937
8938 if (collector_address_set == 0)
8939 {
8940 errmsg ("collector_address required");
8941 return -99;
8942 }
8943
8944 if (src_address_set == 0)
8945 {
8946 errmsg ("src_address required");
8947 return -99;
8948 }
8949
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008950 M (SET_IPFIX_EXPORTER, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008951
Jakub Grajciar2f71a882019-10-10 14:21:22 +02008952 memcpy (mp->collector_address.un.ip4, collector_address.data,
Damjan Marion7cd468a2016-12-19 23:05:39 +01008953 sizeof (collector_address.data));
8954 mp->collector_port = htons ((u16) collector_port);
Jakub Grajciar2f71a882019-10-10 14:21:22 +02008955 memcpy (mp->src_address.un.ip4, src_address.data,
8956 sizeof (src_address.data));
Damjan Marion7cd468a2016-12-19 23:05:39 +01008957 mp->vrf_id = htonl (vrf_id);
8958 mp->path_mtu = htonl (path_mtu);
8959 mp->template_interval = htonl (template_interval);
8960 mp->udp_checksum = udp_checksum;
8961
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008962 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008963 W (ret);
8964 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008965}
8966
8967static int
8968api_set_ipfix_classify_stream (vat_main_t * vam)
8969{
8970 unformat_input_t *i = vam->input;
8971 vl_api_set_ipfix_classify_stream_t *mp;
8972 u32 domain_id = 0;
8973 u32 src_port = UDP_DST_PORT_ipfix;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008974 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008975
8976 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8977 {
8978 if (unformat (i, "domain %d", &domain_id))
8979 ;
8980 else if (unformat (i, "src_port %d", &src_port))
8981 ;
8982 else
8983 {
8984 errmsg ("unknown input `%U'", format_unformat_error, i);
8985 return -99;
8986 }
8987 }
8988
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008989 M (SET_IPFIX_CLASSIFY_STREAM, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008990
8991 mp->domain_id = htonl (domain_id);
8992 mp->src_port = htons ((u16) src_port);
8993
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008994 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008995 W (ret);
8996 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008997}
8998
8999static int
9000api_ipfix_classify_table_add_del (vat_main_t * vam)
9001{
9002 unformat_input_t *i = vam->input;
9003 vl_api_ipfix_classify_table_add_del_t *mp;
9004 int is_add = -1;
9005 u32 classify_table_index = ~0;
9006 u8 ip_version = 0;
9007 u8 transport_protocol = 255;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009008 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009009
9010 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9011 {
9012 if (unformat (i, "add"))
9013 is_add = 1;
9014 else if (unformat (i, "del"))
9015 is_add = 0;
9016 else if (unformat (i, "table %d", &classify_table_index))
9017 ;
9018 else if (unformat (i, "ip4"))
9019 ip_version = 4;
9020 else if (unformat (i, "ip6"))
9021 ip_version = 6;
9022 else if (unformat (i, "tcp"))
9023 transport_protocol = 6;
9024 else if (unformat (i, "udp"))
9025 transport_protocol = 17;
9026 else
9027 {
9028 errmsg ("unknown input `%U'", format_unformat_error, i);
9029 return -99;
9030 }
9031 }
9032
9033 if (is_add == -1)
9034 {
9035 errmsg ("expecting: add|del");
9036 return -99;
9037 }
9038 if (classify_table_index == ~0)
9039 {
9040 errmsg ("classifier table not specified");
9041 return -99;
9042 }
9043 if (ip_version == 0)
9044 {
9045 errmsg ("IP version not specified");
9046 return -99;
9047 }
9048
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009049 M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009050
9051 mp->is_add = is_add;
9052 mp->table_id = htonl (classify_table_index);
9053 mp->ip_version = ip_version;
9054 mp->transport_protocol = transport_protocol;
9055
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009056 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06009057 W (ret);
9058 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009059}
9060
9061static int
9062api_get_node_index (vat_main_t * vam)
9063{
9064 unformat_input_t *i = vam->input;
9065 vl_api_get_node_index_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009066 u8 *name = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009067 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009068
9069 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9070 {
9071 if (unformat (i, "node %s", &name))
9072 ;
9073 else
9074 break;
9075 }
9076 if (name == 0)
9077 {
9078 errmsg ("node name required");
9079 return -99;
9080 }
9081 if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9082 {
9083 errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9084 return -99;
9085 }
9086
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009087 M (GET_NODE_INDEX, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009088 clib_memcpy (mp->node_name, name, vec_len (name));
9089 vec_free (name);
9090
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009091 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06009092 W (ret);
9093 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009094}
9095
9096static int
9097api_get_next_index (vat_main_t * vam)
9098{
9099 unformat_input_t *i = vam->input;
9100 vl_api_get_next_index_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009101 u8 *node_name = 0, *next_node_name = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009102 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009103
9104 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9105 {
9106 if (unformat (i, "node-name %s", &node_name))
9107 ;
9108 else if (unformat (i, "next-node-name %s", &next_node_name))
9109 break;
9110 }
9111
9112 if (node_name == 0)
9113 {
9114 errmsg ("node name required");
9115 return -99;
9116 }
9117 if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
9118 {
9119 errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9120 return -99;
9121 }
9122
9123 if (next_node_name == 0)
9124 {
9125 errmsg ("next node name required");
9126 return -99;
9127 }
9128 if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
9129 {
9130 errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
9131 return -99;
9132 }
9133
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009134 M (GET_NEXT_INDEX, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009135 clib_memcpy (mp->node_name, node_name, vec_len (node_name));
9136 clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
9137 vec_free (node_name);
9138 vec_free (next_node_name);
9139
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009140 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06009141 W (ret);
9142 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009143}
9144
9145static int
9146api_add_node_next (vat_main_t * vam)
9147{
9148 unformat_input_t *i = vam->input;
9149 vl_api_add_node_next_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009150 u8 *name = 0;
9151 u8 *next = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009152 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009153
9154 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9155 {
9156 if (unformat (i, "node %s", &name))
9157 ;
9158 else if (unformat (i, "next %s", &next))
9159 ;
9160 else
9161 break;
9162 }
9163 if (name == 0)
9164 {
9165 errmsg ("node name required");
9166 return -99;
9167 }
9168 if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9169 {
9170 errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9171 return -99;
9172 }
9173 if (next == 0)
9174 {
9175 errmsg ("next node required");
9176 return -99;
9177 }
9178 if (vec_len (next) >= ARRAY_LEN (mp->next_name))
9179 {
9180 errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
9181 return -99;
9182 }
9183
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009184 M (ADD_NODE_NEXT, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009185 clib_memcpy (mp->node_name, name, vec_len (name));
9186 clib_memcpy (mp->next_name, next, vec_len (next));
9187 vec_free (name);
9188 vec_free (next);
9189
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009190 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06009191 W (ret);
9192 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009193}
9194
Damjan Marion8389fb92017-10-13 18:29:53 +02009195static void vl_api_sw_interface_tap_v2_details_t_handler
9196 (vl_api_sw_interface_tap_v2_details_t * mp)
9197{
9198 vat_main_t *vam = &vat_main;
9199
Jakub Grajciar5de4fb72019-09-03 10:40:01 +02009200 u8 *ip4 =
9201 format (0, "%U/%d", format_ip4_address, mp->host_ip4_prefix.address,
9202 mp->host_ip4_prefix.len);
9203 u8 *ip6 =
9204 format (0, "%U/%d", format_ip6_address, mp->host_ip6_prefix.address,
9205 mp->host_ip6_prefix.len);
Milan Lenco73e7f422017-12-14 10:04:25 +01009206
9207 print (vam->ofp,
Andrew Yourtchenko754f24b2019-01-07 20:56:46 +01009208 "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
Milan Lenco73e7f422017-12-14 10:04:25 +01009209 mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
9210 ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
9211 format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
Andrew Yourtchenko754f24b2019-01-07 20:56:46 +01009212 mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
Milan Lenco73e7f422017-12-14 10:04:25 +01009213
9214 vec_free (ip4);
9215 vec_free (ip6);
Damjan Marion8389fb92017-10-13 18:29:53 +02009216}
9217
9218static void vl_api_sw_interface_tap_v2_details_t_handler_json
9219 (vl_api_sw_interface_tap_v2_details_t * mp)
9220{
9221 vat_main_t *vam = &vat_main;
9222 vat_json_node_t *node = NULL;
9223
9224 if (VAT_JSON_ARRAY != vam->json_tree.type)
9225 {
9226 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9227 vat_json_init_array (&vam->json_tree);
9228 }
9229 node = vat_json_array_add (&vam->json_tree);
9230
9231 vat_json_init_object (node);
Milan Lenco73e7f422017-12-14 10:04:25 +01009232 vat_json_object_add_uint (node, "id", ntohl (mp->id));
Damjan Marion8389fb92017-10-13 18:29:53 +02009233 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
Andrew Yourtchenko754f24b2019-01-07 20:56:46 +01009234 vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
Damjan Marion8389fb92017-10-13 18:29:53 +02009235 vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
Milan Lenco73e7f422017-12-14 10:04:25 +01009236 vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
9237 vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
9238 vat_json_object_add_string_copy (node, "host_mac_addr",
9239 format (0, "%U", format_ethernet_address,
9240 &mp->host_mac_addr));
9241 vat_json_object_add_string_copy (node, "host_namespace",
9242 mp->host_namespace);
9243 vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
9244 vat_json_object_add_string_copy (node, "host_ip4_addr",
9245 format (0, "%U/%d", format_ip4_address,
Jakub Grajciar5de4fb72019-09-03 10:40:01 +02009246 mp->host_ip4_prefix.address,
9247 mp->host_ip4_prefix.len));
9248 vat_json_object_add_string_copy (node, "host_ip6_prefix",
Milan Lenco73e7f422017-12-14 10:04:25 +01009249 format (0, "%U/%d", format_ip6_address,
Jakub Grajciar5de4fb72019-09-03 10:40:01 +02009250 mp->host_ip6_prefix.address,
9251 mp->host_ip6_prefix.len));
Milan Lenco73e7f422017-12-14 10:04:25 +01009252
Damjan Marion8389fb92017-10-13 18:29:53 +02009253}
9254
9255static int
9256api_sw_interface_tap_v2_dump (vat_main_t * vam)
9257{
9258 vl_api_sw_interface_tap_v2_dump_t *mp;
9259 vl_api_control_ping_t *mp_ping;
9260 int ret;
9261
Milan Lenco73e7f422017-12-14 10:04:25 +01009262 print (vam->ofp,
9263 "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
9264 "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
9265 "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
9266 "host_ip6_addr");
9267
Damjan Marion8389fb92017-10-13 18:29:53 +02009268 /* Get list of tap interfaces */
9269 M (SW_INTERFACE_TAP_V2_DUMP, mp);
9270 S (mp);
9271
9272 /* Use a control ping for synchronization */
9273 MPING (CONTROL_PING, mp_ping);
9274 S (mp_ping);
9275
9276 W (ret);
9277 return ret;
9278}
9279
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01009280static void vl_api_sw_interface_virtio_pci_details_t_handler
9281 (vl_api_sw_interface_virtio_pci_details_t * mp)
9282{
9283 vat_main_t *vam = &vat_main;
9284
9285 typedef union
9286 {
9287 struct
9288 {
9289 u16 domain;
9290 u8 bus;
9291 u8 slot:5;
9292 u8 function:3;
9293 };
9294 u32 as_u32;
9295 } pci_addr_t;
9296 pci_addr_t addr;
Jakub Grajciar2c504f82019-09-26 10:34:41 +02009297
9298 addr.domain = ntohs (mp->pci_addr.domain);
9299 addr.bus = mp->pci_addr.bus;
9300 addr.slot = mp->pci_addr.slot;
9301 addr.function = mp->pci_addr.function;
9302
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01009303 u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
9304 addr.slot, addr.function);
9305
9306 print (vam->ofp,
9307 "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
9308 pci_addr, ntohl (mp->sw_if_index),
9309 ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
9310 format_ethernet_address, mp->mac_addr,
9311 clib_net_to_host_u64 (mp->features));
9312 vec_free (pci_addr);
9313}
9314
9315static void vl_api_sw_interface_virtio_pci_details_t_handler_json
9316 (vl_api_sw_interface_virtio_pci_details_t * mp)
9317{
9318 vat_main_t *vam = &vat_main;
9319 vat_json_node_t *node = NULL;
Jakub Grajciar2c504f82019-09-26 10:34:41 +02009320 vlib_pci_addr_t pci_addr;
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01009321
9322 if (VAT_JSON_ARRAY != vam->json_tree.type)
9323 {
9324 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9325 vat_json_init_array (&vam->json_tree);
9326 }
9327 node = vat_json_array_add (&vam->json_tree);
9328
Jakub Grajciar2c504f82019-09-26 10:34:41 +02009329 pci_addr.domain = ntohs (mp->pci_addr.domain);
9330 pci_addr.bus = mp->pci_addr.bus;
9331 pci_addr.slot = mp->pci_addr.slot;
9332 pci_addr.function = mp->pci_addr.function;
9333
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01009334 vat_json_init_object (node);
Jakub Grajciar2c504f82019-09-26 10:34:41 +02009335 vat_json_object_add_uint (node, "pci-addr", pci_addr.as_u32);
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01009336 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9337 vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
9338 vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
9339 vat_json_object_add_uint (node, "features",
9340 clib_net_to_host_u64 (mp->features));
9341 vat_json_object_add_string_copy (node, "mac_addr",
9342 format (0, "%U", format_ethernet_address,
9343 &mp->mac_addr));
9344}
9345
9346static int
9347api_sw_interface_virtio_pci_dump (vat_main_t * vam)
9348{
9349 vl_api_sw_interface_virtio_pci_dump_t *mp;
9350 vl_api_control_ping_t *mp_ping;
9351 int ret;
9352
9353 print (vam->ofp,
9354 "\n%-12s %-12s %-12s %-12s %-17s %-08s",
9355 "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
9356 "mac_addr", "features");
9357
9358 /* Get list of tap interfaces */
9359 M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
9360 S (mp);
9361
9362 /* Use a control ping for synchronization */
9363 MPING (CONTROL_PING, mp_ping);
9364 S (mp_ping);
9365
9366 W (ret);
9367 return ret;
9368}
9369
eyal bariaf86a482018-04-17 11:20:27 +03009370static int
9371api_vxlan_offload_rx (vat_main_t * vam)
9372{
9373 unformat_input_t *line_input = vam->input;
9374 vl_api_vxlan_offload_rx_t *mp;
9375 u32 hw_if_index = ~0, rx_if_index = ~0;
9376 u8 is_add = 1;
9377 int ret;
9378
9379 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9380 {
9381 if (unformat (line_input, "del"))
9382 is_add = 0;
9383 else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
9384 &hw_if_index))
9385 ;
9386 else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
9387 ;
9388 else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
9389 &rx_if_index))
9390 ;
9391 else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
9392 ;
9393 else
9394 {
9395 errmsg ("parse error '%U'", format_unformat_error, line_input);
9396 return -99;
9397 }
9398 }
9399
9400 if (hw_if_index == ~0)
9401 {
9402 errmsg ("no hw interface");
9403 return -99;
9404 }
9405
9406 if (rx_if_index == ~0)
9407 {
9408 errmsg ("no rx tunnel");
9409 return -99;
9410 }
9411
9412 M (VXLAN_OFFLOAD_RX, mp);
9413
9414 mp->hw_if_index = ntohl (hw_if_index);
9415 mp->sw_if_index = ntohl (rx_if_index);
9416 mp->enable = is_add;
9417
9418 S (mp);
9419 W (ret);
9420 return ret;
9421}
9422
Damjan Marion7cd468a2016-12-19 23:05:39 +01009423static uword unformat_vxlan_decap_next
9424 (unformat_input_t * input, va_list * args)
9425{
9426 u32 *result = va_arg (*args, u32 *);
9427 u32 tmp;
9428
9429 if (unformat (input, "l2"))
9430 *result = VXLAN_INPUT_NEXT_L2_INPUT;
9431 else if (unformat (input, "%d", &tmp))
9432 *result = tmp;
9433 else
9434 return 0;
9435 return 1;
9436}
9437
9438static int
9439api_vxlan_add_del_tunnel (vat_main_t * vam)
9440{
9441 unformat_input_t *line_input = vam->input;
9442 vl_api_vxlan_add_del_tunnel_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009443 ip46_address_t src, dst;
9444 u8 is_add = 1;
9445 u8 ipv4_set = 0, ipv6_set = 0;
9446 u8 src_set = 0;
9447 u8 dst_set = 0;
9448 u8 grp_set = 0;
Jon Loeliger3d460bd2018-02-01 16:36:12 -06009449 u32 instance = ~0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009450 u32 mcast_sw_if_index = ~0;
9451 u32 encap_vrf_id = 0;
9452 u32 decap_next_index = ~0;
9453 u32 vni = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009454 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009455
9456 /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
Dave Barachb7b92992018-10-17 10:38:51 -04009457 clib_memset (&src, 0, sizeof src);
9458 clib_memset (&dst, 0, sizeof dst);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009459
9460 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9461 {
9462 if (unformat (line_input, "del"))
9463 is_add = 0;
Jon Loeliger3d460bd2018-02-01 16:36:12 -06009464 else if (unformat (line_input, "instance %d", &instance))
9465 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009466 else
9467 if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
9468 {
9469 ipv4_set = 1;
9470 src_set = 1;
9471 }
9472 else
9473 if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
9474 {
9475 ipv4_set = 1;
9476 dst_set = 1;
9477 }
9478 else
9479 if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
9480 {
9481 ipv6_set = 1;
9482 src_set = 1;
9483 }
9484 else
9485 if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
9486 {
9487 ipv6_set = 1;
9488 dst_set = 1;
9489 }
9490 else if (unformat (line_input, "group %U %U",
9491 unformat_ip4_address, &dst.ip4,
9492 api_unformat_sw_if_index, vam, &mcast_sw_if_index))
9493 {
9494 grp_set = dst_set = 1;
9495 ipv4_set = 1;
9496 }
9497 else if (unformat (line_input, "group %U",
9498 unformat_ip4_address, &dst.ip4))
9499 {
9500 grp_set = dst_set = 1;
9501 ipv4_set = 1;
9502 }
9503 else if (unformat (line_input, "group %U %U",
9504 unformat_ip6_address, &dst.ip6,
9505 api_unformat_sw_if_index, vam, &mcast_sw_if_index))
9506 {
9507 grp_set = dst_set = 1;
9508 ipv6_set = 1;
9509 }
9510 else if (unformat (line_input, "group %U",
9511 unformat_ip6_address, &dst.ip6))
9512 {
9513 grp_set = dst_set = 1;
9514 ipv6_set = 1;
9515 }
9516 else
9517 if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
9518 ;
9519 else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
9520 ;
9521 else if (unformat (line_input, "decap-next %U",
9522 unformat_vxlan_decap_next, &decap_next_index))
9523 ;
9524 else if (unformat (line_input, "vni %d", &vni))
9525 ;
9526 else
9527 {
9528 errmsg ("parse error '%U'", format_unformat_error, line_input);
9529 return -99;
9530 }
9531 }
9532
9533 if (src_set == 0)
9534 {
9535 errmsg ("tunnel src address not specified");
9536 return -99;
9537 }
9538 if (dst_set == 0)
9539 {
9540 errmsg ("tunnel dst address not specified");
9541 return -99;
9542 }
9543
9544 if (grp_set && !ip46_address_is_multicast (&dst))
9545 {
9546 errmsg ("tunnel group address not multicast");
9547 return -99;
9548 }
9549 if (grp_set && mcast_sw_if_index == ~0)
9550 {
9551 errmsg ("tunnel nonexistent multicast device");
9552 return -99;
9553 }
9554 if (grp_set == 0 && ip46_address_is_multicast (&dst))
9555 {
9556 errmsg ("tunnel dst address must be unicast");
9557 return -99;
9558 }
9559
9560
9561 if (ipv4_set && ipv6_set)
9562 {
9563 errmsg ("both IPv4 and IPv6 addresses specified");
9564 return -99;
9565 }
9566
9567 if ((vni == 0) || (vni >> 24))
9568 {
9569 errmsg ("vni not specified or out of range");
9570 return -99;
9571 }
9572
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009573 M (VXLAN_ADD_DEL_TUNNEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009574
9575 if (ipv6_set)
9576 {
Jakub Grajciar7c0eb562020-03-02 13:55:31 +01009577 clib_memcpy (mp->src_address.un.ip6, &src.ip6, sizeof (src.ip6));
9578 clib_memcpy (mp->dst_address.un.ip6, &dst.ip6, sizeof (dst.ip6));
Damjan Marion7cd468a2016-12-19 23:05:39 +01009579 }
9580 else
9581 {
Jakub Grajciar7c0eb562020-03-02 13:55:31 +01009582 clib_memcpy (mp->src_address.un.ip4, &src.ip4, sizeof (src.ip4));
9583 clib_memcpy (mp->dst_address.un.ip4, &dst.ip4, sizeof (dst.ip4));
Damjan Marion7cd468a2016-12-19 23:05:39 +01009584 }
Jakub Grajciar7c0eb562020-03-02 13:55:31 +01009585 mp->src_address.af = ipv6_set;
9586 mp->dst_address.af = ipv6_set;
Jon Loeliger3d460bd2018-02-01 16:36:12 -06009587
9588 mp->instance = htonl (instance);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009589 mp->encap_vrf_id = ntohl (encap_vrf_id);
9590 mp->decap_next_index = ntohl (decap_next_index);
9591 mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
9592 mp->vni = ntohl (vni);
9593 mp->is_add = is_add;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009594
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009595 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06009596 W (ret);
9597 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009598}
9599
9600static void vl_api_vxlan_tunnel_details_t_handler
9601 (vl_api_vxlan_tunnel_details_t * mp)
9602{
9603 vat_main_t *vam = &vat_main;
Jakub Grajciar7c0eb562020-03-02 13:55:31 +01009604 ip46_address_t src =
9605 to_ip46 (mp->dst_address.af, (u8 *) & mp->dst_address.un);
9606 ip46_address_t dst =
9607 to_ip46 (mp->dst_address.af, (u8 *) & mp->src_address.un);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009608
Jon Loeliger3d460bd2018-02-01 16:36:12 -06009609 print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
Damjan Marion7cd468a2016-12-19 23:05:39 +01009610 ntohl (mp->sw_if_index),
Jon Loeliger3d460bd2018-02-01 16:36:12 -06009611 ntohl (mp->instance),
Damjan Marion7cd468a2016-12-19 23:05:39 +01009612 format_ip46_address, &src, IP46_TYPE_ANY,
9613 format_ip46_address, &dst, IP46_TYPE_ANY,
9614 ntohl (mp->encap_vrf_id),
9615 ntohl (mp->decap_next_index), ntohl (mp->vni),
9616 ntohl (mp->mcast_sw_if_index));
9617}
9618
9619static void vl_api_vxlan_tunnel_details_t_handler_json
9620 (vl_api_vxlan_tunnel_details_t * mp)
9621{
9622 vat_main_t *vam = &vat_main;
9623 vat_json_node_t *node = NULL;
9624
9625 if (VAT_JSON_ARRAY != vam->json_tree.type)
9626 {
9627 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9628 vat_json_init_array (&vam->json_tree);
9629 }
9630 node = vat_json_array_add (&vam->json_tree);
9631
9632 vat_json_init_object (node);
9633 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
Jon Loeliger3d460bd2018-02-01 16:36:12 -06009634
9635 vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
9636
Jakub Grajciar7c0eb562020-03-02 13:55:31 +01009637 if (mp->src_address.af)
Damjan Marion7cd468a2016-12-19 23:05:39 +01009638 {
9639 struct in6_addr ip6;
9640
Jakub Grajciar7c0eb562020-03-02 13:55:31 +01009641 clib_memcpy (&ip6, mp->src_address.un.ip6, sizeof (ip6));
Damjan Marion7cd468a2016-12-19 23:05:39 +01009642 vat_json_object_add_ip6 (node, "src_address", ip6);
Jakub Grajciar7c0eb562020-03-02 13:55:31 +01009643 clib_memcpy (&ip6, mp->dst_address.un.ip6, sizeof (ip6));
Damjan Marion7cd468a2016-12-19 23:05:39 +01009644 vat_json_object_add_ip6 (node, "dst_address", ip6);
9645 }
9646 else
9647 {
9648 struct in_addr ip4;
9649
Jakub Grajciar7c0eb562020-03-02 13:55:31 +01009650 clib_memcpy (&ip4, mp->src_address.un.ip4, sizeof (ip4));
Damjan Marion7cd468a2016-12-19 23:05:39 +01009651 vat_json_object_add_ip4 (node, "src_address", ip4);
Jakub Grajciar7c0eb562020-03-02 13:55:31 +01009652 clib_memcpy (&ip4, mp->dst_address.un.ip4, sizeof (ip4));
Damjan Marion7cd468a2016-12-19 23:05:39 +01009653 vat_json_object_add_ip4 (node, "dst_address", ip4);
9654 }
9655 vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
9656 vat_json_object_add_uint (node, "decap_next_index",
9657 ntohl (mp->decap_next_index));
9658 vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
Damjan Marion7cd468a2016-12-19 23:05:39 +01009659 vat_json_object_add_uint (node, "mcast_sw_if_index",
9660 ntohl (mp->mcast_sw_if_index));
9661}
9662
9663static int
9664api_vxlan_tunnel_dump (vat_main_t * vam)
9665{
9666 unformat_input_t *i = vam->input;
9667 vl_api_vxlan_tunnel_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -06009668 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009669 u32 sw_if_index;
9670 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009671 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009672
9673 /* Parse args required to build the message */
9674 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9675 {
9676 if (unformat (i, "sw_if_index %d", &sw_if_index))
9677 sw_if_index_set = 1;
9678 else
9679 break;
9680 }
9681
9682 if (sw_if_index_set == 0)
9683 {
9684 sw_if_index = ~0;
9685 }
9686
9687 if (!vam->json_output)
9688 {
Jon Loeliger3d460bd2018-02-01 16:36:12 -06009689 print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
9690 "sw_if_index", "instance", "src_address", "dst_address",
Damjan Marion7cd468a2016-12-19 23:05:39 +01009691 "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
9692 }
9693
9694 /* Get list of vxlan-tunnel interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009695 M (VXLAN_TUNNEL_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009696
9697 mp->sw_if_index = htonl (sw_if_index);
9698
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009699 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009700
9701 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -04009702 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06009703 S (mp_ping);
9704
Jon Loeliger56c7b012017-02-01 12:31:41 -06009705 W (ret);
9706 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009707}
9708
9709static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01009710api_l2_fib_clear_table (vat_main_t * vam)
9711{
9712// unformat_input_t * i = vam->input;
9713 vl_api_l2_fib_clear_table_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009714 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009715
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009716 M (L2_FIB_CLEAR_TABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009717
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009718 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06009719 W (ret);
9720 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009721}
9722
9723static int
9724api_l2_interface_efp_filter (vat_main_t * vam)
9725{
9726 unformat_input_t *i = vam->input;
9727 vl_api_l2_interface_efp_filter_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009728 u32 sw_if_index;
9729 u8 enable = 1;
9730 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009731 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009732
9733 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9734 {
9735 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9736 sw_if_index_set = 1;
9737 else if (unformat (i, "sw_if_index %d", &sw_if_index))
9738 sw_if_index_set = 1;
9739 else if (unformat (i, "enable"))
9740 enable = 1;
9741 else if (unformat (i, "disable"))
9742 enable = 0;
9743 else
9744 {
9745 clib_warning ("parse error '%U'", format_unformat_error, i);
9746 return -99;
9747 }
9748 }
9749
9750 if (sw_if_index_set == 0)
9751 {
9752 errmsg ("missing sw_if_index");
9753 return -99;
9754 }
9755
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009756 M (L2_INTERFACE_EFP_FILTER, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009757
9758 mp->sw_if_index = ntohl (sw_if_index);
9759 mp->enable_disable = enable;
9760
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009761 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06009762 W (ret);
9763 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009764}
9765
9766#define foreach_vtr_op \
9767_("disable", L2_VTR_DISABLED) \
9768_("push-1", L2_VTR_PUSH_1) \
9769_("push-2", L2_VTR_PUSH_2) \
9770_("pop-1", L2_VTR_POP_1) \
9771_("pop-2", L2_VTR_POP_2) \
9772_("translate-1-1", L2_VTR_TRANSLATE_1_1) \
9773_("translate-1-2", L2_VTR_TRANSLATE_1_2) \
9774_("translate-2-1", L2_VTR_TRANSLATE_2_1) \
9775_("translate-2-2", L2_VTR_TRANSLATE_2_2)
9776
9777static int
9778api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
9779{
9780 unformat_input_t *i = vam->input;
9781 vl_api_l2_interface_vlan_tag_rewrite_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009782 u32 sw_if_index;
9783 u8 sw_if_index_set = 0;
9784 u8 vtr_op_set = 0;
9785 u32 vtr_op = 0;
9786 u32 push_dot1q = 1;
9787 u32 tag1 = ~0;
9788 u32 tag2 = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009789 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009790
9791 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9792 {
9793 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9794 sw_if_index_set = 1;
9795 else if (unformat (i, "sw_if_index %d", &sw_if_index))
9796 sw_if_index_set = 1;
9797 else if (unformat (i, "vtr_op %d", &vtr_op))
9798 vtr_op_set = 1;
9799#define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
9800 foreach_vtr_op
9801#undef _
9802 else if (unformat (i, "push_dot1q %d", &push_dot1q))
9803 ;
9804 else if (unformat (i, "tag1 %d", &tag1))
9805 ;
9806 else if (unformat (i, "tag2 %d", &tag2))
9807 ;
9808 else
9809 {
9810 clib_warning ("parse error '%U'", format_unformat_error, i);
9811 return -99;
9812 }
9813 }
9814
9815 if ((sw_if_index_set == 0) || (vtr_op_set == 0))
9816 {
9817 errmsg ("missing vtr operation or sw_if_index");
9818 return -99;
9819 }
9820
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009821 M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
9822 mp->sw_if_index = ntohl (sw_if_index);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009823 mp->vtr_op = ntohl (vtr_op);
9824 mp->push_dot1q = ntohl (push_dot1q);
9825 mp->tag1 = ntohl (tag1);
9826 mp->tag2 = ntohl (tag2);
9827
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009828 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06009829 W (ret);
9830 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009831}
9832
9833static int
9834api_create_vhost_user_if (vat_main_t * vam)
9835{
9836 unformat_input_t *i = vam->input;
9837 vl_api_create_vhost_user_if_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009838 u8 *file_name;
9839 u8 is_server = 0;
9840 u8 file_name_set = 0;
9841 u32 custom_dev_instance = ~0;
9842 u8 hwaddr[6];
9843 u8 use_custom_mac = 0;
Mohsin Kazmiee2e58f2018-08-21 16:07:03 +02009844 u8 disable_mrg_rxbuf = 0;
9845 u8 disable_indirect_desc = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009846 u8 *tag = 0;
Steven Luong4208a4c2019-05-06 08:51:56 -07009847 u8 enable_gso = 0;
Steven Luongbc0d9ff2020-03-23 09:34:59 -07009848 u8 enable_packed = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009849 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009850
9851 /* Shut up coverity */
Dave Barachb7b92992018-10-17 10:38:51 -04009852 clib_memset (hwaddr, 0, sizeof (hwaddr));
Damjan Marion7cd468a2016-12-19 23:05:39 +01009853
9854 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9855 {
9856 if (unformat (i, "socket %s", &file_name))
9857 {
9858 file_name_set = 1;
9859 }
9860 else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
9861 ;
9862 else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
9863 use_custom_mac = 1;
9864 else if (unformat (i, "server"))
9865 is_server = 1;
Mohsin Kazmiee2e58f2018-08-21 16:07:03 +02009866 else if (unformat (i, "disable_mrg_rxbuf"))
9867 disable_mrg_rxbuf = 1;
9868 else if (unformat (i, "disable_indirect_desc"))
9869 disable_indirect_desc = 1;
Steven Luong4208a4c2019-05-06 08:51:56 -07009870 else if (unformat (i, "gso"))
9871 enable_gso = 1;
Steven Luongbc0d9ff2020-03-23 09:34:59 -07009872 else if (unformat (i, "packed"))
9873 enable_packed = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009874 else if (unformat (i, "tag %s", &tag))
9875 ;
9876 else
9877 break;
9878 }
9879
9880 if (file_name_set == 0)
9881 {
9882 errmsg ("missing socket file name");
9883 return -99;
9884 }
9885
9886 if (vec_len (file_name) > 255)
9887 {
9888 errmsg ("socket file name too long");
9889 return -99;
9890 }
9891 vec_add1 (file_name, 0);
9892
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009893 M (CREATE_VHOST_USER_IF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009894
9895 mp->is_server = is_server;
Mohsin Kazmiee2e58f2018-08-21 16:07:03 +02009896 mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
9897 mp->disable_indirect_desc = disable_indirect_desc;
Steven Luong4208a4c2019-05-06 08:51:56 -07009898 mp->enable_gso = enable_gso;
Steven Luongbc0d9ff2020-03-23 09:34:59 -07009899 mp->enable_packed = enable_packed;
Steven Luong27ba5002020-11-17 13:30:44 -08009900 mp->custom_dev_instance = ntohl (custom_dev_instance);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009901 clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
9902 vec_free (file_name);
9903 if (custom_dev_instance != ~0)
Steven Luong27ba5002020-11-17 13:30:44 -08009904 mp->renumber = 1;
Mohsin Kazmiee2e58f2018-08-21 16:07:03 +02009905
Damjan Marion7cd468a2016-12-19 23:05:39 +01009906 mp->use_custom_mac = use_custom_mac;
9907 clib_memcpy (mp->mac_address, hwaddr, 6);
9908 if (tag)
9909 strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
9910 vec_free (tag);
9911
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009912 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06009913 W (ret);
9914 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009915}
9916
9917static int
9918api_modify_vhost_user_if (vat_main_t * vam)
9919{
9920 unformat_input_t *i = vam->input;
9921 vl_api_modify_vhost_user_if_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009922 u8 *file_name;
9923 u8 is_server = 0;
9924 u8 file_name_set = 0;
9925 u32 custom_dev_instance = ~0;
9926 u8 sw_if_index_set = 0;
9927 u32 sw_if_index = (u32) ~ 0;
Steven Luong4208a4c2019-05-06 08:51:56 -07009928 u8 enable_gso = 0;
Steven Luongbc0d9ff2020-03-23 09:34:59 -07009929 u8 enable_packed = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009930 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009931
9932 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9933 {
9934 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9935 sw_if_index_set = 1;
9936 else if (unformat (i, "sw_if_index %d", &sw_if_index))
9937 sw_if_index_set = 1;
9938 else if (unformat (i, "socket %s", &file_name))
9939 {
9940 file_name_set = 1;
9941 }
9942 else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
9943 ;
9944 else if (unformat (i, "server"))
9945 is_server = 1;
Steven Luong4208a4c2019-05-06 08:51:56 -07009946 else if (unformat (i, "gso"))
9947 enable_gso = 1;
Steven Luongbc0d9ff2020-03-23 09:34:59 -07009948 else if (unformat (i, "packed"))
9949 enable_packed = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009950 else
9951 break;
9952 }
9953
9954 if (sw_if_index_set == 0)
9955 {
9956 errmsg ("missing sw_if_index or interface name");
9957 return -99;
9958 }
9959
9960 if (file_name_set == 0)
9961 {
9962 errmsg ("missing socket file name");
9963 return -99;
9964 }
9965
9966 if (vec_len (file_name) > 255)
9967 {
9968 errmsg ("socket file name too long");
9969 return -99;
9970 }
9971 vec_add1 (file_name, 0);
9972
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009973 M (MODIFY_VHOST_USER_IF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009974
9975 mp->sw_if_index = ntohl (sw_if_index);
9976 mp->is_server = is_server;
Steven Luong4208a4c2019-05-06 08:51:56 -07009977 mp->enable_gso = enable_gso;
Steven Luongbc0d9ff2020-03-23 09:34:59 -07009978 mp->enable_packed = enable_packed;
Steven Luong27ba5002020-11-17 13:30:44 -08009979 mp->custom_dev_instance = ntohl (custom_dev_instance);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009980 clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
9981 vec_free (file_name);
9982 if (custom_dev_instance != ~0)
Steven Luong27ba5002020-11-17 13:30:44 -08009983 mp->renumber = 1;
9984
9985 S (mp);
9986 W (ret);
9987 return ret;
9988}
9989
9990static int
9991api_create_vhost_user_if_v2 (vat_main_t * vam)
9992{
9993 unformat_input_t *i = vam->input;
9994 vl_api_create_vhost_user_if_v2_t *mp;
9995 u8 *file_name;
9996 u8 is_server = 0;
9997 u8 file_name_set = 0;
9998 u32 custom_dev_instance = ~0;
9999 u8 hwaddr[6];
10000 u8 use_custom_mac = 0;
10001 u8 disable_mrg_rxbuf = 0;
10002 u8 disable_indirect_desc = 0;
10003 u8 *tag = 0;
10004 u8 enable_gso = 0;
10005 u8 enable_packed = 0;
10006 u8 enable_event_idx = 0;
10007 int ret;
10008
10009 /* Shut up coverity */
10010 clib_memset (hwaddr, 0, sizeof (hwaddr));
10011
10012 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
Damjan Marion7cd468a2016-12-19 23:05:39 +010010013 {
Steven Luong27ba5002020-11-17 13:30:44 -080010014 if (unformat (i, "socket %s", &file_name))
10015 {
10016 file_name_set = 1;
10017 }
10018 else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10019 ;
10020 else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
10021 use_custom_mac = 1;
10022 else if (unformat (i, "server"))
10023 is_server = 1;
10024 else if (unformat (i, "disable_mrg_rxbuf"))
10025 disable_mrg_rxbuf = 1;
10026 else if (unformat (i, "disable_indirect_desc"))
10027 disable_indirect_desc = 1;
10028 else if (unformat (i, "gso"))
10029 enable_gso = 1;
10030 else if (unformat (i, "packed"))
10031 enable_packed = 1;
10032 else if (unformat (i, "event-idx"))
10033 enable_event_idx = 1;
10034 else if (unformat (i, "tag %s", &tag))
10035 ;
10036 else
10037 break;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010038 }
10039
Steven Luong27ba5002020-11-17 13:30:44 -080010040 if (file_name_set == 0)
10041 {
10042 errmsg ("missing socket file name");
10043 return -99;
10044 }
10045
10046 if (vec_len (file_name) > 255)
10047 {
10048 errmsg ("socket file name too long");
10049 return -99;
10050 }
10051 vec_add1 (file_name, 0);
10052
10053 M (CREATE_VHOST_USER_IF_V2, mp);
10054
10055 mp->is_server = is_server;
10056 mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
10057 mp->disable_indirect_desc = disable_indirect_desc;
10058 mp->enable_gso = enable_gso;
10059 mp->enable_packed = enable_packed;
10060 mp->enable_event_idx = enable_event_idx;
10061 mp->custom_dev_instance = ntohl (custom_dev_instance);
10062 clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10063 vec_free (file_name);
10064 if (custom_dev_instance != ~0)
10065 mp->renumber = 1;
10066
10067 mp->use_custom_mac = use_custom_mac;
10068 clib_memcpy (mp->mac_address, hwaddr, 6);
10069 if (tag)
10070 strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
10071 vec_free (tag);
10072
10073 S (mp);
10074 W (ret);
10075 return ret;
10076}
10077
10078static int
10079api_modify_vhost_user_if_v2 (vat_main_t * vam)
10080{
10081 unformat_input_t *i = vam->input;
10082 vl_api_modify_vhost_user_if_v2_t *mp;
10083 u8 *file_name;
10084 u8 is_server = 0;
10085 u8 file_name_set = 0;
10086 u32 custom_dev_instance = ~0;
10087 u8 sw_if_index_set = 0;
10088 u32 sw_if_index = (u32) ~ 0;
10089 u8 enable_gso = 0;
10090 u8 enable_packed = 0;
10091 u8 enable_event_idx = 0;
10092 int ret;
10093
10094 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10095 {
10096 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10097 sw_if_index_set = 1;
10098 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10099 sw_if_index_set = 1;
10100 else if (unformat (i, "socket %s", &file_name))
10101 {
10102 file_name_set = 1;
10103 }
10104 else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10105 ;
10106 else if (unformat (i, "server"))
10107 is_server = 1;
10108 else if (unformat (i, "gso"))
10109 enable_gso = 1;
10110 else if (unformat (i, "packed"))
10111 enable_packed = 1;
10112 else if (unformat (i, "event-idx"))
10113 enable_event_idx = 1;
10114 else
10115 break;
10116 }
10117
10118 if (sw_if_index_set == 0)
10119 {
10120 errmsg ("missing sw_if_index or interface name");
10121 return -99;
10122 }
10123
10124 if (file_name_set == 0)
10125 {
10126 errmsg ("missing socket file name");
10127 return -99;
10128 }
10129
10130 if (vec_len (file_name) > 255)
10131 {
10132 errmsg ("socket file name too long");
10133 return -99;
10134 }
10135 vec_add1 (file_name, 0);
10136
10137 M (MODIFY_VHOST_USER_IF_V2, mp);
10138
10139 mp->sw_if_index = ntohl (sw_if_index);
10140 mp->is_server = is_server;
10141 mp->enable_gso = enable_gso;
10142 mp->enable_packed = enable_packed;
10143 mp->enable_event_idx = enable_event_idx;
10144 mp->custom_dev_instance = ntohl (custom_dev_instance);
10145 clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10146 vec_free (file_name);
10147 if (custom_dev_instance != ~0)
10148 mp->renumber = 1;
10149
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010150 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010151 W (ret);
10152 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010153}
10154
10155static int
10156api_delete_vhost_user_if (vat_main_t * vam)
10157{
10158 unformat_input_t *i = vam->input;
10159 vl_api_delete_vhost_user_if_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010160 u32 sw_if_index = ~0;
10161 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010162 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010163
10164 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10165 {
10166 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10167 sw_if_index_set = 1;
10168 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10169 sw_if_index_set = 1;
10170 else
10171 break;
10172 }
10173
10174 if (sw_if_index_set == 0)
10175 {
10176 errmsg ("missing sw_if_index or interface name");
10177 return -99;
10178 }
10179
10180
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010181 M (DELETE_VHOST_USER_IF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010182
10183 mp->sw_if_index = ntohl (sw_if_index);
10184
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010185 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010186 W (ret);
10187 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010188}
10189
10190static void vl_api_sw_interface_vhost_user_details_t_handler
10191 (vl_api_sw_interface_vhost_user_details_t * mp)
10192{
10193 vat_main_t *vam = &vat_main;
Jakub Grajciar5d4c99f2019-09-26 10:21:59 +020010194 u64 features;
10195
10196 features =
10197 clib_net_to_host_u32 (mp->features_first_32) | ((u64)
10198 clib_net_to_host_u32
10199 (mp->features_last_32) <<
10200 32);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010201
Steven Luong150bf5a2020-11-17 15:56:10 -080010202 print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %16llx %6d %7d %s",
10203 (char *) mp->interface_name, ntohl (mp->sw_if_index),
10204 ntohl (mp->virtio_net_hdr_sz), features, mp->is_server,
Stevenf3b53642017-05-01 14:03:02 -070010205 ntohl (mp->num_regions), (char *) mp->sock_filename);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010206 print (vam->ofp, " Status: '%s'", strerror (ntohl (mp->sock_errno)));
10207}
10208
10209static void vl_api_sw_interface_vhost_user_details_t_handler_json
10210 (vl_api_sw_interface_vhost_user_details_t * mp)
10211{
10212 vat_main_t *vam = &vat_main;
10213 vat_json_node_t *node = NULL;
10214
10215 if (VAT_JSON_ARRAY != vam->json_tree.type)
10216 {
10217 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10218 vat_json_init_array (&vam->json_tree);
10219 }
10220 node = vat_json_array_add (&vam->json_tree);
10221
10222 vat_json_init_object (node);
10223 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10224 vat_json_object_add_string_copy (node, "interface_name",
10225 mp->interface_name);
10226 vat_json_object_add_uint (node, "virtio_net_hdr_sz",
10227 ntohl (mp->virtio_net_hdr_sz));
Jakub Grajciar5d4c99f2019-09-26 10:21:59 +020010228 vat_json_object_add_uint (node, "features_first_32",
10229 clib_net_to_host_u32 (mp->features_first_32));
10230 vat_json_object_add_uint (node, "features_last_32",
10231 clib_net_to_host_u32 (mp->features_last_32));
Damjan Marion7cd468a2016-12-19 23:05:39 +010010232 vat_json_object_add_uint (node, "is_server", mp->is_server);
10233 vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
10234 vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
10235 vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
10236}
10237
10238static int
10239api_sw_interface_vhost_user_dump (vat_main_t * vam)
10240{
Steven Luonga0e8d962020-05-18 17:12:56 -070010241 unformat_input_t *i = vam->input;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010242 vl_api_sw_interface_vhost_user_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010243 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010244 int ret;
Steven Luonga0e8d962020-05-18 17:12:56 -070010245 u32 sw_if_index = ~0;
10246
10247 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10248 {
10249 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10250 ;
10251 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10252 ;
10253 else
10254 break;
10255 }
10256
Steven Luong150bf5a2020-11-17 15:56:10 -080010257 print (vam->ofp, "Interface name idx hdr_sz features "
10258 "server regions filename");
Damjan Marion7cd468a2016-12-19 23:05:39 +010010259
10260 /* Get list of vhost-user interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010261 M (SW_INTERFACE_VHOST_USER_DUMP, mp);
Steven Luonga0e8d962020-05-18 17:12:56 -070010262 mp->sw_if_index = ntohl (sw_if_index);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010263 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010264
10265 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040010266 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010267 S (mp_ping);
10268
Jon Loeliger56c7b012017-02-01 12:31:41 -060010269 W (ret);
10270 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010271}
10272
10273static int
10274api_show_version (vat_main_t * vam)
10275{
10276 vl_api_show_version_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010277 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010278
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010279 M (SHOW_VERSION, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010280
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010281 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010282 W (ret);
10283 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010284}
10285
10286
10287static int
10288api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
10289{
10290 unformat_input_t *line_input = vam->input;
10291 vl_api_vxlan_gpe_add_del_tunnel_t *mp;
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010292 ip46_address_t local, remote;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010293 u8 is_add = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010294 u8 local_set = 0;
10295 u8 remote_set = 0;
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010296 u8 grp_set = 0;
10297 u32 mcast_sw_if_index = ~0;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010298 u32 encap_vrf_id = 0;
10299 u32 decap_vrf_id = 0;
10300 u8 protocol = ~0;
10301 u32 vni;
10302 u8 vni_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010303 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010304
10305 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10306 {
10307 if (unformat (line_input, "del"))
10308 is_add = 0;
10309 else if (unformat (line_input, "local %U",
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010310 unformat_ip46_address, &local))
Damjan Marion7cd468a2016-12-19 23:05:39 +010010311 {
10312 local_set = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010313 }
10314 else if (unformat (line_input, "remote %U",
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010315 unformat_ip46_address, &remote))
Damjan Marion7cd468a2016-12-19 23:05:39 +010010316 {
10317 remote_set = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010318 }
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010319 else if (unformat (line_input, "group %U %U",
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010320 unformat_ip46_address, &remote,
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010321 api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10322 {
10323 grp_set = remote_set = 1;
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010324 }
10325 else if (unformat (line_input, "group %U",
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010326 unformat_ip46_address, &remote))
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010327 {
10328 grp_set = remote_set = 1;
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010329 }
10330 else
10331 if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10332 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010333 else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10334 ;
10335 else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
10336 ;
10337 else if (unformat (line_input, "vni %d", &vni))
10338 vni_set = 1;
10339 else if (unformat (line_input, "next-ip4"))
10340 protocol = 1;
10341 else if (unformat (line_input, "next-ip6"))
10342 protocol = 2;
10343 else if (unformat (line_input, "next-ethernet"))
10344 protocol = 3;
10345 else if (unformat (line_input, "next-nsh"))
10346 protocol = 4;
10347 else
10348 {
10349 errmsg ("parse error '%U'", format_unformat_error, line_input);
10350 return -99;
10351 }
10352 }
10353
10354 if (local_set == 0)
10355 {
10356 errmsg ("tunnel local address not specified");
10357 return -99;
10358 }
10359 if (remote_set == 0)
10360 {
10361 errmsg ("tunnel remote address not specified");
10362 return -99;
10363 }
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010364 if (grp_set && mcast_sw_if_index == ~0)
10365 {
10366 errmsg ("tunnel nonexistent multicast device");
10367 return -99;
10368 }
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010369 if (ip46_address_is_ip4 (&local) != ip46_address_is_ip4 (&remote))
Damjan Marion7cd468a2016-12-19 23:05:39 +010010370 {
10371 errmsg ("both IPv4 and IPv6 addresses specified");
10372 return -99;
10373 }
10374
10375 if (vni_set == 0)
10376 {
10377 errmsg ("vni not specified");
10378 return -99;
10379 }
10380
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010381 M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010382
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010383 ip_address_encode (&local,
10384 ip46_address_is_ip4 (&local) ? IP46_TYPE_IP4 :
10385 IP46_TYPE_IP6, &mp->local);
10386 ip_address_encode (&remote,
10387 ip46_address_is_ip4 (&remote) ? IP46_TYPE_IP4 :
10388 IP46_TYPE_IP6, &mp->remote);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010389
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010390 mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010391 mp->encap_vrf_id = ntohl (encap_vrf_id);
10392 mp->decap_vrf_id = ntohl (decap_vrf_id);
10393 mp->protocol = protocol;
10394 mp->vni = ntohl (vni);
10395 mp->is_add = is_add;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010396
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010397 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010398 W (ret);
10399 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010400}
10401
10402static void vl_api_vxlan_gpe_tunnel_details_t_handler
10403 (vl_api_vxlan_gpe_tunnel_details_t * mp)
10404{
10405 vat_main_t *vam = &vat_main;
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010406 ip46_address_t local, remote;
10407
10408 ip_address_decode (&mp->local, &local);
10409 ip_address_decode (&mp->remote, &remote);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010410
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010411 print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
Damjan Marion7cd468a2016-12-19 23:05:39 +010010412 ntohl (mp->sw_if_index),
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010413 format_ip46_address, &local, IP46_TYPE_ANY,
10414 format_ip46_address, &remote, IP46_TYPE_ANY,
10415 ntohl (mp->vni), mp->protocol,
10416 ntohl (mp->mcast_sw_if_index),
Damjan Marion7cd468a2016-12-19 23:05:39 +010010417 ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
10418}
10419
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010420
Damjan Marion7cd468a2016-12-19 23:05:39 +010010421static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
10422 (vl_api_vxlan_gpe_tunnel_details_t * mp)
10423{
10424 vat_main_t *vam = &vat_main;
10425 vat_json_node_t *node = NULL;
10426 struct in_addr ip4;
10427 struct in6_addr ip6;
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010428 ip46_address_t local, remote;
10429
10430 ip_address_decode (&mp->local, &local);
10431 ip_address_decode (&mp->remote, &remote);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010432
10433 if (VAT_JSON_ARRAY != vam->json_tree.type)
10434 {
10435 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10436 vat_json_init_array (&vam->json_tree);
10437 }
10438 node = vat_json_array_add (&vam->json_tree);
10439
10440 vat_json_init_object (node);
10441 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010442 if (ip46_address_is_ip4 (&local))
Damjan Marion7cd468a2016-12-19 23:05:39 +010010443 {
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010444 clib_memcpy (&ip4, &local.ip4, sizeof (ip4));
10445 vat_json_object_add_ip4 (node, "local", ip4);
10446 clib_memcpy (&ip4, &remote.ip4, sizeof (ip4));
10447 vat_json_object_add_ip4 (node, "remote", ip4);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010448 }
10449 else
10450 {
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010451 clib_memcpy (&ip6, &local.ip6, sizeof (ip6));
10452 vat_json_object_add_ip6 (node, "local", ip6);
10453 clib_memcpy (&ip6, &remote.ip6, sizeof (ip6));
10454 vat_json_object_add_ip6 (node, "remote", ip6);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010455 }
10456 vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10457 vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010458 vat_json_object_add_uint (node, "mcast_sw_if_index",
10459 ntohl (mp->mcast_sw_if_index));
Damjan Marion7cd468a2016-12-19 23:05:39 +010010460 vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10461 vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
10462 vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10463}
10464
10465static int
10466api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
10467{
10468 unformat_input_t *i = vam->input;
10469 vl_api_vxlan_gpe_tunnel_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010470 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010471 u32 sw_if_index;
10472 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010473 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010474
10475 /* Parse args required to build the message */
10476 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10477 {
10478 if (unformat (i, "sw_if_index %d", &sw_if_index))
10479 sw_if_index_set = 1;
10480 else
10481 break;
10482 }
10483
10484 if (sw_if_index_set == 0)
10485 {
10486 sw_if_index = ~0;
10487 }
10488
10489 if (!vam->json_output)
10490 {
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010491 print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
Damjan Marion7cd468a2016-12-19 23:05:39 +010010492 "sw_if_index", "local", "remote", "vni",
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010493 "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
Damjan Marion7cd468a2016-12-19 23:05:39 +010010494 }
10495
10496 /* Get list of vxlan-tunnel interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010497 M (VXLAN_GPE_TUNNEL_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010498
10499 mp->sw_if_index = htonl (sw_if_index);
10500
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010501 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010502
10503 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040010504 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010505 S (mp_ping);
10506
Jon Loeliger56c7b012017-02-01 12:31:41 -060010507 W (ret);
10508 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010509}
10510
Ole Troan01384fe2017-05-12 11:55:35 +020010511static void vl_api_l2_fib_table_details_t_handler
10512 (vl_api_l2_fib_table_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010010513{
10514 vat_main_t *vam = &vat_main;
10515
10516 print (vam->ofp, "%3" PRIu32 " %U %3" PRIu32
10517 " %d %d %d",
Mohsin Kazmi57938f62017-10-27 21:28:07 +020010518 ntohl (mp->bd_id), format_ethernet_address, mp->mac,
Damjan Marion7cd468a2016-12-19 23:05:39 +010010519 ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
10520 mp->bvi_mac);
10521}
10522
Ole Troan01384fe2017-05-12 11:55:35 +020010523static void vl_api_l2_fib_table_details_t_handler_json
10524 (vl_api_l2_fib_table_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010010525{
10526 vat_main_t *vam = &vat_main;
10527 vat_json_node_t *node = NULL;
10528
10529 if (VAT_JSON_ARRAY != vam->json_tree.type)
10530 {
10531 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10532 vat_json_init_array (&vam->json_tree);
10533 }
10534 node = vat_json_array_add (&vam->json_tree);
10535
10536 vat_json_init_object (node);
10537 vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
Mohsin Kazmi57938f62017-10-27 21:28:07 +020010538 vat_json_object_add_bytes (node, "mac", mp->mac, 6);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010539 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10540 vat_json_object_add_uint (node, "static_mac", mp->static_mac);
10541 vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
10542 vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
10543}
10544
10545static int
10546api_l2_fib_table_dump (vat_main_t * vam)
10547{
10548 unformat_input_t *i = vam->input;
10549 vl_api_l2_fib_table_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010550 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010551 u32 bd_id;
10552 u8 bd_id_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010553 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010554
10555 /* Parse args required to build the message */
10556 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10557 {
10558 if (unformat (i, "bd_id %d", &bd_id))
10559 bd_id_set = 1;
10560 else
10561 break;
10562 }
10563
10564 if (bd_id_set == 0)
10565 {
10566 errmsg ("missing bridge domain");
10567 return -99;
10568 }
10569
10570 print (vam->ofp, "BD-ID Mac Address sw-ndx Static Filter BVI");
10571
10572 /* Get list of l2 fib entries */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010573 M (L2_FIB_TABLE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010574
10575 mp->bd_id = ntohl (bd_id);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010576 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010577
10578 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040010579 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010580 S (mp_ping);
10581
Jon Loeliger56c7b012017-02-01 12:31:41 -060010582 W (ret);
10583 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010584}
10585
10586
10587static int
10588api_interface_name_renumber (vat_main_t * vam)
10589{
10590 unformat_input_t *line_input = vam->input;
10591 vl_api_interface_name_renumber_t *mp;
10592 u32 sw_if_index = ~0;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010593 u32 new_show_dev_instance = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010594 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010595
10596 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10597 {
10598 if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
10599 &sw_if_index))
10600 ;
10601 else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
10602 ;
10603 else if (unformat (line_input, "new_show_dev_instance %d",
10604 &new_show_dev_instance))
10605 ;
10606 else
10607 break;
10608 }
10609
10610 if (sw_if_index == ~0)
10611 {
10612 errmsg ("missing interface name or sw_if_index");
10613 return -99;
10614 }
10615
10616 if (new_show_dev_instance == ~0)
10617 {
10618 errmsg ("missing new_show_dev_instance");
10619 return -99;
10620 }
10621
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010622 M (INTERFACE_NAME_RENUMBER, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010623
10624 mp->sw_if_index = ntohl (sw_if_index);
10625 mp->new_show_dev_instance = ntohl (new_show_dev_instance);
10626
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010627 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010628 W (ret);
10629 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010630}
10631
10632static int
John Lo8d00fff2017-08-03 00:35:36 -040010633api_want_l2_macs_events (vat_main_t * vam)
10634{
10635 unformat_input_t *line_input = vam->input;
10636 vl_api_want_l2_macs_events_t *mp;
10637 u8 enable_disable = 1;
10638 u32 scan_delay = 0;
10639 u32 max_macs_in_event = 0;
10640 u32 learn_limit = 0;
10641 int ret;
10642
10643 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10644 {
10645 if (unformat (line_input, "learn-limit %d", &learn_limit))
10646 ;
10647 else if (unformat (line_input, "scan-delay %d", &scan_delay))
10648 ;
10649 else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
10650 ;
10651 else if (unformat (line_input, "disable"))
10652 enable_disable = 0;
10653 else
10654 break;
10655 }
10656
10657 M (WANT_L2_MACS_EVENTS, mp);
10658 mp->enable_disable = enable_disable;
10659 mp->pid = htonl (getpid ());
10660 mp->learn_limit = htonl (learn_limit);
10661 mp->scan_delay = (u8) scan_delay;
10662 mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
10663 S (mp);
10664 W (ret);
10665 return ret;
10666}
10667
10668static int
Damjan Marion7cd468a2016-12-19 23:05:39 +010010669api_input_acl_set_interface (vat_main_t * vam)
10670{
10671 unformat_input_t *i = vam->input;
10672 vl_api_input_acl_set_interface_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010673 u32 sw_if_index;
10674 int sw_if_index_set;
10675 u32 ip4_table_index = ~0;
10676 u32 ip6_table_index = ~0;
10677 u32 l2_table_index = ~0;
10678 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010679 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010680
10681 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10682 {
10683 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10684 sw_if_index_set = 1;
10685 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10686 sw_if_index_set = 1;
10687 else if (unformat (i, "del"))
10688 is_add = 0;
10689 else if (unformat (i, "ip4-table %d", &ip4_table_index))
10690 ;
10691 else if (unformat (i, "ip6-table %d", &ip6_table_index))
10692 ;
10693 else if (unformat (i, "l2-table %d", &l2_table_index))
10694 ;
10695 else
10696 {
10697 clib_warning ("parse error '%U'", format_unformat_error, i);
10698 return -99;
10699 }
10700 }
10701
10702 if (sw_if_index_set == 0)
10703 {
10704 errmsg ("missing interface name or sw_if_index");
10705 return -99;
10706 }
10707
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010708 M (INPUT_ACL_SET_INTERFACE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010709
10710 mp->sw_if_index = ntohl (sw_if_index);
10711 mp->ip4_table_index = ntohl (ip4_table_index);
10712 mp->ip6_table_index = ntohl (ip6_table_index);
10713 mp->l2_table_index = ntohl (l2_table_index);
10714 mp->is_add = is_add;
10715
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010716 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010717 W (ret);
10718 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010719}
10720
10721static int
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +010010722api_output_acl_set_interface (vat_main_t * vam)
10723{
10724 unformat_input_t *i = vam->input;
10725 vl_api_output_acl_set_interface_t *mp;
10726 u32 sw_if_index;
10727 int sw_if_index_set;
10728 u32 ip4_table_index = ~0;
10729 u32 ip6_table_index = ~0;
10730 u32 l2_table_index = ~0;
10731 u8 is_add = 1;
10732 int ret;
10733
10734 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10735 {
10736 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10737 sw_if_index_set = 1;
10738 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10739 sw_if_index_set = 1;
10740 else if (unformat (i, "del"))
10741 is_add = 0;
10742 else if (unformat (i, "ip4-table %d", &ip4_table_index))
10743 ;
10744 else if (unformat (i, "ip6-table %d", &ip6_table_index))
10745 ;
10746 else if (unformat (i, "l2-table %d", &l2_table_index))
10747 ;
10748 else
10749 {
10750 clib_warning ("parse error '%U'", format_unformat_error, i);
10751 return -99;
10752 }
10753 }
10754
10755 if (sw_if_index_set == 0)
10756 {
10757 errmsg ("missing interface name or sw_if_index");
10758 return -99;
10759 }
10760
10761 M (OUTPUT_ACL_SET_INTERFACE, mp);
10762
10763 mp->sw_if_index = ntohl (sw_if_index);
10764 mp->ip4_table_index = ntohl (ip4_table_index);
10765 mp->ip6_table_index = ntohl (ip6_table_index);
10766 mp->l2_table_index = ntohl (l2_table_index);
10767 mp->is_add = is_add;
10768
10769 S (mp);
10770 W (ret);
10771 return ret;
10772}
10773
10774static int
Damjan Marion7cd468a2016-12-19 23:05:39 +010010775api_ip_address_dump (vat_main_t * vam)
10776{
10777 unformat_input_t *i = vam->input;
10778 vl_api_ip_address_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010779 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010780 u32 sw_if_index = ~0;
10781 u8 sw_if_index_set = 0;
10782 u8 ipv4_set = 0;
10783 u8 ipv6_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010784 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010785
10786 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10787 {
10788 if (unformat (i, "sw_if_index %d", &sw_if_index))
10789 sw_if_index_set = 1;
10790 else
10791 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10792 sw_if_index_set = 1;
10793 else if (unformat (i, "ipv4"))
10794 ipv4_set = 1;
10795 else if (unformat (i, "ipv6"))
10796 ipv6_set = 1;
10797 else
10798 break;
10799 }
10800
10801 if (ipv4_set && ipv6_set)
10802 {
10803 errmsg ("ipv4 and ipv6 flags cannot be both set");
10804 return -99;
10805 }
10806
10807 if ((!ipv4_set) && (!ipv6_set))
10808 {
10809 errmsg ("no ipv4 nor ipv6 flag set");
10810 return -99;
10811 }
10812
10813 if (sw_if_index_set == 0)
10814 {
10815 errmsg ("missing interface name or sw_if_index");
10816 return -99;
10817 }
10818
10819 vam->current_sw_if_index = sw_if_index;
10820 vam->is_ipv6 = ipv6_set;
10821
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010822 M (IP_ADDRESS_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010823 mp->sw_if_index = ntohl (sw_if_index);
10824 mp->is_ipv6 = ipv6_set;
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010825 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010826
10827 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040010828 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010829 S (mp_ping);
10830
Jon Loeliger56c7b012017-02-01 12:31:41 -060010831 W (ret);
10832 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010833}
10834
10835static int
10836api_ip_dump (vat_main_t * vam)
10837{
10838 vl_api_ip_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010839 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010840 unformat_input_t *in = vam->input;
10841 int ipv4_set = 0;
10842 int ipv6_set = 0;
10843 int is_ipv6;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010844 int i;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010845 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010846
10847 while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
10848 {
10849 if (unformat (in, "ipv4"))
10850 ipv4_set = 1;
10851 else if (unformat (in, "ipv6"))
10852 ipv6_set = 1;
10853 else
10854 break;
10855 }
10856
10857 if (ipv4_set && ipv6_set)
10858 {
10859 errmsg ("ipv4 and ipv6 flags cannot be both set");
10860 return -99;
10861 }
10862
10863 if ((!ipv4_set) && (!ipv6_set))
10864 {
10865 errmsg ("no ipv4 nor ipv6 flag set");
10866 return -99;
10867 }
10868
10869 is_ipv6 = ipv6_set;
10870 vam->is_ipv6 = is_ipv6;
10871
10872 /* free old data */
10873 for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
10874 {
10875 vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
10876 }
10877 vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
10878
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010879 M (IP_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010880 mp->is_ipv6 = ipv6_set;
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010881 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010882
10883 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040010884 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010885 S (mp_ping);
10886
Jon Loeliger56c7b012017-02-01 12:31:41 -060010887 W (ret);
10888 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010889}
10890
10891static int
10892api_ipsec_spd_add_del (vat_main_t * vam)
10893{
10894 unformat_input_t *i = vam->input;
10895 vl_api_ipsec_spd_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010896 u32 spd_id = ~0;
10897 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010898 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010899
10900 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10901 {
10902 if (unformat (i, "spd_id %d", &spd_id))
10903 ;
10904 else if (unformat (i, "del"))
10905 is_add = 0;
10906 else
10907 {
10908 clib_warning ("parse error '%U'", format_unformat_error, i);
10909 return -99;
10910 }
10911 }
10912 if (spd_id == ~0)
10913 {
10914 errmsg ("spd_id must be set");
10915 return -99;
10916 }
10917
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010918 M (IPSEC_SPD_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010919
10920 mp->spd_id = ntohl (spd_id);
10921 mp->is_add = is_add;
10922
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010923 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010924 W (ret);
10925 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010926}
10927
10928static int
10929api_ipsec_interface_add_del_spd (vat_main_t * vam)
10930{
10931 unformat_input_t *i = vam->input;
10932 vl_api_ipsec_interface_add_del_spd_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010933 u32 sw_if_index;
10934 u8 sw_if_index_set = 0;
10935 u32 spd_id = (u32) ~ 0;
10936 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010937 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010938
10939 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10940 {
10941 if (unformat (i, "del"))
10942 is_add = 0;
10943 else if (unformat (i, "spd_id %d", &spd_id))
10944 ;
10945 else
10946 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10947 sw_if_index_set = 1;
10948 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10949 sw_if_index_set = 1;
10950 else
10951 {
10952 clib_warning ("parse error '%U'", format_unformat_error, i);
10953 return -99;
10954 }
10955
10956 }
10957
10958 if (spd_id == (u32) ~ 0)
10959 {
10960 errmsg ("spd_id must be set");
10961 return -99;
10962 }
10963
10964 if (sw_if_index_set == 0)
10965 {
10966 errmsg ("missing interface name or sw_if_index");
10967 return -99;
10968 }
10969
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010970 M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010971
10972 mp->spd_id = ntohl (spd_id);
10973 mp->sw_if_index = ntohl (sw_if_index);
10974 mp->is_add = is_add;
10975
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010976 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010977 W (ret);
10978 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010979}
10980
10981static int
Neale Ranns17dcec02019-01-09 21:22:20 -080010982api_ipsec_spd_entry_add_del (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010010983{
10984 unformat_input_t *i = vam->input;
Neale Ranns17dcec02019-01-09 21:22:20 -080010985 vl_api_ipsec_spd_entry_add_del_t *mp;
Benoît Ganne49ee6842019-04-30 11:50:46 +020010986 u8 is_add = 1, is_outbound = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010987 u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
10988 i32 priority = 0;
10989 u32 rport_start = 0, rport_stop = (u32) ~ 0;
10990 u32 lport_start = 0, lport_stop = (u32) ~ 0;
Neale Ranns17dcec02019-01-09 21:22:20 -080010991 vl_api_address_t laddr_start = { }, laddr_stop =
10992 {
10993 }, raddr_start =
10994 {
10995 }, raddr_stop =
10996 {
10997 };
Jon Loeliger56c7b012017-02-01 12:31:41 -060010998 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010999
Damjan Marion7cd468a2016-12-19 23:05:39 +010011000 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11001 {
11002 if (unformat (i, "del"))
11003 is_add = 0;
11004 if (unformat (i, "outbound"))
11005 is_outbound = 1;
11006 if (unformat (i, "inbound"))
11007 is_outbound = 0;
11008 else if (unformat (i, "spd_id %d", &spd_id))
11009 ;
11010 else if (unformat (i, "sa_id %d", &sa_id))
11011 ;
11012 else if (unformat (i, "priority %d", &priority))
11013 ;
11014 else if (unformat (i, "protocol %d", &protocol))
11015 ;
11016 else if (unformat (i, "lport_start %d", &lport_start))
11017 ;
11018 else if (unformat (i, "lport_stop %d", &lport_stop))
11019 ;
11020 else if (unformat (i, "rport_start %d", &rport_start))
11021 ;
11022 else if (unformat (i, "rport_stop %d", &rport_stop))
11023 ;
Neale Ranns17dcec02019-01-09 21:22:20 -080011024 else if (unformat (i, "laddr_start %U",
11025 unformat_vl_api_address, &laddr_start))
Benoît Ganne49ee6842019-04-30 11:50:46 +020011026 ;
Neale Ranns17dcec02019-01-09 21:22:20 -080011027 else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
11028 &laddr_stop))
Benoît Ganne49ee6842019-04-30 11:50:46 +020011029 ;
Neale Ranns17dcec02019-01-09 21:22:20 -080011030 else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
11031 &raddr_start))
Benoît Ganne49ee6842019-04-30 11:50:46 +020011032 ;
Neale Ranns17dcec02019-01-09 21:22:20 -080011033 else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
11034 &raddr_stop))
Benoît Ganne49ee6842019-04-30 11:50:46 +020011035 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011036 else
11037 if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
11038 {
11039 if (policy == IPSEC_POLICY_ACTION_RESOLVE)
11040 {
11041 clib_warning ("unsupported action: 'resolve'");
11042 return -99;
11043 }
11044 }
11045 else
11046 {
11047 clib_warning ("parse error '%U'", format_unformat_error, i);
11048 return -99;
11049 }
11050
11051 }
11052
Neale Ranns17dcec02019-01-09 21:22:20 -080011053 M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011054
Damjan Marion7cd468a2016-12-19 23:05:39 +010011055 mp->is_add = is_add;
Neale Ranns17dcec02019-01-09 21:22:20 -080011056
11057 mp->entry.spd_id = ntohl (spd_id);
11058 mp->entry.priority = ntohl (priority);
11059 mp->entry.is_outbound = is_outbound;
11060
11061 clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
11062 sizeof (vl_api_address_t));
11063 clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
11064 sizeof (vl_api_address_t));
11065 clib_memcpy (&mp->entry.local_address_start, &laddr_start,
11066 sizeof (vl_api_address_t));
11067 clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
11068 sizeof (vl_api_address_t));
11069
11070 mp->entry.protocol = (u8) protocol;
11071 mp->entry.local_port_start = ntohs ((u16) lport_start);
11072 mp->entry.local_port_stop = ntohs ((u16) lport_stop);
11073 mp->entry.remote_port_start = ntohs ((u16) rport_start);
11074 mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
11075 mp->entry.policy = (u8) policy;
11076 mp->entry.sa_id = ntohl (sa_id);
Neale Ranns17dcec02019-01-09 21:22:20 -080011077
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011078 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011079 W (ret);
11080 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011081}
11082
11083static int
Neale Ranns17dcec02019-01-09 21:22:20 -080011084api_ipsec_sad_entry_add_del (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010011085{
11086 unformat_input_t *i = vam->input;
Neale Ranns17dcec02019-01-09 21:22:20 -080011087 vl_api_ipsec_sad_entry_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011088 u32 sad_id = 0, spi = 0;
11089 u8 *ck = 0, *ik = 0;
11090 u8 is_add = 1;
11091
Neale Ranns17dcec02019-01-09 21:22:20 -080011092 vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
11093 vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
11094 vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
11095 vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
11096 vl_api_address_t tun_src, tun_dst;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011097 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011098
11099 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11100 {
11101 if (unformat (i, "del"))
11102 is_add = 0;
11103 else if (unformat (i, "sad_id %d", &sad_id))
11104 ;
11105 else if (unformat (i, "spi %d", &spi))
11106 ;
11107 else if (unformat (i, "esp"))
Neale Ranns17dcec02019-01-09 21:22:20 -080011108 protocol = IPSEC_API_PROTO_ESP;
11109 else
11110 if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
Damjan Marion7cd468a2016-12-19 23:05:39 +010011111 {
Neale Ranns17dcec02019-01-09 21:22:20 -080011112 flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
11113 if (ADDRESS_IP6 == tun_src.af)
11114 flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011115 }
11116 else
Neale Ranns17dcec02019-01-09 21:22:20 -080011117 if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
Damjan Marion7cd468a2016-12-19 23:05:39 +010011118 {
Neale Ranns17dcec02019-01-09 21:22:20 -080011119 flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
11120 if (ADDRESS_IP6 == tun_src.af)
11121 flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011122 }
Neale Ranns17dcec02019-01-09 21:22:20 -080011123 else
11124 if (unformat (i, "crypto_alg %U",
11125 unformat_ipsec_api_crypto_alg, &crypto_alg))
11126 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011127 else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11128 ;
Neale Ranns17dcec02019-01-09 21:22:20 -080011129 else if (unformat (i, "integ_alg %U",
11130 unformat_ipsec_api_integ_alg, &integ_alg))
11131 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011132 else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11133 ;
11134 else
11135 {
11136 clib_warning ("parse error '%U'", format_unformat_error, i);
11137 return -99;
11138 }
11139
11140 }
11141
Neale Ranns17dcec02019-01-09 21:22:20 -080011142 M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011143
Damjan Marion7cd468a2016-12-19 23:05:39 +010011144 mp->is_add = is_add;
Neale Ranns17dcec02019-01-09 21:22:20 -080011145 mp->entry.sad_id = ntohl (sad_id);
11146 mp->entry.protocol = protocol;
11147 mp->entry.spi = ntohl (spi);
11148 mp->entry.flags = flags;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011149
Neale Ranns17dcec02019-01-09 21:22:20 -080011150 mp->entry.crypto_algorithm = crypto_alg;
11151 mp->entry.integrity_algorithm = integ_alg;
11152 mp->entry.crypto_key.length = vec_len (ck);
11153 mp->entry.integrity_key.length = vec_len (ik);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011154
Neale Ranns17dcec02019-01-09 21:22:20 -080011155 if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
11156 mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
11157
11158 if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
11159 mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011160
11161 if (ck)
Neale Ranns17dcec02019-01-09 21:22:20 -080011162 clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011163 if (ik)
Neale Ranns17dcec02019-01-09 21:22:20 -080011164 clib_memcpy (mp->entry.integrity_key.data, ik,
11165 mp->entry.integrity_key.length);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011166
Neale Ranns17dcec02019-01-09 21:22:20 -080011167 if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
Damjan Marion7cd468a2016-12-19 23:05:39 +010011168 {
Neale Ranns17dcec02019-01-09 21:22:20 -080011169 clib_memcpy (&mp->entry.tunnel_src, &tun_src,
11170 sizeof (mp->entry.tunnel_src));
11171 clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
11172 sizeof (mp->entry.tunnel_dst));
Damjan Marion7cd468a2016-12-19 23:05:39 +010011173 }
11174
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011175 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011176 W (ret);
11177 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011178}
11179
Matthew Smith28029532017-09-26 13:33:44 -050011180static void
11181vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
11182{
11183 vat_main_t *vam = &vat_main;
11184
11185 print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
Neale Ranns8d7c5022019-02-06 01:41:05 -080011186 "crypto_key %U integ_alg %u integ_key %U flags %x "
Matthew Smith28029532017-09-26 13:33:44 -050011187 "tunnel_src_addr %U tunnel_dst_addr %U "
11188 "salt %u seq_outbound %lu last_seq_inbound %lu "
Matthew Smith48d32b42020-04-02 07:45:49 -050011189 "replay_window %lu stat_index %u\n",
Neale Ranns8d7c5022019-02-06 01:41:05 -080011190 ntohl (mp->entry.sad_id),
11191 ntohl (mp->sw_if_index),
11192 ntohl (mp->entry.spi),
11193 ntohl (mp->entry.protocol),
11194 ntohl (mp->entry.crypto_algorithm),
11195 format_hex_bytes, mp->entry.crypto_key.data,
11196 mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
11197 format_hex_bytes, mp->entry.integrity_key.data,
11198 mp->entry.integrity_key.length, ntohl (mp->entry.flags),
11199 format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
11200 &mp->entry.tunnel_dst, ntohl (mp->salt),
Matthew Smith28029532017-09-26 13:33:44 -050011201 clib_net_to_host_u64 (mp->seq_outbound),
11202 clib_net_to_host_u64 (mp->last_seq_inbound),
Matthew Smith48d32b42020-04-02 07:45:49 -050011203 clib_net_to_host_u64 (mp->replay_window), ntohl (mp->stat_index));
Matthew Smith28029532017-09-26 13:33:44 -050011204}
11205
11206#define vl_api_ipsec_sa_details_t_endian vl_noop_handler
11207#define vl_api_ipsec_sa_details_t_print vl_noop_handler
11208
11209static void vl_api_ipsec_sa_details_t_handler_json
11210 (vl_api_ipsec_sa_details_t * mp)
11211{
11212 vat_main_t *vam = &vat_main;
11213 vat_json_node_t *node = NULL;
Neale Ranns8d7c5022019-02-06 01:41:05 -080011214 vl_api_ipsec_sad_flags_t flags;
Matthew Smith28029532017-09-26 13:33:44 -050011215
11216 if (VAT_JSON_ARRAY != vam->json_tree.type)
11217 {
11218 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11219 vat_json_init_array (&vam->json_tree);
11220 }
11221 node = vat_json_array_add (&vam->json_tree);
11222
11223 vat_json_init_object (node);
Neale Ranns8d7c5022019-02-06 01:41:05 -080011224 vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
Matthew Smith28029532017-09-26 13:33:44 -050011225 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
Neale Ranns8d7c5022019-02-06 01:41:05 -080011226 vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
11227 vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
11228 vat_json_object_add_uint (node, "crypto_alg",
11229 ntohl (mp->entry.crypto_algorithm));
11230 vat_json_object_add_uint (node, "integ_alg",
11231 ntohl (mp->entry.integrity_algorithm));
11232 flags = ntohl (mp->entry.flags);
11233 vat_json_object_add_uint (node, "use_esn",
Damjan Marion1e3aa5e2019-03-28 10:58:59 +010011234 ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
Neale Ranns8d7c5022019-02-06 01:41:05 -080011235 vat_json_object_add_uint (node, "use_anti_replay",
11236 ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
11237 vat_json_object_add_uint (node, "is_tunnel",
11238 ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
11239 vat_json_object_add_uint (node, "is_tunnel_ip6",
11240 ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
11241 vat_json_object_add_uint (node, "udp_encap",
11242 ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
11243 vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
11244 mp->entry.crypto_key.length);
11245 vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
11246 mp->entry.integrity_key.length);
Neale Ranns5a8844b2019-04-16 07:15:35 +000011247 vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
11248 vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
Matthew Smith28029532017-09-26 13:33:44 -050011249 vat_json_object_add_uint (node, "replay_window",
11250 clib_net_to_host_u64 (mp->replay_window));
Matthew Smith48d32b42020-04-02 07:45:49 -050011251 vat_json_object_add_uint (node, "stat_index", ntohl (mp->stat_index));
Matthew Smith28029532017-09-26 13:33:44 -050011252}
11253
11254static int
11255api_ipsec_sa_dump (vat_main_t * vam)
11256{
11257 unformat_input_t *i = vam->input;
11258 vl_api_ipsec_sa_dump_t *mp;
11259 vl_api_control_ping_t *mp_ping;
11260 u32 sa_id = ~0;
11261 int ret;
11262
11263 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11264 {
11265 if (unformat (i, "sa_id %d", &sa_id))
11266 ;
11267 else
11268 {
11269 clib_warning ("parse error '%U'", format_unformat_error, i);
11270 return -99;
11271 }
11272 }
11273
11274 M (IPSEC_SA_DUMP, mp);
11275
11276 mp->sa_id = ntohl (sa_id);
11277
11278 S (mp);
11279
11280 /* Use a control ping for synchronization */
11281 M (CONTROL_PING, mp_ping);
11282 S (mp_ping);
11283
11284 W (ret);
11285 return ret;
11286}
11287
Matthew Smithb0972cb2017-05-02 16:20:41 -050011288static int
Damjan Marion7cd468a2016-12-19 23:05:39 +010011289api_get_first_msg_id (vat_main_t * vam)
11290{
11291 vl_api_get_first_msg_id_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011292 unformat_input_t *i = vam->input;
11293 u8 *name;
11294 u8 name_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011295 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011296
11297 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11298 {
11299 if (unformat (i, "client %s", &name))
11300 name_set = 1;
11301 else
11302 break;
11303 }
11304
11305 if (name_set == 0)
11306 {
11307 errmsg ("missing client name");
11308 return -99;
11309 }
11310 vec_add1 (name, 0);
11311
11312 if (vec_len (name) > 63)
11313 {
11314 errmsg ("client name too long");
11315 return -99;
11316 }
11317
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011318 M (GET_FIRST_MSG_ID, mp);
Ole Troan7adaa222019-08-27 15:05:27 +020011319 clib_memcpy (mp->name, name, vec_len (name));
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011320 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011321 W (ret);
11322 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011323}
11324
11325static int
11326api_cop_interface_enable_disable (vat_main_t * vam)
11327{
11328 unformat_input_t *line_input = vam->input;
11329 vl_api_cop_interface_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011330 u32 sw_if_index = ~0;
11331 u8 enable_disable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011332 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011333
11334 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11335 {
11336 if (unformat (line_input, "disable"))
11337 enable_disable = 0;
11338 if (unformat (line_input, "enable"))
11339 enable_disable = 1;
11340 else if (unformat (line_input, "%U", api_unformat_sw_if_index,
11341 vam, &sw_if_index))
11342 ;
11343 else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11344 ;
11345 else
11346 break;
11347 }
11348
11349 if (sw_if_index == ~0)
11350 {
11351 errmsg ("missing interface name or sw_if_index");
11352 return -99;
11353 }
11354
11355 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011356 M (COP_INTERFACE_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011357 mp->sw_if_index = ntohl (sw_if_index);
11358 mp->enable_disable = enable_disable;
11359
11360 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011361 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011362 /* Wait for the reply */
Jon Loeliger56c7b012017-02-01 12:31:41 -060011363 W (ret);
11364 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011365}
11366
11367static int
11368api_cop_whitelist_enable_disable (vat_main_t * vam)
11369{
11370 unformat_input_t *line_input = vam->input;
11371 vl_api_cop_whitelist_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011372 u32 sw_if_index = ~0;
11373 u8 ip4 = 0, ip6 = 0, default_cop = 0;
11374 u32 fib_id = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011375 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011376
11377 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11378 {
11379 if (unformat (line_input, "ip4"))
11380 ip4 = 1;
11381 else if (unformat (line_input, "ip6"))
11382 ip6 = 1;
11383 else if (unformat (line_input, "default"))
11384 default_cop = 1;
11385 else if (unformat (line_input, "%U", api_unformat_sw_if_index,
11386 vam, &sw_if_index))
11387 ;
11388 else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11389 ;
11390 else if (unformat (line_input, "fib-id %d", &fib_id))
11391 ;
11392 else
11393 break;
11394 }
11395
11396 if (sw_if_index == ~0)
11397 {
11398 errmsg ("missing interface name or sw_if_index");
11399 return -99;
11400 }
11401
11402 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011403 M (COP_WHITELIST_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011404 mp->sw_if_index = ntohl (sw_if_index);
11405 mp->fib_id = ntohl (fib_id);
11406 mp->ip4 = ip4;
11407 mp->ip6 = ip6;
11408 mp->default_cop = default_cop;
11409
11410 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011411 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011412 /* Wait for the reply */
Jon Loeliger56c7b012017-02-01 12:31:41 -060011413 W (ret);
11414 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011415}
11416
11417static int
11418api_get_node_graph (vat_main_t * vam)
11419{
11420 vl_api_get_node_graph_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011421 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011422
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011423 M (GET_NODE_GRAPH, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011424
11425 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011426 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011427 /* Wait for the reply */
Jon Loeliger56c7b012017-02-01 12:31:41 -060011428 W (ret);
11429 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011430}
11431
Damjan Marion7cd468a2016-12-19 23:05:39 +010011432static int
11433api_af_packet_create (vat_main_t * vam)
11434{
11435 unformat_input_t *i = vam->input;
11436 vl_api_af_packet_create_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011437 u8 *host_if_name = 0;
11438 u8 hw_addr[6];
11439 u8 random_hw_addr = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011440 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011441
Dave Barachb7b92992018-10-17 10:38:51 -040011442 clib_memset (hw_addr, 0, sizeof (hw_addr));
Damjan Marion7cd468a2016-12-19 23:05:39 +010011443
11444 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11445 {
11446 if (unformat (i, "name %s", &host_if_name))
11447 vec_add1 (host_if_name, 0);
11448 else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
11449 random_hw_addr = 0;
11450 else
11451 break;
11452 }
11453
11454 if (!vec_len (host_if_name))
11455 {
11456 errmsg ("host-interface name must be specified");
11457 return -99;
11458 }
11459
11460 if (vec_len (host_if_name) > 64)
11461 {
11462 errmsg ("host-interface name too long");
11463 return -99;
11464 }
11465
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011466 M (AF_PACKET_CREATE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011467
11468 clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
11469 clib_memcpy (mp->hw_addr, hw_addr, 6);
11470 mp->use_random_hw_addr = random_hw_addr;
11471 vec_free (host_if_name);
11472
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011473 S (mp);
Dave Baracha1a093d2017-03-02 13:13:23 -050011474
11475 /* *INDENT-OFF* */
11476 W2 (ret,
11477 ({
11478 if (ret == 0)
11479 fprintf (vam->ofp ? vam->ofp : stderr,
11480 " new sw_if_index = %d\n", vam->sw_if_index);
11481 }));
11482 /* *INDENT-ON* */
Jon Loeliger56c7b012017-02-01 12:31:41 -060011483 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011484}
11485
11486static int
11487api_af_packet_delete (vat_main_t * vam)
11488{
11489 unformat_input_t *i = vam->input;
11490 vl_api_af_packet_delete_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011491 u8 *host_if_name = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011492 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011493
11494 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11495 {
11496 if (unformat (i, "name %s", &host_if_name))
11497 vec_add1 (host_if_name, 0);
11498 else
11499 break;
11500 }
11501
11502 if (!vec_len (host_if_name))
11503 {
11504 errmsg ("host-interface name must be specified");
11505 return -99;
11506 }
11507
11508 if (vec_len (host_if_name) > 64)
11509 {
11510 errmsg ("host-interface name too long");
11511 return -99;
11512 }
11513
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011514 M (AF_PACKET_DELETE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011515
11516 clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
11517 vec_free (host_if_name);
11518
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011519 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011520 W (ret);
11521 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011522}
11523
Mohsin Kazmi04e0bb22018-05-28 18:55:37 +020011524static void vl_api_af_packet_details_t_handler
11525 (vl_api_af_packet_details_t * mp)
11526{
11527 vat_main_t *vam = &vat_main;
11528
11529 print (vam->ofp, "%-16s %d",
11530 mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
11531}
11532
11533static void vl_api_af_packet_details_t_handler_json
11534 (vl_api_af_packet_details_t * mp)
11535{
11536 vat_main_t *vam = &vat_main;
11537 vat_json_node_t *node = NULL;
11538
11539 if (VAT_JSON_ARRAY != vam->json_tree.type)
11540 {
11541 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11542 vat_json_init_array (&vam->json_tree);
11543 }
11544 node = vat_json_array_add (&vam->json_tree);
11545
11546 vat_json_init_object (node);
11547 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11548 vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
11549}
11550
11551static int
11552api_af_packet_dump (vat_main_t * vam)
11553{
11554 vl_api_af_packet_dump_t *mp;
11555 vl_api_control_ping_t *mp_ping;
11556 int ret;
11557
11558 print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
11559 /* Get list of tap interfaces */
11560 M (AF_PACKET_DUMP, mp);
11561 S (mp);
11562
11563 /* Use a control ping for synchronization */
11564 MPING (CONTROL_PING, mp_ping);
11565 S (mp_ping);
11566
11567 W (ret);
11568 return ret;
11569}
11570
Damjan Marion7cd468a2016-12-19 23:05:39 +010011571static int
11572api_policer_add_del (vat_main_t * vam)
11573{
11574 unformat_input_t *i = vam->input;
11575 vl_api_policer_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011576 u8 is_add = 1;
11577 u8 *name = 0;
11578 u32 cir = 0;
11579 u32 eir = 0;
11580 u64 cb = 0;
11581 u64 eb = 0;
11582 u8 rate_type = 0;
11583 u8 round_type = 0;
11584 u8 type = 0;
11585 u8 color_aware = 0;
11586 sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011587 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011588
11589 conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
11590 conform_action.dscp = 0;
11591 exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
11592 exceed_action.dscp = 0;
11593 violate_action.action_type = SSE2_QOS_ACTION_DROP;
11594 violate_action.dscp = 0;
11595
11596 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11597 {
11598 if (unformat (i, "del"))
11599 is_add = 0;
11600 else if (unformat (i, "name %s", &name))
11601 vec_add1 (name, 0);
11602 else if (unformat (i, "cir %u", &cir))
11603 ;
11604 else if (unformat (i, "eir %u", &eir))
11605 ;
11606 else if (unformat (i, "cb %u", &cb))
11607 ;
11608 else if (unformat (i, "eb %u", &eb))
11609 ;
11610 else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
11611 &rate_type))
11612 ;
11613 else if (unformat (i, "round_type %U", unformat_policer_round_type,
11614 &round_type))
11615 ;
11616 else if (unformat (i, "type %U", unformat_policer_type, &type))
11617 ;
11618 else if (unformat (i, "conform_action %U", unformat_policer_action_type,
11619 &conform_action))
11620 ;
11621 else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
11622 &exceed_action))
11623 ;
11624 else if (unformat (i, "violate_action %U", unformat_policer_action_type,
11625 &violate_action))
11626 ;
11627 else if (unformat (i, "color-aware"))
11628 color_aware = 1;
11629 else
11630 break;
11631 }
11632
11633 if (!vec_len (name))
11634 {
11635 errmsg ("policer name must be specified");
11636 return -99;
11637 }
11638
11639 if (vec_len (name) > 64)
11640 {
11641 errmsg ("policer name too long");
11642 return -99;
11643 }
11644
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011645 M (POLICER_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011646
11647 clib_memcpy (mp->name, name, vec_len (name));
11648 vec_free (name);
11649 mp->is_add = is_add;
Neale Rannsd91c1db2017-07-31 02:30:50 -070011650 mp->cir = ntohl (cir);
11651 mp->eir = ntohl (eir);
11652 mp->cb = clib_net_to_host_u64 (cb);
11653 mp->eb = clib_net_to_host_u64 (eb);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011654 mp->rate_type = rate_type;
11655 mp->round_type = round_type;
11656 mp->type = type;
Jakub Grajciarcd01fb42020-03-02 13:16:53 +010011657 mp->conform_action.type = conform_action.action_type;
11658 mp->conform_action.dscp = conform_action.dscp;
11659 mp->exceed_action.type = exceed_action.action_type;
11660 mp->exceed_action.dscp = exceed_action.dscp;
11661 mp->violate_action.type = violate_action.action_type;
11662 mp->violate_action.dscp = violate_action.dscp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011663 mp->color_aware = color_aware;
11664
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011665 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011666 W (ret);
11667 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011668}
11669
11670static int
11671api_policer_dump (vat_main_t * vam)
11672{
11673 unformat_input_t *i = vam->input;
11674 vl_api_policer_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011675 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011676 u8 *match_name = 0;
11677 u8 match_name_valid = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011678 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011679
11680 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11681 {
11682 if (unformat (i, "name %s", &match_name))
11683 {
11684 vec_add1 (match_name, 0);
11685 match_name_valid = 1;
11686 }
11687 else
11688 break;
11689 }
11690
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011691 M (POLICER_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011692 mp->match_name_valid = match_name_valid;
11693 clib_memcpy (mp->match_name, match_name, vec_len (match_name));
11694 vec_free (match_name);
11695 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011696 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011697
11698 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040011699 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011700 S (mp_ping);
11701
Damjan Marion7cd468a2016-12-19 23:05:39 +010011702 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060011703 W (ret);
11704 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011705}
11706
11707static int
11708api_policer_classify_set_interface (vat_main_t * vam)
11709{
11710 unformat_input_t *i = vam->input;
11711 vl_api_policer_classify_set_interface_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011712 u32 sw_if_index;
11713 int sw_if_index_set;
11714 u32 ip4_table_index = ~0;
11715 u32 ip6_table_index = ~0;
11716 u32 l2_table_index = ~0;
11717 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011718 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011719
11720 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11721 {
11722 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11723 sw_if_index_set = 1;
11724 else if (unformat (i, "sw_if_index %d", &sw_if_index))
11725 sw_if_index_set = 1;
11726 else if (unformat (i, "del"))
11727 is_add = 0;
11728 else if (unformat (i, "ip4-table %d", &ip4_table_index))
11729 ;
11730 else if (unformat (i, "ip6-table %d", &ip6_table_index))
11731 ;
11732 else if (unformat (i, "l2-table %d", &l2_table_index))
11733 ;
11734 else
11735 {
11736 clib_warning ("parse error '%U'", format_unformat_error, i);
11737 return -99;
11738 }
11739 }
11740
11741 if (sw_if_index_set == 0)
11742 {
11743 errmsg ("missing interface name or sw_if_index");
11744 return -99;
11745 }
11746
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011747 M (POLICER_CLASSIFY_SET_INTERFACE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011748
11749 mp->sw_if_index = ntohl (sw_if_index);
11750 mp->ip4_table_index = ntohl (ip4_table_index);
11751 mp->ip6_table_index = ntohl (ip6_table_index);
11752 mp->l2_table_index = ntohl (l2_table_index);
11753 mp->is_add = is_add;
11754
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011755 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011756 W (ret);
11757 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011758}
11759
11760static int
11761api_policer_classify_dump (vat_main_t * vam)
11762{
11763 unformat_input_t *i = vam->input;
11764 vl_api_policer_classify_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011765 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011766 u8 type = POLICER_CLASSIFY_N_TABLES;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011767 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011768
11769 if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
11770 ;
11771 else
11772 {
11773 errmsg ("classify table type must be specified");
11774 return -99;
11775 }
11776
11777 if (!vam->json_output)
11778 {
11779 print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
11780 }
11781
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011782 M (POLICER_CLASSIFY_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011783 mp->type = type;
11784 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011785 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011786
11787 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040011788 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011789 S (mp_ping);
11790
Damjan Marion7cd468a2016-12-19 23:05:39 +010011791 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060011792 W (ret);
11793 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011794}
11795
Neale Ranns097fa662018-05-01 05:17:55 -070011796static u8 *
11797format_fib_api_path_nh_proto (u8 * s, va_list * args)
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011798{
Neale Ranns097fa662018-05-01 05:17:55 -070011799 vl_api_fib_path_nh_proto_t proto =
11800 va_arg (*args, vl_api_fib_path_nh_proto_t);
11801
11802 switch (proto)
11803 {
11804 case FIB_API_PATH_NH_PROTO_IP4:
11805 s = format (s, "ip4");
11806 break;
11807 case FIB_API_PATH_NH_PROTO_IP6:
11808 s = format (s, "ip6");
11809 break;
11810 case FIB_API_PATH_NH_PROTO_MPLS:
11811 s = format (s, "mpls");
11812 break;
11813 case FIB_API_PATH_NH_PROTO_BIER:
11814 s = format (s, "bier");
11815 break;
11816 case FIB_API_PATH_NH_PROTO_ETHERNET:
11817 s = format (s, "ethernet");
11818 break;
11819 }
11820
11821 return (s);
11822}
11823
11824static u8 *
11825format_vl_api_ip_address_union (u8 * s, va_list * args)
11826{
Jakub Grajciar7dd63e52020-03-19 08:03:55 +010011827 vl_api_address_family_t af = va_arg (*args, int);
Neale Ranns097fa662018-05-01 05:17:55 -070011828 const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
11829
11830 switch (af)
11831 {
11832 case ADDRESS_IP4:
11833 s = format (s, "%U", format_ip4_address, u->ip4);
11834 break;
11835 case ADDRESS_IP6:
11836 s = format (s, "%U", format_ip6_address, u->ip6);
11837 break;
11838 }
11839 return (s);
11840}
11841
11842static u8 *
11843format_vl_api_fib_path_type (u8 * s, va_list * args)
11844{
11845 vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
11846
11847 switch (t)
11848 {
11849 case FIB_API_PATH_TYPE_NORMAL:
11850 s = format (s, "normal");
11851 break;
11852 case FIB_API_PATH_TYPE_LOCAL:
11853 s = format (s, "local");
11854 break;
11855 case FIB_API_PATH_TYPE_DROP:
11856 s = format (s, "drop");
11857 break;
11858 case FIB_API_PATH_TYPE_UDP_ENCAP:
11859 s = format (s, "udp-encap");
11860 break;
11861 case FIB_API_PATH_TYPE_BIER_IMP:
11862 s = format (s, "bier-imp");
11863 break;
11864 case FIB_API_PATH_TYPE_ICMP_UNREACH:
11865 s = format (s, "unreach");
11866 break;
11867 case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
11868 s = format (s, "prohibit");
11869 break;
11870 case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
11871 s = format (s, "src-lookup");
11872 break;
11873 case FIB_API_PATH_TYPE_DVR:
11874 s = format (s, "dvr");
11875 break;
11876 case FIB_API_PATH_TYPE_INTERFACE_RX:
11877 s = format (s, "interface-rx");
11878 break;
11879 case FIB_API_PATH_TYPE_CLASSIFY:
11880 s = format (s, "classify");
11881 break;
11882 }
11883
11884 return (s);
11885}
11886
11887static void
11888vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
11889{
11890 print (vam->ofp,
11891 " weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
11892 ntohl (fp->weight), ntohl (fp->sw_if_index),
11893 format_vl_api_fib_path_type, fp->type,
11894 format_fib_api_path_nh_proto, fp->proto,
11895 format_vl_api_ip_address_union, &fp->nh.address);
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011896}
11897
11898static void
11899vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
Neale Ranns31ed7442018-02-23 05:29:09 -080011900 vl_api_fib_path_t * fp)
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011901{
11902 struct in_addr ip4;
11903 struct in6_addr ip6;
11904
11905 vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
11906 vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
Neale Ranns097fa662018-05-01 05:17:55 -070011907 vat_json_object_add_uint (node, "type", fp->type);
11908 vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
11909 if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011910 {
Neale Ranns097fa662018-05-01 05:17:55 -070011911 clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011912 vat_json_object_add_ip4 (node, "next_hop", ip4);
11913 }
Dave Barachc35f3e82020-04-02 10:44:09 -040011914 else if (fp->proto == FIB_API_PATH_NH_PROTO_IP6)
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011915 {
Neale Ranns097fa662018-05-01 05:17:55 -070011916 clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011917 vat_json_object_add_ip6 (node, "next_hop", ip6);
11918 }
11919}
11920
11921static void
11922vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010011923{
11924 vat_main_t *vam = &vat_main;
Neale Ranns097fa662018-05-01 05:17:55 -070011925 int count = ntohl (mp->mt_tunnel.mt_n_paths);
Neale Ranns31ed7442018-02-23 05:29:09 -080011926 vl_api_fib_path_t *fp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011927 i32 i;
11928
Neale Ranns097fa662018-05-01 05:17:55 -070011929 print (vam->ofp, "sw_if_index %d via:",
11930 ntohl (mp->mt_tunnel.mt_sw_if_index));
11931 fp = mp->mt_tunnel.mt_paths;
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011932 for (i = 0; i < count; i++)
Damjan Marion7cd468a2016-12-19 23:05:39 +010011933 {
Neale Ranns097fa662018-05-01 05:17:55 -070011934 vl_api_fib_path_print (vam, fp);
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011935 fp++;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011936 }
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011937
Damjan Marion7cd468a2016-12-19 23:05:39 +010011938 print (vam->ofp, "");
11939}
11940
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011941#define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
11942#define vl_api_mpls_tunnel_details_t_print vl_noop_handler
11943
11944static void
11945vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010011946{
11947 vat_main_t *vam = &vat_main;
11948 vat_json_node_t *node = NULL;
Neale Ranns097fa662018-05-01 05:17:55 -070011949 int count = ntohl (mp->mt_tunnel.mt_n_paths);
Neale Ranns31ed7442018-02-23 05:29:09 -080011950 vl_api_fib_path_t *fp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011951 i32 i;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011952
11953 if (VAT_JSON_ARRAY != vam->json_tree.type)
11954 {
11955 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11956 vat_json_init_array (&vam->json_tree);
11957 }
11958 node = vat_json_array_add (&vam->json_tree);
11959
11960 vat_json_init_object (node);
Neale Ranns097fa662018-05-01 05:17:55 -070011961 vat_json_object_add_uint (node, "sw_if_index",
11962 ntohl (mp->mt_tunnel.mt_sw_if_index));
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011963
Neale Ranns097fa662018-05-01 05:17:55 -070011964 vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011965
Neale Ranns097fa662018-05-01 05:17:55 -070011966 fp = mp->mt_tunnel.mt_paths;
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011967 for (i = 0; i < count; i++)
Damjan Marion7cd468a2016-12-19 23:05:39 +010011968 {
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011969 vl_api_mpls_fib_path_json_print (node, fp);
11970 fp++;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011971 }
11972}
11973
11974static int
11975api_mpls_tunnel_dump (vat_main_t * vam)
11976{
11977 vl_api_mpls_tunnel_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011978 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011979 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011980
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011981 M (MPLS_TUNNEL_DUMP, mp);
Neale Ranns097fa662018-05-01 05:17:55 -070011982
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011983 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011984
11985 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040011986 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011987 S (mp_ping);
11988
Jon Loeliger56c7b012017-02-01 12:31:41 -060011989 W (ret);
11990 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011991}
11992
Neale Ranns097fa662018-05-01 05:17:55 -070011993#define vl_api_mpls_table_details_t_endian vl_noop_handler
11994#define vl_api_mpls_table_details_t_print vl_noop_handler
Damjan Marion7cd468a2016-12-19 23:05:39 +010011995
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011996
Damjan Marion7cd468a2016-12-19 23:05:39 +010011997static void
Neale Ranns097fa662018-05-01 05:17:55 -070011998vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010011999{
12000 vat_main_t *vam = &vat_main;
Neale Ranns097fa662018-05-01 05:17:55 -070012001
12002 print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
12003}
12004
12005static void vl_api_mpls_table_details_t_handler_json
12006 (vl_api_mpls_table_details_t * mp)
12007{
12008 vat_main_t *vam = &vat_main;
12009 vat_json_node_t *node = NULL;
12010
12011 if (VAT_JSON_ARRAY != vam->json_tree.type)
12012 {
12013 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12014 vat_json_init_array (&vam->json_tree);
12015 }
12016 node = vat_json_array_add (&vam->json_tree);
12017
12018 vat_json_init_object (node);
12019 vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
12020}
12021
12022static int
12023api_mpls_table_dump (vat_main_t * vam)
12024{
12025 vl_api_mpls_table_dump_t *mp;
12026 vl_api_control_ping_t *mp_ping;
12027 int ret;
12028
12029 M (MPLS_TABLE_DUMP, mp);
12030 S (mp);
12031
12032 /* Use a control ping for synchronization */
12033 MPING (CONTROL_PING, mp_ping);
12034 S (mp_ping);
12035
12036 W (ret);
12037 return ret;
12038}
12039
12040#define vl_api_mpls_route_details_t_endian vl_noop_handler
12041#define vl_api_mpls_route_details_t_print vl_noop_handler
12042
12043static void
12044vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
12045{
12046 vat_main_t *vam = &vat_main;
Dave Barach4bda2d92019-07-03 15:21:50 -040012047 int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
Neale Ranns31ed7442018-02-23 05:29:09 -080012048 vl_api_fib_path_t *fp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012049 int i;
12050
12051 print (vam->ofp,
12052 "table-id %d, label %u, ess_bit %u",
Neale Ranns097fa662018-05-01 05:17:55 -070012053 ntohl (mp->mr_route.mr_table_id),
12054 ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
12055 fp = mp->mr_route.mr_paths;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012056 for (i = 0; i < count; i++)
12057 {
Neale Ranns097fa662018-05-01 05:17:55 -070012058 vl_api_fib_path_print (vam, fp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012059 fp++;
12060 }
12061}
12062
Neale Ranns097fa662018-05-01 05:17:55 -070012063static void vl_api_mpls_route_details_t_handler_json
12064 (vl_api_mpls_route_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012065{
12066 vat_main_t *vam = &vat_main;
Dave Barach4bda2d92019-07-03 15:21:50 -040012067 int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012068 vat_json_node_t *node = NULL;
Neale Ranns31ed7442018-02-23 05:29:09 -080012069 vl_api_fib_path_t *fp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012070 int i;
12071
12072 if (VAT_JSON_ARRAY != vam->json_tree.type)
12073 {
12074 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12075 vat_json_init_array (&vam->json_tree);
12076 }
12077 node = vat_json_array_add (&vam->json_tree);
12078
12079 vat_json_init_object (node);
Neale Ranns097fa662018-05-01 05:17:55 -070012080 vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
12081 vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
12082 vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
Damjan Marion7cd468a2016-12-19 23:05:39 +010012083 vat_json_object_add_uint (node, "path_count", count);
Neale Ranns097fa662018-05-01 05:17:55 -070012084 fp = mp->mr_route.mr_paths;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012085 for (i = 0; i < count; i++)
12086 {
Neale Ranns0f26c5a2017-03-01 15:12:11 -080012087 vl_api_mpls_fib_path_json_print (node, fp);
12088 fp++;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012089 }
12090}
12091
12092static int
Neale Ranns097fa662018-05-01 05:17:55 -070012093api_mpls_route_dump (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012094{
Neale Ranns097fa662018-05-01 05:17:55 -070012095 unformat_input_t *input = vam->input;
12096 vl_api_mpls_route_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012097 vl_api_control_ping_t *mp_ping;
Neale Ranns097fa662018-05-01 05:17:55 -070012098 u32 table_id;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012099 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012100
Neale Ranns097fa662018-05-01 05:17:55 -070012101 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12102 {
12103 if (unformat (input, "table_id %d", &table_id))
12104 ;
12105 else
12106 break;
12107 }
12108 if (table_id == ~0)
12109 {
12110 errmsg ("missing table id");
12111 return -99;
12112 }
12113
12114 M (MPLS_ROUTE_DUMP, mp);
12115
12116 mp->table.mt_table_id = ntohl (table_id);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012117 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012118
12119 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040012120 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012121 S (mp_ping);
12122
Jon Loeliger56c7b012017-02-01 12:31:41 -060012123 W (ret);
12124 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012125}
12126
Neale Ranns097fa662018-05-01 05:17:55 -070012127#define vl_api_ip_table_details_t_endian vl_noop_handler
12128#define vl_api_ip_table_details_t_print vl_noop_handler
Damjan Marion7cd468a2016-12-19 23:05:39 +010012129
12130static void
Neale Ranns097fa662018-05-01 05:17:55 -070012131vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012132{
12133 vat_main_t *vam = &vat_main;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012134
12135 print (vam->ofp,
Neale Ranns097fa662018-05-01 05:17:55 -070012136 "%s; table-id %d, prefix %U/%d",
12137 mp->table.name, ntohl (mp->table.table_id));
Damjan Marion7cd468a2016-12-19 23:05:39 +010012138}
12139
Neale Ranns097fa662018-05-01 05:17:55 -070012140
12141static void vl_api_ip_table_details_t_handler_json
12142 (vl_api_ip_table_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012143{
12144 vat_main_t *vam = &vat_main;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012145 vat_json_node_t *node = NULL;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012146
12147 if (VAT_JSON_ARRAY != vam->json_tree.type)
12148 {
12149 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12150 vat_json_init_array (&vam->json_tree);
12151 }
12152 node = vat_json_array_add (&vam->json_tree);
12153
12154 vat_json_init_object (node);
Neale Ranns097fa662018-05-01 05:17:55 -070012155 vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
Damjan Marion7cd468a2016-12-19 23:05:39 +010012156}
12157
12158static int
Neale Ranns097fa662018-05-01 05:17:55 -070012159api_ip_table_dump (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012160{
Neale Ranns097fa662018-05-01 05:17:55 -070012161 vl_api_ip_table_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012162 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012163 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012164
Neale Ranns097fa662018-05-01 05:17:55 -070012165 M (IP_TABLE_DUMP, mp);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012166 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012167
12168 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040012169 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012170 S (mp_ping);
12171
Jon Loeliger56c7b012017-02-01 12:31:41 -060012172 W (ret);
12173 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012174}
12175
Neale Ranns5a8123b2017-01-26 01:18:23 -080012176static int
Neale Ranns097fa662018-05-01 05:17:55 -070012177api_ip_mtable_dump (vat_main_t * vam)
Neale Ranns5a8123b2017-01-26 01:18:23 -080012178{
Neale Ranns097fa662018-05-01 05:17:55 -070012179 vl_api_ip_mtable_dump_t *mp;
Neale Ranns5a8123b2017-01-26 01:18:23 -080012180 vl_api_control_ping_t *mp_ping;
12181 int ret;
12182
Neale Ranns097fa662018-05-01 05:17:55 -070012183 M (IP_MTABLE_DUMP, mp);
12184 S (mp);
12185
12186 /* Use a control ping for synchronization */
12187 MPING (CONTROL_PING, mp_ping);
12188 S (mp_ping);
12189
12190 W (ret);
12191 return ret;
12192}
12193
12194static int
12195api_ip_mroute_dump (vat_main_t * vam)
12196{
12197 unformat_input_t *input = vam->input;
12198 vl_api_control_ping_t *mp_ping;
12199 vl_api_ip_mroute_dump_t *mp;
12200 int ret, is_ip6;
12201 u32 table_id;
12202
12203 is_ip6 = 0;
12204 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12205 {
12206 if (unformat (input, "table_id %d", &table_id))
12207 ;
12208 else if (unformat (input, "ip6"))
12209 is_ip6 = 1;
12210 else if (unformat (input, "ip4"))
12211 is_ip6 = 0;
12212 else
12213 break;
12214 }
12215 if (table_id == ~0)
12216 {
12217 errmsg ("missing table id");
12218 return -99;
12219 }
12220
12221 M (IP_MROUTE_DUMP, mp);
12222 mp->table.table_id = table_id;
12223 mp->table.is_ip6 = is_ip6;
Neale Ranns5a8123b2017-01-26 01:18:23 -080012224 S (mp);
12225
12226 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040012227 MPING (CONTROL_PING, mp_ping);
Neale Ranns5a8123b2017-01-26 01:18:23 -080012228 S (mp_ping);
12229
12230 W (ret);
12231 return ret;
12232}
12233
Neale Ranns097fa662018-05-01 05:17:55 -070012234#define vl_api_ip_route_details_t_endian vl_noop_handler
12235#define vl_api_ip_route_details_t_print vl_noop_handler
Damjan Marion7cd468a2016-12-19 23:05:39 +010012236
12237static void
Neale Ranns097fa662018-05-01 05:17:55 -070012238vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012239{
12240 vat_main_t *vam = &vat_main;
Neale Ranns097fa662018-05-01 05:17:55 -070012241 u8 count = mp->route.n_paths;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012242 vl_api_fib_path_t *fp;
12243 int i;
12244
12245 print (vam->ofp,
Neale Ranns097fa662018-05-01 05:17:55 -070012246 "table-id %d, prefix %U/%d",
12247 ntohl (mp->route.table_id),
Paul Vinciguerraab055082019-06-06 14:07:55 -040012248 format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012249 for (i = 0; i < count; i++)
12250 {
Neale Ranns097fa662018-05-01 05:17:55 -070012251 fp = &mp->route.paths[i];
12252
12253 vl_api_fib_path_print (vam, fp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012254 fp++;
12255 }
12256}
12257
Neale Ranns097fa662018-05-01 05:17:55 -070012258static void vl_api_ip_route_details_t_handler_json
12259 (vl_api_ip_route_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012260{
12261 vat_main_t *vam = &vat_main;
Neale Ranns097fa662018-05-01 05:17:55 -070012262 u8 count = mp->route.n_paths;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012263 vat_json_node_t *node = NULL;
12264 struct in_addr ip4;
12265 struct in6_addr ip6;
12266 vl_api_fib_path_t *fp;
12267 int i;
12268
12269 if (VAT_JSON_ARRAY != vam->json_tree.type)
12270 {
12271 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12272 vat_json_init_array (&vam->json_tree);
12273 }
12274 node = vat_json_array_add (&vam->json_tree);
12275
12276 vat_json_init_object (node);
Neale Ranns097fa662018-05-01 05:17:55 -070012277 vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
12278 if (ADDRESS_IP6 == mp->route.prefix.address.af)
12279 {
12280 clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
12281 vat_json_object_add_ip6 (node, "prefix", ip6);
12282 }
12283 else
12284 {
12285 clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
12286 vat_json_object_add_ip4 (node, "prefix", ip4);
12287 }
Paul Vinciguerraab055082019-06-06 14:07:55 -040012288 vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012289 vat_json_object_add_uint (node, "path_count", count);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012290 for (i = 0; i < count; i++)
12291 {
Neale Ranns097fa662018-05-01 05:17:55 -070012292 fp = &mp->route.paths[i];
12293 vl_api_mpls_fib_path_json_print (node, fp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012294 }
12295}
12296
12297static int
Neale Ranns097fa662018-05-01 05:17:55 -070012298api_ip_route_dump (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012299{
Neale Ranns097fa662018-05-01 05:17:55 -070012300 unformat_input_t *input = vam->input;
12301 vl_api_ip_route_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012302 vl_api_control_ping_t *mp_ping;
Neale Ranns097fa662018-05-01 05:17:55 -070012303 u32 table_id;
12304 u8 is_ip6;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012305 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012306
Neale Ranns097fa662018-05-01 05:17:55 -070012307 is_ip6 = 0;
12308 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12309 {
12310 if (unformat (input, "table_id %d", &table_id))
12311 ;
12312 else if (unformat (input, "ip6"))
12313 is_ip6 = 1;
12314 else if (unformat (input, "ip4"))
12315 is_ip6 = 0;
12316 else
12317 break;
12318 }
12319 if (table_id == ~0)
12320 {
12321 errmsg ("missing table id");
12322 return -99;
12323 }
Damjan Marion7cd468a2016-12-19 23:05:39 +010012324
Neale Ranns097fa662018-05-01 05:17:55 -070012325 M (IP_ROUTE_DUMP, mp);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012326
Neale Ranns097fa662018-05-01 05:17:55 -070012327 mp->table.table_id = table_id;
12328 mp->table.is_ip6 = is_ip6;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012329
Neale Ranns5a8123b2017-01-26 01:18:23 -080012330 S (mp);
12331
12332 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040012333 MPING (CONTROL_PING, mp_ping);
Neale Ranns5a8123b2017-01-26 01:18:23 -080012334 S (mp_ping);
12335
12336 W (ret);
12337 return ret;
12338}
12339
Damjan Marion7cd468a2016-12-19 23:05:39 +010012340int
12341api_classify_table_ids (vat_main_t * vam)
12342{
12343 vl_api_classify_table_ids_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012344 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012345
12346 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012347 M (CLASSIFY_TABLE_IDS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012348 mp->context = 0;
12349
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012350 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012351 W (ret);
12352 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012353}
12354
12355int
12356api_classify_table_by_interface (vat_main_t * vam)
12357{
12358 unformat_input_t *input = vam->input;
12359 vl_api_classify_table_by_interface_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012360
12361 u32 sw_if_index = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012362 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012363 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12364 {
12365 if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12366 ;
12367 else if (unformat (input, "sw_if_index %d", &sw_if_index))
12368 ;
12369 else
12370 break;
12371 }
12372 if (sw_if_index == ~0)
12373 {
12374 errmsg ("missing interface name or sw_if_index");
12375 return -99;
12376 }
12377
12378 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012379 M (CLASSIFY_TABLE_BY_INTERFACE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012380 mp->context = 0;
12381 mp->sw_if_index = ntohl (sw_if_index);
12382
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012383 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012384 W (ret);
12385 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012386}
12387
12388int
12389api_classify_table_info (vat_main_t * vam)
12390{
12391 unformat_input_t *input = vam->input;
12392 vl_api_classify_table_info_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012393
12394 u32 table_id = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012395 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012396 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12397 {
12398 if (unformat (input, "table_id %d", &table_id))
12399 ;
12400 else
12401 break;
12402 }
12403 if (table_id == ~0)
12404 {
12405 errmsg ("missing table id");
12406 return -99;
12407 }
12408
12409 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012410 M (CLASSIFY_TABLE_INFO, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012411 mp->context = 0;
12412 mp->table_id = ntohl (table_id);
12413
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012414 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012415 W (ret);
12416 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012417}
12418
12419int
12420api_classify_session_dump (vat_main_t * vam)
12421{
12422 unformat_input_t *input = vam->input;
12423 vl_api_classify_session_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012424 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012425
12426 u32 table_id = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012427 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012428 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12429 {
12430 if (unformat (input, "table_id %d", &table_id))
12431 ;
12432 else
12433 break;
12434 }
12435 if (table_id == ~0)
12436 {
12437 errmsg ("missing table id");
12438 return -99;
12439 }
12440
12441 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012442 M (CLASSIFY_SESSION_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012443 mp->context = 0;
12444 mp->table_id = ntohl (table_id);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012445 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012446
12447 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040012448 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012449 S (mp_ping);
12450
Jon Loeliger56c7b012017-02-01 12:31:41 -060012451 W (ret);
12452 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012453}
12454
12455static void
12456vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
12457{
12458 vat_main_t *vam = &vat_main;
12459
12460 print (vam->ofp, "collector_address %U, collector_port %d, "
12461 "src_address %U, vrf_id %d, path_mtu %u, "
12462 "template_interval %u, udp_checksum %d",
12463 format_ip4_address, mp->collector_address,
12464 ntohs (mp->collector_port),
12465 format_ip4_address, mp->src_address,
12466 ntohl (mp->vrf_id), ntohl (mp->path_mtu),
12467 ntohl (mp->template_interval), mp->udp_checksum);
12468
12469 vam->retval = 0;
12470 vam->result_ready = 1;
12471}
12472
12473static void
12474 vl_api_ipfix_exporter_details_t_handler_json
12475 (vl_api_ipfix_exporter_details_t * mp)
12476{
12477 vat_main_t *vam = &vat_main;
12478 vat_json_node_t node;
12479 struct in_addr collector_address;
12480 struct in_addr src_address;
12481
12482 vat_json_init_object (&node);
12483 clib_memcpy (&collector_address, &mp->collector_address,
12484 sizeof (collector_address));
12485 vat_json_object_add_ip4 (&node, "collector_address", collector_address);
12486 vat_json_object_add_uint (&node, "collector_port",
12487 ntohs (mp->collector_port));
12488 clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
12489 vat_json_object_add_ip4 (&node, "src_address", src_address);
12490 vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
12491 vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
12492 vat_json_object_add_uint (&node, "template_interval",
12493 ntohl (mp->template_interval));
12494 vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
12495
12496 vat_json_print (vam->ofp, &node);
12497 vat_json_free (&node);
12498 vam->retval = 0;
12499 vam->result_ready = 1;
12500}
12501
12502int
12503api_ipfix_exporter_dump (vat_main_t * vam)
12504{
12505 vl_api_ipfix_exporter_dump_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012506 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012507
12508 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012509 M (IPFIX_EXPORTER_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012510 mp->context = 0;
12511
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012512 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012513 W (ret);
12514 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012515}
12516
12517static int
12518api_ipfix_classify_stream_dump (vat_main_t * vam)
12519{
12520 vl_api_ipfix_classify_stream_dump_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012521 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012522
12523 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012524 M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012525 mp->context = 0;
12526
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012527 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012528 W (ret);
12529 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012530 /* NOTREACHED */
12531 return 0;
12532}
12533
12534static void
12535 vl_api_ipfix_classify_stream_details_t_handler
12536 (vl_api_ipfix_classify_stream_details_t * mp)
12537{
12538 vat_main_t *vam = &vat_main;
12539 print (vam->ofp, "domain_id %d, src_port %d",
12540 ntohl (mp->domain_id), ntohs (mp->src_port));
12541 vam->retval = 0;
12542 vam->result_ready = 1;
12543}
12544
12545static void
12546 vl_api_ipfix_classify_stream_details_t_handler_json
12547 (vl_api_ipfix_classify_stream_details_t * mp)
12548{
12549 vat_main_t *vam = &vat_main;
12550 vat_json_node_t node;
12551
12552 vat_json_init_object (&node);
12553 vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
12554 vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
12555
12556 vat_json_print (vam->ofp, &node);
12557 vat_json_free (&node);
12558 vam->retval = 0;
12559 vam->result_ready = 1;
12560}
12561
12562static int
12563api_ipfix_classify_table_dump (vat_main_t * vam)
12564{
12565 vl_api_ipfix_classify_table_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012566 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012567 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012568
12569 if (!vam->json_output)
12570 {
12571 print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
12572 "transport_protocol");
12573 }
12574
12575 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012576 M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012577
12578 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012579 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012580
12581 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040012582 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012583 S (mp_ping);
12584
Jon Loeliger56c7b012017-02-01 12:31:41 -060012585 W (ret);
12586 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012587}
12588
12589static void
12590 vl_api_ipfix_classify_table_details_t_handler
12591 (vl_api_ipfix_classify_table_details_t * mp)
12592{
12593 vat_main_t *vam = &vat_main;
12594 print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
12595 mp->transport_protocol);
12596}
12597
12598static void
12599 vl_api_ipfix_classify_table_details_t_handler_json
12600 (vl_api_ipfix_classify_table_details_t * mp)
12601{
12602 vat_json_node_t *node = NULL;
12603 vat_main_t *vam = &vat_main;
12604
12605 if (VAT_JSON_ARRAY != vam->json_tree.type)
12606 {
12607 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12608 vat_json_init_array (&vam->json_tree);
12609 }
12610
12611 node = vat_json_array_add (&vam->json_tree);
12612 vat_json_init_object (node);
12613
12614 vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
12615 vat_json_object_add_uint (node, "ip_version", mp->ip_version);
12616 vat_json_object_add_uint (node, "transport_protocol",
12617 mp->transport_protocol);
12618}
12619
12620static int
12621api_sw_interface_span_enable_disable (vat_main_t * vam)
12622{
12623 unformat_input_t *i = vam->input;
12624 vl_api_sw_interface_span_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012625 u32 src_sw_if_index = ~0;
12626 u32 dst_sw_if_index = ~0;
12627 u8 state = 3;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012628 int ret;
Eyal Bari001fd402017-07-16 09:34:53 +030012629 u8 is_l2 = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012630
12631 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12632 {
12633 if (unformat
12634 (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
12635 ;
12636 else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
12637 ;
12638 else
12639 if (unformat
12640 (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
12641 ;
12642 else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
12643 ;
12644 else if (unformat (i, "disable"))
12645 state = 0;
12646 else if (unformat (i, "rx"))
12647 state = 1;
12648 else if (unformat (i, "tx"))
12649 state = 2;
12650 else if (unformat (i, "both"))
12651 state = 3;
Eyal Bari001fd402017-07-16 09:34:53 +030012652 else if (unformat (i, "l2"))
12653 is_l2 = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012654 else
12655 break;
12656 }
12657
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012658 M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012659
12660 mp->sw_if_index_from = htonl (src_sw_if_index);
12661 mp->sw_if_index_to = htonl (dst_sw_if_index);
12662 mp->state = state;
Eyal Bari001fd402017-07-16 09:34:53 +030012663 mp->is_l2 = is_l2;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012664
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012665 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012666 W (ret);
12667 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012668}
12669
12670static void
12671vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
12672 * mp)
12673{
12674 vat_main_t *vam = &vat_main;
12675 u8 *sw_if_from_name = 0;
12676 u8 *sw_if_to_name = 0;
12677 u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
12678 u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
12679 char *states[] = { "none", "rx", "tx", "both" };
12680 hash_pair_t *p;
12681
12682 /* *INDENT-OFF* */
12683 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
12684 ({
12685 if ((u32) p->value[0] == sw_if_index_from)
12686 {
12687 sw_if_from_name = (u8 *)(p->key);
12688 if (sw_if_to_name)
12689 break;
12690 }
12691 if ((u32) p->value[0] == sw_if_index_to)
12692 {
12693 sw_if_to_name = (u8 *)(p->key);
12694 if (sw_if_from_name)
12695 break;
12696 }
12697 }));
12698 /* *INDENT-ON* */
Jon Loeliger179ab362018-03-12 14:50:08 -050012699 print (vam->ofp, "%20s => %20s (%s) %s",
12700 sw_if_from_name, sw_if_to_name, states[mp->state],
12701 mp->is_l2 ? "l2" : "device");
Damjan Marion7cd468a2016-12-19 23:05:39 +010012702}
12703
12704static void
12705 vl_api_sw_interface_span_details_t_handler_json
12706 (vl_api_sw_interface_span_details_t * mp)
12707{
12708 vat_main_t *vam = &vat_main;
12709 vat_json_node_t *node = NULL;
12710 u8 *sw_if_from_name = 0;
12711 u8 *sw_if_to_name = 0;
12712 u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
12713 u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
12714 hash_pair_t *p;
12715
12716 /* *INDENT-OFF* */
12717 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
12718 ({
12719 if ((u32) p->value[0] == sw_if_index_from)
12720 {
12721 sw_if_from_name = (u8 *)(p->key);
12722 if (sw_if_to_name)
12723 break;
12724 }
12725 if ((u32) p->value[0] == sw_if_index_to)
12726 {
12727 sw_if_to_name = (u8 *)(p->key);
12728 if (sw_if_from_name)
12729 break;
12730 }
12731 }));
12732 /* *INDENT-ON* */
12733
12734 if (VAT_JSON_ARRAY != vam->json_tree.type)
12735 {
12736 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12737 vat_json_init_array (&vam->json_tree);
12738 }
12739 node = vat_json_array_add (&vam->json_tree);
12740
12741 vat_json_init_object (node);
12742 vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
12743 vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
12744 vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
Neale Ranns05b2bf22017-01-30 06:44:58 -080012745 if (0 != sw_if_to_name)
12746 {
12747 vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
12748 }
Damjan Marion7cd468a2016-12-19 23:05:39 +010012749 vat_json_object_add_uint (node, "state", mp->state);
Jon Loeliger179ab362018-03-12 14:50:08 -050012750 vat_json_object_add_uint (node, "is-l2", mp->is_l2);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012751}
12752
12753static int
12754api_sw_interface_span_dump (vat_main_t * vam)
12755{
Eyal Bari5b311202017-07-31 13:12:30 +030012756 unformat_input_t *input = vam->input;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012757 vl_api_sw_interface_span_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012758 vl_api_control_ping_t *mp_ping;
Eyal Bari5b311202017-07-31 13:12:30 +030012759 u8 is_l2 = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012760 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012761
Eyal Bari5b311202017-07-31 13:12:30 +030012762 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12763 {
12764 if (unformat (input, "l2"))
12765 is_l2 = 1;
12766 else
12767 break;
12768 }
12769
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012770 M (SW_INTERFACE_SPAN_DUMP, mp);
Eyal Bari5b311202017-07-31 13:12:30 +030012771 mp->is_l2 = is_l2;
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012772 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012773
12774 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040012775 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012776 S (mp_ping);
12777
Jon Loeliger56c7b012017-02-01 12:31:41 -060012778 W (ret);
12779 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012780}
12781
12782int
12783api_pg_create_interface (vat_main_t * vam)
12784{
12785 unformat_input_t *input = vam->input;
12786 vl_api_pg_create_interface_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012787
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +020012788 u32 if_id = ~0, gso_size = 0;
12789 u8 gso_enabled = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012790 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012791 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12792 {
12793 if (unformat (input, "if_id %d", &if_id))
12794 ;
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +020012795 else if (unformat (input, "gso-enabled"))
12796 {
12797 gso_enabled = 1;
12798 if (unformat (input, "gso-size %u", &gso_size))
12799 ;
12800 else
12801 {
12802 errmsg ("missing gso-size");
12803 return -99;
12804 }
12805 }
Damjan Marion7cd468a2016-12-19 23:05:39 +010012806 else
12807 break;
12808 }
12809 if (if_id == ~0)
12810 {
12811 errmsg ("missing pg interface index");
12812 return -99;
12813 }
12814
12815 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012816 M (PG_CREATE_INTERFACE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012817 mp->context = 0;
12818 mp->interface_id = ntohl (if_id);
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +020012819 mp->gso_enabled = gso_enabled;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012820
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012821 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012822 W (ret);
12823 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012824}
12825
12826int
12827api_pg_capture (vat_main_t * vam)
12828{
12829 unformat_input_t *input = vam->input;
12830 vl_api_pg_capture_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012831
12832 u32 if_id = ~0;
12833 u8 enable = 1;
12834 u32 count = 1;
12835 u8 pcap_file_set = 0;
12836 u8 *pcap_file = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012837 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012838 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12839 {
12840 if (unformat (input, "if_id %d", &if_id))
12841 ;
12842 else if (unformat (input, "pcap %s", &pcap_file))
12843 pcap_file_set = 1;
12844 else if (unformat (input, "count %d", &count))
12845 ;
12846 else if (unformat (input, "disable"))
12847 enable = 0;
12848 else
12849 break;
12850 }
12851 if (if_id == ~0)
12852 {
12853 errmsg ("missing pg interface index");
12854 return -99;
12855 }
12856 if (pcap_file_set > 0)
12857 {
12858 if (vec_len (pcap_file) > 255)
12859 {
12860 errmsg ("pcap file name is too long");
12861 return -99;
12862 }
12863 }
12864
Damjan Marion7cd468a2016-12-19 23:05:39 +010012865 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012866 M (PG_CAPTURE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012867 mp->context = 0;
12868 mp->interface_id = ntohl (if_id);
12869 mp->is_enabled = enable;
12870 mp->count = ntohl (count);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012871 if (pcap_file_set != 0)
12872 {
Jakub Grajciardb863292020-01-30 14:14:15 +010012873 vl_api_vec_to_api_string (pcap_file, &mp->pcap_file_name);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012874 }
12875 vec_free (pcap_file);
12876
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012877 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012878 W (ret);
12879 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012880}
12881
12882int
12883api_pg_enable_disable (vat_main_t * vam)
12884{
12885 unformat_input_t *input = vam->input;
12886 vl_api_pg_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012887
12888 u8 enable = 1;
12889 u8 stream_name_set = 0;
12890 u8 *stream_name = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012891 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012892 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12893 {
12894 if (unformat (input, "stream %s", &stream_name))
12895 stream_name_set = 1;
12896 else if (unformat (input, "disable"))
12897 enable = 0;
12898 else
12899 break;
12900 }
12901
12902 if (stream_name_set > 0)
12903 {
12904 if (vec_len (stream_name) > 255)
12905 {
12906 errmsg ("stream name too long");
12907 return -99;
12908 }
12909 }
12910
Damjan Marion7cd468a2016-12-19 23:05:39 +010012911 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012912 M (PG_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012913 mp->context = 0;
12914 mp->is_enabled = enable;
12915 if (stream_name_set != 0)
12916 {
Jakub Grajciardb863292020-01-30 14:14:15 +010012917 vl_api_vec_to_api_string (stream_name, &mp->stream_name);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012918 }
12919 vec_free (stream_name);
12920
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012921 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012922 W (ret);
12923 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012924}
12925
12926int
Mohsin Kazmif382b062020-08-11 15:00:44 +020012927api_pg_interface_enable_disable_coalesce (vat_main_t * vam)
12928{
12929 unformat_input_t *input = vam->input;
12930 vl_api_pg_interface_enable_disable_coalesce_t *mp;
12931
12932 u32 sw_if_index = ~0;
12933 u8 enable = 1;
12934 int ret;
12935 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12936 {
12937 if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12938 ;
12939 else if (unformat (input, "sw_if_index %d", &sw_if_index))
12940 ;
12941 else if (unformat (input, "disable"))
12942 enable = 0;
12943 else
12944 break;
12945 }
12946
12947 if (sw_if_index == ~0)
12948 {
12949 errmsg ("Interface required but not specified");
12950 return -99;
12951 }
12952
12953 /* Construct the API message */
12954 M (PG_INTERFACE_ENABLE_DISABLE_COALESCE, mp);
12955 mp->context = 0;
12956 mp->coalesce_enabled = enable;
12957 mp->sw_if_index = htonl (sw_if_index);
12958
12959 S (mp);
12960 W (ret);
12961 return ret;
12962}
12963
12964int
Damjan Marion7cd468a2016-12-19 23:05:39 +010012965api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
12966{
12967 unformat_input_t *input = vam->input;
12968 vl_api_ip_source_and_port_range_check_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012969
12970 u16 *low_ports = 0;
12971 u16 *high_ports = 0;
12972 u16 this_low;
12973 u16 this_hi;
Neale Ranns37029302018-08-10 05:30:06 -070012974 vl_api_prefix_t prefix;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012975 u32 tmp, tmp2;
12976 u8 prefix_set = 0;
12977 u32 vrf_id = ~0;
12978 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012979 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012980
12981 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12982 {
Neale Ranns37029302018-08-10 05:30:06 -070012983 if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
12984 prefix_set = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012985 else if (unformat (input, "vrf %d", &vrf_id))
12986 ;
12987 else if (unformat (input, "del"))
12988 is_add = 0;
12989 else if (unformat (input, "port %d", &tmp))
12990 {
12991 if (tmp == 0 || tmp > 65535)
12992 {
12993 errmsg ("port %d out of range", tmp);
12994 return -99;
12995 }
12996 this_low = tmp;
12997 this_hi = this_low + 1;
12998 vec_add1 (low_ports, this_low);
12999 vec_add1 (high_ports, this_hi);
13000 }
13001 else if (unformat (input, "range %d - %d", &tmp, &tmp2))
13002 {
13003 if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
13004 {
13005 errmsg ("incorrect range parameters");
13006 return -99;
13007 }
13008 this_low = tmp;
13009 /* Note: in debug CLI +1 is added to high before
13010 passing to real fn that does "the work"
13011 (ip_source_and_port_range_check_add_del).
13012 This fn is a wrapper around the binary API fn a
13013 control plane will call, which expects this increment
13014 to have occurred. Hence letting the binary API control
13015 plane fn do the increment for consistency between VAT
13016 and other control planes.
13017 */
13018 this_hi = tmp2;
13019 vec_add1 (low_ports, this_low);
13020 vec_add1 (high_ports, this_hi);
13021 }
13022 else
13023 break;
13024 }
13025
13026 if (prefix_set == 0)
13027 {
13028 errmsg ("<address>/<mask> not specified");
13029 return -99;
13030 }
13031
13032 if (vrf_id == ~0)
13033 {
13034 errmsg ("VRF ID required, not specified");
13035 return -99;
13036 }
13037
13038 if (vrf_id == 0)
13039 {
13040 errmsg
13041 ("VRF ID should not be default. Should be distinct VRF for this purpose.");
13042 return -99;
13043 }
13044
13045 if (vec_len (low_ports) == 0)
13046 {
13047 errmsg ("At least one port or port range required");
13048 return -99;
13049 }
13050
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013051 M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013052
13053 mp->is_add = is_add;
13054
Neale Ranns37029302018-08-10 05:30:06 -070013055 clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
Damjan Marion7cd468a2016-12-19 23:05:39 +010013056
Damjan Marion7cd468a2016-12-19 23:05:39 +010013057 mp->number_of_ranges = vec_len (low_ports);
13058
13059 clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
13060 vec_free (low_ports);
13061
13062 clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
13063 vec_free (high_ports);
13064
13065 mp->vrf_id = ntohl (vrf_id);
13066
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013067 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013068 W (ret);
13069 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013070}
13071
13072int
13073api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
13074{
13075 unformat_input_t *input = vam->input;
13076 vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013077 u32 sw_if_index = ~0;
13078 int vrf_set = 0;
13079 u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
13080 u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
13081 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013082 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013083
13084 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13085 {
13086 if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13087 ;
13088 else if (unformat (input, "sw_if_index %d", &sw_if_index))
13089 ;
13090 else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
13091 vrf_set = 1;
13092 else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
13093 vrf_set = 1;
13094 else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
13095 vrf_set = 1;
13096 else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
13097 vrf_set = 1;
13098 else if (unformat (input, "del"))
13099 is_add = 0;
13100 else
13101 break;
13102 }
13103
13104 if (sw_if_index == ~0)
13105 {
13106 errmsg ("Interface required but not specified");
13107 return -99;
13108 }
13109
13110 if (vrf_set == 0)
13111 {
13112 errmsg ("VRF ID required but not specified");
13113 return -99;
13114 }
13115
13116 if (tcp_out_vrf_id == 0
13117 || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
13118 {
13119 errmsg
13120 ("VRF ID should not be default. Should be distinct VRF for this purpose.");
13121 return -99;
13122 }
13123
13124 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013125 M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013126
13127 mp->sw_if_index = ntohl (sw_if_index);
13128 mp->is_add = is_add;
13129 mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
13130 mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
13131 mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
13132 mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
13133
13134 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013135 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013136
13137 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060013138 W (ret);
13139 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013140}
13141
13142static int
Pavel Kotuceke88865d2018-11-28 07:42:11 +010013143api_set_punt (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010013144{
13145 unformat_input_t *i = vam->input;
Neale Ranns50f0ac02019-05-15 02:13:37 -070013146 vl_api_address_family_t af;
Pavel Kotuceke88865d2018-11-28 07:42:11 +010013147 vl_api_set_punt_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013148 u32 protocol = ~0;
13149 u32 port = ~0;
13150 int is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013151 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013152
13153 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13154 {
Neale Ranns50f0ac02019-05-15 02:13:37 -070013155 if (unformat (i, "%U", unformat_vl_api_address_family, &af))
Damjan Marion7cd468a2016-12-19 23:05:39 +010013156 ;
13157 else if (unformat (i, "protocol %d", &protocol))
13158 ;
13159 else if (unformat (i, "port %d", &port))
13160 ;
13161 else if (unformat (i, "del"))
13162 is_add = 0;
13163 else
13164 {
13165 clib_warning ("parse error '%U'", format_unformat_error, i);
13166 return -99;
13167 }
13168 }
13169
Pavel Kotuceke88865d2018-11-28 07:42:11 +010013170 M (SET_PUNT, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013171
13172 mp->is_add = (u8) is_add;
Neale Ranns50f0ac02019-05-15 02:13:37 -070013173 mp->punt.type = PUNT_API_TYPE_L4;
13174 mp->punt.punt.l4.af = af;
13175 mp->punt.punt.l4.protocol = (u8) protocol;
13176 mp->punt.punt.l4.port = htons ((u16) port);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013177
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013178 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013179 W (ret);
13180 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013181}
13182
Damjan Marion7cd468a2016-12-19 23:05:39 +010013183static int
13184api_delete_subif (vat_main_t * vam)
13185{
13186 unformat_input_t *i = vam->input;
13187 vl_api_delete_subif_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013188 u32 sw_if_index = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013189 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013190
13191 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13192 {
13193 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13194 ;
13195 if (unformat (i, "sw_if_index %d", &sw_if_index))
13196 ;
13197 else
13198 break;
13199 }
13200
13201 if (sw_if_index == ~0)
13202 {
13203 errmsg ("missing sw_if_index");
13204 return -99;
13205 }
13206
13207 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013208 M (DELETE_SUBIF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013209 mp->sw_if_index = ntohl (sw_if_index);
13210
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013211 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013212 W (ret);
13213 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013214}
13215
13216#define foreach_pbb_vtr_op \
13217_("disable", L2_VTR_DISABLED) \
13218_("pop", L2_VTR_POP_2) \
13219_("push", L2_VTR_PUSH_2)
13220
13221static int
13222api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
13223{
13224 unformat_input_t *i = vam->input;
13225 vl_api_l2_interface_pbb_tag_rewrite_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013226 u32 sw_if_index = ~0, vtr_op = ~0;
13227 u16 outer_tag = ~0;
13228 u8 dmac[6], smac[6];
13229 u8 dmac_set = 0, smac_set = 0;
13230 u16 vlanid = 0;
13231 u32 sid = ~0;
13232 u32 tmp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013233 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013234
13235 /* Shut up coverity */
Dave Barachb7b92992018-10-17 10:38:51 -040013236 clib_memset (dmac, 0, sizeof (dmac));
13237 clib_memset (smac, 0, sizeof (smac));
Damjan Marion7cd468a2016-12-19 23:05:39 +010013238
13239 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13240 {
13241 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13242 ;
13243 else if (unformat (i, "sw_if_index %d", &sw_if_index))
13244 ;
13245 else if (unformat (i, "vtr_op %d", &vtr_op))
13246 ;
13247#define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
13248 foreach_pbb_vtr_op
13249#undef _
13250 else if (unformat (i, "translate_pbb_stag"))
13251 {
13252 if (unformat (i, "%d", &tmp))
13253 {
13254 vtr_op = L2_VTR_TRANSLATE_2_1;
13255 outer_tag = tmp;
13256 }
13257 else
13258 {
13259 errmsg
13260 ("translate_pbb_stag operation requires outer tag definition");
13261 return -99;
13262 }
13263 }
13264 else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
13265 dmac_set++;
13266 else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
13267 smac_set++;
13268 else if (unformat (i, "sid %d", &sid))
13269 ;
13270 else if (unformat (i, "vlanid %d", &tmp))
13271 vlanid = tmp;
13272 else
13273 {
13274 clib_warning ("parse error '%U'", format_unformat_error, i);
13275 return -99;
13276 }
13277 }
13278
13279 if ((sw_if_index == ~0) || (vtr_op == ~0))
13280 {
13281 errmsg ("missing sw_if_index or vtr operation");
13282 return -99;
13283 }
13284 if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
13285 && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
13286 {
13287 errmsg
13288 ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
13289 return -99;
13290 }
13291
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013292 M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013293 mp->sw_if_index = ntohl (sw_if_index);
13294 mp->vtr_op = ntohl (vtr_op);
13295 mp->outer_tag = ntohs (outer_tag);
13296 clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
13297 clib_memcpy (mp->b_smac, smac, sizeof (smac));
13298 mp->b_vlanid = ntohs (vlanid);
13299 mp->i_sid = ntohl (sid);
13300
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013301 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013302 W (ret);
13303 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013304}
13305
13306static int
13307api_flow_classify_set_interface (vat_main_t * vam)
13308{
13309 unformat_input_t *i = vam->input;
13310 vl_api_flow_classify_set_interface_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013311 u32 sw_if_index;
13312 int sw_if_index_set;
13313 u32 ip4_table_index = ~0;
13314 u32 ip6_table_index = ~0;
13315 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013316 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013317
13318 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13319 {
13320 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13321 sw_if_index_set = 1;
13322 else if (unformat (i, "sw_if_index %d", &sw_if_index))
13323 sw_if_index_set = 1;
13324 else if (unformat (i, "del"))
13325 is_add = 0;
13326 else if (unformat (i, "ip4-table %d", &ip4_table_index))
13327 ;
13328 else if (unformat (i, "ip6-table %d", &ip6_table_index))
13329 ;
13330 else
13331 {
13332 clib_warning ("parse error '%U'", format_unformat_error, i);
13333 return -99;
13334 }
13335 }
13336
13337 if (sw_if_index_set == 0)
13338 {
13339 errmsg ("missing interface name or sw_if_index");
13340 return -99;
13341 }
13342
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013343 M (FLOW_CLASSIFY_SET_INTERFACE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013344
13345 mp->sw_if_index = ntohl (sw_if_index);
13346 mp->ip4_table_index = ntohl (ip4_table_index);
13347 mp->ip6_table_index = ntohl (ip6_table_index);
13348 mp->is_add = is_add;
13349
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013350 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013351 W (ret);
13352 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013353}
13354
13355static int
13356api_flow_classify_dump (vat_main_t * vam)
13357{
13358 unformat_input_t *i = vam->input;
13359 vl_api_flow_classify_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060013360 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013361 u8 type = FLOW_CLASSIFY_N_TABLES;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013362 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013363
13364 if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
13365 ;
13366 else
13367 {
13368 errmsg ("classify table type must be specified");
13369 return -99;
13370 }
13371
13372 if (!vam->json_output)
13373 {
13374 print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
13375 }
13376
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013377 M (FLOW_CLASSIFY_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013378 mp->type = type;
13379 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013380 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013381
13382 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040013383 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060013384 S (mp_ping);
13385
Damjan Marion7cd468a2016-12-19 23:05:39 +010013386 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060013387 W (ret);
13388 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013389}
13390
13391static int
13392api_feature_enable_disable (vat_main_t * vam)
13393{
13394 unformat_input_t *i = vam->input;
13395 vl_api_feature_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013396 u8 *arc_name = 0;
13397 u8 *feature_name = 0;
13398 u32 sw_if_index = ~0;
13399 u8 enable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013400 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013401
13402 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13403 {
13404 if (unformat (i, "arc_name %s", &arc_name))
13405 ;
13406 else if (unformat (i, "feature_name %s", &feature_name))
13407 ;
13408 else
13409 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13410 ;
13411 else if (unformat (i, "sw_if_index %d", &sw_if_index))
13412 ;
13413 else if (unformat (i, "disable"))
13414 enable = 0;
13415 else
13416 break;
13417 }
13418
13419 if (arc_name == 0)
13420 {
13421 errmsg ("missing arc name");
13422 return -99;
13423 }
13424 if (vec_len (arc_name) > 63)
13425 {
13426 errmsg ("arc name too long");
13427 }
13428
13429 if (feature_name == 0)
13430 {
13431 errmsg ("missing feature name");
13432 return -99;
13433 }
13434 if (vec_len (feature_name) > 63)
13435 {
13436 errmsg ("feature name too long");
13437 }
13438
13439 if (sw_if_index == ~0)
13440 {
13441 errmsg ("missing interface name or sw_if_index");
13442 return -99;
13443 }
13444
13445 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013446 M (FEATURE_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013447 mp->sw_if_index = ntohl (sw_if_index);
13448 mp->enable = enable;
13449 clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
13450 clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
13451 vec_free (arc_name);
13452 vec_free (feature_name);
13453
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013454 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013455 W (ret);
13456 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013457}
13458
13459static int
Mohsin Kazmi29467b52019-10-08 19:42:38 +020013460api_feature_gso_enable_disable (vat_main_t * vam)
13461{
13462 unformat_input_t *i = vam->input;
13463 vl_api_feature_gso_enable_disable_t *mp;
13464 u32 sw_if_index = ~0;
13465 u8 enable = 1;
13466 int ret;
13467
13468 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13469 {
13470 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13471 ;
13472 else if (unformat (i, "sw_if_index %d", &sw_if_index))
13473 ;
13474 else if (unformat (i, "enable"))
13475 enable = 1;
13476 else if (unformat (i, "disable"))
13477 enable = 0;
13478 else
13479 break;
13480 }
13481
13482 if (sw_if_index == ~0)
13483 {
13484 errmsg ("missing interface name or sw_if_index");
13485 return -99;
13486 }
13487
13488 /* Construct the API message */
13489 M (FEATURE_GSO_ENABLE_DISABLE, mp);
13490 mp->sw_if_index = ntohl (sw_if_index);
13491 mp->enable_disable = enable;
13492
13493 S (mp);
13494 W (ret);
13495 return ret;
13496}
13497
13498static int
Damjan Marion7cd468a2016-12-19 23:05:39 +010013499api_sw_interface_tag_add_del (vat_main_t * vam)
13500{
13501 unformat_input_t *i = vam->input;
13502 vl_api_sw_interface_tag_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013503 u32 sw_if_index = ~0;
13504 u8 *tag = 0;
13505 u8 enable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013506 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013507
13508 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13509 {
13510 if (unformat (i, "tag %s", &tag))
13511 ;
13512 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13513 ;
13514 else if (unformat (i, "sw_if_index %d", &sw_if_index))
13515 ;
13516 else if (unformat (i, "del"))
13517 enable = 0;
13518 else
13519 break;
13520 }
13521
13522 if (sw_if_index == ~0)
13523 {
13524 errmsg ("missing interface name or sw_if_index");
13525 return -99;
13526 }
13527
13528 if (enable && (tag == 0))
13529 {
13530 errmsg ("no tag specified");
13531 return -99;
13532 }
13533
13534 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013535 M (SW_INTERFACE_TAG_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013536 mp->sw_if_index = ntohl (sw_if_index);
13537 mp->is_add = enable;
13538 if (enable)
Ole Troane5ff5a32019-08-23 22:55:18 +020013539 strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013540 vec_free (tag);
13541
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013542 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013543 W (ret);
13544 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013545}
13546
Matthew Smithe0792fd2019-07-12 11:48:24 -050013547static int
13548api_sw_interface_add_del_mac_address (vat_main_t * vam)
13549{
13550 unformat_input_t *i = vam->input;
13551 vl_api_mac_address_t mac = { 0 };
13552 vl_api_sw_interface_add_del_mac_address_t *mp;
13553 u32 sw_if_index = ~0;
13554 u8 is_add = 1;
13555 u8 mac_set = 0;
13556 int ret;
13557
13558 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13559 {
13560 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13561 ;
13562 else if (unformat (i, "sw_if_index %d", &sw_if_index))
13563 ;
13564 else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
13565 mac_set++;
13566 else if (unformat (i, "del"))
13567 is_add = 0;
13568 else
13569 break;
13570 }
13571
13572 if (sw_if_index == ~0)
13573 {
13574 errmsg ("missing interface name or sw_if_index");
13575 return -99;
13576 }
13577
13578 if (!mac_set)
13579 {
13580 errmsg ("missing MAC address");
13581 return -99;
13582 }
13583
13584 /* Construct the API message */
13585 M (SW_INTERFACE_ADD_DEL_MAC_ADDRESS, mp);
13586 mp->sw_if_index = ntohl (sw_if_index);
13587 mp->is_add = is_add;
13588 clib_memcpy (&mp->addr, &mac, sizeof (mac));
13589
13590 S (mp);
13591 W (ret);
13592 return ret;
13593}
13594
Damjan Marion7cd468a2016-12-19 23:05:39 +010013595static void vl_api_l2_xconnect_details_t_handler
13596 (vl_api_l2_xconnect_details_t * mp)
13597{
13598 vat_main_t *vam = &vat_main;
13599
13600 print (vam->ofp, "%15d%15d",
13601 ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
13602}
13603
13604static void vl_api_l2_xconnect_details_t_handler_json
13605 (vl_api_l2_xconnect_details_t * mp)
13606{
13607 vat_main_t *vam = &vat_main;
13608 vat_json_node_t *node = NULL;
13609
13610 if (VAT_JSON_ARRAY != vam->json_tree.type)
13611 {
13612 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13613 vat_json_init_array (&vam->json_tree);
13614 }
13615 node = vat_json_array_add (&vam->json_tree);
13616
13617 vat_json_init_object (node);
13618 vat_json_object_add_uint (node, "rx_sw_if_index",
13619 ntohl (mp->rx_sw_if_index));
13620 vat_json_object_add_uint (node, "tx_sw_if_index",
13621 ntohl (mp->tx_sw_if_index));
13622}
13623
13624static int
13625api_l2_xconnect_dump (vat_main_t * vam)
13626{
13627 vl_api_l2_xconnect_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060013628 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013629 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013630
13631 if (!vam->json_output)
13632 {
13633 print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
13634 }
13635
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013636 M (L2_XCONNECT_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013637
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013638 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013639
13640 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040013641 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060013642 S (mp_ping);
13643
Jon Loeliger56c7b012017-02-01 12:31:41 -060013644 W (ret);
13645 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013646}
13647
13648static int
Ole Troand7231612018-06-07 10:17:57 +020013649api_hw_interface_set_mtu (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010013650{
13651 unformat_input_t *i = vam->input;
Ole Troand7231612018-06-07 10:17:57 +020013652 vl_api_hw_interface_set_mtu_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013653 u32 sw_if_index = ~0;
13654 u32 mtu = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013655 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013656
13657 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13658 {
13659 if (unformat (i, "mtu %d", &mtu))
13660 ;
13661 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13662 ;
13663 else if (unformat (i, "sw_if_index %d", &sw_if_index))
13664 ;
13665 else
13666 break;
13667 }
13668
13669 if (sw_if_index == ~0)
13670 {
13671 errmsg ("missing interface name or sw_if_index");
13672 return -99;
13673 }
13674
13675 if (mtu == 0)
13676 {
13677 errmsg ("no mtu specified");
13678 return -99;
13679 }
13680
13681 /* Construct the API message */
Ole Troand7231612018-06-07 10:17:57 +020013682 M (HW_INTERFACE_SET_MTU, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013683 mp->sw_if_index = ntohl (sw_if_index);
13684 mp->mtu = ntohs ((u16) mtu);
13685
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013686 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013687 W (ret);
13688 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013689}
13690
Pavel Kotucek6899a302017-06-08 08:46:10 +020013691static int
13692api_p2p_ethernet_add (vat_main_t * vam)
13693{
13694 unformat_input_t *i = vam->input;
13695 vl_api_p2p_ethernet_add_t *mp;
13696 u32 parent_if_index = ~0;
Pavel Kotucek15ac81c2017-06-20 14:00:26 +020013697 u32 sub_id = ~0;
Pavel Kotucek6899a302017-06-08 08:46:10 +020013698 u8 remote_mac[6];
13699 u8 mac_set = 0;
13700 int ret;
13701
Dave Barachb7b92992018-10-17 10:38:51 -040013702 clib_memset (remote_mac, 0, sizeof (remote_mac));
Pavel Kotucek6899a302017-06-08 08:46:10 +020013703 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13704 {
13705 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
13706 ;
13707 else if (unformat (i, "sw_if_index %d", &parent_if_index))
13708 ;
13709 else
13710 if (unformat
13711 (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
13712 mac_set++;
Pavel Kotucek15ac81c2017-06-20 14:00:26 +020013713 else if (unformat (i, "sub_id %d", &sub_id))
13714 ;
Pavel Kotucek6899a302017-06-08 08:46:10 +020013715 else
13716 {
13717 clib_warning ("parse error '%U'", format_unformat_error, i);
13718 return -99;
13719 }
13720 }
13721
13722 if (parent_if_index == ~0)
13723 {
13724 errmsg ("missing interface name or sw_if_index");
13725 return -99;
13726 }
13727 if (mac_set == 0)
13728 {
13729 errmsg ("missing remote mac address");
13730 return -99;
13731 }
Pavel Kotucek15ac81c2017-06-20 14:00:26 +020013732 if (sub_id == ~0)
13733 {
13734 errmsg ("missing sub-interface id");
13735 return -99;
13736 }
Pavel Kotucek6899a302017-06-08 08:46:10 +020013737
13738 M (P2P_ETHERNET_ADD, mp);
13739 mp->parent_if_index = ntohl (parent_if_index);
Pavel Kotucek15ac81c2017-06-20 14:00:26 +020013740 mp->subif_id = ntohl (sub_id);
Pavel Kotucek6899a302017-06-08 08:46:10 +020013741 clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
13742
13743 S (mp);
13744 W (ret);
13745 return ret;
13746}
13747
13748static int
13749api_p2p_ethernet_del (vat_main_t * vam)
13750{
13751 unformat_input_t *i = vam->input;
13752 vl_api_p2p_ethernet_del_t *mp;
13753 u32 parent_if_index = ~0;
13754 u8 remote_mac[6];
13755 u8 mac_set = 0;
13756 int ret;
13757
Dave Barachb7b92992018-10-17 10:38:51 -040013758 clib_memset (remote_mac, 0, sizeof (remote_mac));
Pavel Kotucek6899a302017-06-08 08:46:10 +020013759 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13760 {
13761 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
13762 ;
13763 else if (unformat (i, "sw_if_index %d", &parent_if_index))
13764 ;
13765 else
13766 if (unformat
13767 (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
13768 mac_set++;
13769 else
13770 {
13771 clib_warning ("parse error '%U'", format_unformat_error, i);
13772 return -99;
13773 }
13774 }
13775
13776 if (parent_if_index == ~0)
13777 {
13778 errmsg ("missing interface name or sw_if_index");
13779 return -99;
13780 }
13781 if (mac_set == 0)
13782 {
13783 errmsg ("missing remote mac address");
13784 return -99;
13785 }
13786
13787 M (P2P_ETHERNET_DEL, mp);
13788 mp->parent_if_index = ntohl (parent_if_index);
13789 clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
13790
13791 S (mp);
13792 W (ret);
13793 return ret;
13794}
Damjan Marion7cd468a2016-12-19 23:05:39 +010013795
13796static int
Dave Barach3bbcfab2017-08-15 19:03:44 -040013797api_tcp_configure_src_addresses (vat_main_t * vam)
13798{
13799 vl_api_tcp_configure_src_addresses_t *mp;
13800 unformat_input_t *i = vam->input;
Neale Rannscbe25aa2019-09-30 10:53:31 +000013801 vl_api_address_t first, last;
Dave Barach3bbcfab2017-08-15 19:03:44 -040013802 u8 range_set = 0;
13803 u32 vrf_id = 0;
13804 int ret;
13805
13806 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13807 {
13808 if (unformat (i, "%U - %U",
Neale Rannscbe25aa2019-09-30 10:53:31 +000013809 unformat_vl_api_address, &first,
13810 unformat_vl_api_address, &last))
Dave Barach3bbcfab2017-08-15 19:03:44 -040013811 {
13812 if (range_set)
13813 {
13814 errmsg ("one range per message (range already set)");
13815 return -99;
13816 }
13817 range_set = 1;
13818 }
Dave Barach3bbcfab2017-08-15 19:03:44 -040013819 else if (unformat (i, "vrf %d", &vrf_id))
13820 ;
13821 else
13822 break;
13823 }
13824
13825 if (range_set == 0)
13826 {
13827 errmsg ("address range not set");
13828 return -99;
13829 }
13830
13831 M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
Neale Rannscbe25aa2019-09-30 10:53:31 +000013832
Dave Barach3bbcfab2017-08-15 19:03:44 -040013833 mp->vrf_id = ntohl (vrf_id);
Neale Rannscbe25aa2019-09-30 10:53:31 +000013834 clib_memcpy (&mp->first_address, &first, sizeof (first));
13835 clib_memcpy (&mp->last_address, &last, sizeof (last));
13836
Dave Barach3bbcfab2017-08-15 19:03:44 -040013837 S (mp);
13838 W (ret);
13839 return ret;
13840}
13841
Florin Coras6e8c6672017-11-10 09:03:54 -080013842static void vl_api_app_namespace_add_del_reply_t_handler
13843 (vl_api_app_namespace_add_del_reply_t * mp)
13844{
13845 vat_main_t *vam = &vat_main;
13846 i32 retval = ntohl (mp->retval);
13847 if (vam->async_mode)
13848 {
13849 vam->async_errors += (retval < 0);
13850 }
13851 else
13852 {
13853 vam->retval = retval;
13854 if (retval == 0)
13855 errmsg ("app ns index %d\n", ntohl (mp->appns_index));
13856 vam->result_ready = 1;
13857 }
13858}
13859
13860static void vl_api_app_namespace_add_del_reply_t_handler_json
13861 (vl_api_app_namespace_add_del_reply_t * mp)
13862{
13863 vat_main_t *vam = &vat_main;
13864 vat_json_node_t node;
13865
13866 vat_json_init_object (&node);
13867 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
13868 vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
13869
13870 vat_json_print (vam->ofp, &node);
13871 vat_json_free (&node);
13872
13873 vam->retval = ntohl (mp->retval);
13874 vam->result_ready = 1;
13875}
13876
Dave Barach3bbcfab2017-08-15 19:03:44 -040013877static int
Florin Corascea194d2017-10-02 00:18:51 -070013878api_app_namespace_add_del (vat_main_t * vam)
13879{
13880 vl_api_app_namespace_add_del_t *mp;
13881 unformat_input_t *i = vam->input;
13882 u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
13883 u32 sw_if_index, ip4_fib_id, ip6_fib_id;
13884 u64 secret;
13885 int ret;
13886
13887 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13888 {
13889 if (unformat (i, "id %_%v%_", &ns_id))
13890 ;
13891 else if (unformat (i, "secret %lu", &secret))
13892 secret_set = 1;
13893 else if (unformat (i, "sw_if_index %d", &sw_if_index))
13894 sw_if_index_set = 1;
13895 else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
13896 ;
13897 else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
13898 ;
13899 else
13900 break;
13901 }
13902 if (!ns_id || !secret_set || !sw_if_index_set)
13903 {
13904 errmsg ("namespace id, secret and sw_if_index must be set");
13905 return -99;
13906 }
13907 if (vec_len (ns_id) > 64)
13908 {
13909 errmsg ("namespace id too long");
13910 return -99;
13911 }
13912 M (APP_NAMESPACE_ADD_DEL, mp);
13913
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010013914 vl_api_vec_to_api_string (ns_id, &mp->namespace_id);
Florin Coras9a9adb22017-10-26 08:16:59 -070013915 mp->secret = clib_host_to_net_u64 (secret);
Florin Corascea194d2017-10-02 00:18:51 -070013916 mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
13917 mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
13918 mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
13919 vec_free (ns_id);
13920 S (mp);
13921 W (ret);
13922 return ret;
13923}
13924
13925static int
Florin Coras90a63982017-12-19 04:50:01 -080013926api_sock_init_shm (vat_main_t * vam)
13927{
13928#if VPP_API_TEST_BUILTIN == 0
13929 unformat_input_t *i = vam->input;
13930 vl_api_shm_elem_config_t *config = 0;
13931 u64 size = 64 << 20;
13932 int rv;
13933
13934 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13935 {
13936 if (unformat (i, "size %U", unformat_memory_size, &size))
13937 ;
13938 else
13939 break;
13940 }
13941
Dave Barach78958722018-05-10 16:44:27 -040013942 /*
13943 * Canned custom ring allocator config.
13944 * Should probably parse all of this
13945 */
13946 vec_validate (config, 6);
Florin Coras90a63982017-12-19 04:50:01 -080013947 config[0].type = VL_API_VLIB_RING;
Florin Coras90a63982017-12-19 04:50:01 -080013948 config[0].size = 256;
Dave Barach78958722018-05-10 16:44:27 -040013949 config[0].count = 32;
13950
13951 config[1].type = VL_API_VLIB_RING;
Florin Coras90a63982017-12-19 04:50:01 -080013952 config[1].size = 1024;
Dave Barach78958722018-05-10 16:44:27 -040013953 config[1].count = 16;
13954
13955 config[2].type = VL_API_VLIB_RING;
Florin Coras90a63982017-12-19 04:50:01 -080013956 config[2].size = 4096;
Dave Barach78958722018-05-10 16:44:27 -040013957 config[2].count = 2;
13958
13959 config[3].type = VL_API_CLIENT_RING;
13960 config[3].size = 256;
13961 config[3].count = 32;
13962
13963 config[4].type = VL_API_CLIENT_RING;
13964 config[4].size = 1024;
13965 config[4].count = 16;
13966
13967 config[5].type = VL_API_CLIENT_RING;
13968 config[5].size = 4096;
13969 config[5].count = 2;
13970
13971 config[6].type = VL_API_QUEUE;
13972 config[6].count = 128;
13973 config[6].size = sizeof (uword);
13974
Tomasz Kulasek97dcf5b2019-01-31 18:26:32 +010013975 rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
Florin Coras90a63982017-12-19 04:50:01 -080013976 if (!rv)
13977 vam->client_index_invalid = 1;
13978 return rv;
13979#else
13980 return -99;
13981#endif
13982}
13983
Florin Coras6c36f532017-11-03 18:32:34 -070013984static void
13985vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
13986{
13987 vat_main_t *vam = &vat_main;
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010013988 fib_prefix_t lcl, rmt;
Florin Coras6c36f532017-11-03 18:32:34 -070013989
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010013990 ip_prefix_decode (&mp->lcl, &lcl);
13991 ip_prefix_decode (&mp->rmt, &rmt);
13992
13993 if (lcl.fp_proto == FIB_PROTOCOL_IP4)
Florin Coras6c36f532017-11-03 18:32:34 -070013994 {
Florin Corasc97a7392017-11-05 23:07:07 -080013995 print (vam->ofp,
13996 "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
Steven85dbac02017-11-07 16:29:53 -080013997 clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010013998 mp->scope, format_ip4_address, &lcl.fp_addr.ip4, lcl.fp_len,
Steven85dbac02017-11-07 16:29:53 -080013999 clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014000 &rmt.fp_addr.ip4, rmt.fp_len,
14001 clib_net_to_host_u16 (mp->rmt_port),
Steven85dbac02017-11-07 16:29:53 -080014002 clib_net_to_host_u32 (mp->action_index), mp->tag);
Florin Coras6c36f532017-11-03 18:32:34 -070014003 }
14004 else
14005 {
Florin Corasc97a7392017-11-05 23:07:07 -080014006 print (vam->ofp,
14007 "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
Steven85dbac02017-11-07 16:29:53 -080014008 clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014009 mp->scope, format_ip6_address, &lcl.fp_addr.ip6, lcl.fp_len,
Steven85dbac02017-11-07 16:29:53 -080014010 clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014011 &rmt.fp_addr.ip6, rmt.fp_len,
14012 clib_net_to_host_u16 (mp->rmt_port),
Steven85dbac02017-11-07 16:29:53 -080014013 clib_net_to_host_u32 (mp->action_index), mp->tag);
Florin Coras6c36f532017-11-03 18:32:34 -070014014 }
14015}
14016
14017static void
14018vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
14019 mp)
14020{
14021 vat_main_t *vam = &vat_main;
14022 vat_json_node_t *node = NULL;
14023 struct in6_addr ip6;
14024 struct in_addr ip4;
14025
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014026 fib_prefix_t lcl, rmt;
14027
14028 ip_prefix_decode (&mp->lcl, &lcl);
14029 ip_prefix_decode (&mp->rmt, &rmt);
14030
Florin Coras6c36f532017-11-03 18:32:34 -070014031 if (VAT_JSON_ARRAY != vam->json_tree.type)
14032 {
14033 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14034 vat_json_init_array (&vam->json_tree);
14035 }
14036 node = vat_json_array_add (&vam->json_tree);
14037 vat_json_init_object (node);
14038
Florin Coras6c36f532017-11-03 18:32:34 -070014039 vat_json_object_add_uint (node, "appns_index",
14040 clib_net_to_host_u32 (mp->appns_index));
14041 vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
14042 vat_json_object_add_uint (node, "scope", mp->scope);
14043 vat_json_object_add_uint (node, "action_index",
14044 clib_net_to_host_u32 (mp->action_index));
14045 vat_json_object_add_uint (node, "lcl_port",
14046 clib_net_to_host_u16 (mp->lcl_port));
14047 vat_json_object_add_uint (node, "rmt_port",
14048 clib_net_to_host_u16 (mp->rmt_port));
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014049 vat_json_object_add_uint (node, "lcl_plen", lcl.fp_len);
14050 vat_json_object_add_uint (node, "rmt_plen", rmt.fp_len);
Florin Corasc97a7392017-11-05 23:07:07 -080014051 vat_json_object_add_string_copy (node, "tag", mp->tag);
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014052 if (lcl.fp_proto == FIB_PROTOCOL_IP4)
Florin Coras6c36f532017-11-03 18:32:34 -070014053 {
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014054 clib_memcpy (&ip4, &lcl.fp_addr.ip4, sizeof (ip4));
Florin Coras6c36f532017-11-03 18:32:34 -070014055 vat_json_object_add_ip4 (node, "lcl_ip", ip4);
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014056 clib_memcpy (&ip4, &rmt.fp_addr.ip4, sizeof (ip4));
Florin Coras6c36f532017-11-03 18:32:34 -070014057 vat_json_object_add_ip4 (node, "rmt_ip", ip4);
14058 }
14059 else
14060 {
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014061 clib_memcpy (&ip6, &lcl.fp_addr.ip6, sizeof (ip6));
Florin Coras6c36f532017-11-03 18:32:34 -070014062 vat_json_object_add_ip6 (node, "lcl_ip", ip6);
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014063 clib_memcpy (&ip6, &rmt.fp_addr.ip6, sizeof (ip6));
Florin Coras6c36f532017-11-03 18:32:34 -070014064 vat_json_object_add_ip6 (node, "rmt_ip", ip6);
14065 }
14066}
14067
Florin Coras1c710452017-10-17 00:03:13 -070014068static int
14069api_session_rule_add_del (vat_main_t * vam)
14070{
14071 vl_api_session_rule_add_del_t *mp;
14072 unformat_input_t *i = vam->input;
14073 u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
14074 u32 appns_index = 0, scope = 0;
14075 ip4_address_t lcl_ip4, rmt_ip4;
14076 ip6_address_t lcl_ip6, rmt_ip6;
14077 u8 is_ip4 = 1, conn_set = 0;
Florin Corasc97a7392017-11-05 23:07:07 -080014078 u8 is_add = 1, *tag = 0;
Florin Coras1c710452017-10-17 00:03:13 -070014079 int ret;
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014080 fib_prefix_t lcl, rmt;
Florin Coras1c710452017-10-17 00:03:13 -070014081
14082 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14083 {
14084 if (unformat (i, "del"))
14085 is_add = 0;
14086 else if (unformat (i, "add"))
14087 ;
14088 else if (unformat (i, "proto tcp"))
14089 proto = 0;
14090 else if (unformat (i, "proto udp"))
14091 proto = 1;
14092 else if (unformat (i, "appns %d", &appns_index))
14093 ;
14094 else if (unformat (i, "scope %d", &scope))
14095 ;
Florin Corasc97a7392017-11-05 23:07:07 -080014096 else if (unformat (i, "tag %_%v%_", &tag))
14097 ;
Florin Coras1c710452017-10-17 00:03:13 -070014098 else
14099 if (unformat
14100 (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
14101 &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
14102 &rmt_port))
14103 {
14104 is_ip4 = 1;
14105 conn_set = 1;
14106 }
14107 else
14108 if (unformat
14109 (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
14110 &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
14111 &rmt_port))
14112 {
14113 is_ip4 = 0;
14114 conn_set = 1;
14115 }
14116 else if (unformat (i, "action %d", &action))
14117 ;
14118 else
14119 break;
14120 }
14121 if (proto == ~0 || !conn_set || action == ~0)
14122 {
14123 errmsg ("transport proto, connection and action must be set");
14124 return -99;
14125 }
14126
14127 if (scope > 3)
14128 {
14129 errmsg ("scope should be 0-3");
14130 return -99;
14131 }
14132
14133 M (SESSION_RULE_ADD_DEL, mp);
14134
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014135 clib_memset (&lcl, 0, sizeof (lcl));
14136 clib_memset (&rmt, 0, sizeof (rmt));
14137 if (is_ip4)
14138 {
14139 ip_set (&lcl.fp_addr, &lcl_ip4, 1);
14140 ip_set (&rmt.fp_addr, &rmt_ip4, 1);
14141 lcl.fp_len = lcl_plen;
14142 rmt.fp_len = rmt_plen;
14143 }
14144 else
14145 {
14146 ip_set (&lcl.fp_addr, &lcl_ip6, 0);
14147 ip_set (&rmt.fp_addr, &rmt_ip6, 0);
14148 lcl.fp_len = lcl_plen;
14149 rmt.fp_len = rmt_plen;
14150 }
14151
14152
14153 ip_prefix_encode (&lcl, &mp->lcl);
14154 ip_prefix_encode (&rmt, &mp->rmt);
Florin Corasc97a7392017-11-05 23:07:07 -080014155 mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
14156 mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014157 mp->transport_proto =
14158 proto ? TRANSPORT_PROTO_API_UDP : TRANSPORT_PROTO_API_TCP;
Florin Coras1c710452017-10-17 00:03:13 -070014159 mp->action_index = clib_host_to_net_u32 (action);
14160 mp->appns_index = clib_host_to_net_u32 (appns_index);
14161 mp->scope = scope;
14162 mp->is_add = is_add;
Florin Corasc97a7392017-11-05 23:07:07 -080014163 if (tag)
14164 {
14165 clib_memcpy (mp->tag, tag, vec_len (tag));
14166 vec_free (tag);
14167 }
Florin Coras1c710452017-10-17 00:03:13 -070014168
14169 S (mp);
14170 W (ret);
14171 return ret;
14172}
Dave Barach65457162017-10-10 17:53:14 -040014173
14174static int
Florin Coras6c36f532017-11-03 18:32:34 -070014175api_session_rules_dump (vat_main_t * vam)
14176{
14177 vl_api_session_rules_dump_t *mp;
14178 vl_api_control_ping_t *mp_ping;
14179 int ret;
14180
14181 if (!vam->json_output)
14182 {
14183 print (vam->ofp, "%=20s", "Session Rules");
14184 }
14185
14186 M (SESSION_RULES_DUMP, mp);
14187 /* send it... */
14188 S (mp);
14189
14190 /* Use a control ping for synchronization */
14191 MPING (CONTROL_PING, mp_ping);
14192 S (mp_ping);
14193
14194 /* Wait for a reply... */
14195 W (ret);
14196 return ret;
14197}
14198
14199static int
Florin Coras595992c2017-11-06 17:17:08 -080014200api_ip_container_proxy_add_del (vat_main_t * vam)
14201{
14202 vl_api_ip_container_proxy_add_del_t *mp;
14203 unformat_input_t *i = vam->input;
Neale Ranns37029302018-08-10 05:30:06 -070014204 u32 sw_if_index = ~0;
14205 vl_api_prefix_t pfx = { };
Florin Coras595992c2017-11-06 17:17:08 -080014206 u8 is_add = 1;
14207 int ret;
14208
14209 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14210 {
14211 if (unformat (i, "del"))
14212 is_add = 0;
14213 else if (unformat (i, "add"))
14214 ;
Neale Ranns37029302018-08-10 05:30:06 -070014215 if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
14216 ;
Florin Coras595992c2017-11-06 17:17:08 -080014217 else if (unformat (i, "sw_if_index %u", &sw_if_index))
14218 ;
14219 else
14220 break;
14221 }
Paul Vinciguerraab055082019-06-06 14:07:55 -040014222 if (sw_if_index == ~0 || pfx.len == 0)
Florin Coras595992c2017-11-06 17:17:08 -080014223 {
14224 errmsg ("address and sw_if_index must be set");
14225 return -99;
14226 }
14227
14228 M (IP_CONTAINER_PROXY_ADD_DEL, mp);
14229
Florin Coras595992c2017-11-06 17:17:08 -080014230 mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
Florin Coras595992c2017-11-06 17:17:08 -080014231 mp->is_add = is_add;
Neale Ranns37029302018-08-10 05:30:06 -070014232 clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
Florin Coras595992c2017-11-06 17:17:08 -080014233
14234 S (mp);
14235 W (ret);
14236 return ret;
14237}
14238
14239static int
Igor Mikhailov (imichail)582caa32018-04-26 21:33:02 -070014240api_qos_record_enable_disable (vat_main_t * vam)
14241{
14242 unformat_input_t *i = vam->input;
14243 vl_api_qos_record_enable_disable_t *mp;
14244 u32 sw_if_index, qs = 0xff;
14245 u8 sw_if_index_set = 0;
14246 u8 enable = 1;
14247 int ret;
14248
14249 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14250 {
14251 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14252 sw_if_index_set = 1;
14253 else if (unformat (i, "sw_if_index %d", &sw_if_index))
14254 sw_if_index_set = 1;
14255 else if (unformat (i, "%U", unformat_qos_source, &qs))
14256 ;
14257 else if (unformat (i, "disable"))
14258 enable = 0;
14259 else
14260 {
14261 clib_warning ("parse error '%U'", format_unformat_error, i);
14262 return -99;
14263 }
14264 }
14265
14266 if (sw_if_index_set == 0)
14267 {
14268 errmsg ("missing interface name or sw_if_index");
14269 return -99;
14270 }
14271 if (qs == 0xff)
14272 {
14273 errmsg ("input location must be specified");
14274 return -99;
14275 }
14276
14277 M (QOS_RECORD_ENABLE_DISABLE, mp);
14278
Neale Ranns5281a902019-07-23 08:16:19 -070014279 mp->record.sw_if_index = ntohl (sw_if_index);
14280 mp->record.input_source = qs;
Igor Mikhailov (imichail)582caa32018-04-26 21:33:02 -070014281 mp->enable = enable;
14282
14283 S (mp);
14284 W (ret);
14285 return ret;
14286}
14287
Dave Barach048a4e52018-06-01 18:52:25 -040014288
Igor Mikhailov (imichail)582caa32018-04-26 21:33:02 -070014289static int
Damjan Marion7cd468a2016-12-19 23:05:39 +010014290q_or_quit (vat_main_t * vam)
14291{
Dave Barachdef19da2017-02-22 17:29:20 -050014292#if VPP_API_TEST_BUILTIN == 0
Damjan Marion7cd468a2016-12-19 23:05:39 +010014293 longjmp (vam->jump_buf, 1);
Dave Barachdef19da2017-02-22 17:29:20 -050014294#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +010014295 return 0; /* not so much */
14296}
14297
14298static int
14299q (vat_main_t * vam)
14300{
14301 return q_or_quit (vam);
14302}
14303
14304static int
14305quit (vat_main_t * vam)
14306{
14307 return q_or_quit (vam);
14308}
14309
14310static int
14311comment (vat_main_t * vam)
14312{
14313 return 0;
14314}
14315
14316static int
Dave Barachb09f4d02019-07-15 16:00:03 -040014317elog_save (vat_main_t * vam)
14318{
14319#if VPP_API_TEST_BUILTIN == 0
14320 elog_main_t *em = &vam->elog_main;
14321 unformat_input_t *i = vam->input;
14322 char *file, *chroot_file;
14323 clib_error_t *error;
14324
14325 if (!unformat (i, "%s", &file))
14326 {
14327 errmsg ("expected file name, got `%U'", format_unformat_error, i);
14328 return 0;
14329 }
14330
14331 /* It's fairly hard to get "../oopsie" through unformat; just in case */
14332 if (strstr (file, "..") || index (file, '/'))
14333 {
14334 errmsg ("illegal characters in filename '%s'", file);
14335 return 0;
14336 }
14337
14338 chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
14339
14340 vec_free (file);
14341
14342 errmsg ("Saving %wd of %wd events to %s",
14343 elog_n_events_in_buffer (em),
14344 elog_buffer_capacity (em), chroot_file);
14345
14346 error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
14347 vec_free (chroot_file);
14348
14349 if (error)
14350 clib_error_report (error);
14351#else
14352 errmsg ("Use the vpp event loger...");
14353#endif
14354
14355 return 0;
14356}
14357
14358static int
14359elog_setup (vat_main_t * vam)
14360{
14361#if VPP_API_TEST_BUILTIN == 0
14362 elog_main_t *em = &vam->elog_main;
14363 unformat_input_t *i = vam->input;
14364 u32 nevents = 128 << 10;
14365
14366 (void) unformat (i, "nevents %d", &nevents);
14367
14368 elog_init (em, nevents);
14369 vl_api_set_elog_main (em);
14370 vl_api_set_elog_trace_api_messages (1);
14371 errmsg ("Event logger initialized with %u events", nevents);
14372#else
14373 errmsg ("Use the vpp event loger...");
14374#endif
14375 return 0;
14376}
14377
14378static int
14379elog_enable (vat_main_t * vam)
14380{
14381#if VPP_API_TEST_BUILTIN == 0
14382 elog_main_t *em = &vam->elog_main;
14383
14384 elog_enable_disable (em, 1 /* enable */ );
14385 vl_api_set_elog_trace_api_messages (1);
14386 errmsg ("Event logger enabled...");
14387#else
14388 errmsg ("Use the vpp event loger...");
14389#endif
14390 return 0;
14391}
14392
14393static int
14394elog_disable (vat_main_t * vam)
14395{
14396#if VPP_API_TEST_BUILTIN == 0
14397 elog_main_t *em = &vam->elog_main;
14398
14399 elog_enable_disable (em, 0 /* enable */ );
14400 vl_api_set_elog_trace_api_messages (1);
14401 errmsg ("Event logger disabled...");
14402#else
14403 errmsg ("Use the vpp event loger...");
14404#endif
14405 return 0;
14406}
14407
14408static int
Dave Barach048a4e52018-06-01 18:52:25 -040014409statseg (vat_main_t * vam)
14410{
14411 ssvm_private_t *ssvmp = &vam->stat_segment;
14412 ssvm_shared_header_t *shared_header = ssvmp->sh;
14413 vlib_counter_t **counters;
14414 u64 thread0_index1_packets;
14415 u64 thread0_index1_bytes;
14416 f64 vector_rate, input_rate;
14417 uword *p;
14418
14419 uword *counter_vector_by_name;
14420 if (vam->stat_segment_lockp == 0)
14421 {
14422 errmsg ("Stat segment not mapped...");
14423 return -99;
14424 }
14425
14426 /* look up "/if/rx for sw_if_index 1 as a test */
14427
14428 clib_spinlock_lock (vam->stat_segment_lockp);
14429
14430 counter_vector_by_name = (uword *) shared_header->opaque[1];
14431
14432 p = hash_get_mem (counter_vector_by_name, "/if/rx");
14433 if (p == 0)
14434 {
14435 clib_spinlock_unlock (vam->stat_segment_lockp);
14436 errmsg ("/if/tx not found?");
14437 return -99;
14438 }
14439
14440 /* Fish per-thread vector of combined counters from shared memory */
14441 counters = (vlib_counter_t **) p[0];
14442
14443 if (vec_len (counters[0]) < 2)
14444 {
14445 clib_spinlock_unlock (vam->stat_segment_lockp);
14446 errmsg ("/if/tx vector length %d", vec_len (counters[0]));
14447 return -99;
14448 }
14449
14450 /* Read thread 0 sw_if_index 1 counter */
14451 thread0_index1_packets = counters[0][1].packets;
14452 thread0_index1_bytes = counters[0][1].bytes;
14453
14454 p = hash_get_mem (counter_vector_by_name, "vector_rate");
14455 if (p == 0)
14456 {
14457 clib_spinlock_unlock (vam->stat_segment_lockp);
14458 errmsg ("vector_rate not found?");
14459 return -99;
14460 }
14461
14462 vector_rate = *(f64 *) (p[0]);
14463 p = hash_get_mem (counter_vector_by_name, "input_rate");
14464 if (p == 0)
14465 {
14466 clib_spinlock_unlock (vam->stat_segment_lockp);
14467 errmsg ("input_rate not found?");
14468 return -99;
14469 }
14470 input_rate = *(f64 *) (p[0]);
14471
14472 clib_spinlock_unlock (vam->stat_segment_lockp);
14473
14474 print (vam->ofp, "vector_rate %.2f input_rate %.2f",
14475 vector_rate, input_rate);
14476 print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
14477 thread0_index1_packets, thread0_index1_bytes);
14478
14479 return 0;
14480}
14481
14482static int
Damjan Marion7cd468a2016-12-19 23:05:39 +010014483cmd_cmp (void *a1, void *a2)
14484{
14485 u8 **c1 = a1;
14486 u8 **c2 = a2;
14487
14488 return strcmp ((char *) (c1[0]), (char *) (c2[0]));
14489}
14490
14491static int
14492help (vat_main_t * vam)
14493{
14494 u8 **cmds = 0;
14495 u8 *name = 0;
14496 hash_pair_t *p;
14497 unformat_input_t *i = vam->input;
14498 int j;
14499
14500 if (unformat (i, "%s", &name))
14501 {
14502 uword *hs;
14503
14504 vec_add1 (name, 0);
14505
14506 hs = hash_get_mem (vam->help_by_name, name);
14507 if (hs)
14508 print (vam->ofp, "usage: %s %s", name, hs[0]);
14509 else
14510 print (vam->ofp, "No such msg / command '%s'", name);
14511 vec_free (name);
14512 return 0;
14513 }
14514
14515 print (vam->ofp, "Help is available for the following:");
14516
14517 /* *INDENT-OFF* */
14518 hash_foreach_pair (p, vam->function_by_name,
14519 ({
14520 vec_add1 (cmds, (u8 *)(p->key));
14521 }));
14522 /* *INDENT-ON* */
14523
14524 vec_sort_with_function (cmds, cmd_cmp);
14525
14526 for (j = 0; j < vec_len (cmds); j++)
14527 print (vam->ofp, "%s", cmds[j]);
14528
14529 vec_free (cmds);
14530 return 0;
14531}
14532
14533static int
14534set (vat_main_t * vam)
14535{
14536 u8 *name = 0, *value = 0;
14537 unformat_input_t *i = vam->input;
14538
14539 if (unformat (i, "%s", &name))
14540 {
14541 /* The input buffer is a vector, not a string. */
14542 value = vec_dup (i->buffer);
14543 vec_delete (value, i->index, 0);
14544 /* Almost certainly has a trailing newline */
14545 if (value[vec_len (value) - 1] == '\n')
14546 value[vec_len (value) - 1] = 0;
14547 /* Make sure it's a proper string, one way or the other */
14548 vec_add1 (value, 0);
14549 (void) clib_macro_set_value (&vam->macro_main,
14550 (char *) name, (char *) value);
14551 }
14552 else
14553 errmsg ("usage: set <name> <value>");
14554
14555 vec_free (name);
14556 vec_free (value);
14557 return 0;
14558}
14559
14560static int
14561unset (vat_main_t * vam)
14562{
14563 u8 *name = 0;
14564
14565 if (unformat (vam->input, "%s", &name))
14566 if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
14567 errmsg ("unset: %s wasn't set", name);
14568 vec_free (name);
14569 return 0;
14570}
14571
14572typedef struct
14573{
14574 u8 *name;
14575 u8 *value;
14576} macro_sort_t;
14577
14578
14579static int
14580macro_sort_cmp (void *a1, void *a2)
14581{
14582 macro_sort_t *s1 = a1;
14583 macro_sort_t *s2 = a2;
14584
14585 return strcmp ((char *) (s1->name), (char *) (s2->name));
14586}
14587
14588static int
14589dump_macro_table (vat_main_t * vam)
14590{
14591 macro_sort_t *sort_me = 0, *sm;
14592 int i;
14593 hash_pair_t *p;
14594
14595 /* *INDENT-OFF* */
14596 hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
14597 ({
14598 vec_add2 (sort_me, sm, 1);
14599 sm->name = (u8 *)(p->key);
14600 sm->value = (u8 *) (p->value[0]);
14601 }));
14602 /* *INDENT-ON* */
14603
14604 vec_sort_with_function (sort_me, macro_sort_cmp);
14605
14606 if (vec_len (sort_me))
14607 print (vam->ofp, "%-15s%s", "Name", "Value");
14608 else
14609 print (vam->ofp, "The macro table is empty...");
14610
14611 for (i = 0; i < vec_len (sort_me); i++)
14612 print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
14613 return 0;
14614}
14615
14616static int
14617dump_node_table (vat_main_t * vam)
14618{
14619 int i, j;
14620 vlib_node_t *node, *next_node;
14621
14622 if (vec_len (vam->graph_nodes) == 0)
14623 {
14624 print (vam->ofp, "Node table empty, issue get_node_graph...");
14625 return 0;
14626 }
14627
Dave Barach1ddbc012018-06-13 09:26:05 -040014628 for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
Damjan Marion7cd468a2016-12-19 23:05:39 +010014629 {
Dave Barach1ddbc012018-06-13 09:26:05 -040014630 node = vam->graph_nodes[0][i];
Damjan Marion7cd468a2016-12-19 23:05:39 +010014631 print (vam->ofp, "[%d] %s", i, node->name);
14632 for (j = 0; j < vec_len (node->next_nodes); j++)
14633 {
14634 if (node->next_nodes[j] != ~0)
14635 {
Dave Barach1ddbc012018-06-13 09:26:05 -040014636 next_node = vam->graph_nodes[0][node->next_nodes[j]];
Damjan Marion7cd468a2016-12-19 23:05:39 +010014637 print (vam->ofp, " [%d] %s", j, next_node->name);
14638 }
14639 }
14640 }
14641 return 0;
14642}
14643
14644static int
14645value_sort_cmp (void *a1, void *a2)
14646{
14647 name_sort_t *n1 = a1;
14648 name_sort_t *n2 = a2;
14649
14650 if (n1->value < n2->value)
14651 return -1;
14652 if (n1->value > n2->value)
14653 return 1;
14654 return 0;
14655}
14656
14657
14658static int
14659dump_msg_api_table (vat_main_t * vam)
14660{
Dave Barach39d69112019-11-27 11:42:13 -050014661 api_main_t *am = vlibapi_get_main ();
Damjan Marion7cd468a2016-12-19 23:05:39 +010014662 name_sort_t *nses = 0, *ns;
14663 hash_pair_t *hp;
14664 int i;
14665
14666 /* *INDENT-OFF* */
14667 hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
14668 ({
14669 vec_add2 (nses, ns, 1);
14670 ns->name = (u8 *)(hp->key);
14671 ns->value = (u32) hp->value[0];
14672 }));
14673 /* *INDENT-ON* */
14674
14675 vec_sort_with_function (nses, value_sort_cmp);
14676
14677 for (i = 0; i < vec_len (nses); i++)
14678 print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
14679 vec_free (nses);
14680 return 0;
14681}
14682
14683static int
14684get_msg_id (vat_main_t * vam)
14685{
14686 u8 *name_and_crc;
14687 u32 message_index;
14688
14689 if (unformat (vam->input, "%s", &name_and_crc))
14690 {
Florin Corase86a8ed2018-01-05 03:20:25 -080014691 message_index = vl_msg_api_get_msg_index (name_and_crc);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014692 if (message_index == ~0)
14693 {
14694 print (vam->ofp, " '%s' not found", name_and_crc);
14695 return 0;
14696 }
14697 print (vam->ofp, " '%s' has message index %d",
14698 name_and_crc, message_index);
14699 return 0;
14700 }
14701 errmsg ("name_and_crc required...");
14702 return 0;
14703}
14704
14705static int
14706search_node_table (vat_main_t * vam)
14707{
14708 unformat_input_t *line_input = vam->input;
14709 u8 *node_to_find;
14710 int j;
14711 vlib_node_t *node, *next_node;
14712 uword *p;
14713
14714 if (vam->graph_node_index_by_name == 0)
14715 {
14716 print (vam->ofp, "Node table empty, issue get_node_graph...");
14717 return 0;
14718 }
14719
14720 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14721 {
14722 if (unformat (line_input, "%s", &node_to_find))
14723 {
14724 vec_add1 (node_to_find, 0);
14725 p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
14726 if (p == 0)
14727 {
14728 print (vam->ofp, "%s not found...", node_to_find);
14729 goto out;
14730 }
Dave Barach1ddbc012018-06-13 09:26:05 -040014731 node = vam->graph_nodes[0][p[0]];
Damjan Marion7cd468a2016-12-19 23:05:39 +010014732 print (vam->ofp, "[%d] %s", p[0], node->name);
14733 for (j = 0; j < vec_len (node->next_nodes); j++)
14734 {
14735 if (node->next_nodes[j] != ~0)
14736 {
Dave Barach1ddbc012018-06-13 09:26:05 -040014737 next_node = vam->graph_nodes[0][node->next_nodes[j]];
Damjan Marion7cd468a2016-12-19 23:05:39 +010014738 print (vam->ofp, " [%d] %s", j, next_node->name);
14739 }
14740 }
14741 }
14742
14743 else
14744 {
14745 clib_warning ("parse error '%U'", format_unformat_error,
14746 line_input);
14747 return -99;
14748 }
14749
14750 out:
14751 vec_free (node_to_find);
14752
14753 }
14754
14755 return 0;
14756}
14757
14758
14759static int
14760script (vat_main_t * vam)
14761{
14762#if (VPP_API_TEST_BUILTIN==0)
14763 u8 *s = 0;
14764 char *save_current_file;
14765 unformat_input_t save_input;
14766 jmp_buf save_jump_buf;
14767 u32 save_line_number;
14768
14769 FILE *new_fp, *save_ifp;
14770
14771 if (unformat (vam->input, "%s", &s))
14772 {
14773 new_fp = fopen ((char *) s, "r");
14774 if (new_fp == 0)
14775 {
14776 errmsg ("Couldn't open script file %s", s);
14777 vec_free (s);
14778 return -99;
14779 }
14780 }
14781 else
14782 {
14783 errmsg ("Missing script name");
14784 return -99;
14785 }
14786
14787 clib_memcpy (&save_input, &vam->input, sizeof (save_input));
14788 clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
14789 save_ifp = vam->ifp;
14790 save_line_number = vam->input_line_number;
14791 save_current_file = (char *) vam->current_file;
14792
14793 vam->input_line_number = 0;
14794 vam->ifp = new_fp;
14795 vam->current_file = s;
14796 do_one_file (vam);
14797
Sirshak Dasb0861822018-05-29 21:13:21 -050014798 clib_memcpy (&vam->input, &save_input, sizeof (save_input));
Damjan Marion7cd468a2016-12-19 23:05:39 +010014799 clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
14800 vam->ifp = save_ifp;
14801 vam->input_line_number = save_line_number;
14802 vam->current_file = (u8 *) save_current_file;
14803 vec_free (s);
14804
14805 return 0;
14806#else
14807 clib_warning ("use the exec command...");
14808 return -99;
14809#endif
14810}
14811
14812static int
14813echo (vat_main_t * vam)
14814{
14815 print (vam->ofp, "%v", vam->input->buffer);
14816 return 0;
14817}
14818
14819/* List of API message constructors, CLI names map to api_xxx */
14820#define foreach_vpe_api_msg \
Jon Loeligerc83c3b72017-02-23 13:57:35 -060014821_(create_loopback,"[mac <mac-addr>] [instance <instance>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014822_(sw_interface_dump,"") \
14823_(sw_interface_set_flags, \
14824 "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
14825_(sw_interface_add_del_address, \
14826 "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
Stevenad8015b2017-10-29 22:10:46 -070014827_(sw_interface_set_rx_mode, \
14828 "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
Mohsin Kazmi54f7c512018-08-23 18:28:11 +020014829_(sw_interface_set_rx_placement, \
14830 "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]") \
Mohsin Kazmif0b42f42018-09-10 18:11:00 +020014831_(sw_interface_rx_placement_dump, \
14832 "[<intfc> | sw_if_index <id>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014833_(sw_interface_set_table, \
14834 "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]") \
14835_(sw_interface_set_mpls_enable, \
14836 "<intfc> | sw_if_index [disable | dis]") \
14837_(sw_interface_set_vpath, \
14838 "<intfc> | sw_if_index <id> enable | disable") \
14839_(sw_interface_set_vxlan_bypass, \
John Lo2b81eb82017-01-30 13:12:10 -050014840 "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014841_(sw_interface_set_l2_xconnect, \
14842 "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
14843 "enable | disable") \
14844_(sw_interface_set_l2_bridge, \
Eyal Barif24991c2017-04-05 05:33:21 +030014845 "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n" \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014846 "[shg <split-horizon-group>] [bvi]\n" \
14847 "enable | disable") \
Eyal Barif24991c2017-04-05 05:33:21 +030014848_(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014849_(bridge_domain_add_del, \
John Lo70bfcaf2017-11-14 13:19:26 -050014850 "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 +010014851_(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n") \
14852_(l2fib_add_del, \
14853 "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 +030014854_(l2fib_flush_bd, "bd_id <bridge-domain-id>") \
14855_(l2fib_flush_int, "<intfc> | sw_if_index <id>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014856_(l2_flags, \
John Lo8d00fff2017-08-03 00:35:36 -040014857 "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014858_(bridge_flags, \
14859 "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
Damjan Marion8389fb92017-10-13 18:29:53 +020014860_(tap_create_v2, \
Mohsin Kazmi50bd1652020-08-26 11:07:48 +020014861 "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 +020014862_(tap_delete_v2, \
14863 "<vpp-if-name> | sw_if_index <id>") \
14864_(sw_interface_tap_v2_dump, "") \
Mohsin Kazmi518251b2020-09-01 17:17:44 +000014865_(virtio_pci_create_v2, \
Mohsin Kazmie347acb2020-09-28 10:26:33 +000014866 "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 +010014867_(virtio_pci_delete, \
14868 "<vpp-if-name> | sw_if_index <id>") \
14869_(sw_interface_virtio_pci_dump, "") \
Steven9cd2d7a2017-12-20 12:43:01 -080014870_(bond_create, \
14871 "[hw-addr <mac-addr>] {round-robin | active-backup | " \
Alexander Chernavinad9d5282018-12-13 09:08:09 -050014872 "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} " \
Steven Luonga1876b82019-08-20 16:58:00 -070014873 "[id <if-id>]") \
Steven Luongea717862020-07-30 07:31:40 -070014874_(bond_create2, \
14875 "[hw-addr <mac-addr>] {mode round-robin | active-backup | " \
14876 "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} " \
14877 "[id <if-id>] [gso]") \
Steven9cd2d7a2017-12-20 12:43:01 -080014878_(bond_delete, \
14879 "<vpp-if-name> | sw_if_index <id>") \
Steven Luong4c4223e2020-07-15 08:44:54 -070014880_(bond_add_member, \
Steven Luonga1876b82019-08-20 16:58:00 -070014881 "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]") \
Steven Luong4c4223e2020-07-15 08:44:54 -070014882_(bond_detach_member, \
Steven9cd2d7a2017-12-20 12:43:01 -080014883 "sw_if_index <n>") \
Steven Luonga1876b82019-08-20 16:58:00 -070014884 _(sw_interface_set_bond_weight, "<intfc> | sw_if_index <nn> weight <value>") \
Steven Luong4c4223e2020-07-15 08:44:54 -070014885 _(sw_bond_interface_dump, "<intfc> | sw_if_index <nn>") \
14886 _(sw_member_interface_dump, \
Steven9cd2d7a2017-12-20 12:43:01 -080014887 "<vpp-if-name> | sw_if_index <id>") \
Neale Ranns28ab9cc2017-08-14 07:18:42 -070014888_(ip_table_add_del, \
John Loe166fd92018-09-13 14:08:59 -040014889 "table <n> [ipv6] [add | del]\n") \
Neale Ranns097fa662018-05-01 05:17:55 -070014890_(ip_route_add_del, \
John Lo22030432018-09-20 16:07:00 -040014891 "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
14892 "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
John Lo06fda9c2018-10-03 16:32:44 -040014893 "[weight <n>] [drop] [local] [classify <n>] [out-label <n>]\n" \
14894 "[multipath] [count <n>] [del]") \
Neale Ranns32e1c012016-11-22 17:07:28 +000014895_(ip_mroute_add_del, \
14896 "<src> <grp>/<mask> [table-id <n>]\n" \
14897 "[<intfc> | sw_if_index <id>] [local] [del]") \
Neale Ranns28ab9cc2017-08-14 07:18:42 -070014898_(mpls_table_add_del, \
John Loe166fd92018-09-13 14:08:59 -040014899 "table <n> [add | del]\n") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014900_(mpls_route_add_del, \
John Loe166fd92018-09-13 14:08:59 -040014901 "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n" \
14902 "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n" \
14903 "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n" \
14904 "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n" \
John Lo06fda9c2018-10-03 16:32:44 -040014905 "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n" \
14906 "[count <n>] [del]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014907_(mpls_ip_bind_unbind, \
14908 "<label> <addr/len>") \
14909_(mpls_tunnel_add_del, \
John Lo06fda9c2018-10-03 16:32:44 -040014910 "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
14911 "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n" \
14912 "[l2-only] [out-label <n>]") \
John Loe166fd92018-09-13 14:08:59 -040014913_(sr_mpls_policy_add, \
14914 "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]") \
14915_(sr_mpls_policy_del, \
14916 "bsid <id>") \
Neale Rannsd792d9c2017-10-21 10:53:20 -070014917_(bier_table_add_del, \
14918 "<label> <sub-domain> <set> <bsl> [del]") \
14919_(bier_route_add_del, \
14920 "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
14921 "[<intfc> | sw_if_index <id>]" \
14922 "[weight <n>] [del] [multipath]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014923_(sw_interface_set_unnumbered, \
14924 "<intfc> | sw_if_index <id> unnum_if_index <id> [del]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014925_(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>") \
14926_(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n" \
14927 "[outer_vlan_id <n>][inner_vlan_id <n>]\n" \
14928 "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n" \
14929 "[outer_vlan_id_any][inner_vlan_id_any]") \
Neale Ranns9db6ada2019-11-08 12:42:31 +000014930_(ip_table_replace_begin, "table <n> [ipv6]") \
14931_(ip_table_flush, "table <n> [ipv6]") \
14932_(ip_table_replace_end, "table <n> [ipv6]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014933_(set_ip_flow_hash, \
14934 "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]") \
14935_(sw_interface_ip6_enable_disable, \
14936 "<intfc> | sw_if_index <id> enable | disable") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014937_(l2_patch_add_del, \
14938 "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
14939 "enable | disable") \
Pablo Camarillofb380952016-12-07 18:34:18 +010014940_(sr_localsid_add_del, \
14941 "(del) address <addr> next_hop <addr> behavior <beh>\n" \
14942 "fib-table <num> (end.psp) sw_if_index <num>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014943_(classify_add_del_table, \
14944 "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n" \
14945 " [del] [del-chain] mask <mask-value>\n" \
14946 " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n" \
14947 " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]") \
14948_(classify_add_del_session, \
14949 "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n" \
14950 " table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n" \
14951 " [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n" \
14952 " [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]") \
14953_(classify_set_interface_ip_table, \
14954 "<intfc> | sw_if_index <nn> table <nn>") \
14955_(classify_set_interface_l2_tables, \
14956 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
14957 " [other-table <nn>]") \
14958_(get_node_index, "node <node-name") \
14959_(add_node_next, "node <node-name> next <next-node-name>") \
eyal bariaf86a482018-04-17 11:20:27 +030014960_(vxlan_offload_rx, \
14961 "hw { <interface name> | hw_if_index <nn>} " \
14962 "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014963_(vxlan_add_del_tunnel, \
14964 "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n" \
Jon Loeliger3d460bd2018-02-01 16:36:12 -060014965 "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n" \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014966 "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]") \
14967_(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014968_(l2_fib_clear_table, "") \
14969_(l2_interface_efp_filter, "sw_if_index <nn> enable | disable") \
14970_(l2_interface_vlan_tag_rewrite, \
14971 "<intfc> | sw_if_index <nn> \n" \
14972 "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n" \
14973 "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>") \
14974_(create_vhost_user_if, \
14975 "socket <filename> [server] [renumber <dev_instance>] " \
Steven Luong4208a4c2019-05-06 08:51:56 -070014976 "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] " \
Steven Luongbc0d9ff2020-03-23 09:34:59 -070014977 "[mac <mac_address>] [packed]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014978_(modify_vhost_user_if, \
14979 "<intfc> | sw_if_index <nn> socket <filename>\n" \
Steven Luongbc0d9ff2020-03-23 09:34:59 -070014980 "[server] [renumber <dev_instance>] [gso] [packed]") \
Steven Luong27ba5002020-11-17 13:30:44 -080014981_(create_vhost_user_if_v2, \
14982 "socket <filename> [server] [renumber <dev_instance>] " \
14983 "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] " \
14984 "[mac <mac_address>] [packed] [event-idx]") \
14985_(modify_vhost_user_if_v2, \
14986 "<intfc> | sw_if_index <nn> socket <filename>\n" \
14987 "[server] [renumber <dev_instance>] [gso] [packed] [event-idx]")\
Damjan Marion7cd468a2016-12-19 23:05:39 +010014988_(delete_vhost_user_if, "<intfc> | sw_if_index <nn>") \
Steven Luonga0e8d962020-05-18 17:12:56 -070014989_(sw_interface_vhost_user_dump, "<intfc> | sw_if_index <nn>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014990_(show_version, "") \
Mohsin Kazmi5d64c782018-09-11 20:27:09 +020014991_(show_threads, "") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014992_(vxlan_gpe_add_del_tunnel, \
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080014993 "local <addr> remote <addr> | group <mcast-ip-addr>\n" \
14994 "{ <intfc> | mcast_sw_if_index <nn> } }\n" \
14995 "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n" \
14996 "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014997_(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]") \
14998_(l2_fib_table_dump, "bd_id <bridge-domain-id>") \
14999_(interface_name_renumber, \
15000 "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>") \
15001_(input_acl_set_interface, \
15002 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
15003 " [l2-table <nn>] [del]") \
John Lo8d00fff2017-08-03 00:35:36 -040015004_(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015005_(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)") \
15006_(ip_dump, "ipv4 | ipv6") \
15007_(ipsec_spd_add_del, "spd_id <n> [del]") \
15008_(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n" \
15009 " spid_id <n> ") \
Neale Ranns17dcec02019-01-09 21:22:20 -080015010_(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n" \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015011 " crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n" \
15012 " integ_alg <alg> integ_key <hex>") \
Neale Ranns17dcec02019-01-09 21:22:20 -080015013_(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n" \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015014 " (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n" \
15015 " laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
15016 " [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
Matthew Smith28029532017-09-26 13:33:44 -050015017_(ipsec_sa_dump, "[sa_id <n>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015018_(delete_loopback,"sw_if_index <nn>") \
15019_(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
John Loe26c81f2019-01-07 15:16:33 -050015020_(bd_ip_mac_flush, "bd_id <bridge-domain-id>") \
15021_(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015022_(want_interface_events, "enable|disable") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015023_(get_first_msg_id, "client <name>") \
15024_(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
15025_(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n" \
15026 "fib-id <nn> [ip4][ip6][default]") \
15027_(get_node_graph, " ") \
15028_(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>") \
15029_(ioam_enable, "[trace] [pow] [ppc <encap|decap>]") \
15030_(ioam_disable, "") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015031_(af_packet_create, "name <host interface name> [hw_addr <mac>]") \
15032_(af_packet_delete, "name <host interface name>") \
Mohsin Kazmi04e0bb22018-05-28 18:55:37 +020015033_(af_packet_dump, "") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015034_(policer_add_del, "name <policer name> <params> [del]") \
15035_(policer_dump, "[name <policer name>]") \
15036_(policer_classify_set_interface, \
15037 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
15038 " [l2-table <nn>] [del]") \
15039_(policer_classify_dump, "type [ip4|ip6|l2]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015040_(mpls_tunnel_dump, "tunnel_index <tunnel-id>") \
Neale Ranns097fa662018-05-01 05:17:55 -070015041_(mpls_table_dump, "") \
15042_(mpls_route_dump, "table-id <ID>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015043_(classify_table_ids, "") \
15044_(classify_table_by_interface, "sw_if_index <sw_if_index>") \
15045_(classify_table_info, "table_id <nn>") \
15046_(classify_session_dump, "table_id <nn>") \
15047_(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] " \
15048 "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] " \
15049 "[template_interval <nn>] [udp_checksum]") \
15050_(ipfix_exporter_dump, "") \
15051_(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
15052_(ipfix_classify_stream_dump, "") \
15053_(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
15054_(ipfix_classify_table_dump, "") \
Eyal Bari001fd402017-07-16 09:34:53 +030015055_(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 +030015056_(sw_interface_span_dump, "[l2]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015057_(get_next_index, "node-name <node-name> next-node-name <node-name>") \
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +020015058_(pg_create_interface, "if_id <nn> [gso-enabled gso-size <size>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015059_(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]") \
15060_(pg_enable_disable, "[stream <id>] disable") \
Mohsin Kazmif382b062020-08-11 15:00:44 +020015061_(pg_interface_enable_disable_coalesce, "<intf> | sw_if_index <nn> enable | disable") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015062_(ip_source_and_port_range_check_add_del, \
15063 "<ip-addr>/<mask> range <nn>-<nn> vrf <id>") \
15064_(ip_source_and_port_range_check_interface_add_del, \
15065 "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]" \
15066 "[udp-in-vrf <id>] [udp-out-vrf <id>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015067_(delete_subif,"<intfc> | sw_if_index <nn>") \
15068_(l2_interface_pbb_tag_rewrite, \
15069 "<intfc> | sw_if_index <nn> \n" \
15070 "[disable | push | pop | translate_pbb_stag <outer_tag>] \n" \
15071 "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]") \
Pavel Kotuceke88865d2018-11-28 07:42:11 +010015072_(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015073_(flow_classify_set_interface, \
15074 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
15075_(flow_classify_dump, "type [ip4|ip6]") \
Neale Ranns097fa662018-05-01 05:17:55 -070015076_(ip_table_dump, "") \
15077_(ip_route_dump, "table-id [ip4|ip6]") \
15078_(ip_mtable_dump, "") \
15079_(ip_mroute_dump, "table-id [ip4|ip6]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015080_(feature_enable_disable, "arc_name <arc_name> " \
15081 "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]") \
Mohsin Kazmi29467b52019-10-08 19:42:38 +020015082_(feature_gso_enable_disable, "<intfc> | sw_if_index <nn> " \
15083 "[enable | disable] ") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015084_(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>" \
15085"[disable]") \
Matthew Smithe0792fd2019-07-12 11:48:24 -050015086_(sw_interface_add_del_mac_address, "<intfc> | sw_if_index <nn> " \
15087 "mac <mac-address> [del]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015088_(l2_xconnect_dump, "") \
Ole Troand7231612018-06-07 10:17:57 +020015089_(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>") \
Pavel Kotucek6899a302017-06-08 08:46:10 +020015090_(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]") \
Pavel Kotucek15ac81c2017-06-20 14:00:26 +020015091_(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
Steve Shin99a0e602017-07-01 04:16:20 +000015092_(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
Dave Barach59b25652017-09-10 15:04:27 -040015093_(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]") \
Florin Coras90a63982017-12-19 04:50:01 -080015094_(sock_init_shm, "size <nnn>") \
Florin Corascea194d2017-10-02 00:18:51 -070015095_(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
Florin Coras1c710452017-10-17 00:03:13 -070015096_(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> " \
15097 "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>") \
Florin Coras6c36f532017-11-03 18:32:34 -070015098_(session_rules_dump, "") \
Florin Coras595992c2017-11-06 17:17:08 -080015099_(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>") \
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +010015100_(output_acl_set_interface, \
15101 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
15102 " [l2-table <nn>] [del]") \
Ole Troane906aac2018-06-14 14:42:14 +020015103_(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
Damjan Marion7cd468a2016-12-19 23:05:39 +010015104
15105/* List of command functions, CLI names map directly to functions */
15106#define foreach_cli_function \
15107_(comment, "usage: comment <ignore-rest-of-line>") \
15108_(dump_interface_table, "usage: dump_interface_table") \
15109_(dump_sub_interface_table, "usage: dump_sub_interface_table") \
15110_(dump_ipv4_table, "usage: dump_ipv4_table") \
15111_(dump_ipv6_table, "usage: dump_ipv6_table") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015112_(dump_macro_table, "usage: dump_macro_table ") \
15113_(dump_node_table, "usage: dump_node_table") \
15114_(dump_msg_api_table, "usage: dump_msg_api_table") \
Dave Barachb09f4d02019-07-15 16:00:03 -040015115_(elog_setup, "usage: elog_setup [nevents, default 128K]") \
15116_(elog_disable, "usage: elog_disable") \
15117_(elog_enable, "usage: elog_enable") \
15118_(elog_save, "usage: elog_save <filename>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015119_(get_msg_id, "usage: get_msg_id name_and_crc") \
15120_(echo, "usage: echo <message>") \
15121_(exec, "usage: exec <vpe-debug-CLI-command>") \
15122_(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>") \
15123_(help, "usage: help") \
15124_(q, "usage: quit") \
15125_(quit, "usage: quit") \
15126_(search_node_table, "usage: search_node_table <name>...") \
15127_(set, "usage: set <variable-name> <value>") \
15128_(script, "usage: script <file-name>") \
Neale Ranns097fa662018-05-01 05:17:55 -070015129_(statseg, "usage: statseg") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015130_(unset, "usage: unset <variable-name>")
Dave Barach048a4e52018-06-01 18:52:25 -040015131
Damjan Marion7cd468a2016-12-19 23:05:39 +010015132#define _(N,n) \
15133 static void vl_api_##n##_t_handler_uni \
15134 (vl_api_##n##_t * mp) \
15135 { \
15136 vat_main_t * vam = &vat_main; \
15137 if (vam->json_output) { \
15138 vl_api_##n##_t_handler_json(mp); \
15139 } else { \
15140 vl_api_##n##_t_handler(mp); \
15141 } \
15142 }
15143foreach_vpe_api_reply_msg;
Dave Baracha1a093d2017-03-02 13:13:23 -050015144#if VPP_API_TEST_BUILTIN == 0
15145foreach_standalone_reply_msg;
15146#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +010015147#undef _
15148
15149void
15150vat_api_hookup (vat_main_t * vam)
15151{
15152#define _(N,n) \
15153 vl_msg_api_set_handlers(VL_API_##N, #n, \
15154 vl_api_##n##_t_handler_uni, \
15155 vl_noop_handler, \
15156 vl_api_##n##_t_endian, \
15157 vl_api_##n##_t_print, \
15158 sizeof(vl_api_##n##_t), 1);
15159 foreach_vpe_api_reply_msg;
Dave Baracha1a093d2017-03-02 13:13:23 -050015160#if VPP_API_TEST_BUILTIN == 0
15161 foreach_standalone_reply_msg;
15162#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +010015163#undef _
15164
15165#if (VPP_API_TEST_BUILTIN==0)
15166 vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015167
15168 vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
15169
15170 vam->function_by_name = hash_create_string (0, sizeof (uword));
15171
15172 vam->help_by_name = hash_create_string (0, sizeof (uword));
Dave Barach45e4f362017-03-07 12:52:31 -050015173#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +010015174
15175 /* API messages we can send */
15176#define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
15177 foreach_vpe_api_msg;
15178#undef _
15179
15180 /* Help strings */
15181#define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
15182 foreach_vpe_api_msg;
15183#undef _
Damjan Marion7cd468a2016-12-19 23:05:39 +010015184
15185 /* CLI functions */
15186#define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
15187 foreach_cli_function;
15188#undef _
15189
15190 /* Help strings */
15191#define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
15192 foreach_cli_function;
15193#undef _
15194}
15195
Dave Baracha1a093d2017-03-02 13:13:23 -050015196#if VPP_API_TEST_BUILTIN
15197static clib_error_t *
15198vat_api_hookup_shim (vlib_main_t * vm)
15199{
15200 vat_api_hookup (&vat_main);
15201 return 0;
15202}
15203
15204VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
15205#endif
15206
Damjan Marion7cd468a2016-12-19 23:05:39 +010015207/*
15208 * fd.io coding-style-patch-verification: ON
15209 *
15210 * Local Variables:
15211 * eval: (c-set-style "gnu")
15212 * End:
15213 */