blob: 90f79079fbe194bc49f1d2da9f5d892f4b53c5b9 [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
Stevenf3b53642017-05-01 14:03:02 -070010202 print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
Damjan Marion7cd468a2016-12-19 23:05:39 +010010203 (char *) mp->interface_name,
10204 ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
Jakub Grajciar5d4c99f2019-09-26 10:21:59 +020010205 features, mp->is_server,
Stevenf3b53642017-05-01 14:03:02 -070010206 ntohl (mp->num_regions), (char *) mp->sock_filename);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010207 print (vam->ofp, " Status: '%s'", strerror (ntohl (mp->sock_errno)));
10208}
10209
10210static void vl_api_sw_interface_vhost_user_details_t_handler_json
10211 (vl_api_sw_interface_vhost_user_details_t * mp)
10212{
10213 vat_main_t *vam = &vat_main;
10214 vat_json_node_t *node = NULL;
10215
10216 if (VAT_JSON_ARRAY != vam->json_tree.type)
10217 {
10218 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10219 vat_json_init_array (&vam->json_tree);
10220 }
10221 node = vat_json_array_add (&vam->json_tree);
10222
10223 vat_json_init_object (node);
10224 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10225 vat_json_object_add_string_copy (node, "interface_name",
10226 mp->interface_name);
10227 vat_json_object_add_uint (node, "virtio_net_hdr_sz",
10228 ntohl (mp->virtio_net_hdr_sz));
Jakub Grajciar5d4c99f2019-09-26 10:21:59 +020010229 vat_json_object_add_uint (node, "features_first_32",
10230 clib_net_to_host_u32 (mp->features_first_32));
10231 vat_json_object_add_uint (node, "features_last_32",
10232 clib_net_to_host_u32 (mp->features_last_32));
Damjan Marion7cd468a2016-12-19 23:05:39 +010010233 vat_json_object_add_uint (node, "is_server", mp->is_server);
10234 vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
10235 vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
10236 vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
10237}
10238
10239static int
10240api_sw_interface_vhost_user_dump (vat_main_t * vam)
10241{
Steven Luonga0e8d962020-05-18 17:12:56 -070010242 unformat_input_t *i = vam->input;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010243 vl_api_sw_interface_vhost_user_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010244 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010245 int ret;
Steven Luonga0e8d962020-05-18 17:12:56 -070010246 u32 sw_if_index = ~0;
10247
10248 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10249 {
10250 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10251 ;
10252 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10253 ;
10254 else
10255 break;
10256 }
10257
Damjan Marion7cd468a2016-12-19 23:05:39 +010010258 print (vam->ofp,
Stevenf3b53642017-05-01 14:03:02 -070010259 "Interface name idx hdr_sz features server regions filename");
Damjan Marion7cd468a2016-12-19 23:05:39 +010010260
10261 /* Get list of vhost-user interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010262 M (SW_INTERFACE_VHOST_USER_DUMP, mp);
Steven Luonga0e8d962020-05-18 17:12:56 -070010263 mp->sw_if_index = ntohl (sw_if_index);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010264 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010265
10266 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040010267 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010268 S (mp_ping);
10269
Jon Loeliger56c7b012017-02-01 12:31:41 -060010270 W (ret);
10271 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010272}
10273
10274static int
10275api_show_version (vat_main_t * vam)
10276{
10277 vl_api_show_version_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010278 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010279
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010280 M (SHOW_VERSION, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010281
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010282 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010283 W (ret);
10284 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010285}
10286
10287
10288static int
10289api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
10290{
10291 unformat_input_t *line_input = vam->input;
10292 vl_api_vxlan_gpe_add_del_tunnel_t *mp;
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010293 ip46_address_t local, remote;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010294 u8 is_add = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010295 u8 local_set = 0;
10296 u8 remote_set = 0;
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010297 u8 grp_set = 0;
10298 u32 mcast_sw_if_index = ~0;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010299 u32 encap_vrf_id = 0;
10300 u32 decap_vrf_id = 0;
10301 u8 protocol = ~0;
10302 u32 vni;
10303 u8 vni_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010304 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010305
10306 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10307 {
10308 if (unformat (line_input, "del"))
10309 is_add = 0;
10310 else if (unformat (line_input, "local %U",
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010311 unformat_ip46_address, &local))
Damjan Marion7cd468a2016-12-19 23:05:39 +010010312 {
10313 local_set = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010314 }
10315 else if (unformat (line_input, "remote %U",
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010316 unformat_ip46_address, &remote))
Damjan Marion7cd468a2016-12-19 23:05:39 +010010317 {
10318 remote_set = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010319 }
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010320 else if (unformat (line_input, "group %U %U",
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010321 unformat_ip46_address, &remote,
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010322 api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10323 {
10324 grp_set = remote_set = 1;
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010325 }
10326 else if (unformat (line_input, "group %U",
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010327 unformat_ip46_address, &remote))
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010328 {
10329 grp_set = remote_set = 1;
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010330 }
10331 else
10332 if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10333 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010334 else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10335 ;
10336 else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
10337 ;
10338 else if (unformat (line_input, "vni %d", &vni))
10339 vni_set = 1;
10340 else if (unformat (line_input, "next-ip4"))
10341 protocol = 1;
10342 else if (unformat (line_input, "next-ip6"))
10343 protocol = 2;
10344 else if (unformat (line_input, "next-ethernet"))
10345 protocol = 3;
10346 else if (unformat (line_input, "next-nsh"))
10347 protocol = 4;
10348 else
10349 {
10350 errmsg ("parse error '%U'", format_unformat_error, line_input);
10351 return -99;
10352 }
10353 }
10354
10355 if (local_set == 0)
10356 {
10357 errmsg ("tunnel local address not specified");
10358 return -99;
10359 }
10360 if (remote_set == 0)
10361 {
10362 errmsg ("tunnel remote address not specified");
10363 return -99;
10364 }
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010365 if (grp_set && mcast_sw_if_index == ~0)
10366 {
10367 errmsg ("tunnel nonexistent multicast device");
10368 return -99;
10369 }
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010370 if (ip46_address_is_ip4 (&local) != ip46_address_is_ip4 (&remote))
Damjan Marion7cd468a2016-12-19 23:05:39 +010010371 {
10372 errmsg ("both IPv4 and IPv6 addresses specified");
10373 return -99;
10374 }
10375
10376 if (vni_set == 0)
10377 {
10378 errmsg ("vni not specified");
10379 return -99;
10380 }
10381
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010382 M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010383
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010384 ip_address_encode (&local,
10385 ip46_address_is_ip4 (&local) ? IP46_TYPE_IP4 :
10386 IP46_TYPE_IP6, &mp->local);
10387 ip_address_encode (&remote,
10388 ip46_address_is_ip4 (&remote) ? IP46_TYPE_IP4 :
10389 IP46_TYPE_IP6, &mp->remote);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010390
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010391 mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010392 mp->encap_vrf_id = ntohl (encap_vrf_id);
10393 mp->decap_vrf_id = ntohl (decap_vrf_id);
10394 mp->protocol = protocol;
10395 mp->vni = ntohl (vni);
10396 mp->is_add = is_add;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010397
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010398 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010399 W (ret);
10400 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010401}
10402
10403static void vl_api_vxlan_gpe_tunnel_details_t_handler
10404 (vl_api_vxlan_gpe_tunnel_details_t * mp)
10405{
10406 vat_main_t *vam = &vat_main;
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010407 ip46_address_t local, remote;
10408
10409 ip_address_decode (&mp->local, &local);
10410 ip_address_decode (&mp->remote, &remote);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010411
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010412 print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
Damjan Marion7cd468a2016-12-19 23:05:39 +010010413 ntohl (mp->sw_if_index),
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010414 format_ip46_address, &local, IP46_TYPE_ANY,
10415 format_ip46_address, &remote, IP46_TYPE_ANY,
10416 ntohl (mp->vni), mp->protocol,
10417 ntohl (mp->mcast_sw_if_index),
Damjan Marion7cd468a2016-12-19 23:05:39 +010010418 ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
10419}
10420
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010421
Damjan Marion7cd468a2016-12-19 23:05:39 +010010422static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
10423 (vl_api_vxlan_gpe_tunnel_details_t * mp)
10424{
10425 vat_main_t *vam = &vat_main;
10426 vat_json_node_t *node = NULL;
10427 struct in_addr ip4;
10428 struct in6_addr ip6;
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010429 ip46_address_t local, remote;
10430
10431 ip_address_decode (&mp->local, &local);
10432 ip_address_decode (&mp->remote, &remote);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010433
10434 if (VAT_JSON_ARRAY != vam->json_tree.type)
10435 {
10436 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10437 vat_json_init_array (&vam->json_tree);
10438 }
10439 node = vat_json_array_add (&vam->json_tree);
10440
10441 vat_json_init_object (node);
10442 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010443 if (ip46_address_is_ip4 (&local))
Damjan Marion7cd468a2016-12-19 23:05:39 +010010444 {
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010445 clib_memcpy (&ip4, &local.ip4, sizeof (ip4));
10446 vat_json_object_add_ip4 (node, "local", ip4);
10447 clib_memcpy (&ip4, &remote.ip4, sizeof (ip4));
10448 vat_json_object_add_ip4 (node, "remote", ip4);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010449 }
10450 else
10451 {
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010452 clib_memcpy (&ip6, &local.ip6, sizeof (ip6));
10453 vat_json_object_add_ip6 (node, "local", ip6);
10454 clib_memcpy (&ip6, &remote.ip6, sizeof (ip6));
10455 vat_json_object_add_ip6 (node, "remote", ip6);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010456 }
10457 vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10458 vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010459 vat_json_object_add_uint (node, "mcast_sw_if_index",
10460 ntohl (mp->mcast_sw_if_index));
Damjan Marion7cd468a2016-12-19 23:05:39 +010010461 vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10462 vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
10463 vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10464}
10465
10466static int
10467api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
10468{
10469 unformat_input_t *i = vam->input;
10470 vl_api_vxlan_gpe_tunnel_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010471 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010472 u32 sw_if_index;
10473 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010474 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010475
10476 /* Parse args required to build the message */
10477 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10478 {
10479 if (unformat (i, "sw_if_index %d", &sw_if_index))
10480 sw_if_index_set = 1;
10481 else
10482 break;
10483 }
10484
10485 if (sw_if_index_set == 0)
10486 {
10487 sw_if_index = ~0;
10488 }
10489
10490 if (!vam->json_output)
10491 {
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010492 print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
Damjan Marion7cd468a2016-12-19 23:05:39 +010010493 "sw_if_index", "local", "remote", "vni",
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010494 "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
Damjan Marion7cd468a2016-12-19 23:05:39 +010010495 }
10496
10497 /* Get list of vxlan-tunnel interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010498 M (VXLAN_GPE_TUNNEL_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010499
10500 mp->sw_if_index = htonl (sw_if_index);
10501
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010502 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010503
10504 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040010505 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010506 S (mp_ping);
10507
Jon Loeliger56c7b012017-02-01 12:31:41 -060010508 W (ret);
10509 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010510}
10511
Ole Troan01384fe2017-05-12 11:55:35 +020010512static void vl_api_l2_fib_table_details_t_handler
10513 (vl_api_l2_fib_table_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010010514{
10515 vat_main_t *vam = &vat_main;
10516
10517 print (vam->ofp, "%3" PRIu32 " %U %3" PRIu32
10518 " %d %d %d",
Mohsin Kazmi57938f62017-10-27 21:28:07 +020010519 ntohl (mp->bd_id), format_ethernet_address, mp->mac,
Damjan Marion7cd468a2016-12-19 23:05:39 +010010520 ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
10521 mp->bvi_mac);
10522}
10523
Ole Troan01384fe2017-05-12 11:55:35 +020010524static void vl_api_l2_fib_table_details_t_handler_json
10525 (vl_api_l2_fib_table_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010010526{
10527 vat_main_t *vam = &vat_main;
10528 vat_json_node_t *node = NULL;
10529
10530 if (VAT_JSON_ARRAY != vam->json_tree.type)
10531 {
10532 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10533 vat_json_init_array (&vam->json_tree);
10534 }
10535 node = vat_json_array_add (&vam->json_tree);
10536
10537 vat_json_init_object (node);
10538 vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
Mohsin Kazmi57938f62017-10-27 21:28:07 +020010539 vat_json_object_add_bytes (node, "mac", mp->mac, 6);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010540 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10541 vat_json_object_add_uint (node, "static_mac", mp->static_mac);
10542 vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
10543 vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
10544}
10545
10546static int
10547api_l2_fib_table_dump (vat_main_t * vam)
10548{
10549 unformat_input_t *i = vam->input;
10550 vl_api_l2_fib_table_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010551 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010552 u32 bd_id;
10553 u8 bd_id_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010554 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010555
10556 /* Parse args required to build the message */
10557 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10558 {
10559 if (unformat (i, "bd_id %d", &bd_id))
10560 bd_id_set = 1;
10561 else
10562 break;
10563 }
10564
10565 if (bd_id_set == 0)
10566 {
10567 errmsg ("missing bridge domain");
10568 return -99;
10569 }
10570
10571 print (vam->ofp, "BD-ID Mac Address sw-ndx Static Filter BVI");
10572
10573 /* Get list of l2 fib entries */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010574 M (L2_FIB_TABLE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010575
10576 mp->bd_id = ntohl (bd_id);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010577 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010578
10579 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040010580 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010581 S (mp_ping);
10582
Jon Loeliger56c7b012017-02-01 12:31:41 -060010583 W (ret);
10584 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010585}
10586
10587
10588static int
10589api_interface_name_renumber (vat_main_t * vam)
10590{
10591 unformat_input_t *line_input = vam->input;
10592 vl_api_interface_name_renumber_t *mp;
10593 u32 sw_if_index = ~0;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010594 u32 new_show_dev_instance = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010595 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010596
10597 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10598 {
10599 if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
10600 &sw_if_index))
10601 ;
10602 else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
10603 ;
10604 else if (unformat (line_input, "new_show_dev_instance %d",
10605 &new_show_dev_instance))
10606 ;
10607 else
10608 break;
10609 }
10610
10611 if (sw_if_index == ~0)
10612 {
10613 errmsg ("missing interface name or sw_if_index");
10614 return -99;
10615 }
10616
10617 if (new_show_dev_instance == ~0)
10618 {
10619 errmsg ("missing new_show_dev_instance");
10620 return -99;
10621 }
10622
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010623 M (INTERFACE_NAME_RENUMBER, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010624
10625 mp->sw_if_index = ntohl (sw_if_index);
10626 mp->new_show_dev_instance = ntohl (new_show_dev_instance);
10627
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010628 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010629 W (ret);
10630 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010631}
10632
10633static int
John Lo8d00fff2017-08-03 00:35:36 -040010634api_want_l2_macs_events (vat_main_t * vam)
10635{
10636 unformat_input_t *line_input = vam->input;
10637 vl_api_want_l2_macs_events_t *mp;
10638 u8 enable_disable = 1;
10639 u32 scan_delay = 0;
10640 u32 max_macs_in_event = 0;
10641 u32 learn_limit = 0;
10642 int ret;
10643
10644 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10645 {
10646 if (unformat (line_input, "learn-limit %d", &learn_limit))
10647 ;
10648 else if (unformat (line_input, "scan-delay %d", &scan_delay))
10649 ;
10650 else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
10651 ;
10652 else if (unformat (line_input, "disable"))
10653 enable_disable = 0;
10654 else
10655 break;
10656 }
10657
10658 M (WANT_L2_MACS_EVENTS, mp);
10659 mp->enable_disable = enable_disable;
10660 mp->pid = htonl (getpid ());
10661 mp->learn_limit = htonl (learn_limit);
10662 mp->scan_delay = (u8) scan_delay;
10663 mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
10664 S (mp);
10665 W (ret);
10666 return ret;
10667}
10668
10669static int
Damjan Marion7cd468a2016-12-19 23:05:39 +010010670api_input_acl_set_interface (vat_main_t * vam)
10671{
10672 unformat_input_t *i = vam->input;
10673 vl_api_input_acl_set_interface_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010674 u32 sw_if_index;
10675 int sw_if_index_set;
10676 u32 ip4_table_index = ~0;
10677 u32 ip6_table_index = ~0;
10678 u32 l2_table_index = ~0;
10679 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010680 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010681
10682 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10683 {
10684 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10685 sw_if_index_set = 1;
10686 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10687 sw_if_index_set = 1;
10688 else if (unformat (i, "del"))
10689 is_add = 0;
10690 else if (unformat (i, "ip4-table %d", &ip4_table_index))
10691 ;
10692 else if (unformat (i, "ip6-table %d", &ip6_table_index))
10693 ;
10694 else if (unformat (i, "l2-table %d", &l2_table_index))
10695 ;
10696 else
10697 {
10698 clib_warning ("parse error '%U'", format_unformat_error, i);
10699 return -99;
10700 }
10701 }
10702
10703 if (sw_if_index_set == 0)
10704 {
10705 errmsg ("missing interface name or sw_if_index");
10706 return -99;
10707 }
10708
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010709 M (INPUT_ACL_SET_INTERFACE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010710
10711 mp->sw_if_index = ntohl (sw_if_index);
10712 mp->ip4_table_index = ntohl (ip4_table_index);
10713 mp->ip6_table_index = ntohl (ip6_table_index);
10714 mp->l2_table_index = ntohl (l2_table_index);
10715 mp->is_add = is_add;
10716
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010717 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010718 W (ret);
10719 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010720}
10721
10722static int
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +010010723api_output_acl_set_interface (vat_main_t * vam)
10724{
10725 unformat_input_t *i = vam->input;
10726 vl_api_output_acl_set_interface_t *mp;
10727 u32 sw_if_index;
10728 int sw_if_index_set;
10729 u32 ip4_table_index = ~0;
10730 u32 ip6_table_index = ~0;
10731 u32 l2_table_index = ~0;
10732 u8 is_add = 1;
10733 int ret;
10734
10735 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10736 {
10737 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10738 sw_if_index_set = 1;
10739 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10740 sw_if_index_set = 1;
10741 else if (unformat (i, "del"))
10742 is_add = 0;
10743 else if (unformat (i, "ip4-table %d", &ip4_table_index))
10744 ;
10745 else if (unformat (i, "ip6-table %d", &ip6_table_index))
10746 ;
10747 else if (unformat (i, "l2-table %d", &l2_table_index))
10748 ;
10749 else
10750 {
10751 clib_warning ("parse error '%U'", format_unformat_error, i);
10752 return -99;
10753 }
10754 }
10755
10756 if (sw_if_index_set == 0)
10757 {
10758 errmsg ("missing interface name or sw_if_index");
10759 return -99;
10760 }
10761
10762 M (OUTPUT_ACL_SET_INTERFACE, mp);
10763
10764 mp->sw_if_index = ntohl (sw_if_index);
10765 mp->ip4_table_index = ntohl (ip4_table_index);
10766 mp->ip6_table_index = ntohl (ip6_table_index);
10767 mp->l2_table_index = ntohl (l2_table_index);
10768 mp->is_add = is_add;
10769
10770 S (mp);
10771 W (ret);
10772 return ret;
10773}
10774
10775static int
Damjan Marion7cd468a2016-12-19 23:05:39 +010010776api_ip_address_dump (vat_main_t * vam)
10777{
10778 unformat_input_t *i = vam->input;
10779 vl_api_ip_address_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010780 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010781 u32 sw_if_index = ~0;
10782 u8 sw_if_index_set = 0;
10783 u8 ipv4_set = 0;
10784 u8 ipv6_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010785 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010786
10787 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10788 {
10789 if (unformat (i, "sw_if_index %d", &sw_if_index))
10790 sw_if_index_set = 1;
10791 else
10792 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10793 sw_if_index_set = 1;
10794 else if (unformat (i, "ipv4"))
10795 ipv4_set = 1;
10796 else if (unformat (i, "ipv6"))
10797 ipv6_set = 1;
10798 else
10799 break;
10800 }
10801
10802 if (ipv4_set && ipv6_set)
10803 {
10804 errmsg ("ipv4 and ipv6 flags cannot be both set");
10805 return -99;
10806 }
10807
10808 if ((!ipv4_set) && (!ipv6_set))
10809 {
10810 errmsg ("no ipv4 nor ipv6 flag set");
10811 return -99;
10812 }
10813
10814 if (sw_if_index_set == 0)
10815 {
10816 errmsg ("missing interface name or sw_if_index");
10817 return -99;
10818 }
10819
10820 vam->current_sw_if_index = sw_if_index;
10821 vam->is_ipv6 = ipv6_set;
10822
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010823 M (IP_ADDRESS_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010824 mp->sw_if_index = ntohl (sw_if_index);
10825 mp->is_ipv6 = ipv6_set;
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010826 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010827
10828 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040010829 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010830 S (mp_ping);
10831
Jon Loeliger56c7b012017-02-01 12:31:41 -060010832 W (ret);
10833 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010834}
10835
10836static int
10837api_ip_dump (vat_main_t * vam)
10838{
10839 vl_api_ip_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010840 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010841 unformat_input_t *in = vam->input;
10842 int ipv4_set = 0;
10843 int ipv6_set = 0;
10844 int is_ipv6;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010845 int i;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010846 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010847
10848 while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
10849 {
10850 if (unformat (in, "ipv4"))
10851 ipv4_set = 1;
10852 else if (unformat (in, "ipv6"))
10853 ipv6_set = 1;
10854 else
10855 break;
10856 }
10857
10858 if (ipv4_set && ipv6_set)
10859 {
10860 errmsg ("ipv4 and ipv6 flags cannot be both set");
10861 return -99;
10862 }
10863
10864 if ((!ipv4_set) && (!ipv6_set))
10865 {
10866 errmsg ("no ipv4 nor ipv6 flag set");
10867 return -99;
10868 }
10869
10870 is_ipv6 = ipv6_set;
10871 vam->is_ipv6 = is_ipv6;
10872
10873 /* free old data */
10874 for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
10875 {
10876 vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
10877 }
10878 vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
10879
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010880 M (IP_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010881 mp->is_ipv6 = ipv6_set;
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010882 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010883
10884 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040010885 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010886 S (mp_ping);
10887
Jon Loeliger56c7b012017-02-01 12:31:41 -060010888 W (ret);
10889 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010890}
10891
10892static int
10893api_ipsec_spd_add_del (vat_main_t * vam)
10894{
10895 unformat_input_t *i = vam->input;
10896 vl_api_ipsec_spd_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010897 u32 spd_id = ~0;
10898 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010899 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010900
10901 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10902 {
10903 if (unformat (i, "spd_id %d", &spd_id))
10904 ;
10905 else if (unformat (i, "del"))
10906 is_add = 0;
10907 else
10908 {
10909 clib_warning ("parse error '%U'", format_unformat_error, i);
10910 return -99;
10911 }
10912 }
10913 if (spd_id == ~0)
10914 {
10915 errmsg ("spd_id must be set");
10916 return -99;
10917 }
10918
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010919 M (IPSEC_SPD_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010920
10921 mp->spd_id = ntohl (spd_id);
10922 mp->is_add = is_add;
10923
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010924 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010925 W (ret);
10926 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010927}
10928
10929static int
10930api_ipsec_interface_add_del_spd (vat_main_t * vam)
10931{
10932 unformat_input_t *i = vam->input;
10933 vl_api_ipsec_interface_add_del_spd_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010934 u32 sw_if_index;
10935 u8 sw_if_index_set = 0;
10936 u32 spd_id = (u32) ~ 0;
10937 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010938 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010939
10940 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10941 {
10942 if (unformat (i, "del"))
10943 is_add = 0;
10944 else if (unformat (i, "spd_id %d", &spd_id))
10945 ;
10946 else
10947 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10948 sw_if_index_set = 1;
10949 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10950 sw_if_index_set = 1;
10951 else
10952 {
10953 clib_warning ("parse error '%U'", format_unformat_error, i);
10954 return -99;
10955 }
10956
10957 }
10958
10959 if (spd_id == (u32) ~ 0)
10960 {
10961 errmsg ("spd_id must be set");
10962 return -99;
10963 }
10964
10965 if (sw_if_index_set == 0)
10966 {
10967 errmsg ("missing interface name or sw_if_index");
10968 return -99;
10969 }
10970
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010971 M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010972
10973 mp->spd_id = ntohl (spd_id);
10974 mp->sw_if_index = ntohl (sw_if_index);
10975 mp->is_add = is_add;
10976
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010977 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010978 W (ret);
10979 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010980}
10981
10982static int
Neale Ranns17dcec02019-01-09 21:22:20 -080010983api_ipsec_spd_entry_add_del (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010010984{
10985 unformat_input_t *i = vam->input;
Neale Ranns17dcec02019-01-09 21:22:20 -080010986 vl_api_ipsec_spd_entry_add_del_t *mp;
Benoît Ganne49ee6842019-04-30 11:50:46 +020010987 u8 is_add = 1, is_outbound = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010988 u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
10989 i32 priority = 0;
10990 u32 rport_start = 0, rport_stop = (u32) ~ 0;
10991 u32 lport_start = 0, lport_stop = (u32) ~ 0;
Neale Ranns17dcec02019-01-09 21:22:20 -080010992 vl_api_address_t laddr_start = { }, laddr_stop =
10993 {
10994 }, raddr_start =
10995 {
10996 }, raddr_stop =
10997 {
10998 };
Jon Loeliger56c7b012017-02-01 12:31:41 -060010999 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011000
Damjan Marion7cd468a2016-12-19 23:05:39 +010011001 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11002 {
11003 if (unformat (i, "del"))
11004 is_add = 0;
11005 if (unformat (i, "outbound"))
11006 is_outbound = 1;
11007 if (unformat (i, "inbound"))
11008 is_outbound = 0;
11009 else if (unformat (i, "spd_id %d", &spd_id))
11010 ;
11011 else if (unformat (i, "sa_id %d", &sa_id))
11012 ;
11013 else if (unformat (i, "priority %d", &priority))
11014 ;
11015 else if (unformat (i, "protocol %d", &protocol))
11016 ;
11017 else if (unformat (i, "lport_start %d", &lport_start))
11018 ;
11019 else if (unformat (i, "lport_stop %d", &lport_stop))
11020 ;
11021 else if (unformat (i, "rport_start %d", &rport_start))
11022 ;
11023 else if (unformat (i, "rport_stop %d", &rport_stop))
11024 ;
Neale Ranns17dcec02019-01-09 21:22:20 -080011025 else if (unformat (i, "laddr_start %U",
11026 unformat_vl_api_address, &laddr_start))
Benoît Ganne49ee6842019-04-30 11:50:46 +020011027 ;
Neale Ranns17dcec02019-01-09 21:22:20 -080011028 else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
11029 &laddr_stop))
Benoît Ganne49ee6842019-04-30 11:50:46 +020011030 ;
Neale Ranns17dcec02019-01-09 21:22:20 -080011031 else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
11032 &raddr_start))
Benoît Ganne49ee6842019-04-30 11:50:46 +020011033 ;
Neale Ranns17dcec02019-01-09 21:22:20 -080011034 else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
11035 &raddr_stop))
Benoît Ganne49ee6842019-04-30 11:50:46 +020011036 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011037 else
11038 if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
11039 {
11040 if (policy == IPSEC_POLICY_ACTION_RESOLVE)
11041 {
11042 clib_warning ("unsupported action: 'resolve'");
11043 return -99;
11044 }
11045 }
11046 else
11047 {
11048 clib_warning ("parse error '%U'", format_unformat_error, i);
11049 return -99;
11050 }
11051
11052 }
11053
Neale Ranns17dcec02019-01-09 21:22:20 -080011054 M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011055
Damjan Marion7cd468a2016-12-19 23:05:39 +010011056 mp->is_add = is_add;
Neale Ranns17dcec02019-01-09 21:22:20 -080011057
11058 mp->entry.spd_id = ntohl (spd_id);
11059 mp->entry.priority = ntohl (priority);
11060 mp->entry.is_outbound = is_outbound;
11061
11062 clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
11063 sizeof (vl_api_address_t));
11064 clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
11065 sizeof (vl_api_address_t));
11066 clib_memcpy (&mp->entry.local_address_start, &laddr_start,
11067 sizeof (vl_api_address_t));
11068 clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
11069 sizeof (vl_api_address_t));
11070
11071 mp->entry.protocol = (u8) protocol;
11072 mp->entry.local_port_start = ntohs ((u16) lport_start);
11073 mp->entry.local_port_stop = ntohs ((u16) lport_stop);
11074 mp->entry.remote_port_start = ntohs ((u16) rport_start);
11075 mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
11076 mp->entry.policy = (u8) policy;
11077 mp->entry.sa_id = ntohl (sa_id);
Neale Ranns17dcec02019-01-09 21:22:20 -080011078
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011079 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011080 W (ret);
11081 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011082}
11083
11084static int
Neale Ranns17dcec02019-01-09 21:22:20 -080011085api_ipsec_sad_entry_add_del (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010011086{
11087 unformat_input_t *i = vam->input;
Neale Ranns17dcec02019-01-09 21:22:20 -080011088 vl_api_ipsec_sad_entry_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011089 u32 sad_id = 0, spi = 0;
11090 u8 *ck = 0, *ik = 0;
11091 u8 is_add = 1;
11092
Neale Ranns17dcec02019-01-09 21:22:20 -080011093 vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
11094 vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
11095 vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
11096 vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
11097 vl_api_address_t tun_src, tun_dst;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011098 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011099
11100 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11101 {
11102 if (unformat (i, "del"))
11103 is_add = 0;
11104 else if (unformat (i, "sad_id %d", &sad_id))
11105 ;
11106 else if (unformat (i, "spi %d", &spi))
11107 ;
11108 else if (unformat (i, "esp"))
Neale Ranns17dcec02019-01-09 21:22:20 -080011109 protocol = IPSEC_API_PROTO_ESP;
11110 else
11111 if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
Damjan Marion7cd468a2016-12-19 23:05:39 +010011112 {
Neale Ranns17dcec02019-01-09 21:22:20 -080011113 flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
11114 if (ADDRESS_IP6 == tun_src.af)
11115 flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011116 }
11117 else
Neale Ranns17dcec02019-01-09 21:22:20 -080011118 if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
Damjan Marion7cd468a2016-12-19 23:05:39 +010011119 {
Neale Ranns17dcec02019-01-09 21:22:20 -080011120 flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
11121 if (ADDRESS_IP6 == tun_src.af)
11122 flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011123 }
Neale Ranns17dcec02019-01-09 21:22:20 -080011124 else
11125 if (unformat (i, "crypto_alg %U",
11126 unformat_ipsec_api_crypto_alg, &crypto_alg))
11127 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011128 else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11129 ;
Neale Ranns17dcec02019-01-09 21:22:20 -080011130 else if (unformat (i, "integ_alg %U",
11131 unformat_ipsec_api_integ_alg, &integ_alg))
11132 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011133 else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11134 ;
11135 else
11136 {
11137 clib_warning ("parse error '%U'", format_unformat_error, i);
11138 return -99;
11139 }
11140
11141 }
11142
Neale Ranns17dcec02019-01-09 21:22:20 -080011143 M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011144
Damjan Marion7cd468a2016-12-19 23:05:39 +010011145 mp->is_add = is_add;
Neale Ranns17dcec02019-01-09 21:22:20 -080011146 mp->entry.sad_id = ntohl (sad_id);
11147 mp->entry.protocol = protocol;
11148 mp->entry.spi = ntohl (spi);
11149 mp->entry.flags = flags;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011150
Neale Ranns17dcec02019-01-09 21:22:20 -080011151 mp->entry.crypto_algorithm = crypto_alg;
11152 mp->entry.integrity_algorithm = integ_alg;
11153 mp->entry.crypto_key.length = vec_len (ck);
11154 mp->entry.integrity_key.length = vec_len (ik);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011155
Neale Ranns17dcec02019-01-09 21:22:20 -080011156 if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
11157 mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
11158
11159 if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
11160 mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011161
11162 if (ck)
Neale Ranns17dcec02019-01-09 21:22:20 -080011163 clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011164 if (ik)
Neale Ranns17dcec02019-01-09 21:22:20 -080011165 clib_memcpy (mp->entry.integrity_key.data, ik,
11166 mp->entry.integrity_key.length);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011167
Neale Ranns17dcec02019-01-09 21:22:20 -080011168 if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
Damjan Marion7cd468a2016-12-19 23:05:39 +010011169 {
Neale Ranns17dcec02019-01-09 21:22:20 -080011170 clib_memcpy (&mp->entry.tunnel_src, &tun_src,
11171 sizeof (mp->entry.tunnel_src));
11172 clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
11173 sizeof (mp->entry.tunnel_dst));
Damjan Marion7cd468a2016-12-19 23:05:39 +010011174 }
11175
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011176 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011177 W (ret);
11178 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011179}
11180
Matthew Smith28029532017-09-26 13:33:44 -050011181static void
11182vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
11183{
11184 vat_main_t *vam = &vat_main;
11185
11186 print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
Neale Ranns8d7c5022019-02-06 01:41:05 -080011187 "crypto_key %U integ_alg %u integ_key %U flags %x "
Matthew Smith28029532017-09-26 13:33:44 -050011188 "tunnel_src_addr %U tunnel_dst_addr %U "
11189 "salt %u seq_outbound %lu last_seq_inbound %lu "
Matthew Smith48d32b42020-04-02 07:45:49 -050011190 "replay_window %lu stat_index %u\n",
Neale Ranns8d7c5022019-02-06 01:41:05 -080011191 ntohl (mp->entry.sad_id),
11192 ntohl (mp->sw_if_index),
11193 ntohl (mp->entry.spi),
11194 ntohl (mp->entry.protocol),
11195 ntohl (mp->entry.crypto_algorithm),
11196 format_hex_bytes, mp->entry.crypto_key.data,
11197 mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
11198 format_hex_bytes, mp->entry.integrity_key.data,
11199 mp->entry.integrity_key.length, ntohl (mp->entry.flags),
11200 format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
11201 &mp->entry.tunnel_dst, ntohl (mp->salt),
Matthew Smith28029532017-09-26 13:33:44 -050011202 clib_net_to_host_u64 (mp->seq_outbound),
11203 clib_net_to_host_u64 (mp->last_seq_inbound),
Matthew Smith48d32b42020-04-02 07:45:49 -050011204 clib_net_to_host_u64 (mp->replay_window), ntohl (mp->stat_index));
Matthew Smith28029532017-09-26 13:33:44 -050011205}
11206
11207#define vl_api_ipsec_sa_details_t_endian vl_noop_handler
11208#define vl_api_ipsec_sa_details_t_print vl_noop_handler
11209
11210static void vl_api_ipsec_sa_details_t_handler_json
11211 (vl_api_ipsec_sa_details_t * mp)
11212{
11213 vat_main_t *vam = &vat_main;
11214 vat_json_node_t *node = NULL;
Neale Ranns8d7c5022019-02-06 01:41:05 -080011215 vl_api_ipsec_sad_flags_t flags;
Matthew Smith28029532017-09-26 13:33:44 -050011216
11217 if (VAT_JSON_ARRAY != vam->json_tree.type)
11218 {
11219 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11220 vat_json_init_array (&vam->json_tree);
11221 }
11222 node = vat_json_array_add (&vam->json_tree);
11223
11224 vat_json_init_object (node);
Neale Ranns8d7c5022019-02-06 01:41:05 -080011225 vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
Matthew Smith28029532017-09-26 13:33:44 -050011226 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
Neale Ranns8d7c5022019-02-06 01:41:05 -080011227 vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
11228 vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
11229 vat_json_object_add_uint (node, "crypto_alg",
11230 ntohl (mp->entry.crypto_algorithm));
11231 vat_json_object_add_uint (node, "integ_alg",
11232 ntohl (mp->entry.integrity_algorithm));
11233 flags = ntohl (mp->entry.flags);
11234 vat_json_object_add_uint (node, "use_esn",
Damjan Marion1e3aa5e2019-03-28 10:58:59 +010011235 ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
Neale Ranns8d7c5022019-02-06 01:41:05 -080011236 vat_json_object_add_uint (node, "use_anti_replay",
11237 ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
11238 vat_json_object_add_uint (node, "is_tunnel",
11239 ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
11240 vat_json_object_add_uint (node, "is_tunnel_ip6",
11241 ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
11242 vat_json_object_add_uint (node, "udp_encap",
11243 ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
11244 vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
11245 mp->entry.crypto_key.length);
11246 vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
11247 mp->entry.integrity_key.length);
Neale Ranns5a8844b2019-04-16 07:15:35 +000011248 vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
11249 vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
Matthew Smith28029532017-09-26 13:33:44 -050011250 vat_json_object_add_uint (node, "replay_window",
11251 clib_net_to_host_u64 (mp->replay_window));
Matthew Smith48d32b42020-04-02 07:45:49 -050011252 vat_json_object_add_uint (node, "stat_index", ntohl (mp->stat_index));
Matthew Smith28029532017-09-26 13:33:44 -050011253}
11254
11255static int
11256api_ipsec_sa_dump (vat_main_t * vam)
11257{
11258 unformat_input_t *i = vam->input;
11259 vl_api_ipsec_sa_dump_t *mp;
11260 vl_api_control_ping_t *mp_ping;
11261 u32 sa_id = ~0;
11262 int ret;
11263
11264 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11265 {
11266 if (unformat (i, "sa_id %d", &sa_id))
11267 ;
11268 else
11269 {
11270 clib_warning ("parse error '%U'", format_unformat_error, i);
11271 return -99;
11272 }
11273 }
11274
11275 M (IPSEC_SA_DUMP, mp);
11276
11277 mp->sa_id = ntohl (sa_id);
11278
11279 S (mp);
11280
11281 /* Use a control ping for synchronization */
11282 M (CONTROL_PING, mp_ping);
11283 S (mp_ping);
11284
11285 W (ret);
11286 return ret;
11287}
11288
Matthew Smithb0972cb2017-05-02 16:20:41 -050011289static int
Damjan Marion7cd468a2016-12-19 23:05:39 +010011290api_get_first_msg_id (vat_main_t * vam)
11291{
11292 vl_api_get_first_msg_id_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011293 unformat_input_t *i = vam->input;
11294 u8 *name;
11295 u8 name_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011296 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011297
11298 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11299 {
11300 if (unformat (i, "client %s", &name))
11301 name_set = 1;
11302 else
11303 break;
11304 }
11305
11306 if (name_set == 0)
11307 {
11308 errmsg ("missing client name");
11309 return -99;
11310 }
11311 vec_add1 (name, 0);
11312
11313 if (vec_len (name) > 63)
11314 {
11315 errmsg ("client name too long");
11316 return -99;
11317 }
11318
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011319 M (GET_FIRST_MSG_ID, mp);
Ole Troan7adaa222019-08-27 15:05:27 +020011320 clib_memcpy (mp->name, name, vec_len (name));
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011321 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011322 W (ret);
11323 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011324}
11325
11326static int
11327api_cop_interface_enable_disable (vat_main_t * vam)
11328{
11329 unformat_input_t *line_input = vam->input;
11330 vl_api_cop_interface_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011331 u32 sw_if_index = ~0;
11332 u8 enable_disable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011333 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011334
11335 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11336 {
11337 if (unformat (line_input, "disable"))
11338 enable_disable = 0;
11339 if (unformat (line_input, "enable"))
11340 enable_disable = 1;
11341 else if (unformat (line_input, "%U", api_unformat_sw_if_index,
11342 vam, &sw_if_index))
11343 ;
11344 else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11345 ;
11346 else
11347 break;
11348 }
11349
11350 if (sw_if_index == ~0)
11351 {
11352 errmsg ("missing interface name or sw_if_index");
11353 return -99;
11354 }
11355
11356 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011357 M (COP_INTERFACE_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011358 mp->sw_if_index = ntohl (sw_if_index);
11359 mp->enable_disable = enable_disable;
11360
11361 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011362 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011363 /* Wait for the reply */
Jon Loeliger56c7b012017-02-01 12:31:41 -060011364 W (ret);
11365 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011366}
11367
11368static int
11369api_cop_whitelist_enable_disable (vat_main_t * vam)
11370{
11371 unformat_input_t *line_input = vam->input;
11372 vl_api_cop_whitelist_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011373 u32 sw_if_index = ~0;
11374 u8 ip4 = 0, ip6 = 0, default_cop = 0;
11375 u32 fib_id = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011376 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011377
11378 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11379 {
11380 if (unformat (line_input, "ip4"))
11381 ip4 = 1;
11382 else if (unformat (line_input, "ip6"))
11383 ip6 = 1;
11384 else if (unformat (line_input, "default"))
11385 default_cop = 1;
11386 else if (unformat (line_input, "%U", api_unformat_sw_if_index,
11387 vam, &sw_if_index))
11388 ;
11389 else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11390 ;
11391 else if (unformat (line_input, "fib-id %d", &fib_id))
11392 ;
11393 else
11394 break;
11395 }
11396
11397 if (sw_if_index == ~0)
11398 {
11399 errmsg ("missing interface name or sw_if_index");
11400 return -99;
11401 }
11402
11403 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011404 M (COP_WHITELIST_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011405 mp->sw_if_index = ntohl (sw_if_index);
11406 mp->fib_id = ntohl (fib_id);
11407 mp->ip4 = ip4;
11408 mp->ip6 = ip6;
11409 mp->default_cop = default_cop;
11410
11411 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011412 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011413 /* Wait for the reply */
Jon Loeliger56c7b012017-02-01 12:31:41 -060011414 W (ret);
11415 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011416}
11417
11418static int
11419api_get_node_graph (vat_main_t * vam)
11420{
11421 vl_api_get_node_graph_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011422 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011423
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011424 M (GET_NODE_GRAPH, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011425
11426 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011427 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011428 /* Wait for the reply */
Jon Loeliger56c7b012017-02-01 12:31:41 -060011429 W (ret);
11430 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011431}
11432
Damjan Marion7cd468a2016-12-19 23:05:39 +010011433static int
11434api_af_packet_create (vat_main_t * vam)
11435{
11436 unformat_input_t *i = vam->input;
11437 vl_api_af_packet_create_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011438 u8 *host_if_name = 0;
11439 u8 hw_addr[6];
11440 u8 random_hw_addr = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011441 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011442
Dave Barachb7b92992018-10-17 10:38:51 -040011443 clib_memset (hw_addr, 0, sizeof (hw_addr));
Damjan Marion7cd468a2016-12-19 23:05:39 +010011444
11445 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11446 {
11447 if (unformat (i, "name %s", &host_if_name))
11448 vec_add1 (host_if_name, 0);
11449 else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
11450 random_hw_addr = 0;
11451 else
11452 break;
11453 }
11454
11455 if (!vec_len (host_if_name))
11456 {
11457 errmsg ("host-interface name must be specified");
11458 return -99;
11459 }
11460
11461 if (vec_len (host_if_name) > 64)
11462 {
11463 errmsg ("host-interface name too long");
11464 return -99;
11465 }
11466
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011467 M (AF_PACKET_CREATE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011468
11469 clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
11470 clib_memcpy (mp->hw_addr, hw_addr, 6);
11471 mp->use_random_hw_addr = random_hw_addr;
11472 vec_free (host_if_name);
11473
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011474 S (mp);
Dave Baracha1a093d2017-03-02 13:13:23 -050011475
11476 /* *INDENT-OFF* */
11477 W2 (ret,
11478 ({
11479 if (ret == 0)
11480 fprintf (vam->ofp ? vam->ofp : stderr,
11481 " new sw_if_index = %d\n", vam->sw_if_index);
11482 }));
11483 /* *INDENT-ON* */
Jon Loeliger56c7b012017-02-01 12:31:41 -060011484 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011485}
11486
11487static int
11488api_af_packet_delete (vat_main_t * vam)
11489{
11490 unformat_input_t *i = vam->input;
11491 vl_api_af_packet_delete_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011492 u8 *host_if_name = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011493 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011494
11495 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11496 {
11497 if (unformat (i, "name %s", &host_if_name))
11498 vec_add1 (host_if_name, 0);
11499 else
11500 break;
11501 }
11502
11503 if (!vec_len (host_if_name))
11504 {
11505 errmsg ("host-interface name must be specified");
11506 return -99;
11507 }
11508
11509 if (vec_len (host_if_name) > 64)
11510 {
11511 errmsg ("host-interface name too long");
11512 return -99;
11513 }
11514
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011515 M (AF_PACKET_DELETE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011516
11517 clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
11518 vec_free (host_if_name);
11519
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011520 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011521 W (ret);
11522 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011523}
11524
Mohsin Kazmi04e0bb22018-05-28 18:55:37 +020011525static void vl_api_af_packet_details_t_handler
11526 (vl_api_af_packet_details_t * mp)
11527{
11528 vat_main_t *vam = &vat_main;
11529
11530 print (vam->ofp, "%-16s %d",
11531 mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
11532}
11533
11534static void vl_api_af_packet_details_t_handler_json
11535 (vl_api_af_packet_details_t * mp)
11536{
11537 vat_main_t *vam = &vat_main;
11538 vat_json_node_t *node = NULL;
11539
11540 if (VAT_JSON_ARRAY != vam->json_tree.type)
11541 {
11542 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11543 vat_json_init_array (&vam->json_tree);
11544 }
11545 node = vat_json_array_add (&vam->json_tree);
11546
11547 vat_json_init_object (node);
11548 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11549 vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
11550}
11551
11552static int
11553api_af_packet_dump (vat_main_t * vam)
11554{
11555 vl_api_af_packet_dump_t *mp;
11556 vl_api_control_ping_t *mp_ping;
11557 int ret;
11558
11559 print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
11560 /* Get list of tap interfaces */
11561 M (AF_PACKET_DUMP, mp);
11562 S (mp);
11563
11564 /* Use a control ping for synchronization */
11565 MPING (CONTROL_PING, mp_ping);
11566 S (mp_ping);
11567
11568 W (ret);
11569 return ret;
11570}
11571
Damjan Marion7cd468a2016-12-19 23:05:39 +010011572static int
11573api_policer_add_del (vat_main_t * vam)
11574{
11575 unformat_input_t *i = vam->input;
11576 vl_api_policer_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011577 u8 is_add = 1;
11578 u8 *name = 0;
11579 u32 cir = 0;
11580 u32 eir = 0;
11581 u64 cb = 0;
11582 u64 eb = 0;
11583 u8 rate_type = 0;
11584 u8 round_type = 0;
11585 u8 type = 0;
11586 u8 color_aware = 0;
11587 sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011588 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011589
11590 conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
11591 conform_action.dscp = 0;
11592 exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
11593 exceed_action.dscp = 0;
11594 violate_action.action_type = SSE2_QOS_ACTION_DROP;
11595 violate_action.dscp = 0;
11596
11597 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11598 {
11599 if (unformat (i, "del"))
11600 is_add = 0;
11601 else if (unformat (i, "name %s", &name))
11602 vec_add1 (name, 0);
11603 else if (unformat (i, "cir %u", &cir))
11604 ;
11605 else if (unformat (i, "eir %u", &eir))
11606 ;
11607 else if (unformat (i, "cb %u", &cb))
11608 ;
11609 else if (unformat (i, "eb %u", &eb))
11610 ;
11611 else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
11612 &rate_type))
11613 ;
11614 else if (unformat (i, "round_type %U", unformat_policer_round_type,
11615 &round_type))
11616 ;
11617 else if (unformat (i, "type %U", unformat_policer_type, &type))
11618 ;
11619 else if (unformat (i, "conform_action %U", unformat_policer_action_type,
11620 &conform_action))
11621 ;
11622 else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
11623 &exceed_action))
11624 ;
11625 else if (unformat (i, "violate_action %U", unformat_policer_action_type,
11626 &violate_action))
11627 ;
11628 else if (unformat (i, "color-aware"))
11629 color_aware = 1;
11630 else
11631 break;
11632 }
11633
11634 if (!vec_len (name))
11635 {
11636 errmsg ("policer name must be specified");
11637 return -99;
11638 }
11639
11640 if (vec_len (name) > 64)
11641 {
11642 errmsg ("policer name too long");
11643 return -99;
11644 }
11645
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011646 M (POLICER_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011647
11648 clib_memcpy (mp->name, name, vec_len (name));
11649 vec_free (name);
11650 mp->is_add = is_add;
Neale Rannsd91c1db2017-07-31 02:30:50 -070011651 mp->cir = ntohl (cir);
11652 mp->eir = ntohl (eir);
11653 mp->cb = clib_net_to_host_u64 (cb);
11654 mp->eb = clib_net_to_host_u64 (eb);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011655 mp->rate_type = rate_type;
11656 mp->round_type = round_type;
11657 mp->type = type;
Jakub Grajciarcd01fb42020-03-02 13:16:53 +010011658 mp->conform_action.type = conform_action.action_type;
11659 mp->conform_action.dscp = conform_action.dscp;
11660 mp->exceed_action.type = exceed_action.action_type;
11661 mp->exceed_action.dscp = exceed_action.dscp;
11662 mp->violate_action.type = violate_action.action_type;
11663 mp->violate_action.dscp = violate_action.dscp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011664 mp->color_aware = color_aware;
11665
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011666 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011667 W (ret);
11668 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011669}
11670
11671static int
11672api_policer_dump (vat_main_t * vam)
11673{
11674 unformat_input_t *i = vam->input;
11675 vl_api_policer_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011676 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011677 u8 *match_name = 0;
11678 u8 match_name_valid = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011679 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011680
11681 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11682 {
11683 if (unformat (i, "name %s", &match_name))
11684 {
11685 vec_add1 (match_name, 0);
11686 match_name_valid = 1;
11687 }
11688 else
11689 break;
11690 }
11691
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011692 M (POLICER_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011693 mp->match_name_valid = match_name_valid;
11694 clib_memcpy (mp->match_name, match_name, vec_len (match_name));
11695 vec_free (match_name);
11696 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011697 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011698
11699 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040011700 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011701 S (mp_ping);
11702
Damjan Marion7cd468a2016-12-19 23:05:39 +010011703 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060011704 W (ret);
11705 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011706}
11707
11708static int
11709api_policer_classify_set_interface (vat_main_t * vam)
11710{
11711 unformat_input_t *i = vam->input;
11712 vl_api_policer_classify_set_interface_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011713 u32 sw_if_index;
11714 int sw_if_index_set;
11715 u32 ip4_table_index = ~0;
11716 u32 ip6_table_index = ~0;
11717 u32 l2_table_index = ~0;
11718 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011719 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011720
11721 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11722 {
11723 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11724 sw_if_index_set = 1;
11725 else if (unformat (i, "sw_if_index %d", &sw_if_index))
11726 sw_if_index_set = 1;
11727 else if (unformat (i, "del"))
11728 is_add = 0;
11729 else if (unformat (i, "ip4-table %d", &ip4_table_index))
11730 ;
11731 else if (unformat (i, "ip6-table %d", &ip6_table_index))
11732 ;
11733 else if (unformat (i, "l2-table %d", &l2_table_index))
11734 ;
11735 else
11736 {
11737 clib_warning ("parse error '%U'", format_unformat_error, i);
11738 return -99;
11739 }
11740 }
11741
11742 if (sw_if_index_set == 0)
11743 {
11744 errmsg ("missing interface name or sw_if_index");
11745 return -99;
11746 }
11747
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011748 M (POLICER_CLASSIFY_SET_INTERFACE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011749
11750 mp->sw_if_index = ntohl (sw_if_index);
11751 mp->ip4_table_index = ntohl (ip4_table_index);
11752 mp->ip6_table_index = ntohl (ip6_table_index);
11753 mp->l2_table_index = ntohl (l2_table_index);
11754 mp->is_add = is_add;
11755
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011756 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011757 W (ret);
11758 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011759}
11760
11761static int
11762api_policer_classify_dump (vat_main_t * vam)
11763{
11764 unformat_input_t *i = vam->input;
11765 vl_api_policer_classify_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011766 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011767 u8 type = POLICER_CLASSIFY_N_TABLES;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011768 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011769
11770 if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
11771 ;
11772 else
11773 {
11774 errmsg ("classify table type must be specified");
11775 return -99;
11776 }
11777
11778 if (!vam->json_output)
11779 {
11780 print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
11781 }
11782
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011783 M (POLICER_CLASSIFY_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011784 mp->type = type;
11785 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011786 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011787
11788 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040011789 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011790 S (mp_ping);
11791
Damjan Marion7cd468a2016-12-19 23:05:39 +010011792 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060011793 W (ret);
11794 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011795}
11796
Neale Ranns097fa662018-05-01 05:17:55 -070011797static u8 *
11798format_fib_api_path_nh_proto (u8 * s, va_list * args)
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011799{
Neale Ranns097fa662018-05-01 05:17:55 -070011800 vl_api_fib_path_nh_proto_t proto =
11801 va_arg (*args, vl_api_fib_path_nh_proto_t);
11802
11803 switch (proto)
11804 {
11805 case FIB_API_PATH_NH_PROTO_IP4:
11806 s = format (s, "ip4");
11807 break;
11808 case FIB_API_PATH_NH_PROTO_IP6:
11809 s = format (s, "ip6");
11810 break;
11811 case FIB_API_PATH_NH_PROTO_MPLS:
11812 s = format (s, "mpls");
11813 break;
11814 case FIB_API_PATH_NH_PROTO_BIER:
11815 s = format (s, "bier");
11816 break;
11817 case FIB_API_PATH_NH_PROTO_ETHERNET:
11818 s = format (s, "ethernet");
11819 break;
11820 }
11821
11822 return (s);
11823}
11824
11825static u8 *
11826format_vl_api_ip_address_union (u8 * s, va_list * args)
11827{
Jakub Grajciar7dd63e52020-03-19 08:03:55 +010011828 vl_api_address_family_t af = va_arg (*args, int);
Neale Ranns097fa662018-05-01 05:17:55 -070011829 const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
11830
11831 switch (af)
11832 {
11833 case ADDRESS_IP4:
11834 s = format (s, "%U", format_ip4_address, u->ip4);
11835 break;
11836 case ADDRESS_IP6:
11837 s = format (s, "%U", format_ip6_address, u->ip6);
11838 break;
11839 }
11840 return (s);
11841}
11842
11843static u8 *
11844format_vl_api_fib_path_type (u8 * s, va_list * args)
11845{
11846 vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
11847
11848 switch (t)
11849 {
11850 case FIB_API_PATH_TYPE_NORMAL:
11851 s = format (s, "normal");
11852 break;
11853 case FIB_API_PATH_TYPE_LOCAL:
11854 s = format (s, "local");
11855 break;
11856 case FIB_API_PATH_TYPE_DROP:
11857 s = format (s, "drop");
11858 break;
11859 case FIB_API_PATH_TYPE_UDP_ENCAP:
11860 s = format (s, "udp-encap");
11861 break;
11862 case FIB_API_PATH_TYPE_BIER_IMP:
11863 s = format (s, "bier-imp");
11864 break;
11865 case FIB_API_PATH_TYPE_ICMP_UNREACH:
11866 s = format (s, "unreach");
11867 break;
11868 case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
11869 s = format (s, "prohibit");
11870 break;
11871 case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
11872 s = format (s, "src-lookup");
11873 break;
11874 case FIB_API_PATH_TYPE_DVR:
11875 s = format (s, "dvr");
11876 break;
11877 case FIB_API_PATH_TYPE_INTERFACE_RX:
11878 s = format (s, "interface-rx");
11879 break;
11880 case FIB_API_PATH_TYPE_CLASSIFY:
11881 s = format (s, "classify");
11882 break;
11883 }
11884
11885 return (s);
11886}
11887
11888static void
11889vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
11890{
11891 print (vam->ofp,
11892 " weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
11893 ntohl (fp->weight), ntohl (fp->sw_if_index),
11894 format_vl_api_fib_path_type, fp->type,
11895 format_fib_api_path_nh_proto, fp->proto,
11896 format_vl_api_ip_address_union, &fp->nh.address);
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011897}
11898
11899static void
11900vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
Neale Ranns31ed7442018-02-23 05:29:09 -080011901 vl_api_fib_path_t * fp)
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011902{
11903 struct in_addr ip4;
11904 struct in6_addr ip6;
11905
11906 vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
11907 vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
Neale Ranns097fa662018-05-01 05:17:55 -070011908 vat_json_object_add_uint (node, "type", fp->type);
11909 vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
11910 if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011911 {
Neale Ranns097fa662018-05-01 05:17:55 -070011912 clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011913 vat_json_object_add_ip4 (node, "next_hop", ip4);
11914 }
Dave Barachc35f3e82020-04-02 10:44:09 -040011915 else if (fp->proto == FIB_API_PATH_NH_PROTO_IP6)
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011916 {
Neale Ranns097fa662018-05-01 05:17:55 -070011917 clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011918 vat_json_object_add_ip6 (node, "next_hop", ip6);
11919 }
11920}
11921
11922static void
11923vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010011924{
11925 vat_main_t *vam = &vat_main;
Neale Ranns097fa662018-05-01 05:17:55 -070011926 int count = ntohl (mp->mt_tunnel.mt_n_paths);
Neale Ranns31ed7442018-02-23 05:29:09 -080011927 vl_api_fib_path_t *fp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011928 i32 i;
11929
Neale Ranns097fa662018-05-01 05:17:55 -070011930 print (vam->ofp, "sw_if_index %d via:",
11931 ntohl (mp->mt_tunnel.mt_sw_if_index));
11932 fp = mp->mt_tunnel.mt_paths;
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011933 for (i = 0; i < count; i++)
Damjan Marion7cd468a2016-12-19 23:05:39 +010011934 {
Neale Ranns097fa662018-05-01 05:17:55 -070011935 vl_api_fib_path_print (vam, fp);
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011936 fp++;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011937 }
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011938
Damjan Marion7cd468a2016-12-19 23:05:39 +010011939 print (vam->ofp, "");
11940}
11941
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011942#define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
11943#define vl_api_mpls_tunnel_details_t_print vl_noop_handler
11944
11945static void
11946vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010011947{
11948 vat_main_t *vam = &vat_main;
11949 vat_json_node_t *node = NULL;
Neale Ranns097fa662018-05-01 05:17:55 -070011950 int count = ntohl (mp->mt_tunnel.mt_n_paths);
Neale Ranns31ed7442018-02-23 05:29:09 -080011951 vl_api_fib_path_t *fp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011952 i32 i;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011953
11954 if (VAT_JSON_ARRAY != vam->json_tree.type)
11955 {
11956 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11957 vat_json_init_array (&vam->json_tree);
11958 }
11959 node = vat_json_array_add (&vam->json_tree);
11960
11961 vat_json_init_object (node);
Neale Ranns097fa662018-05-01 05:17:55 -070011962 vat_json_object_add_uint (node, "sw_if_index",
11963 ntohl (mp->mt_tunnel.mt_sw_if_index));
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011964
Neale Ranns097fa662018-05-01 05:17:55 -070011965 vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011966
Neale Ranns097fa662018-05-01 05:17:55 -070011967 fp = mp->mt_tunnel.mt_paths;
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011968 for (i = 0; i < count; i++)
Damjan Marion7cd468a2016-12-19 23:05:39 +010011969 {
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011970 vl_api_mpls_fib_path_json_print (node, fp);
11971 fp++;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011972 }
11973}
11974
11975static int
11976api_mpls_tunnel_dump (vat_main_t * vam)
11977{
11978 vl_api_mpls_tunnel_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011979 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011980 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011981
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011982 M (MPLS_TUNNEL_DUMP, mp);
Neale Ranns097fa662018-05-01 05:17:55 -070011983
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011984 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011985
11986 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040011987 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011988 S (mp_ping);
11989
Jon Loeliger56c7b012017-02-01 12:31:41 -060011990 W (ret);
11991 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011992}
11993
Neale Ranns097fa662018-05-01 05:17:55 -070011994#define vl_api_mpls_table_details_t_endian vl_noop_handler
11995#define vl_api_mpls_table_details_t_print vl_noop_handler
Damjan Marion7cd468a2016-12-19 23:05:39 +010011996
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011997
Damjan Marion7cd468a2016-12-19 23:05:39 +010011998static void
Neale Ranns097fa662018-05-01 05:17:55 -070011999vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012000{
12001 vat_main_t *vam = &vat_main;
Neale Ranns097fa662018-05-01 05:17:55 -070012002
12003 print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
12004}
12005
12006static void vl_api_mpls_table_details_t_handler_json
12007 (vl_api_mpls_table_details_t * mp)
12008{
12009 vat_main_t *vam = &vat_main;
12010 vat_json_node_t *node = NULL;
12011
12012 if (VAT_JSON_ARRAY != vam->json_tree.type)
12013 {
12014 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12015 vat_json_init_array (&vam->json_tree);
12016 }
12017 node = vat_json_array_add (&vam->json_tree);
12018
12019 vat_json_init_object (node);
12020 vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
12021}
12022
12023static int
12024api_mpls_table_dump (vat_main_t * vam)
12025{
12026 vl_api_mpls_table_dump_t *mp;
12027 vl_api_control_ping_t *mp_ping;
12028 int ret;
12029
12030 M (MPLS_TABLE_DUMP, mp);
12031 S (mp);
12032
12033 /* Use a control ping for synchronization */
12034 MPING (CONTROL_PING, mp_ping);
12035 S (mp_ping);
12036
12037 W (ret);
12038 return ret;
12039}
12040
12041#define vl_api_mpls_route_details_t_endian vl_noop_handler
12042#define vl_api_mpls_route_details_t_print vl_noop_handler
12043
12044static void
12045vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
12046{
12047 vat_main_t *vam = &vat_main;
Dave Barach4bda2d92019-07-03 15:21:50 -040012048 int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
Neale Ranns31ed7442018-02-23 05:29:09 -080012049 vl_api_fib_path_t *fp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012050 int i;
12051
12052 print (vam->ofp,
12053 "table-id %d, label %u, ess_bit %u",
Neale Ranns097fa662018-05-01 05:17:55 -070012054 ntohl (mp->mr_route.mr_table_id),
12055 ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
12056 fp = mp->mr_route.mr_paths;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012057 for (i = 0; i < count; i++)
12058 {
Neale Ranns097fa662018-05-01 05:17:55 -070012059 vl_api_fib_path_print (vam, fp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012060 fp++;
12061 }
12062}
12063
Neale Ranns097fa662018-05-01 05:17:55 -070012064static void vl_api_mpls_route_details_t_handler_json
12065 (vl_api_mpls_route_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012066{
12067 vat_main_t *vam = &vat_main;
Dave Barach4bda2d92019-07-03 15:21:50 -040012068 int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012069 vat_json_node_t *node = NULL;
Neale Ranns31ed7442018-02-23 05:29:09 -080012070 vl_api_fib_path_t *fp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012071 int i;
12072
12073 if (VAT_JSON_ARRAY != vam->json_tree.type)
12074 {
12075 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12076 vat_json_init_array (&vam->json_tree);
12077 }
12078 node = vat_json_array_add (&vam->json_tree);
12079
12080 vat_json_init_object (node);
Neale Ranns097fa662018-05-01 05:17:55 -070012081 vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
12082 vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
12083 vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
Damjan Marion7cd468a2016-12-19 23:05:39 +010012084 vat_json_object_add_uint (node, "path_count", count);
Neale Ranns097fa662018-05-01 05:17:55 -070012085 fp = mp->mr_route.mr_paths;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012086 for (i = 0; i < count; i++)
12087 {
Neale Ranns0f26c5a2017-03-01 15:12:11 -080012088 vl_api_mpls_fib_path_json_print (node, fp);
12089 fp++;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012090 }
12091}
12092
12093static int
Neale Ranns097fa662018-05-01 05:17:55 -070012094api_mpls_route_dump (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012095{
Neale Ranns097fa662018-05-01 05:17:55 -070012096 unformat_input_t *input = vam->input;
12097 vl_api_mpls_route_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012098 vl_api_control_ping_t *mp_ping;
Neale Ranns097fa662018-05-01 05:17:55 -070012099 u32 table_id;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012100 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012101
Neale Ranns097fa662018-05-01 05:17:55 -070012102 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12103 {
12104 if (unformat (input, "table_id %d", &table_id))
12105 ;
12106 else
12107 break;
12108 }
12109 if (table_id == ~0)
12110 {
12111 errmsg ("missing table id");
12112 return -99;
12113 }
12114
12115 M (MPLS_ROUTE_DUMP, mp);
12116
12117 mp->table.mt_table_id = ntohl (table_id);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012118 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012119
12120 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040012121 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012122 S (mp_ping);
12123
Jon Loeliger56c7b012017-02-01 12:31:41 -060012124 W (ret);
12125 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012126}
12127
Neale Ranns097fa662018-05-01 05:17:55 -070012128#define vl_api_ip_table_details_t_endian vl_noop_handler
12129#define vl_api_ip_table_details_t_print vl_noop_handler
Damjan Marion7cd468a2016-12-19 23:05:39 +010012130
12131static void
Neale Ranns097fa662018-05-01 05:17:55 -070012132vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012133{
12134 vat_main_t *vam = &vat_main;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012135
12136 print (vam->ofp,
Neale Ranns097fa662018-05-01 05:17:55 -070012137 "%s; table-id %d, prefix %U/%d",
12138 mp->table.name, ntohl (mp->table.table_id));
Damjan Marion7cd468a2016-12-19 23:05:39 +010012139}
12140
Neale Ranns097fa662018-05-01 05:17:55 -070012141
12142static void vl_api_ip_table_details_t_handler_json
12143 (vl_api_ip_table_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012144{
12145 vat_main_t *vam = &vat_main;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012146 vat_json_node_t *node = NULL;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012147
12148 if (VAT_JSON_ARRAY != vam->json_tree.type)
12149 {
12150 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12151 vat_json_init_array (&vam->json_tree);
12152 }
12153 node = vat_json_array_add (&vam->json_tree);
12154
12155 vat_json_init_object (node);
Neale Ranns097fa662018-05-01 05:17:55 -070012156 vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
Damjan Marion7cd468a2016-12-19 23:05:39 +010012157}
12158
12159static int
Neale Ranns097fa662018-05-01 05:17:55 -070012160api_ip_table_dump (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012161{
Neale Ranns097fa662018-05-01 05:17:55 -070012162 vl_api_ip_table_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012163 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012164 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012165
Neale Ranns097fa662018-05-01 05:17:55 -070012166 M (IP_TABLE_DUMP, mp);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012167 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012168
12169 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040012170 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012171 S (mp_ping);
12172
Jon Loeliger56c7b012017-02-01 12:31:41 -060012173 W (ret);
12174 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012175}
12176
Neale Ranns5a8123b2017-01-26 01:18:23 -080012177static int
Neale Ranns097fa662018-05-01 05:17:55 -070012178api_ip_mtable_dump (vat_main_t * vam)
Neale Ranns5a8123b2017-01-26 01:18:23 -080012179{
Neale Ranns097fa662018-05-01 05:17:55 -070012180 vl_api_ip_mtable_dump_t *mp;
Neale Ranns5a8123b2017-01-26 01:18:23 -080012181 vl_api_control_ping_t *mp_ping;
12182 int ret;
12183
Neale Ranns097fa662018-05-01 05:17:55 -070012184 M (IP_MTABLE_DUMP, mp);
12185 S (mp);
12186
12187 /* Use a control ping for synchronization */
12188 MPING (CONTROL_PING, mp_ping);
12189 S (mp_ping);
12190
12191 W (ret);
12192 return ret;
12193}
12194
12195static int
12196api_ip_mroute_dump (vat_main_t * vam)
12197{
12198 unformat_input_t *input = vam->input;
12199 vl_api_control_ping_t *mp_ping;
12200 vl_api_ip_mroute_dump_t *mp;
12201 int ret, is_ip6;
12202 u32 table_id;
12203
12204 is_ip6 = 0;
12205 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12206 {
12207 if (unformat (input, "table_id %d", &table_id))
12208 ;
12209 else if (unformat (input, "ip6"))
12210 is_ip6 = 1;
12211 else if (unformat (input, "ip4"))
12212 is_ip6 = 0;
12213 else
12214 break;
12215 }
12216 if (table_id == ~0)
12217 {
12218 errmsg ("missing table id");
12219 return -99;
12220 }
12221
12222 M (IP_MROUTE_DUMP, mp);
12223 mp->table.table_id = table_id;
12224 mp->table.is_ip6 = is_ip6;
Neale Ranns5a8123b2017-01-26 01:18:23 -080012225 S (mp);
12226
12227 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040012228 MPING (CONTROL_PING, mp_ping);
Neale Ranns5a8123b2017-01-26 01:18:23 -080012229 S (mp_ping);
12230
12231 W (ret);
12232 return ret;
12233}
12234
Neale Ranns097fa662018-05-01 05:17:55 -070012235#define vl_api_ip_route_details_t_endian vl_noop_handler
12236#define vl_api_ip_route_details_t_print vl_noop_handler
Damjan Marion7cd468a2016-12-19 23:05:39 +010012237
12238static void
Neale Ranns097fa662018-05-01 05:17:55 -070012239vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012240{
12241 vat_main_t *vam = &vat_main;
Neale Ranns097fa662018-05-01 05:17:55 -070012242 u8 count = mp->route.n_paths;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012243 vl_api_fib_path_t *fp;
12244 int i;
12245
12246 print (vam->ofp,
Neale Ranns097fa662018-05-01 05:17:55 -070012247 "table-id %d, prefix %U/%d",
12248 ntohl (mp->route.table_id),
Paul Vinciguerraab055082019-06-06 14:07:55 -040012249 format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012250 for (i = 0; i < count; i++)
12251 {
Neale Ranns097fa662018-05-01 05:17:55 -070012252 fp = &mp->route.paths[i];
12253
12254 vl_api_fib_path_print (vam, fp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012255 fp++;
12256 }
12257}
12258
Neale Ranns097fa662018-05-01 05:17:55 -070012259static void vl_api_ip_route_details_t_handler_json
12260 (vl_api_ip_route_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012261{
12262 vat_main_t *vam = &vat_main;
Neale Ranns097fa662018-05-01 05:17:55 -070012263 u8 count = mp->route.n_paths;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012264 vat_json_node_t *node = NULL;
12265 struct in_addr ip4;
12266 struct in6_addr ip6;
12267 vl_api_fib_path_t *fp;
12268 int i;
12269
12270 if (VAT_JSON_ARRAY != vam->json_tree.type)
12271 {
12272 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12273 vat_json_init_array (&vam->json_tree);
12274 }
12275 node = vat_json_array_add (&vam->json_tree);
12276
12277 vat_json_init_object (node);
Neale Ranns097fa662018-05-01 05:17:55 -070012278 vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
12279 if (ADDRESS_IP6 == mp->route.prefix.address.af)
12280 {
12281 clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
12282 vat_json_object_add_ip6 (node, "prefix", ip6);
12283 }
12284 else
12285 {
12286 clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
12287 vat_json_object_add_ip4 (node, "prefix", ip4);
12288 }
Paul Vinciguerraab055082019-06-06 14:07:55 -040012289 vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012290 vat_json_object_add_uint (node, "path_count", count);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012291 for (i = 0; i < count; i++)
12292 {
Neale Ranns097fa662018-05-01 05:17:55 -070012293 fp = &mp->route.paths[i];
12294 vl_api_mpls_fib_path_json_print (node, fp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012295 }
12296}
12297
12298static int
Neale Ranns097fa662018-05-01 05:17:55 -070012299api_ip_route_dump (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012300{
Neale Ranns097fa662018-05-01 05:17:55 -070012301 unformat_input_t *input = vam->input;
12302 vl_api_ip_route_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012303 vl_api_control_ping_t *mp_ping;
Neale Ranns097fa662018-05-01 05:17:55 -070012304 u32 table_id;
12305 u8 is_ip6;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012306 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012307
Neale Ranns097fa662018-05-01 05:17:55 -070012308 is_ip6 = 0;
12309 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12310 {
12311 if (unformat (input, "table_id %d", &table_id))
12312 ;
12313 else if (unformat (input, "ip6"))
12314 is_ip6 = 1;
12315 else if (unformat (input, "ip4"))
12316 is_ip6 = 0;
12317 else
12318 break;
12319 }
12320 if (table_id == ~0)
12321 {
12322 errmsg ("missing table id");
12323 return -99;
12324 }
Damjan Marion7cd468a2016-12-19 23:05:39 +010012325
Neale Ranns097fa662018-05-01 05:17:55 -070012326 M (IP_ROUTE_DUMP, mp);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012327
Neale Ranns097fa662018-05-01 05:17:55 -070012328 mp->table.table_id = table_id;
12329 mp->table.is_ip6 = is_ip6;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012330
Neale Ranns5a8123b2017-01-26 01:18:23 -080012331 S (mp);
12332
12333 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040012334 MPING (CONTROL_PING, mp_ping);
Neale Ranns5a8123b2017-01-26 01:18:23 -080012335 S (mp_ping);
12336
12337 W (ret);
12338 return ret;
12339}
12340
Damjan Marion7cd468a2016-12-19 23:05:39 +010012341int
12342api_classify_table_ids (vat_main_t * vam)
12343{
12344 vl_api_classify_table_ids_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012345 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012346
12347 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012348 M (CLASSIFY_TABLE_IDS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012349 mp->context = 0;
12350
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012351 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012352 W (ret);
12353 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012354}
12355
12356int
12357api_classify_table_by_interface (vat_main_t * vam)
12358{
12359 unformat_input_t *input = vam->input;
12360 vl_api_classify_table_by_interface_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012361
12362 u32 sw_if_index = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012363 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012364 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12365 {
12366 if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12367 ;
12368 else if (unformat (input, "sw_if_index %d", &sw_if_index))
12369 ;
12370 else
12371 break;
12372 }
12373 if (sw_if_index == ~0)
12374 {
12375 errmsg ("missing interface name or sw_if_index");
12376 return -99;
12377 }
12378
12379 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012380 M (CLASSIFY_TABLE_BY_INTERFACE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012381 mp->context = 0;
12382 mp->sw_if_index = ntohl (sw_if_index);
12383
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012384 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012385 W (ret);
12386 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012387}
12388
12389int
12390api_classify_table_info (vat_main_t * vam)
12391{
12392 unformat_input_t *input = vam->input;
12393 vl_api_classify_table_info_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012394
12395 u32 table_id = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012396 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012397 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12398 {
12399 if (unformat (input, "table_id %d", &table_id))
12400 ;
12401 else
12402 break;
12403 }
12404 if (table_id == ~0)
12405 {
12406 errmsg ("missing table id");
12407 return -99;
12408 }
12409
12410 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012411 M (CLASSIFY_TABLE_INFO, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012412 mp->context = 0;
12413 mp->table_id = ntohl (table_id);
12414
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012415 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012416 W (ret);
12417 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012418}
12419
12420int
12421api_classify_session_dump (vat_main_t * vam)
12422{
12423 unformat_input_t *input = vam->input;
12424 vl_api_classify_session_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012425 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012426
12427 u32 table_id = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012428 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012429 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12430 {
12431 if (unformat (input, "table_id %d", &table_id))
12432 ;
12433 else
12434 break;
12435 }
12436 if (table_id == ~0)
12437 {
12438 errmsg ("missing table id");
12439 return -99;
12440 }
12441
12442 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012443 M (CLASSIFY_SESSION_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012444 mp->context = 0;
12445 mp->table_id = ntohl (table_id);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012446 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012447
12448 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040012449 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012450 S (mp_ping);
12451
Jon Loeliger56c7b012017-02-01 12:31:41 -060012452 W (ret);
12453 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012454}
12455
12456static void
12457vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
12458{
12459 vat_main_t *vam = &vat_main;
12460
12461 print (vam->ofp, "collector_address %U, collector_port %d, "
12462 "src_address %U, vrf_id %d, path_mtu %u, "
12463 "template_interval %u, udp_checksum %d",
12464 format_ip4_address, mp->collector_address,
12465 ntohs (mp->collector_port),
12466 format_ip4_address, mp->src_address,
12467 ntohl (mp->vrf_id), ntohl (mp->path_mtu),
12468 ntohl (mp->template_interval), mp->udp_checksum);
12469
12470 vam->retval = 0;
12471 vam->result_ready = 1;
12472}
12473
12474static void
12475 vl_api_ipfix_exporter_details_t_handler_json
12476 (vl_api_ipfix_exporter_details_t * mp)
12477{
12478 vat_main_t *vam = &vat_main;
12479 vat_json_node_t node;
12480 struct in_addr collector_address;
12481 struct in_addr src_address;
12482
12483 vat_json_init_object (&node);
12484 clib_memcpy (&collector_address, &mp->collector_address,
12485 sizeof (collector_address));
12486 vat_json_object_add_ip4 (&node, "collector_address", collector_address);
12487 vat_json_object_add_uint (&node, "collector_port",
12488 ntohs (mp->collector_port));
12489 clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
12490 vat_json_object_add_ip4 (&node, "src_address", src_address);
12491 vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
12492 vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
12493 vat_json_object_add_uint (&node, "template_interval",
12494 ntohl (mp->template_interval));
12495 vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
12496
12497 vat_json_print (vam->ofp, &node);
12498 vat_json_free (&node);
12499 vam->retval = 0;
12500 vam->result_ready = 1;
12501}
12502
12503int
12504api_ipfix_exporter_dump (vat_main_t * vam)
12505{
12506 vl_api_ipfix_exporter_dump_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012507 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012508
12509 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012510 M (IPFIX_EXPORTER_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012511 mp->context = 0;
12512
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012513 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012514 W (ret);
12515 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012516}
12517
12518static int
12519api_ipfix_classify_stream_dump (vat_main_t * vam)
12520{
12521 vl_api_ipfix_classify_stream_dump_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012522 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012523
12524 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012525 M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012526 mp->context = 0;
12527
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012528 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012529 W (ret);
12530 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012531 /* NOTREACHED */
12532 return 0;
12533}
12534
12535static void
12536 vl_api_ipfix_classify_stream_details_t_handler
12537 (vl_api_ipfix_classify_stream_details_t * mp)
12538{
12539 vat_main_t *vam = &vat_main;
12540 print (vam->ofp, "domain_id %d, src_port %d",
12541 ntohl (mp->domain_id), ntohs (mp->src_port));
12542 vam->retval = 0;
12543 vam->result_ready = 1;
12544}
12545
12546static void
12547 vl_api_ipfix_classify_stream_details_t_handler_json
12548 (vl_api_ipfix_classify_stream_details_t * mp)
12549{
12550 vat_main_t *vam = &vat_main;
12551 vat_json_node_t node;
12552
12553 vat_json_init_object (&node);
12554 vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
12555 vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
12556
12557 vat_json_print (vam->ofp, &node);
12558 vat_json_free (&node);
12559 vam->retval = 0;
12560 vam->result_ready = 1;
12561}
12562
12563static int
12564api_ipfix_classify_table_dump (vat_main_t * vam)
12565{
12566 vl_api_ipfix_classify_table_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012567 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012568 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012569
12570 if (!vam->json_output)
12571 {
12572 print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
12573 "transport_protocol");
12574 }
12575
12576 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012577 M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012578
12579 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012580 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012581
12582 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040012583 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012584 S (mp_ping);
12585
Jon Loeliger56c7b012017-02-01 12:31:41 -060012586 W (ret);
12587 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012588}
12589
12590static void
12591 vl_api_ipfix_classify_table_details_t_handler
12592 (vl_api_ipfix_classify_table_details_t * mp)
12593{
12594 vat_main_t *vam = &vat_main;
12595 print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
12596 mp->transport_protocol);
12597}
12598
12599static void
12600 vl_api_ipfix_classify_table_details_t_handler_json
12601 (vl_api_ipfix_classify_table_details_t * mp)
12602{
12603 vat_json_node_t *node = NULL;
12604 vat_main_t *vam = &vat_main;
12605
12606 if (VAT_JSON_ARRAY != vam->json_tree.type)
12607 {
12608 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12609 vat_json_init_array (&vam->json_tree);
12610 }
12611
12612 node = vat_json_array_add (&vam->json_tree);
12613 vat_json_init_object (node);
12614
12615 vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
12616 vat_json_object_add_uint (node, "ip_version", mp->ip_version);
12617 vat_json_object_add_uint (node, "transport_protocol",
12618 mp->transport_protocol);
12619}
12620
12621static int
12622api_sw_interface_span_enable_disable (vat_main_t * vam)
12623{
12624 unformat_input_t *i = vam->input;
12625 vl_api_sw_interface_span_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012626 u32 src_sw_if_index = ~0;
12627 u32 dst_sw_if_index = ~0;
12628 u8 state = 3;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012629 int ret;
Eyal Bari001fd402017-07-16 09:34:53 +030012630 u8 is_l2 = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012631
12632 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12633 {
12634 if (unformat
12635 (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
12636 ;
12637 else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
12638 ;
12639 else
12640 if (unformat
12641 (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
12642 ;
12643 else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
12644 ;
12645 else if (unformat (i, "disable"))
12646 state = 0;
12647 else if (unformat (i, "rx"))
12648 state = 1;
12649 else if (unformat (i, "tx"))
12650 state = 2;
12651 else if (unformat (i, "both"))
12652 state = 3;
Eyal Bari001fd402017-07-16 09:34:53 +030012653 else if (unformat (i, "l2"))
12654 is_l2 = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012655 else
12656 break;
12657 }
12658
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012659 M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012660
12661 mp->sw_if_index_from = htonl (src_sw_if_index);
12662 mp->sw_if_index_to = htonl (dst_sw_if_index);
12663 mp->state = state;
Eyal Bari001fd402017-07-16 09:34:53 +030012664 mp->is_l2 = is_l2;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012665
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012666 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012667 W (ret);
12668 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012669}
12670
12671static void
12672vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
12673 * mp)
12674{
12675 vat_main_t *vam = &vat_main;
12676 u8 *sw_if_from_name = 0;
12677 u8 *sw_if_to_name = 0;
12678 u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
12679 u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
12680 char *states[] = { "none", "rx", "tx", "both" };
12681 hash_pair_t *p;
12682
12683 /* *INDENT-OFF* */
12684 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
12685 ({
12686 if ((u32) p->value[0] == sw_if_index_from)
12687 {
12688 sw_if_from_name = (u8 *)(p->key);
12689 if (sw_if_to_name)
12690 break;
12691 }
12692 if ((u32) p->value[0] == sw_if_index_to)
12693 {
12694 sw_if_to_name = (u8 *)(p->key);
12695 if (sw_if_from_name)
12696 break;
12697 }
12698 }));
12699 /* *INDENT-ON* */
Jon Loeliger179ab362018-03-12 14:50:08 -050012700 print (vam->ofp, "%20s => %20s (%s) %s",
12701 sw_if_from_name, sw_if_to_name, states[mp->state],
12702 mp->is_l2 ? "l2" : "device");
Damjan Marion7cd468a2016-12-19 23:05:39 +010012703}
12704
12705static void
12706 vl_api_sw_interface_span_details_t_handler_json
12707 (vl_api_sw_interface_span_details_t * mp)
12708{
12709 vat_main_t *vam = &vat_main;
12710 vat_json_node_t *node = NULL;
12711 u8 *sw_if_from_name = 0;
12712 u8 *sw_if_to_name = 0;
12713 u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
12714 u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
12715 hash_pair_t *p;
12716
12717 /* *INDENT-OFF* */
12718 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
12719 ({
12720 if ((u32) p->value[0] == sw_if_index_from)
12721 {
12722 sw_if_from_name = (u8 *)(p->key);
12723 if (sw_if_to_name)
12724 break;
12725 }
12726 if ((u32) p->value[0] == sw_if_index_to)
12727 {
12728 sw_if_to_name = (u8 *)(p->key);
12729 if (sw_if_from_name)
12730 break;
12731 }
12732 }));
12733 /* *INDENT-ON* */
12734
12735 if (VAT_JSON_ARRAY != vam->json_tree.type)
12736 {
12737 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12738 vat_json_init_array (&vam->json_tree);
12739 }
12740 node = vat_json_array_add (&vam->json_tree);
12741
12742 vat_json_init_object (node);
12743 vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
12744 vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
12745 vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
Neale Ranns05b2bf22017-01-30 06:44:58 -080012746 if (0 != sw_if_to_name)
12747 {
12748 vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
12749 }
Damjan Marion7cd468a2016-12-19 23:05:39 +010012750 vat_json_object_add_uint (node, "state", mp->state);
Jon Loeliger179ab362018-03-12 14:50:08 -050012751 vat_json_object_add_uint (node, "is-l2", mp->is_l2);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012752}
12753
12754static int
12755api_sw_interface_span_dump (vat_main_t * vam)
12756{
Eyal Bari5b311202017-07-31 13:12:30 +030012757 unformat_input_t *input = vam->input;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012758 vl_api_sw_interface_span_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012759 vl_api_control_ping_t *mp_ping;
Eyal Bari5b311202017-07-31 13:12:30 +030012760 u8 is_l2 = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012761 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012762
Eyal Bari5b311202017-07-31 13:12:30 +030012763 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12764 {
12765 if (unformat (input, "l2"))
12766 is_l2 = 1;
12767 else
12768 break;
12769 }
12770
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012771 M (SW_INTERFACE_SPAN_DUMP, mp);
Eyal Bari5b311202017-07-31 13:12:30 +030012772 mp->is_l2 = is_l2;
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012773 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012774
12775 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040012776 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012777 S (mp_ping);
12778
Jon Loeliger56c7b012017-02-01 12:31:41 -060012779 W (ret);
12780 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012781}
12782
12783int
12784api_pg_create_interface (vat_main_t * vam)
12785{
12786 unformat_input_t *input = vam->input;
12787 vl_api_pg_create_interface_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012788
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +020012789 u32 if_id = ~0, gso_size = 0;
12790 u8 gso_enabled = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012791 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012792 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12793 {
12794 if (unformat (input, "if_id %d", &if_id))
12795 ;
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +020012796 else if (unformat (input, "gso-enabled"))
12797 {
12798 gso_enabled = 1;
12799 if (unformat (input, "gso-size %u", &gso_size))
12800 ;
12801 else
12802 {
12803 errmsg ("missing gso-size");
12804 return -99;
12805 }
12806 }
Damjan Marion7cd468a2016-12-19 23:05:39 +010012807 else
12808 break;
12809 }
12810 if (if_id == ~0)
12811 {
12812 errmsg ("missing pg interface index");
12813 return -99;
12814 }
12815
12816 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012817 M (PG_CREATE_INTERFACE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012818 mp->context = 0;
12819 mp->interface_id = ntohl (if_id);
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +020012820 mp->gso_enabled = gso_enabled;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012821
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012822 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012823 W (ret);
12824 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012825}
12826
12827int
12828api_pg_capture (vat_main_t * vam)
12829{
12830 unformat_input_t *input = vam->input;
12831 vl_api_pg_capture_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012832
12833 u32 if_id = ~0;
12834 u8 enable = 1;
12835 u32 count = 1;
12836 u8 pcap_file_set = 0;
12837 u8 *pcap_file = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012838 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012839 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12840 {
12841 if (unformat (input, "if_id %d", &if_id))
12842 ;
12843 else if (unformat (input, "pcap %s", &pcap_file))
12844 pcap_file_set = 1;
12845 else if (unformat (input, "count %d", &count))
12846 ;
12847 else if (unformat (input, "disable"))
12848 enable = 0;
12849 else
12850 break;
12851 }
12852 if (if_id == ~0)
12853 {
12854 errmsg ("missing pg interface index");
12855 return -99;
12856 }
12857 if (pcap_file_set > 0)
12858 {
12859 if (vec_len (pcap_file) > 255)
12860 {
12861 errmsg ("pcap file name is too long");
12862 return -99;
12863 }
12864 }
12865
Damjan Marion7cd468a2016-12-19 23:05:39 +010012866 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012867 M (PG_CAPTURE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012868 mp->context = 0;
12869 mp->interface_id = ntohl (if_id);
12870 mp->is_enabled = enable;
12871 mp->count = ntohl (count);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012872 if (pcap_file_set != 0)
12873 {
Jakub Grajciardb863292020-01-30 14:14:15 +010012874 vl_api_vec_to_api_string (pcap_file, &mp->pcap_file_name);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012875 }
12876 vec_free (pcap_file);
12877
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012878 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012879 W (ret);
12880 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012881}
12882
12883int
12884api_pg_enable_disable (vat_main_t * vam)
12885{
12886 unformat_input_t *input = vam->input;
12887 vl_api_pg_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012888
12889 u8 enable = 1;
12890 u8 stream_name_set = 0;
12891 u8 *stream_name = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012892 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012893 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12894 {
12895 if (unformat (input, "stream %s", &stream_name))
12896 stream_name_set = 1;
12897 else if (unformat (input, "disable"))
12898 enable = 0;
12899 else
12900 break;
12901 }
12902
12903 if (stream_name_set > 0)
12904 {
12905 if (vec_len (stream_name) > 255)
12906 {
12907 errmsg ("stream name too long");
12908 return -99;
12909 }
12910 }
12911
Damjan Marion7cd468a2016-12-19 23:05:39 +010012912 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012913 M (PG_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012914 mp->context = 0;
12915 mp->is_enabled = enable;
12916 if (stream_name_set != 0)
12917 {
Jakub Grajciardb863292020-01-30 14:14:15 +010012918 vl_api_vec_to_api_string (stream_name, &mp->stream_name);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012919 }
12920 vec_free (stream_name);
12921
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012922 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012923 W (ret);
12924 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012925}
12926
12927int
Mohsin Kazmif382b062020-08-11 15:00:44 +020012928api_pg_interface_enable_disable_coalesce (vat_main_t * vam)
12929{
12930 unformat_input_t *input = vam->input;
12931 vl_api_pg_interface_enable_disable_coalesce_t *mp;
12932
12933 u32 sw_if_index = ~0;
12934 u8 enable = 1;
12935 int ret;
12936 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12937 {
12938 if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12939 ;
12940 else if (unformat (input, "sw_if_index %d", &sw_if_index))
12941 ;
12942 else if (unformat (input, "disable"))
12943 enable = 0;
12944 else
12945 break;
12946 }
12947
12948 if (sw_if_index == ~0)
12949 {
12950 errmsg ("Interface required but not specified");
12951 return -99;
12952 }
12953
12954 /* Construct the API message */
12955 M (PG_INTERFACE_ENABLE_DISABLE_COALESCE, mp);
12956 mp->context = 0;
12957 mp->coalesce_enabled = enable;
12958 mp->sw_if_index = htonl (sw_if_index);
12959
12960 S (mp);
12961 W (ret);
12962 return ret;
12963}
12964
12965int
Damjan Marion7cd468a2016-12-19 23:05:39 +010012966api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
12967{
12968 unformat_input_t *input = vam->input;
12969 vl_api_ip_source_and_port_range_check_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012970
12971 u16 *low_ports = 0;
12972 u16 *high_ports = 0;
12973 u16 this_low;
12974 u16 this_hi;
Neale Ranns37029302018-08-10 05:30:06 -070012975 vl_api_prefix_t prefix;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012976 u32 tmp, tmp2;
12977 u8 prefix_set = 0;
12978 u32 vrf_id = ~0;
12979 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012980 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012981
12982 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12983 {
Neale Ranns37029302018-08-10 05:30:06 -070012984 if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
12985 prefix_set = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012986 else if (unformat (input, "vrf %d", &vrf_id))
12987 ;
12988 else if (unformat (input, "del"))
12989 is_add = 0;
12990 else if (unformat (input, "port %d", &tmp))
12991 {
12992 if (tmp == 0 || tmp > 65535)
12993 {
12994 errmsg ("port %d out of range", tmp);
12995 return -99;
12996 }
12997 this_low = tmp;
12998 this_hi = this_low + 1;
12999 vec_add1 (low_ports, this_low);
13000 vec_add1 (high_ports, this_hi);
13001 }
13002 else if (unformat (input, "range %d - %d", &tmp, &tmp2))
13003 {
13004 if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
13005 {
13006 errmsg ("incorrect range parameters");
13007 return -99;
13008 }
13009 this_low = tmp;
13010 /* Note: in debug CLI +1 is added to high before
13011 passing to real fn that does "the work"
13012 (ip_source_and_port_range_check_add_del).
13013 This fn is a wrapper around the binary API fn a
13014 control plane will call, which expects this increment
13015 to have occurred. Hence letting the binary API control
13016 plane fn do the increment for consistency between VAT
13017 and other control planes.
13018 */
13019 this_hi = tmp2;
13020 vec_add1 (low_ports, this_low);
13021 vec_add1 (high_ports, this_hi);
13022 }
13023 else
13024 break;
13025 }
13026
13027 if (prefix_set == 0)
13028 {
13029 errmsg ("<address>/<mask> not specified");
13030 return -99;
13031 }
13032
13033 if (vrf_id == ~0)
13034 {
13035 errmsg ("VRF ID required, not specified");
13036 return -99;
13037 }
13038
13039 if (vrf_id == 0)
13040 {
13041 errmsg
13042 ("VRF ID should not be default. Should be distinct VRF for this purpose.");
13043 return -99;
13044 }
13045
13046 if (vec_len (low_ports) == 0)
13047 {
13048 errmsg ("At least one port or port range required");
13049 return -99;
13050 }
13051
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013052 M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013053
13054 mp->is_add = is_add;
13055
Neale Ranns37029302018-08-10 05:30:06 -070013056 clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
Damjan Marion7cd468a2016-12-19 23:05:39 +010013057
Damjan Marion7cd468a2016-12-19 23:05:39 +010013058 mp->number_of_ranges = vec_len (low_ports);
13059
13060 clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
13061 vec_free (low_ports);
13062
13063 clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
13064 vec_free (high_ports);
13065
13066 mp->vrf_id = ntohl (vrf_id);
13067
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013068 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013069 W (ret);
13070 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013071}
13072
13073int
13074api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
13075{
13076 unformat_input_t *input = vam->input;
13077 vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013078 u32 sw_if_index = ~0;
13079 int vrf_set = 0;
13080 u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
13081 u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
13082 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013083 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013084
13085 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13086 {
13087 if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13088 ;
13089 else if (unformat (input, "sw_if_index %d", &sw_if_index))
13090 ;
13091 else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
13092 vrf_set = 1;
13093 else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
13094 vrf_set = 1;
13095 else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
13096 vrf_set = 1;
13097 else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
13098 vrf_set = 1;
13099 else if (unformat (input, "del"))
13100 is_add = 0;
13101 else
13102 break;
13103 }
13104
13105 if (sw_if_index == ~0)
13106 {
13107 errmsg ("Interface required but not specified");
13108 return -99;
13109 }
13110
13111 if (vrf_set == 0)
13112 {
13113 errmsg ("VRF ID required but not specified");
13114 return -99;
13115 }
13116
13117 if (tcp_out_vrf_id == 0
13118 || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
13119 {
13120 errmsg
13121 ("VRF ID should not be default. Should be distinct VRF for this purpose.");
13122 return -99;
13123 }
13124
13125 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013126 M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013127
13128 mp->sw_if_index = ntohl (sw_if_index);
13129 mp->is_add = is_add;
13130 mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
13131 mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
13132 mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
13133 mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
13134
13135 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013136 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013137
13138 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060013139 W (ret);
13140 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013141}
13142
13143static int
Pavel Kotuceke88865d2018-11-28 07:42:11 +010013144api_set_punt (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010013145{
13146 unformat_input_t *i = vam->input;
Neale Ranns50f0ac02019-05-15 02:13:37 -070013147 vl_api_address_family_t af;
Pavel Kotuceke88865d2018-11-28 07:42:11 +010013148 vl_api_set_punt_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013149 u32 protocol = ~0;
13150 u32 port = ~0;
13151 int is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013152 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013153
13154 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13155 {
Neale Ranns50f0ac02019-05-15 02:13:37 -070013156 if (unformat (i, "%U", unformat_vl_api_address_family, &af))
Damjan Marion7cd468a2016-12-19 23:05:39 +010013157 ;
13158 else if (unformat (i, "protocol %d", &protocol))
13159 ;
13160 else if (unformat (i, "port %d", &port))
13161 ;
13162 else if (unformat (i, "del"))
13163 is_add = 0;
13164 else
13165 {
13166 clib_warning ("parse error '%U'", format_unformat_error, i);
13167 return -99;
13168 }
13169 }
13170
Pavel Kotuceke88865d2018-11-28 07:42:11 +010013171 M (SET_PUNT, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013172
13173 mp->is_add = (u8) is_add;
Neale Ranns50f0ac02019-05-15 02:13:37 -070013174 mp->punt.type = PUNT_API_TYPE_L4;
13175 mp->punt.punt.l4.af = af;
13176 mp->punt.punt.l4.protocol = (u8) protocol;
13177 mp->punt.punt.l4.port = htons ((u16) port);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013178
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013179 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013180 W (ret);
13181 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013182}
13183
Damjan Marion7cd468a2016-12-19 23:05:39 +010013184static int
13185api_delete_subif (vat_main_t * vam)
13186{
13187 unformat_input_t *i = vam->input;
13188 vl_api_delete_subif_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013189 u32 sw_if_index = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013190 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013191
13192 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13193 {
13194 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13195 ;
13196 if (unformat (i, "sw_if_index %d", &sw_if_index))
13197 ;
13198 else
13199 break;
13200 }
13201
13202 if (sw_if_index == ~0)
13203 {
13204 errmsg ("missing sw_if_index");
13205 return -99;
13206 }
13207
13208 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013209 M (DELETE_SUBIF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013210 mp->sw_if_index = ntohl (sw_if_index);
13211
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013212 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013213 W (ret);
13214 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013215}
13216
13217#define foreach_pbb_vtr_op \
13218_("disable", L2_VTR_DISABLED) \
13219_("pop", L2_VTR_POP_2) \
13220_("push", L2_VTR_PUSH_2)
13221
13222static int
13223api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
13224{
13225 unformat_input_t *i = vam->input;
13226 vl_api_l2_interface_pbb_tag_rewrite_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013227 u32 sw_if_index = ~0, vtr_op = ~0;
13228 u16 outer_tag = ~0;
13229 u8 dmac[6], smac[6];
13230 u8 dmac_set = 0, smac_set = 0;
13231 u16 vlanid = 0;
13232 u32 sid = ~0;
13233 u32 tmp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013234 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013235
13236 /* Shut up coverity */
Dave Barachb7b92992018-10-17 10:38:51 -040013237 clib_memset (dmac, 0, sizeof (dmac));
13238 clib_memset (smac, 0, sizeof (smac));
Damjan Marion7cd468a2016-12-19 23:05:39 +010013239
13240 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13241 {
13242 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13243 ;
13244 else if (unformat (i, "sw_if_index %d", &sw_if_index))
13245 ;
13246 else if (unformat (i, "vtr_op %d", &vtr_op))
13247 ;
13248#define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
13249 foreach_pbb_vtr_op
13250#undef _
13251 else if (unformat (i, "translate_pbb_stag"))
13252 {
13253 if (unformat (i, "%d", &tmp))
13254 {
13255 vtr_op = L2_VTR_TRANSLATE_2_1;
13256 outer_tag = tmp;
13257 }
13258 else
13259 {
13260 errmsg
13261 ("translate_pbb_stag operation requires outer tag definition");
13262 return -99;
13263 }
13264 }
13265 else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
13266 dmac_set++;
13267 else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
13268 smac_set++;
13269 else if (unformat (i, "sid %d", &sid))
13270 ;
13271 else if (unformat (i, "vlanid %d", &tmp))
13272 vlanid = tmp;
13273 else
13274 {
13275 clib_warning ("parse error '%U'", format_unformat_error, i);
13276 return -99;
13277 }
13278 }
13279
13280 if ((sw_if_index == ~0) || (vtr_op == ~0))
13281 {
13282 errmsg ("missing sw_if_index or vtr operation");
13283 return -99;
13284 }
13285 if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
13286 && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
13287 {
13288 errmsg
13289 ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
13290 return -99;
13291 }
13292
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013293 M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013294 mp->sw_if_index = ntohl (sw_if_index);
13295 mp->vtr_op = ntohl (vtr_op);
13296 mp->outer_tag = ntohs (outer_tag);
13297 clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
13298 clib_memcpy (mp->b_smac, smac, sizeof (smac));
13299 mp->b_vlanid = ntohs (vlanid);
13300 mp->i_sid = ntohl (sid);
13301
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013302 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013303 W (ret);
13304 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013305}
13306
13307static int
13308api_flow_classify_set_interface (vat_main_t * vam)
13309{
13310 unformat_input_t *i = vam->input;
13311 vl_api_flow_classify_set_interface_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013312 u32 sw_if_index;
13313 int sw_if_index_set;
13314 u32 ip4_table_index = ~0;
13315 u32 ip6_table_index = ~0;
13316 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013317 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013318
13319 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13320 {
13321 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13322 sw_if_index_set = 1;
13323 else if (unformat (i, "sw_if_index %d", &sw_if_index))
13324 sw_if_index_set = 1;
13325 else if (unformat (i, "del"))
13326 is_add = 0;
13327 else if (unformat (i, "ip4-table %d", &ip4_table_index))
13328 ;
13329 else if (unformat (i, "ip6-table %d", &ip6_table_index))
13330 ;
13331 else
13332 {
13333 clib_warning ("parse error '%U'", format_unformat_error, i);
13334 return -99;
13335 }
13336 }
13337
13338 if (sw_if_index_set == 0)
13339 {
13340 errmsg ("missing interface name or sw_if_index");
13341 return -99;
13342 }
13343
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013344 M (FLOW_CLASSIFY_SET_INTERFACE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013345
13346 mp->sw_if_index = ntohl (sw_if_index);
13347 mp->ip4_table_index = ntohl (ip4_table_index);
13348 mp->ip6_table_index = ntohl (ip6_table_index);
13349 mp->is_add = is_add;
13350
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013351 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013352 W (ret);
13353 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013354}
13355
13356static int
13357api_flow_classify_dump (vat_main_t * vam)
13358{
13359 unformat_input_t *i = vam->input;
13360 vl_api_flow_classify_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060013361 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013362 u8 type = FLOW_CLASSIFY_N_TABLES;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013363 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013364
13365 if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
13366 ;
13367 else
13368 {
13369 errmsg ("classify table type must be specified");
13370 return -99;
13371 }
13372
13373 if (!vam->json_output)
13374 {
13375 print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
13376 }
13377
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013378 M (FLOW_CLASSIFY_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013379 mp->type = type;
13380 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013381 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013382
13383 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040013384 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060013385 S (mp_ping);
13386
Damjan Marion7cd468a2016-12-19 23:05:39 +010013387 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060013388 W (ret);
13389 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013390}
13391
13392static int
13393api_feature_enable_disable (vat_main_t * vam)
13394{
13395 unformat_input_t *i = vam->input;
13396 vl_api_feature_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013397 u8 *arc_name = 0;
13398 u8 *feature_name = 0;
13399 u32 sw_if_index = ~0;
13400 u8 enable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013401 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013402
13403 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13404 {
13405 if (unformat (i, "arc_name %s", &arc_name))
13406 ;
13407 else if (unformat (i, "feature_name %s", &feature_name))
13408 ;
13409 else
13410 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13411 ;
13412 else if (unformat (i, "sw_if_index %d", &sw_if_index))
13413 ;
13414 else if (unformat (i, "disable"))
13415 enable = 0;
13416 else
13417 break;
13418 }
13419
13420 if (arc_name == 0)
13421 {
13422 errmsg ("missing arc name");
13423 return -99;
13424 }
13425 if (vec_len (arc_name) > 63)
13426 {
13427 errmsg ("arc name too long");
13428 }
13429
13430 if (feature_name == 0)
13431 {
13432 errmsg ("missing feature name");
13433 return -99;
13434 }
13435 if (vec_len (feature_name) > 63)
13436 {
13437 errmsg ("feature name too long");
13438 }
13439
13440 if (sw_if_index == ~0)
13441 {
13442 errmsg ("missing interface name or sw_if_index");
13443 return -99;
13444 }
13445
13446 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013447 M (FEATURE_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013448 mp->sw_if_index = ntohl (sw_if_index);
13449 mp->enable = enable;
13450 clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
13451 clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
13452 vec_free (arc_name);
13453 vec_free (feature_name);
13454
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013455 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013456 W (ret);
13457 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013458}
13459
13460static int
Mohsin Kazmi29467b52019-10-08 19:42:38 +020013461api_feature_gso_enable_disable (vat_main_t * vam)
13462{
13463 unformat_input_t *i = vam->input;
13464 vl_api_feature_gso_enable_disable_t *mp;
13465 u32 sw_if_index = ~0;
13466 u8 enable = 1;
13467 int ret;
13468
13469 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13470 {
13471 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13472 ;
13473 else if (unformat (i, "sw_if_index %d", &sw_if_index))
13474 ;
13475 else if (unformat (i, "enable"))
13476 enable = 1;
13477 else if (unformat (i, "disable"))
13478 enable = 0;
13479 else
13480 break;
13481 }
13482
13483 if (sw_if_index == ~0)
13484 {
13485 errmsg ("missing interface name or sw_if_index");
13486 return -99;
13487 }
13488
13489 /* Construct the API message */
13490 M (FEATURE_GSO_ENABLE_DISABLE, mp);
13491 mp->sw_if_index = ntohl (sw_if_index);
13492 mp->enable_disable = enable;
13493
13494 S (mp);
13495 W (ret);
13496 return ret;
13497}
13498
13499static int
Damjan Marion7cd468a2016-12-19 23:05:39 +010013500api_sw_interface_tag_add_del (vat_main_t * vam)
13501{
13502 unformat_input_t *i = vam->input;
13503 vl_api_sw_interface_tag_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013504 u32 sw_if_index = ~0;
13505 u8 *tag = 0;
13506 u8 enable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013507 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013508
13509 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13510 {
13511 if (unformat (i, "tag %s", &tag))
13512 ;
13513 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13514 ;
13515 else if (unformat (i, "sw_if_index %d", &sw_if_index))
13516 ;
13517 else if (unformat (i, "del"))
13518 enable = 0;
13519 else
13520 break;
13521 }
13522
13523 if (sw_if_index == ~0)
13524 {
13525 errmsg ("missing interface name or sw_if_index");
13526 return -99;
13527 }
13528
13529 if (enable && (tag == 0))
13530 {
13531 errmsg ("no tag specified");
13532 return -99;
13533 }
13534
13535 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013536 M (SW_INTERFACE_TAG_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013537 mp->sw_if_index = ntohl (sw_if_index);
13538 mp->is_add = enable;
13539 if (enable)
Ole Troane5ff5a32019-08-23 22:55:18 +020013540 strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013541 vec_free (tag);
13542
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013543 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013544 W (ret);
13545 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013546}
13547
Matthew Smithe0792fd2019-07-12 11:48:24 -050013548static int
13549api_sw_interface_add_del_mac_address (vat_main_t * vam)
13550{
13551 unformat_input_t *i = vam->input;
13552 vl_api_mac_address_t mac = { 0 };
13553 vl_api_sw_interface_add_del_mac_address_t *mp;
13554 u32 sw_if_index = ~0;
13555 u8 is_add = 1;
13556 u8 mac_set = 0;
13557 int ret;
13558
13559 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13560 {
13561 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13562 ;
13563 else if (unformat (i, "sw_if_index %d", &sw_if_index))
13564 ;
13565 else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
13566 mac_set++;
13567 else if (unformat (i, "del"))
13568 is_add = 0;
13569 else
13570 break;
13571 }
13572
13573 if (sw_if_index == ~0)
13574 {
13575 errmsg ("missing interface name or sw_if_index");
13576 return -99;
13577 }
13578
13579 if (!mac_set)
13580 {
13581 errmsg ("missing MAC address");
13582 return -99;
13583 }
13584
13585 /* Construct the API message */
13586 M (SW_INTERFACE_ADD_DEL_MAC_ADDRESS, mp);
13587 mp->sw_if_index = ntohl (sw_if_index);
13588 mp->is_add = is_add;
13589 clib_memcpy (&mp->addr, &mac, sizeof (mac));
13590
13591 S (mp);
13592 W (ret);
13593 return ret;
13594}
13595
Damjan Marion7cd468a2016-12-19 23:05:39 +010013596static void vl_api_l2_xconnect_details_t_handler
13597 (vl_api_l2_xconnect_details_t * mp)
13598{
13599 vat_main_t *vam = &vat_main;
13600
13601 print (vam->ofp, "%15d%15d",
13602 ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
13603}
13604
13605static void vl_api_l2_xconnect_details_t_handler_json
13606 (vl_api_l2_xconnect_details_t * mp)
13607{
13608 vat_main_t *vam = &vat_main;
13609 vat_json_node_t *node = NULL;
13610
13611 if (VAT_JSON_ARRAY != vam->json_tree.type)
13612 {
13613 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13614 vat_json_init_array (&vam->json_tree);
13615 }
13616 node = vat_json_array_add (&vam->json_tree);
13617
13618 vat_json_init_object (node);
13619 vat_json_object_add_uint (node, "rx_sw_if_index",
13620 ntohl (mp->rx_sw_if_index));
13621 vat_json_object_add_uint (node, "tx_sw_if_index",
13622 ntohl (mp->tx_sw_if_index));
13623}
13624
13625static int
13626api_l2_xconnect_dump (vat_main_t * vam)
13627{
13628 vl_api_l2_xconnect_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060013629 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013630 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013631
13632 if (!vam->json_output)
13633 {
13634 print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
13635 }
13636
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013637 M (L2_XCONNECT_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013638
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013639 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013640
13641 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040013642 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060013643 S (mp_ping);
13644
Jon Loeliger56c7b012017-02-01 12:31:41 -060013645 W (ret);
13646 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013647}
13648
13649static int
Ole Troand7231612018-06-07 10:17:57 +020013650api_hw_interface_set_mtu (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010013651{
13652 unformat_input_t *i = vam->input;
Ole Troand7231612018-06-07 10:17:57 +020013653 vl_api_hw_interface_set_mtu_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013654 u32 sw_if_index = ~0;
13655 u32 mtu = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013656 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013657
13658 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13659 {
13660 if (unformat (i, "mtu %d", &mtu))
13661 ;
13662 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13663 ;
13664 else if (unformat (i, "sw_if_index %d", &sw_if_index))
13665 ;
13666 else
13667 break;
13668 }
13669
13670 if (sw_if_index == ~0)
13671 {
13672 errmsg ("missing interface name or sw_if_index");
13673 return -99;
13674 }
13675
13676 if (mtu == 0)
13677 {
13678 errmsg ("no mtu specified");
13679 return -99;
13680 }
13681
13682 /* Construct the API message */
Ole Troand7231612018-06-07 10:17:57 +020013683 M (HW_INTERFACE_SET_MTU, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013684 mp->sw_if_index = ntohl (sw_if_index);
13685 mp->mtu = ntohs ((u16) mtu);
13686
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013687 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013688 W (ret);
13689 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013690}
13691
Pavel Kotucek6899a302017-06-08 08:46:10 +020013692static int
13693api_p2p_ethernet_add (vat_main_t * vam)
13694{
13695 unformat_input_t *i = vam->input;
13696 vl_api_p2p_ethernet_add_t *mp;
13697 u32 parent_if_index = ~0;
Pavel Kotucek15ac81c2017-06-20 14:00:26 +020013698 u32 sub_id = ~0;
Pavel Kotucek6899a302017-06-08 08:46:10 +020013699 u8 remote_mac[6];
13700 u8 mac_set = 0;
13701 int ret;
13702
Dave Barachb7b92992018-10-17 10:38:51 -040013703 clib_memset (remote_mac, 0, sizeof (remote_mac));
Pavel Kotucek6899a302017-06-08 08:46:10 +020013704 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13705 {
13706 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
13707 ;
13708 else if (unformat (i, "sw_if_index %d", &parent_if_index))
13709 ;
13710 else
13711 if (unformat
13712 (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
13713 mac_set++;
Pavel Kotucek15ac81c2017-06-20 14:00:26 +020013714 else if (unformat (i, "sub_id %d", &sub_id))
13715 ;
Pavel Kotucek6899a302017-06-08 08:46:10 +020013716 else
13717 {
13718 clib_warning ("parse error '%U'", format_unformat_error, i);
13719 return -99;
13720 }
13721 }
13722
13723 if (parent_if_index == ~0)
13724 {
13725 errmsg ("missing interface name or sw_if_index");
13726 return -99;
13727 }
13728 if (mac_set == 0)
13729 {
13730 errmsg ("missing remote mac address");
13731 return -99;
13732 }
Pavel Kotucek15ac81c2017-06-20 14:00:26 +020013733 if (sub_id == ~0)
13734 {
13735 errmsg ("missing sub-interface id");
13736 return -99;
13737 }
Pavel Kotucek6899a302017-06-08 08:46:10 +020013738
13739 M (P2P_ETHERNET_ADD, mp);
13740 mp->parent_if_index = ntohl (parent_if_index);
Pavel Kotucek15ac81c2017-06-20 14:00:26 +020013741 mp->subif_id = ntohl (sub_id);
Pavel Kotucek6899a302017-06-08 08:46:10 +020013742 clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
13743
13744 S (mp);
13745 W (ret);
13746 return ret;
13747}
13748
13749static int
13750api_p2p_ethernet_del (vat_main_t * vam)
13751{
13752 unformat_input_t *i = vam->input;
13753 vl_api_p2p_ethernet_del_t *mp;
13754 u32 parent_if_index = ~0;
13755 u8 remote_mac[6];
13756 u8 mac_set = 0;
13757 int ret;
13758
Dave Barachb7b92992018-10-17 10:38:51 -040013759 clib_memset (remote_mac, 0, sizeof (remote_mac));
Pavel Kotucek6899a302017-06-08 08:46:10 +020013760 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13761 {
13762 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
13763 ;
13764 else if (unformat (i, "sw_if_index %d", &parent_if_index))
13765 ;
13766 else
13767 if (unformat
13768 (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
13769 mac_set++;
13770 else
13771 {
13772 clib_warning ("parse error '%U'", format_unformat_error, i);
13773 return -99;
13774 }
13775 }
13776
13777 if (parent_if_index == ~0)
13778 {
13779 errmsg ("missing interface name or sw_if_index");
13780 return -99;
13781 }
13782 if (mac_set == 0)
13783 {
13784 errmsg ("missing remote mac address");
13785 return -99;
13786 }
13787
13788 M (P2P_ETHERNET_DEL, mp);
13789 mp->parent_if_index = ntohl (parent_if_index);
13790 clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
13791
13792 S (mp);
13793 W (ret);
13794 return ret;
13795}
Damjan Marion7cd468a2016-12-19 23:05:39 +010013796
13797static int
Dave Barach3bbcfab2017-08-15 19:03:44 -040013798api_tcp_configure_src_addresses (vat_main_t * vam)
13799{
13800 vl_api_tcp_configure_src_addresses_t *mp;
13801 unformat_input_t *i = vam->input;
Neale Rannscbe25aa2019-09-30 10:53:31 +000013802 vl_api_address_t first, last;
Dave Barach3bbcfab2017-08-15 19:03:44 -040013803 u8 range_set = 0;
13804 u32 vrf_id = 0;
13805 int ret;
13806
13807 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13808 {
13809 if (unformat (i, "%U - %U",
Neale Rannscbe25aa2019-09-30 10:53:31 +000013810 unformat_vl_api_address, &first,
13811 unformat_vl_api_address, &last))
Dave Barach3bbcfab2017-08-15 19:03:44 -040013812 {
13813 if (range_set)
13814 {
13815 errmsg ("one range per message (range already set)");
13816 return -99;
13817 }
13818 range_set = 1;
13819 }
Dave Barach3bbcfab2017-08-15 19:03:44 -040013820 else if (unformat (i, "vrf %d", &vrf_id))
13821 ;
13822 else
13823 break;
13824 }
13825
13826 if (range_set == 0)
13827 {
13828 errmsg ("address range not set");
13829 return -99;
13830 }
13831
13832 M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
Neale Rannscbe25aa2019-09-30 10:53:31 +000013833
Dave Barach3bbcfab2017-08-15 19:03:44 -040013834 mp->vrf_id = ntohl (vrf_id);
Neale Rannscbe25aa2019-09-30 10:53:31 +000013835 clib_memcpy (&mp->first_address, &first, sizeof (first));
13836 clib_memcpy (&mp->last_address, &last, sizeof (last));
13837
Dave Barach3bbcfab2017-08-15 19:03:44 -040013838 S (mp);
13839 W (ret);
13840 return ret;
13841}
13842
Florin Coras6e8c6672017-11-10 09:03:54 -080013843static void vl_api_app_namespace_add_del_reply_t_handler
13844 (vl_api_app_namespace_add_del_reply_t * mp)
13845{
13846 vat_main_t *vam = &vat_main;
13847 i32 retval = ntohl (mp->retval);
13848 if (vam->async_mode)
13849 {
13850 vam->async_errors += (retval < 0);
13851 }
13852 else
13853 {
13854 vam->retval = retval;
13855 if (retval == 0)
13856 errmsg ("app ns index %d\n", ntohl (mp->appns_index));
13857 vam->result_ready = 1;
13858 }
13859}
13860
13861static void vl_api_app_namespace_add_del_reply_t_handler_json
13862 (vl_api_app_namespace_add_del_reply_t * mp)
13863{
13864 vat_main_t *vam = &vat_main;
13865 vat_json_node_t node;
13866
13867 vat_json_init_object (&node);
13868 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
13869 vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
13870
13871 vat_json_print (vam->ofp, &node);
13872 vat_json_free (&node);
13873
13874 vam->retval = ntohl (mp->retval);
13875 vam->result_ready = 1;
13876}
13877
Dave Barach3bbcfab2017-08-15 19:03:44 -040013878static int
Florin Corascea194d2017-10-02 00:18:51 -070013879api_app_namespace_add_del (vat_main_t * vam)
13880{
13881 vl_api_app_namespace_add_del_t *mp;
13882 unformat_input_t *i = vam->input;
13883 u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
13884 u32 sw_if_index, ip4_fib_id, ip6_fib_id;
13885 u64 secret;
13886 int ret;
13887
13888 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13889 {
13890 if (unformat (i, "id %_%v%_", &ns_id))
13891 ;
13892 else if (unformat (i, "secret %lu", &secret))
13893 secret_set = 1;
13894 else if (unformat (i, "sw_if_index %d", &sw_if_index))
13895 sw_if_index_set = 1;
13896 else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
13897 ;
13898 else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
13899 ;
13900 else
13901 break;
13902 }
13903 if (!ns_id || !secret_set || !sw_if_index_set)
13904 {
13905 errmsg ("namespace id, secret and sw_if_index must be set");
13906 return -99;
13907 }
13908 if (vec_len (ns_id) > 64)
13909 {
13910 errmsg ("namespace id too long");
13911 return -99;
13912 }
13913 M (APP_NAMESPACE_ADD_DEL, mp);
13914
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010013915 vl_api_vec_to_api_string (ns_id, &mp->namespace_id);
Florin Coras9a9adb22017-10-26 08:16:59 -070013916 mp->secret = clib_host_to_net_u64 (secret);
Florin Corascea194d2017-10-02 00:18:51 -070013917 mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
13918 mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
13919 mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
13920 vec_free (ns_id);
13921 S (mp);
13922 W (ret);
13923 return ret;
13924}
13925
13926static int
Florin Coras90a63982017-12-19 04:50:01 -080013927api_sock_init_shm (vat_main_t * vam)
13928{
13929#if VPP_API_TEST_BUILTIN == 0
13930 unformat_input_t *i = vam->input;
13931 vl_api_shm_elem_config_t *config = 0;
13932 u64 size = 64 << 20;
13933 int rv;
13934
13935 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13936 {
13937 if (unformat (i, "size %U", unformat_memory_size, &size))
13938 ;
13939 else
13940 break;
13941 }
13942
Dave Barach78958722018-05-10 16:44:27 -040013943 /*
13944 * Canned custom ring allocator config.
13945 * Should probably parse all of this
13946 */
13947 vec_validate (config, 6);
Florin Coras90a63982017-12-19 04:50:01 -080013948 config[0].type = VL_API_VLIB_RING;
Florin Coras90a63982017-12-19 04:50:01 -080013949 config[0].size = 256;
Dave Barach78958722018-05-10 16:44:27 -040013950 config[0].count = 32;
13951
13952 config[1].type = VL_API_VLIB_RING;
Florin Coras90a63982017-12-19 04:50:01 -080013953 config[1].size = 1024;
Dave Barach78958722018-05-10 16:44:27 -040013954 config[1].count = 16;
13955
13956 config[2].type = VL_API_VLIB_RING;
Florin Coras90a63982017-12-19 04:50:01 -080013957 config[2].size = 4096;
Dave Barach78958722018-05-10 16:44:27 -040013958 config[2].count = 2;
13959
13960 config[3].type = VL_API_CLIENT_RING;
13961 config[3].size = 256;
13962 config[3].count = 32;
13963
13964 config[4].type = VL_API_CLIENT_RING;
13965 config[4].size = 1024;
13966 config[4].count = 16;
13967
13968 config[5].type = VL_API_CLIENT_RING;
13969 config[5].size = 4096;
13970 config[5].count = 2;
13971
13972 config[6].type = VL_API_QUEUE;
13973 config[6].count = 128;
13974 config[6].size = sizeof (uword);
13975
Tomasz Kulasek97dcf5b2019-01-31 18:26:32 +010013976 rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
Florin Coras90a63982017-12-19 04:50:01 -080013977 if (!rv)
13978 vam->client_index_invalid = 1;
13979 return rv;
13980#else
13981 return -99;
13982#endif
13983}
13984
Florin Coras6c36f532017-11-03 18:32:34 -070013985static void
13986vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
13987{
13988 vat_main_t *vam = &vat_main;
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010013989 fib_prefix_t lcl, rmt;
Florin Coras6c36f532017-11-03 18:32:34 -070013990
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010013991 ip_prefix_decode (&mp->lcl, &lcl);
13992 ip_prefix_decode (&mp->rmt, &rmt);
13993
13994 if (lcl.fp_proto == FIB_PROTOCOL_IP4)
Florin Coras6c36f532017-11-03 18:32:34 -070013995 {
Florin Corasc97a7392017-11-05 23:07:07 -080013996 print (vam->ofp,
13997 "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
Steven85dbac02017-11-07 16:29:53 -080013998 clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010013999 mp->scope, format_ip4_address, &lcl.fp_addr.ip4, lcl.fp_len,
Steven85dbac02017-11-07 16:29:53 -080014000 clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014001 &rmt.fp_addr.ip4, rmt.fp_len,
14002 clib_net_to_host_u16 (mp->rmt_port),
Steven85dbac02017-11-07 16:29:53 -080014003 clib_net_to_host_u32 (mp->action_index), mp->tag);
Florin Coras6c36f532017-11-03 18:32:34 -070014004 }
14005 else
14006 {
Florin Corasc97a7392017-11-05 23:07:07 -080014007 print (vam->ofp,
14008 "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
Steven85dbac02017-11-07 16:29:53 -080014009 clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014010 mp->scope, format_ip6_address, &lcl.fp_addr.ip6, lcl.fp_len,
Steven85dbac02017-11-07 16:29:53 -080014011 clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014012 &rmt.fp_addr.ip6, rmt.fp_len,
14013 clib_net_to_host_u16 (mp->rmt_port),
Steven85dbac02017-11-07 16:29:53 -080014014 clib_net_to_host_u32 (mp->action_index), mp->tag);
Florin Coras6c36f532017-11-03 18:32:34 -070014015 }
14016}
14017
14018static void
14019vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
14020 mp)
14021{
14022 vat_main_t *vam = &vat_main;
14023 vat_json_node_t *node = NULL;
14024 struct in6_addr ip6;
14025 struct in_addr ip4;
14026
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014027 fib_prefix_t lcl, rmt;
14028
14029 ip_prefix_decode (&mp->lcl, &lcl);
14030 ip_prefix_decode (&mp->rmt, &rmt);
14031
Florin Coras6c36f532017-11-03 18:32:34 -070014032 if (VAT_JSON_ARRAY != vam->json_tree.type)
14033 {
14034 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14035 vat_json_init_array (&vam->json_tree);
14036 }
14037 node = vat_json_array_add (&vam->json_tree);
14038 vat_json_init_object (node);
14039
Florin Coras6c36f532017-11-03 18:32:34 -070014040 vat_json_object_add_uint (node, "appns_index",
14041 clib_net_to_host_u32 (mp->appns_index));
14042 vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
14043 vat_json_object_add_uint (node, "scope", mp->scope);
14044 vat_json_object_add_uint (node, "action_index",
14045 clib_net_to_host_u32 (mp->action_index));
14046 vat_json_object_add_uint (node, "lcl_port",
14047 clib_net_to_host_u16 (mp->lcl_port));
14048 vat_json_object_add_uint (node, "rmt_port",
14049 clib_net_to_host_u16 (mp->rmt_port));
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014050 vat_json_object_add_uint (node, "lcl_plen", lcl.fp_len);
14051 vat_json_object_add_uint (node, "rmt_plen", rmt.fp_len);
Florin Corasc97a7392017-11-05 23:07:07 -080014052 vat_json_object_add_string_copy (node, "tag", mp->tag);
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014053 if (lcl.fp_proto == FIB_PROTOCOL_IP4)
Florin Coras6c36f532017-11-03 18:32:34 -070014054 {
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014055 clib_memcpy (&ip4, &lcl.fp_addr.ip4, sizeof (ip4));
Florin Coras6c36f532017-11-03 18:32:34 -070014056 vat_json_object_add_ip4 (node, "lcl_ip", ip4);
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014057 clib_memcpy (&ip4, &rmt.fp_addr.ip4, sizeof (ip4));
Florin Coras6c36f532017-11-03 18:32:34 -070014058 vat_json_object_add_ip4 (node, "rmt_ip", ip4);
14059 }
14060 else
14061 {
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014062 clib_memcpy (&ip6, &lcl.fp_addr.ip6, sizeof (ip6));
Florin Coras6c36f532017-11-03 18:32:34 -070014063 vat_json_object_add_ip6 (node, "lcl_ip", ip6);
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014064 clib_memcpy (&ip6, &rmt.fp_addr.ip6, sizeof (ip6));
Florin Coras6c36f532017-11-03 18:32:34 -070014065 vat_json_object_add_ip6 (node, "rmt_ip", ip6);
14066 }
14067}
14068
Florin Coras1c710452017-10-17 00:03:13 -070014069static int
14070api_session_rule_add_del (vat_main_t * vam)
14071{
14072 vl_api_session_rule_add_del_t *mp;
14073 unformat_input_t *i = vam->input;
14074 u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
14075 u32 appns_index = 0, scope = 0;
14076 ip4_address_t lcl_ip4, rmt_ip4;
14077 ip6_address_t lcl_ip6, rmt_ip6;
14078 u8 is_ip4 = 1, conn_set = 0;
Florin Corasc97a7392017-11-05 23:07:07 -080014079 u8 is_add = 1, *tag = 0;
Florin Coras1c710452017-10-17 00:03:13 -070014080 int ret;
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014081 fib_prefix_t lcl, rmt;
Florin Coras1c710452017-10-17 00:03:13 -070014082
14083 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14084 {
14085 if (unformat (i, "del"))
14086 is_add = 0;
14087 else if (unformat (i, "add"))
14088 ;
14089 else if (unformat (i, "proto tcp"))
14090 proto = 0;
14091 else if (unformat (i, "proto udp"))
14092 proto = 1;
14093 else if (unformat (i, "appns %d", &appns_index))
14094 ;
14095 else if (unformat (i, "scope %d", &scope))
14096 ;
Florin Corasc97a7392017-11-05 23:07:07 -080014097 else if (unformat (i, "tag %_%v%_", &tag))
14098 ;
Florin Coras1c710452017-10-17 00:03:13 -070014099 else
14100 if (unformat
14101 (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
14102 &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
14103 &rmt_port))
14104 {
14105 is_ip4 = 1;
14106 conn_set = 1;
14107 }
14108 else
14109 if (unformat
14110 (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
14111 &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
14112 &rmt_port))
14113 {
14114 is_ip4 = 0;
14115 conn_set = 1;
14116 }
14117 else if (unformat (i, "action %d", &action))
14118 ;
14119 else
14120 break;
14121 }
14122 if (proto == ~0 || !conn_set || action == ~0)
14123 {
14124 errmsg ("transport proto, connection and action must be set");
14125 return -99;
14126 }
14127
14128 if (scope > 3)
14129 {
14130 errmsg ("scope should be 0-3");
14131 return -99;
14132 }
14133
14134 M (SESSION_RULE_ADD_DEL, mp);
14135
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014136 clib_memset (&lcl, 0, sizeof (lcl));
14137 clib_memset (&rmt, 0, sizeof (rmt));
14138 if (is_ip4)
14139 {
14140 ip_set (&lcl.fp_addr, &lcl_ip4, 1);
14141 ip_set (&rmt.fp_addr, &rmt_ip4, 1);
14142 lcl.fp_len = lcl_plen;
14143 rmt.fp_len = rmt_plen;
14144 }
14145 else
14146 {
14147 ip_set (&lcl.fp_addr, &lcl_ip6, 0);
14148 ip_set (&rmt.fp_addr, &rmt_ip6, 0);
14149 lcl.fp_len = lcl_plen;
14150 rmt.fp_len = rmt_plen;
14151 }
14152
14153
14154 ip_prefix_encode (&lcl, &mp->lcl);
14155 ip_prefix_encode (&rmt, &mp->rmt);
Florin Corasc97a7392017-11-05 23:07:07 -080014156 mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
14157 mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014158 mp->transport_proto =
14159 proto ? TRANSPORT_PROTO_API_UDP : TRANSPORT_PROTO_API_TCP;
Florin Coras1c710452017-10-17 00:03:13 -070014160 mp->action_index = clib_host_to_net_u32 (action);
14161 mp->appns_index = clib_host_to_net_u32 (appns_index);
14162 mp->scope = scope;
14163 mp->is_add = is_add;
Florin Corasc97a7392017-11-05 23:07:07 -080014164 if (tag)
14165 {
14166 clib_memcpy (mp->tag, tag, vec_len (tag));
14167 vec_free (tag);
14168 }
Florin Coras1c710452017-10-17 00:03:13 -070014169
14170 S (mp);
14171 W (ret);
14172 return ret;
14173}
Dave Barach65457162017-10-10 17:53:14 -040014174
14175static int
Florin Coras6c36f532017-11-03 18:32:34 -070014176api_session_rules_dump (vat_main_t * vam)
14177{
14178 vl_api_session_rules_dump_t *mp;
14179 vl_api_control_ping_t *mp_ping;
14180 int ret;
14181
14182 if (!vam->json_output)
14183 {
14184 print (vam->ofp, "%=20s", "Session Rules");
14185 }
14186
14187 M (SESSION_RULES_DUMP, mp);
14188 /* send it... */
14189 S (mp);
14190
14191 /* Use a control ping for synchronization */
14192 MPING (CONTROL_PING, mp_ping);
14193 S (mp_ping);
14194
14195 /* Wait for a reply... */
14196 W (ret);
14197 return ret;
14198}
14199
14200static int
Florin Coras595992c2017-11-06 17:17:08 -080014201api_ip_container_proxy_add_del (vat_main_t * vam)
14202{
14203 vl_api_ip_container_proxy_add_del_t *mp;
14204 unformat_input_t *i = vam->input;
Neale Ranns37029302018-08-10 05:30:06 -070014205 u32 sw_if_index = ~0;
14206 vl_api_prefix_t pfx = { };
Florin Coras595992c2017-11-06 17:17:08 -080014207 u8 is_add = 1;
14208 int ret;
14209
14210 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14211 {
14212 if (unformat (i, "del"))
14213 is_add = 0;
14214 else if (unformat (i, "add"))
14215 ;
Neale Ranns37029302018-08-10 05:30:06 -070014216 if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
14217 ;
Florin Coras595992c2017-11-06 17:17:08 -080014218 else if (unformat (i, "sw_if_index %u", &sw_if_index))
14219 ;
14220 else
14221 break;
14222 }
Paul Vinciguerraab055082019-06-06 14:07:55 -040014223 if (sw_if_index == ~0 || pfx.len == 0)
Florin Coras595992c2017-11-06 17:17:08 -080014224 {
14225 errmsg ("address and sw_if_index must be set");
14226 return -99;
14227 }
14228
14229 M (IP_CONTAINER_PROXY_ADD_DEL, mp);
14230
Florin Coras595992c2017-11-06 17:17:08 -080014231 mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
Florin Coras595992c2017-11-06 17:17:08 -080014232 mp->is_add = is_add;
Neale Ranns37029302018-08-10 05:30:06 -070014233 clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
Florin Coras595992c2017-11-06 17:17:08 -080014234
14235 S (mp);
14236 W (ret);
14237 return ret;
14238}
14239
14240static int
Igor Mikhailov (imichail)582caa32018-04-26 21:33:02 -070014241api_qos_record_enable_disable (vat_main_t * vam)
14242{
14243 unformat_input_t *i = vam->input;
14244 vl_api_qos_record_enable_disable_t *mp;
14245 u32 sw_if_index, qs = 0xff;
14246 u8 sw_if_index_set = 0;
14247 u8 enable = 1;
14248 int ret;
14249
14250 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14251 {
14252 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14253 sw_if_index_set = 1;
14254 else if (unformat (i, "sw_if_index %d", &sw_if_index))
14255 sw_if_index_set = 1;
14256 else if (unformat (i, "%U", unformat_qos_source, &qs))
14257 ;
14258 else if (unformat (i, "disable"))
14259 enable = 0;
14260 else
14261 {
14262 clib_warning ("parse error '%U'", format_unformat_error, i);
14263 return -99;
14264 }
14265 }
14266
14267 if (sw_if_index_set == 0)
14268 {
14269 errmsg ("missing interface name or sw_if_index");
14270 return -99;
14271 }
14272 if (qs == 0xff)
14273 {
14274 errmsg ("input location must be specified");
14275 return -99;
14276 }
14277
14278 M (QOS_RECORD_ENABLE_DISABLE, mp);
14279
Neale Ranns5281a902019-07-23 08:16:19 -070014280 mp->record.sw_if_index = ntohl (sw_if_index);
14281 mp->record.input_source = qs;
Igor Mikhailov (imichail)582caa32018-04-26 21:33:02 -070014282 mp->enable = enable;
14283
14284 S (mp);
14285 W (ret);
14286 return ret;
14287}
14288
Dave Barach048a4e52018-06-01 18:52:25 -040014289
Igor Mikhailov (imichail)582caa32018-04-26 21:33:02 -070014290static int
Damjan Marion7cd468a2016-12-19 23:05:39 +010014291q_or_quit (vat_main_t * vam)
14292{
Dave Barachdef19da2017-02-22 17:29:20 -050014293#if VPP_API_TEST_BUILTIN == 0
Damjan Marion7cd468a2016-12-19 23:05:39 +010014294 longjmp (vam->jump_buf, 1);
Dave Barachdef19da2017-02-22 17:29:20 -050014295#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +010014296 return 0; /* not so much */
14297}
14298
14299static int
14300q (vat_main_t * vam)
14301{
14302 return q_or_quit (vam);
14303}
14304
14305static int
14306quit (vat_main_t * vam)
14307{
14308 return q_or_quit (vam);
14309}
14310
14311static int
14312comment (vat_main_t * vam)
14313{
14314 return 0;
14315}
14316
14317static int
Dave Barachb09f4d02019-07-15 16:00:03 -040014318elog_save (vat_main_t * vam)
14319{
14320#if VPP_API_TEST_BUILTIN == 0
14321 elog_main_t *em = &vam->elog_main;
14322 unformat_input_t *i = vam->input;
14323 char *file, *chroot_file;
14324 clib_error_t *error;
14325
14326 if (!unformat (i, "%s", &file))
14327 {
14328 errmsg ("expected file name, got `%U'", format_unformat_error, i);
14329 return 0;
14330 }
14331
14332 /* It's fairly hard to get "../oopsie" through unformat; just in case */
14333 if (strstr (file, "..") || index (file, '/'))
14334 {
14335 errmsg ("illegal characters in filename '%s'", file);
14336 return 0;
14337 }
14338
14339 chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
14340
14341 vec_free (file);
14342
14343 errmsg ("Saving %wd of %wd events to %s",
14344 elog_n_events_in_buffer (em),
14345 elog_buffer_capacity (em), chroot_file);
14346
14347 error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
14348 vec_free (chroot_file);
14349
14350 if (error)
14351 clib_error_report (error);
14352#else
14353 errmsg ("Use the vpp event loger...");
14354#endif
14355
14356 return 0;
14357}
14358
14359static int
14360elog_setup (vat_main_t * vam)
14361{
14362#if VPP_API_TEST_BUILTIN == 0
14363 elog_main_t *em = &vam->elog_main;
14364 unformat_input_t *i = vam->input;
14365 u32 nevents = 128 << 10;
14366
14367 (void) unformat (i, "nevents %d", &nevents);
14368
14369 elog_init (em, nevents);
14370 vl_api_set_elog_main (em);
14371 vl_api_set_elog_trace_api_messages (1);
14372 errmsg ("Event logger initialized with %u events", nevents);
14373#else
14374 errmsg ("Use the vpp event loger...");
14375#endif
14376 return 0;
14377}
14378
14379static int
14380elog_enable (vat_main_t * vam)
14381{
14382#if VPP_API_TEST_BUILTIN == 0
14383 elog_main_t *em = &vam->elog_main;
14384
14385 elog_enable_disable (em, 1 /* enable */ );
14386 vl_api_set_elog_trace_api_messages (1);
14387 errmsg ("Event logger enabled...");
14388#else
14389 errmsg ("Use the vpp event loger...");
14390#endif
14391 return 0;
14392}
14393
14394static int
14395elog_disable (vat_main_t * vam)
14396{
14397#if VPP_API_TEST_BUILTIN == 0
14398 elog_main_t *em = &vam->elog_main;
14399
14400 elog_enable_disable (em, 0 /* enable */ );
14401 vl_api_set_elog_trace_api_messages (1);
14402 errmsg ("Event logger disabled...");
14403#else
14404 errmsg ("Use the vpp event loger...");
14405#endif
14406 return 0;
14407}
14408
14409static int
Dave Barach048a4e52018-06-01 18:52:25 -040014410statseg (vat_main_t * vam)
14411{
14412 ssvm_private_t *ssvmp = &vam->stat_segment;
14413 ssvm_shared_header_t *shared_header = ssvmp->sh;
14414 vlib_counter_t **counters;
14415 u64 thread0_index1_packets;
14416 u64 thread0_index1_bytes;
14417 f64 vector_rate, input_rate;
14418 uword *p;
14419
14420 uword *counter_vector_by_name;
14421 if (vam->stat_segment_lockp == 0)
14422 {
14423 errmsg ("Stat segment not mapped...");
14424 return -99;
14425 }
14426
14427 /* look up "/if/rx for sw_if_index 1 as a test */
14428
14429 clib_spinlock_lock (vam->stat_segment_lockp);
14430
14431 counter_vector_by_name = (uword *) shared_header->opaque[1];
14432
14433 p = hash_get_mem (counter_vector_by_name, "/if/rx");
14434 if (p == 0)
14435 {
14436 clib_spinlock_unlock (vam->stat_segment_lockp);
14437 errmsg ("/if/tx not found?");
14438 return -99;
14439 }
14440
14441 /* Fish per-thread vector of combined counters from shared memory */
14442 counters = (vlib_counter_t **) p[0];
14443
14444 if (vec_len (counters[0]) < 2)
14445 {
14446 clib_spinlock_unlock (vam->stat_segment_lockp);
14447 errmsg ("/if/tx vector length %d", vec_len (counters[0]));
14448 return -99;
14449 }
14450
14451 /* Read thread 0 sw_if_index 1 counter */
14452 thread0_index1_packets = counters[0][1].packets;
14453 thread0_index1_bytes = counters[0][1].bytes;
14454
14455 p = hash_get_mem (counter_vector_by_name, "vector_rate");
14456 if (p == 0)
14457 {
14458 clib_spinlock_unlock (vam->stat_segment_lockp);
14459 errmsg ("vector_rate not found?");
14460 return -99;
14461 }
14462
14463 vector_rate = *(f64 *) (p[0]);
14464 p = hash_get_mem (counter_vector_by_name, "input_rate");
14465 if (p == 0)
14466 {
14467 clib_spinlock_unlock (vam->stat_segment_lockp);
14468 errmsg ("input_rate not found?");
14469 return -99;
14470 }
14471 input_rate = *(f64 *) (p[0]);
14472
14473 clib_spinlock_unlock (vam->stat_segment_lockp);
14474
14475 print (vam->ofp, "vector_rate %.2f input_rate %.2f",
14476 vector_rate, input_rate);
14477 print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
14478 thread0_index1_packets, thread0_index1_bytes);
14479
14480 return 0;
14481}
14482
14483static int
Damjan Marion7cd468a2016-12-19 23:05:39 +010014484cmd_cmp (void *a1, void *a2)
14485{
14486 u8 **c1 = a1;
14487 u8 **c2 = a2;
14488
14489 return strcmp ((char *) (c1[0]), (char *) (c2[0]));
14490}
14491
14492static int
14493help (vat_main_t * vam)
14494{
14495 u8 **cmds = 0;
14496 u8 *name = 0;
14497 hash_pair_t *p;
14498 unformat_input_t *i = vam->input;
14499 int j;
14500
14501 if (unformat (i, "%s", &name))
14502 {
14503 uword *hs;
14504
14505 vec_add1 (name, 0);
14506
14507 hs = hash_get_mem (vam->help_by_name, name);
14508 if (hs)
14509 print (vam->ofp, "usage: %s %s", name, hs[0]);
14510 else
14511 print (vam->ofp, "No such msg / command '%s'", name);
14512 vec_free (name);
14513 return 0;
14514 }
14515
14516 print (vam->ofp, "Help is available for the following:");
14517
14518 /* *INDENT-OFF* */
14519 hash_foreach_pair (p, vam->function_by_name,
14520 ({
14521 vec_add1 (cmds, (u8 *)(p->key));
14522 }));
14523 /* *INDENT-ON* */
14524
14525 vec_sort_with_function (cmds, cmd_cmp);
14526
14527 for (j = 0; j < vec_len (cmds); j++)
14528 print (vam->ofp, "%s", cmds[j]);
14529
14530 vec_free (cmds);
14531 return 0;
14532}
14533
14534static int
14535set (vat_main_t * vam)
14536{
14537 u8 *name = 0, *value = 0;
14538 unformat_input_t *i = vam->input;
14539
14540 if (unformat (i, "%s", &name))
14541 {
14542 /* The input buffer is a vector, not a string. */
14543 value = vec_dup (i->buffer);
14544 vec_delete (value, i->index, 0);
14545 /* Almost certainly has a trailing newline */
14546 if (value[vec_len (value) - 1] == '\n')
14547 value[vec_len (value) - 1] = 0;
14548 /* Make sure it's a proper string, one way or the other */
14549 vec_add1 (value, 0);
14550 (void) clib_macro_set_value (&vam->macro_main,
14551 (char *) name, (char *) value);
14552 }
14553 else
14554 errmsg ("usage: set <name> <value>");
14555
14556 vec_free (name);
14557 vec_free (value);
14558 return 0;
14559}
14560
14561static int
14562unset (vat_main_t * vam)
14563{
14564 u8 *name = 0;
14565
14566 if (unformat (vam->input, "%s", &name))
14567 if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
14568 errmsg ("unset: %s wasn't set", name);
14569 vec_free (name);
14570 return 0;
14571}
14572
14573typedef struct
14574{
14575 u8 *name;
14576 u8 *value;
14577} macro_sort_t;
14578
14579
14580static int
14581macro_sort_cmp (void *a1, void *a2)
14582{
14583 macro_sort_t *s1 = a1;
14584 macro_sort_t *s2 = a2;
14585
14586 return strcmp ((char *) (s1->name), (char *) (s2->name));
14587}
14588
14589static int
14590dump_macro_table (vat_main_t * vam)
14591{
14592 macro_sort_t *sort_me = 0, *sm;
14593 int i;
14594 hash_pair_t *p;
14595
14596 /* *INDENT-OFF* */
14597 hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
14598 ({
14599 vec_add2 (sort_me, sm, 1);
14600 sm->name = (u8 *)(p->key);
14601 sm->value = (u8 *) (p->value[0]);
14602 }));
14603 /* *INDENT-ON* */
14604
14605 vec_sort_with_function (sort_me, macro_sort_cmp);
14606
14607 if (vec_len (sort_me))
14608 print (vam->ofp, "%-15s%s", "Name", "Value");
14609 else
14610 print (vam->ofp, "The macro table is empty...");
14611
14612 for (i = 0; i < vec_len (sort_me); i++)
14613 print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
14614 return 0;
14615}
14616
14617static int
14618dump_node_table (vat_main_t * vam)
14619{
14620 int i, j;
14621 vlib_node_t *node, *next_node;
14622
14623 if (vec_len (vam->graph_nodes) == 0)
14624 {
14625 print (vam->ofp, "Node table empty, issue get_node_graph...");
14626 return 0;
14627 }
14628
Dave Barach1ddbc012018-06-13 09:26:05 -040014629 for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
Damjan Marion7cd468a2016-12-19 23:05:39 +010014630 {
Dave Barach1ddbc012018-06-13 09:26:05 -040014631 node = vam->graph_nodes[0][i];
Damjan Marion7cd468a2016-12-19 23:05:39 +010014632 print (vam->ofp, "[%d] %s", i, node->name);
14633 for (j = 0; j < vec_len (node->next_nodes); j++)
14634 {
14635 if (node->next_nodes[j] != ~0)
14636 {
Dave Barach1ddbc012018-06-13 09:26:05 -040014637 next_node = vam->graph_nodes[0][node->next_nodes[j]];
Damjan Marion7cd468a2016-12-19 23:05:39 +010014638 print (vam->ofp, " [%d] %s", j, next_node->name);
14639 }
14640 }
14641 }
14642 return 0;
14643}
14644
14645static int
14646value_sort_cmp (void *a1, void *a2)
14647{
14648 name_sort_t *n1 = a1;
14649 name_sort_t *n2 = a2;
14650
14651 if (n1->value < n2->value)
14652 return -1;
14653 if (n1->value > n2->value)
14654 return 1;
14655 return 0;
14656}
14657
14658
14659static int
14660dump_msg_api_table (vat_main_t * vam)
14661{
Dave Barach39d69112019-11-27 11:42:13 -050014662 api_main_t *am = vlibapi_get_main ();
Damjan Marion7cd468a2016-12-19 23:05:39 +010014663 name_sort_t *nses = 0, *ns;
14664 hash_pair_t *hp;
14665 int i;
14666
14667 /* *INDENT-OFF* */
14668 hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
14669 ({
14670 vec_add2 (nses, ns, 1);
14671 ns->name = (u8 *)(hp->key);
14672 ns->value = (u32) hp->value[0];
14673 }));
14674 /* *INDENT-ON* */
14675
14676 vec_sort_with_function (nses, value_sort_cmp);
14677
14678 for (i = 0; i < vec_len (nses); i++)
14679 print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
14680 vec_free (nses);
14681 return 0;
14682}
14683
14684static int
14685get_msg_id (vat_main_t * vam)
14686{
14687 u8 *name_and_crc;
14688 u32 message_index;
14689
14690 if (unformat (vam->input, "%s", &name_and_crc))
14691 {
Florin Corase86a8ed2018-01-05 03:20:25 -080014692 message_index = vl_msg_api_get_msg_index (name_and_crc);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014693 if (message_index == ~0)
14694 {
14695 print (vam->ofp, " '%s' not found", name_and_crc);
14696 return 0;
14697 }
14698 print (vam->ofp, " '%s' has message index %d",
14699 name_and_crc, message_index);
14700 return 0;
14701 }
14702 errmsg ("name_and_crc required...");
14703 return 0;
14704}
14705
14706static int
14707search_node_table (vat_main_t * vam)
14708{
14709 unformat_input_t *line_input = vam->input;
14710 u8 *node_to_find;
14711 int j;
14712 vlib_node_t *node, *next_node;
14713 uword *p;
14714
14715 if (vam->graph_node_index_by_name == 0)
14716 {
14717 print (vam->ofp, "Node table empty, issue get_node_graph...");
14718 return 0;
14719 }
14720
14721 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14722 {
14723 if (unformat (line_input, "%s", &node_to_find))
14724 {
14725 vec_add1 (node_to_find, 0);
14726 p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
14727 if (p == 0)
14728 {
14729 print (vam->ofp, "%s not found...", node_to_find);
14730 goto out;
14731 }
Dave Barach1ddbc012018-06-13 09:26:05 -040014732 node = vam->graph_nodes[0][p[0]];
Damjan Marion7cd468a2016-12-19 23:05:39 +010014733 print (vam->ofp, "[%d] %s", p[0], node->name);
14734 for (j = 0; j < vec_len (node->next_nodes); j++)
14735 {
14736 if (node->next_nodes[j] != ~0)
14737 {
Dave Barach1ddbc012018-06-13 09:26:05 -040014738 next_node = vam->graph_nodes[0][node->next_nodes[j]];
Damjan Marion7cd468a2016-12-19 23:05:39 +010014739 print (vam->ofp, " [%d] %s", j, next_node->name);
14740 }
14741 }
14742 }
14743
14744 else
14745 {
14746 clib_warning ("parse error '%U'", format_unformat_error,
14747 line_input);
14748 return -99;
14749 }
14750
14751 out:
14752 vec_free (node_to_find);
14753
14754 }
14755
14756 return 0;
14757}
14758
14759
14760static int
14761script (vat_main_t * vam)
14762{
14763#if (VPP_API_TEST_BUILTIN==0)
14764 u8 *s = 0;
14765 char *save_current_file;
14766 unformat_input_t save_input;
14767 jmp_buf save_jump_buf;
14768 u32 save_line_number;
14769
14770 FILE *new_fp, *save_ifp;
14771
14772 if (unformat (vam->input, "%s", &s))
14773 {
14774 new_fp = fopen ((char *) s, "r");
14775 if (new_fp == 0)
14776 {
14777 errmsg ("Couldn't open script file %s", s);
14778 vec_free (s);
14779 return -99;
14780 }
14781 }
14782 else
14783 {
14784 errmsg ("Missing script name");
14785 return -99;
14786 }
14787
14788 clib_memcpy (&save_input, &vam->input, sizeof (save_input));
14789 clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
14790 save_ifp = vam->ifp;
14791 save_line_number = vam->input_line_number;
14792 save_current_file = (char *) vam->current_file;
14793
14794 vam->input_line_number = 0;
14795 vam->ifp = new_fp;
14796 vam->current_file = s;
14797 do_one_file (vam);
14798
Sirshak Dasb0861822018-05-29 21:13:21 -050014799 clib_memcpy (&vam->input, &save_input, sizeof (save_input));
Damjan Marion7cd468a2016-12-19 23:05:39 +010014800 clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
14801 vam->ifp = save_ifp;
14802 vam->input_line_number = save_line_number;
14803 vam->current_file = (u8 *) save_current_file;
14804 vec_free (s);
14805
14806 return 0;
14807#else
14808 clib_warning ("use the exec command...");
14809 return -99;
14810#endif
14811}
14812
14813static int
14814echo (vat_main_t * vam)
14815{
14816 print (vam->ofp, "%v", vam->input->buffer);
14817 return 0;
14818}
14819
14820/* List of API message constructors, CLI names map to api_xxx */
14821#define foreach_vpe_api_msg \
Jon Loeligerc83c3b72017-02-23 13:57:35 -060014822_(create_loopback,"[mac <mac-addr>] [instance <instance>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014823_(sw_interface_dump,"") \
14824_(sw_interface_set_flags, \
14825 "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
14826_(sw_interface_add_del_address, \
14827 "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
Stevenad8015b2017-10-29 22:10:46 -070014828_(sw_interface_set_rx_mode, \
14829 "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
Mohsin Kazmi54f7c512018-08-23 18:28:11 +020014830_(sw_interface_set_rx_placement, \
14831 "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]") \
Mohsin Kazmif0b42f42018-09-10 18:11:00 +020014832_(sw_interface_rx_placement_dump, \
14833 "[<intfc> | sw_if_index <id>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014834_(sw_interface_set_table, \
14835 "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]") \
14836_(sw_interface_set_mpls_enable, \
14837 "<intfc> | sw_if_index [disable | dis]") \
14838_(sw_interface_set_vpath, \
14839 "<intfc> | sw_if_index <id> enable | disable") \
14840_(sw_interface_set_vxlan_bypass, \
John Lo2b81eb82017-01-30 13:12:10 -050014841 "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014842_(sw_interface_set_l2_xconnect, \
14843 "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
14844 "enable | disable") \
14845_(sw_interface_set_l2_bridge, \
Eyal Barif24991c2017-04-05 05:33:21 +030014846 "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n" \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014847 "[shg <split-horizon-group>] [bvi]\n" \
14848 "enable | disable") \
Eyal Barif24991c2017-04-05 05:33:21 +030014849_(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014850_(bridge_domain_add_del, \
John Lo70bfcaf2017-11-14 13:19:26 -050014851 "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 +010014852_(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n") \
14853_(l2fib_add_del, \
14854 "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 +030014855_(l2fib_flush_bd, "bd_id <bridge-domain-id>") \
14856_(l2fib_flush_int, "<intfc> | sw_if_index <id>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014857_(l2_flags, \
John Lo8d00fff2017-08-03 00:35:36 -040014858 "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014859_(bridge_flags, \
14860 "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
Damjan Marion8389fb92017-10-13 18:29:53 +020014861_(tap_create_v2, \
Mohsin Kazmi50bd1652020-08-26 11:07:48 +020014862 "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 +020014863_(tap_delete_v2, \
14864 "<vpp-if-name> | sw_if_index <id>") \
14865_(sw_interface_tap_v2_dump, "") \
Mohsin Kazmi518251b2020-09-01 17:17:44 +000014866_(virtio_pci_create_v2, \
Mohsin Kazmie347acb2020-09-28 10:26:33 +000014867 "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 +010014868_(virtio_pci_delete, \
14869 "<vpp-if-name> | sw_if_index <id>") \
14870_(sw_interface_virtio_pci_dump, "") \
Steven9cd2d7a2017-12-20 12:43:01 -080014871_(bond_create, \
14872 "[hw-addr <mac-addr>] {round-robin | active-backup | " \
Alexander Chernavinad9d5282018-12-13 09:08:09 -050014873 "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} " \
Steven Luonga1876b82019-08-20 16:58:00 -070014874 "[id <if-id>]") \
Steven Luongea717862020-07-30 07:31:40 -070014875_(bond_create2, \
14876 "[hw-addr <mac-addr>] {mode round-robin | active-backup | " \
14877 "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} " \
14878 "[id <if-id>] [gso]") \
Steven9cd2d7a2017-12-20 12:43:01 -080014879_(bond_delete, \
14880 "<vpp-if-name> | sw_if_index <id>") \
Steven Luong4c4223e2020-07-15 08:44:54 -070014881_(bond_add_member, \
Steven Luonga1876b82019-08-20 16:58:00 -070014882 "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]") \
Steven Luong4c4223e2020-07-15 08:44:54 -070014883_(bond_detach_member, \
Steven9cd2d7a2017-12-20 12:43:01 -080014884 "sw_if_index <n>") \
Steven Luonga1876b82019-08-20 16:58:00 -070014885 _(sw_interface_set_bond_weight, "<intfc> | sw_if_index <nn> weight <value>") \
Steven Luong4c4223e2020-07-15 08:44:54 -070014886 _(sw_bond_interface_dump, "<intfc> | sw_if_index <nn>") \
14887 _(sw_member_interface_dump, \
Steven9cd2d7a2017-12-20 12:43:01 -080014888 "<vpp-if-name> | sw_if_index <id>") \
Neale Ranns28ab9cc2017-08-14 07:18:42 -070014889_(ip_table_add_del, \
John Loe166fd92018-09-13 14:08:59 -040014890 "table <n> [ipv6] [add | del]\n") \
Neale Ranns097fa662018-05-01 05:17:55 -070014891_(ip_route_add_del, \
John Lo22030432018-09-20 16:07:00 -040014892 "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
14893 "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
John Lo06fda9c2018-10-03 16:32:44 -040014894 "[weight <n>] [drop] [local] [classify <n>] [out-label <n>]\n" \
14895 "[multipath] [count <n>] [del]") \
Neale Ranns32e1c012016-11-22 17:07:28 +000014896_(ip_mroute_add_del, \
14897 "<src> <grp>/<mask> [table-id <n>]\n" \
14898 "[<intfc> | sw_if_index <id>] [local] [del]") \
Neale Ranns28ab9cc2017-08-14 07:18:42 -070014899_(mpls_table_add_del, \
John Loe166fd92018-09-13 14:08:59 -040014900 "table <n> [add | del]\n") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014901_(mpls_route_add_del, \
John Loe166fd92018-09-13 14:08:59 -040014902 "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n" \
14903 "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n" \
14904 "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n" \
14905 "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n" \
John Lo06fda9c2018-10-03 16:32:44 -040014906 "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n" \
14907 "[count <n>] [del]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014908_(mpls_ip_bind_unbind, \
14909 "<label> <addr/len>") \
14910_(mpls_tunnel_add_del, \
John Lo06fda9c2018-10-03 16:32:44 -040014911 "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
14912 "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n" \
14913 "[l2-only] [out-label <n>]") \
John Loe166fd92018-09-13 14:08:59 -040014914_(sr_mpls_policy_add, \
14915 "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]") \
14916_(sr_mpls_policy_del, \
14917 "bsid <id>") \
Neale Rannsd792d9c2017-10-21 10:53:20 -070014918_(bier_table_add_del, \
14919 "<label> <sub-domain> <set> <bsl> [del]") \
14920_(bier_route_add_del, \
14921 "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
14922 "[<intfc> | sw_if_index <id>]" \
14923 "[weight <n>] [del] [multipath]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014924_(sw_interface_set_unnumbered, \
14925 "<intfc> | sw_if_index <id> unnum_if_index <id> [del]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014926_(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>") \
14927_(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n" \
14928 "[outer_vlan_id <n>][inner_vlan_id <n>]\n" \
14929 "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n" \
14930 "[outer_vlan_id_any][inner_vlan_id_any]") \
Neale Ranns9db6ada2019-11-08 12:42:31 +000014931_(ip_table_replace_begin, "table <n> [ipv6]") \
14932_(ip_table_flush, "table <n> [ipv6]") \
14933_(ip_table_replace_end, "table <n> [ipv6]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014934_(set_ip_flow_hash, \
14935 "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]") \
14936_(sw_interface_ip6_enable_disable, \
14937 "<intfc> | sw_if_index <id> enable | disable") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014938_(l2_patch_add_del, \
14939 "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
14940 "enable | disable") \
Pablo Camarillofb380952016-12-07 18:34:18 +010014941_(sr_localsid_add_del, \
14942 "(del) address <addr> next_hop <addr> behavior <beh>\n" \
14943 "fib-table <num> (end.psp) sw_if_index <num>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014944_(classify_add_del_table, \
14945 "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n" \
14946 " [del] [del-chain] mask <mask-value>\n" \
14947 " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n" \
14948 " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]") \
14949_(classify_add_del_session, \
14950 "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n" \
14951 " table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n" \
14952 " [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n" \
14953 " [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]") \
14954_(classify_set_interface_ip_table, \
14955 "<intfc> | sw_if_index <nn> table <nn>") \
14956_(classify_set_interface_l2_tables, \
14957 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
14958 " [other-table <nn>]") \
14959_(get_node_index, "node <node-name") \
14960_(add_node_next, "node <node-name> next <next-node-name>") \
eyal bariaf86a482018-04-17 11:20:27 +030014961_(vxlan_offload_rx, \
14962 "hw { <interface name> | hw_if_index <nn>} " \
14963 "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014964_(vxlan_add_del_tunnel, \
14965 "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n" \
Jon Loeliger3d460bd2018-02-01 16:36:12 -060014966 "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n" \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014967 "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]") \
14968_(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014969_(l2_fib_clear_table, "") \
14970_(l2_interface_efp_filter, "sw_if_index <nn> enable | disable") \
14971_(l2_interface_vlan_tag_rewrite, \
14972 "<intfc> | sw_if_index <nn> \n" \
14973 "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n" \
14974 "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>") \
14975_(create_vhost_user_if, \
14976 "socket <filename> [server] [renumber <dev_instance>] " \
Steven Luong4208a4c2019-05-06 08:51:56 -070014977 "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] " \
Steven Luongbc0d9ff2020-03-23 09:34:59 -070014978 "[mac <mac_address>] [packed]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014979_(modify_vhost_user_if, \
14980 "<intfc> | sw_if_index <nn> socket <filename>\n" \
Steven Luongbc0d9ff2020-03-23 09:34:59 -070014981 "[server] [renumber <dev_instance>] [gso] [packed]") \
Steven Luong27ba5002020-11-17 13:30:44 -080014982_(create_vhost_user_if_v2, \
14983 "socket <filename> [server] [renumber <dev_instance>] " \
14984 "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] " \
14985 "[mac <mac_address>] [packed] [event-idx]") \
14986_(modify_vhost_user_if_v2, \
14987 "<intfc> | sw_if_index <nn> socket <filename>\n" \
14988 "[server] [renumber <dev_instance>] [gso] [packed] [event-idx]")\
Damjan Marion7cd468a2016-12-19 23:05:39 +010014989_(delete_vhost_user_if, "<intfc> | sw_if_index <nn>") \
Steven Luonga0e8d962020-05-18 17:12:56 -070014990_(sw_interface_vhost_user_dump, "<intfc> | sw_if_index <nn>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014991_(show_version, "") \
Mohsin Kazmi5d64c782018-09-11 20:27:09 +020014992_(show_threads, "") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014993_(vxlan_gpe_add_del_tunnel, \
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080014994 "local <addr> remote <addr> | group <mcast-ip-addr>\n" \
14995 "{ <intfc> | mcast_sw_if_index <nn> } }\n" \
14996 "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n" \
14997 "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014998_(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]") \
14999_(l2_fib_table_dump, "bd_id <bridge-domain-id>") \
15000_(interface_name_renumber, \
15001 "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>") \
15002_(input_acl_set_interface, \
15003 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
15004 " [l2-table <nn>] [del]") \
John Lo8d00fff2017-08-03 00:35:36 -040015005_(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015006_(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)") \
15007_(ip_dump, "ipv4 | ipv6") \
15008_(ipsec_spd_add_del, "spd_id <n> [del]") \
15009_(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n" \
15010 " spid_id <n> ") \
Neale Ranns17dcec02019-01-09 21:22:20 -080015011_(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n" \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015012 " crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n" \
15013 " integ_alg <alg> integ_key <hex>") \
Neale Ranns17dcec02019-01-09 21:22:20 -080015014_(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n" \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015015 " (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n" \
15016 " laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
15017 " [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
Matthew Smith28029532017-09-26 13:33:44 -050015018_(ipsec_sa_dump, "[sa_id <n>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015019_(delete_loopback,"sw_if_index <nn>") \
15020_(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
John Loe26c81f2019-01-07 15:16:33 -050015021_(bd_ip_mac_flush, "bd_id <bridge-domain-id>") \
15022_(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015023_(want_interface_events, "enable|disable") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015024_(get_first_msg_id, "client <name>") \
15025_(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
15026_(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n" \
15027 "fib-id <nn> [ip4][ip6][default]") \
15028_(get_node_graph, " ") \
15029_(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>") \
15030_(ioam_enable, "[trace] [pow] [ppc <encap|decap>]") \
15031_(ioam_disable, "") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015032_(af_packet_create, "name <host interface name> [hw_addr <mac>]") \
15033_(af_packet_delete, "name <host interface name>") \
Mohsin Kazmi04e0bb22018-05-28 18:55:37 +020015034_(af_packet_dump, "") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015035_(policer_add_del, "name <policer name> <params> [del]") \
15036_(policer_dump, "[name <policer name>]") \
15037_(policer_classify_set_interface, \
15038 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
15039 " [l2-table <nn>] [del]") \
15040_(policer_classify_dump, "type [ip4|ip6|l2]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015041_(mpls_tunnel_dump, "tunnel_index <tunnel-id>") \
Neale Ranns097fa662018-05-01 05:17:55 -070015042_(mpls_table_dump, "") \
15043_(mpls_route_dump, "table-id <ID>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015044_(classify_table_ids, "") \
15045_(classify_table_by_interface, "sw_if_index <sw_if_index>") \
15046_(classify_table_info, "table_id <nn>") \
15047_(classify_session_dump, "table_id <nn>") \
15048_(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] " \
15049 "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] " \
15050 "[template_interval <nn>] [udp_checksum]") \
15051_(ipfix_exporter_dump, "") \
15052_(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
15053_(ipfix_classify_stream_dump, "") \
15054_(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
15055_(ipfix_classify_table_dump, "") \
Eyal Bari001fd402017-07-16 09:34:53 +030015056_(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 +030015057_(sw_interface_span_dump, "[l2]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015058_(get_next_index, "node-name <node-name> next-node-name <node-name>") \
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +020015059_(pg_create_interface, "if_id <nn> [gso-enabled gso-size <size>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015060_(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]") \
15061_(pg_enable_disable, "[stream <id>] disable") \
Mohsin Kazmif382b062020-08-11 15:00:44 +020015062_(pg_interface_enable_disable_coalesce, "<intf> | sw_if_index <nn> enable | disable") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015063_(ip_source_and_port_range_check_add_del, \
15064 "<ip-addr>/<mask> range <nn>-<nn> vrf <id>") \
15065_(ip_source_and_port_range_check_interface_add_del, \
15066 "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]" \
15067 "[udp-in-vrf <id>] [udp-out-vrf <id>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015068_(delete_subif,"<intfc> | sw_if_index <nn>") \
15069_(l2_interface_pbb_tag_rewrite, \
15070 "<intfc> | sw_if_index <nn> \n" \
15071 "[disable | push | pop | translate_pbb_stag <outer_tag>] \n" \
15072 "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]") \
Pavel Kotuceke88865d2018-11-28 07:42:11 +010015073_(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015074_(flow_classify_set_interface, \
15075 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
15076_(flow_classify_dump, "type [ip4|ip6]") \
Neale Ranns097fa662018-05-01 05:17:55 -070015077_(ip_table_dump, "") \
15078_(ip_route_dump, "table-id [ip4|ip6]") \
15079_(ip_mtable_dump, "") \
15080_(ip_mroute_dump, "table-id [ip4|ip6]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015081_(feature_enable_disable, "arc_name <arc_name> " \
15082 "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]") \
Mohsin Kazmi29467b52019-10-08 19:42:38 +020015083_(feature_gso_enable_disable, "<intfc> | sw_if_index <nn> " \
15084 "[enable | disable] ") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015085_(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>" \
15086"[disable]") \
Matthew Smithe0792fd2019-07-12 11:48:24 -050015087_(sw_interface_add_del_mac_address, "<intfc> | sw_if_index <nn> " \
15088 "mac <mac-address> [del]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015089_(l2_xconnect_dump, "") \
Ole Troand7231612018-06-07 10:17:57 +020015090_(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>") \
Pavel Kotucek6899a302017-06-08 08:46:10 +020015091_(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]") \
Pavel Kotucek15ac81c2017-06-20 14:00:26 +020015092_(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
Steve Shin99a0e602017-07-01 04:16:20 +000015093_(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
Dave Barach59b25652017-09-10 15:04:27 -040015094_(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]") \
Florin Coras90a63982017-12-19 04:50:01 -080015095_(sock_init_shm, "size <nnn>") \
Florin Corascea194d2017-10-02 00:18:51 -070015096_(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
Florin Coras1c710452017-10-17 00:03:13 -070015097_(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> " \
15098 "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>") \
Florin Coras6c36f532017-11-03 18:32:34 -070015099_(session_rules_dump, "") \
Florin Coras595992c2017-11-06 17:17:08 -080015100_(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>") \
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +010015101_(output_acl_set_interface, \
15102 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
15103 " [l2-table <nn>] [del]") \
Ole Troane906aac2018-06-14 14:42:14 +020015104_(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
Damjan Marion7cd468a2016-12-19 23:05:39 +010015105
15106/* List of command functions, CLI names map directly to functions */
15107#define foreach_cli_function \
15108_(comment, "usage: comment <ignore-rest-of-line>") \
15109_(dump_interface_table, "usage: dump_interface_table") \
15110_(dump_sub_interface_table, "usage: dump_sub_interface_table") \
15111_(dump_ipv4_table, "usage: dump_ipv4_table") \
15112_(dump_ipv6_table, "usage: dump_ipv6_table") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015113_(dump_macro_table, "usage: dump_macro_table ") \
15114_(dump_node_table, "usage: dump_node_table") \
15115_(dump_msg_api_table, "usage: dump_msg_api_table") \
Dave Barachb09f4d02019-07-15 16:00:03 -040015116_(elog_setup, "usage: elog_setup [nevents, default 128K]") \
15117_(elog_disable, "usage: elog_disable") \
15118_(elog_enable, "usage: elog_enable") \
15119_(elog_save, "usage: elog_save <filename>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015120_(get_msg_id, "usage: get_msg_id name_and_crc") \
15121_(echo, "usage: echo <message>") \
15122_(exec, "usage: exec <vpe-debug-CLI-command>") \
15123_(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>") \
15124_(help, "usage: help") \
15125_(q, "usage: quit") \
15126_(quit, "usage: quit") \
15127_(search_node_table, "usage: search_node_table <name>...") \
15128_(set, "usage: set <variable-name> <value>") \
15129_(script, "usage: script <file-name>") \
Neale Ranns097fa662018-05-01 05:17:55 -070015130_(statseg, "usage: statseg") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015131_(unset, "usage: unset <variable-name>")
Dave Barach048a4e52018-06-01 18:52:25 -040015132
Damjan Marion7cd468a2016-12-19 23:05:39 +010015133#define _(N,n) \
15134 static void vl_api_##n##_t_handler_uni \
15135 (vl_api_##n##_t * mp) \
15136 { \
15137 vat_main_t * vam = &vat_main; \
15138 if (vam->json_output) { \
15139 vl_api_##n##_t_handler_json(mp); \
15140 } else { \
15141 vl_api_##n##_t_handler(mp); \
15142 } \
15143 }
15144foreach_vpe_api_reply_msg;
Dave Baracha1a093d2017-03-02 13:13:23 -050015145#if VPP_API_TEST_BUILTIN == 0
15146foreach_standalone_reply_msg;
15147#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +010015148#undef _
15149
15150void
15151vat_api_hookup (vat_main_t * vam)
15152{
15153#define _(N,n) \
15154 vl_msg_api_set_handlers(VL_API_##N, #n, \
15155 vl_api_##n##_t_handler_uni, \
15156 vl_noop_handler, \
15157 vl_api_##n##_t_endian, \
15158 vl_api_##n##_t_print, \
15159 sizeof(vl_api_##n##_t), 1);
15160 foreach_vpe_api_reply_msg;
Dave Baracha1a093d2017-03-02 13:13:23 -050015161#if VPP_API_TEST_BUILTIN == 0
15162 foreach_standalone_reply_msg;
15163#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +010015164#undef _
15165
15166#if (VPP_API_TEST_BUILTIN==0)
15167 vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015168
15169 vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
15170
15171 vam->function_by_name = hash_create_string (0, sizeof (uword));
15172
15173 vam->help_by_name = hash_create_string (0, sizeof (uword));
Dave Barach45e4f362017-03-07 12:52:31 -050015174#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +010015175
15176 /* API messages we can send */
15177#define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
15178 foreach_vpe_api_msg;
15179#undef _
15180
15181 /* Help strings */
15182#define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
15183 foreach_vpe_api_msg;
15184#undef _
Damjan Marion7cd468a2016-12-19 23:05:39 +010015185
15186 /* CLI functions */
15187#define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
15188 foreach_cli_function;
15189#undef _
15190
15191 /* Help strings */
15192#define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
15193 foreach_cli_function;
15194#undef _
15195}
15196
Dave Baracha1a093d2017-03-02 13:13:23 -050015197#if VPP_API_TEST_BUILTIN
15198static clib_error_t *
15199vat_api_hookup_shim (vlib_main_t * vm)
15200{
15201 vat_api_hookup (&vat_main);
15202 return 0;
15203}
15204
15205VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
15206#endif
15207
Damjan Marion7cd468a2016-12-19 23:05:39 +010015208/*
15209 * fd.io coding-style-patch-verification: ON
15210 *
15211 * Local Variables:
15212 * eval: (c-set-style "gnu")
15213 * End:
15214 */