blob: 3f4d74f656fa7431ff8e9ce4c0a3dce614f888fe [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
2434static void vl_api_ip_address_details_t_handler
2435 (vl_api_ip_address_details_t * mp)
2436{
2437 vat_main_t *vam = &vat_main;
2438 static ip_address_details_t empty_ip_address_details = { {0} };
2439 ip_address_details_t *address = NULL;
2440 ip_details_t *current_ip_details = NULL;
2441 ip_details_t *details = NULL;
2442
2443 details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2444
2445 if (!details || vam->current_sw_if_index >= vec_len (details)
2446 || !details[vam->current_sw_if_index].present)
2447 {
2448 errmsg ("ip address details arrived but not stored");
2449 errmsg ("ip_dump should be called first");
2450 return;
2451 }
2452
2453 current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2454
2455#define addresses (current_ip_details->addr)
2456
2457 vec_validate_init_empty (addresses, vec_len (addresses),
2458 empty_ip_address_details);
2459
2460 address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2461
Neale Ranns097fa662018-05-01 05:17:55 -07002462 clib_memcpy (&address->ip, &mp->prefix.address.un, sizeof (address->ip));
Paul Vinciguerraab055082019-06-06 14:07:55 -04002463 address->prefix_length = mp->prefix.len;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002464#undef addresses
2465}
2466
2467static void vl_api_ip_address_details_t_handler_json
2468 (vl_api_ip_address_details_t * mp)
2469{
2470 vat_main_t *vam = &vat_main;
2471 vat_json_node_t *node = NULL;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002472
2473 if (VAT_JSON_ARRAY != vam->json_tree.type)
2474 {
2475 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2476 vat_json_init_array (&vam->json_tree);
2477 }
2478 node = vat_json_array_add (&vam->json_tree);
2479
2480 vat_json_init_object (node);
Neale Ranns097fa662018-05-01 05:17:55 -07002481 vat_json_object_add_prefix (node, &mp->prefix);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002482}
2483
2484static void
2485vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2486{
2487 vat_main_t *vam = &vat_main;
2488 static ip_details_t empty_ip_details = { 0 };
2489 ip_details_t *ip = NULL;
2490 u32 sw_if_index = ~0;
2491
2492 sw_if_index = ntohl (mp->sw_if_index);
2493
2494 vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2495 sw_if_index, empty_ip_details);
2496
2497 ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2498 sw_if_index);
2499
2500 ip->present = 1;
2501}
2502
2503static void
2504vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2505{
2506 vat_main_t *vam = &vat_main;
2507
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 vat_json_array_add_uint (&vam->json_tree,
2514 clib_net_to_host_u32 (mp->sw_if_index));
2515}
2516
Damjan Marion7cd468a2016-12-19 23:05:39 +01002517static void vl_api_get_first_msg_id_reply_t_handler
2518 (vl_api_get_first_msg_id_reply_t * mp)
2519{
2520 vat_main_t *vam = &vat_main;
2521 i32 retval = ntohl (mp->retval);
2522
2523 if (vam->async_mode)
2524 {
2525 vam->async_errors += (retval < 0);
2526 }
2527 else
2528 {
2529 vam->retval = retval;
2530 vam->result_ready = 1;
2531 }
2532 if (retval >= 0)
2533 {
2534 errmsg ("first message id %d", ntohs (mp->first_msg_id));
2535 }
2536}
2537
2538static void vl_api_get_first_msg_id_reply_t_handler_json
2539 (vl_api_get_first_msg_id_reply_t * mp)
2540{
2541 vat_main_t *vam = &vat_main;
2542 vat_json_node_t node;
2543
2544 vat_json_init_object (&node);
2545 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2546 vat_json_object_add_uint (&node, "first_msg_id",
2547 (uint) ntohs (mp->first_msg_id));
2548
2549 vat_json_print (vam->ofp, &node);
2550 vat_json_free (&node);
2551
2552 vam->retval = ntohl (mp->retval);
2553 vam->result_ready = 1;
2554}
2555
2556static void vl_api_get_node_graph_reply_t_handler
2557 (vl_api_get_node_graph_reply_t * mp)
2558{
2559 vat_main_t *vam = &vat_main;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002560 i32 retval = ntohl (mp->retval);
2561 u8 *pvt_copy, *reply;
2562 void *oldheap;
2563 vlib_node_t *node;
2564 int i;
2565
2566 if (vam->async_mode)
2567 {
2568 vam->async_errors += (retval < 0);
2569 }
2570 else
2571 {
2572 vam->retval = retval;
2573 vam->result_ready = 1;
2574 }
2575
2576 /* "Should never happen..." */
2577 if (retval != 0)
2578 return;
2579
Damjan Marion7bee80c2017-04-26 15:32:12 +02002580 reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002581 pvt_copy = vec_dup (reply);
2582
2583 /* Toss the shared-memory original... */
Nathan Skrzypczak0aa40132019-11-25 16:29:38 +01002584 oldheap = vl_msg_push_heap ();
Damjan Marion7cd468a2016-12-19 23:05:39 +01002585
2586 vec_free (reply);
2587
Nathan Skrzypczak0aa40132019-11-25 16:29:38 +01002588 vl_msg_pop_heap (oldheap);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002589
2590 if (vam->graph_nodes)
2591 {
2592 hash_free (vam->graph_node_index_by_name);
2593
Dave Barach1ddbc012018-06-13 09:26:05 -04002594 for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002595 {
Dave Barach1ddbc012018-06-13 09:26:05 -04002596 node = vam->graph_nodes[0][i];
Damjan Marion7cd468a2016-12-19 23:05:39 +01002597 vec_free (node->name);
2598 vec_free (node->next_nodes);
2599 vec_free (node);
2600 }
Dave Barach1ddbc012018-06-13 09:26:05 -04002601 vec_free (vam->graph_nodes[0]);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002602 vec_free (vam->graph_nodes);
2603 }
2604
2605 vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2606 vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2607 vec_free (pvt_copy);
2608
Dave Barach1ddbc012018-06-13 09:26:05 -04002609 for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002610 {
Dave Barach1ddbc012018-06-13 09:26:05 -04002611 node = vam->graph_nodes[0][i];
Damjan Marion7cd468a2016-12-19 23:05:39 +01002612 hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2613 }
2614}
2615
2616static void vl_api_get_node_graph_reply_t_handler_json
2617 (vl_api_get_node_graph_reply_t * mp)
2618{
2619 vat_main_t *vam = &vat_main;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002620 void *oldheap;
2621 vat_json_node_t node;
2622 u8 *reply;
2623
2624 /* $$$$ make this real? */
2625 vat_json_init_object (&node);
2626 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2627 vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2628
Damjan Marion7bee80c2017-04-26 15:32:12 +02002629 reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002630
2631 /* Toss the shared-memory original... */
Nathan Skrzypczak0aa40132019-11-25 16:29:38 +01002632 oldheap = vl_msg_push_heap ();
Damjan Marion7cd468a2016-12-19 23:05:39 +01002633
2634 vec_free (reply);
2635
Nathan Skrzypczak0aa40132019-11-25 16:29:38 +01002636 vl_msg_pop_heap (oldheap);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002637
2638 vat_json_print (vam->ofp, &node);
2639 vat_json_free (&node);
2640
2641 vam->retval = ntohl (mp->retval);
2642 vam->result_ready = 1;
2643}
2644
Damjan Marion7cd468a2016-12-19 23:05:39 +01002645static u8 *
2646format_policer_type (u8 * s, va_list * va)
2647{
2648 u32 i = va_arg (*va, u32);
2649
2650 if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2651 s = format (s, "1r2c");
2652 else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2653 s = format (s, "1r3c");
2654 else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2655 s = format (s, "2r3c-2698");
2656 else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2657 s = format (s, "2r3c-4115");
2658 else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2659 s = format (s, "2r3c-mef5cf1");
2660 else
2661 s = format (s, "ILLEGAL");
2662 return s;
2663}
2664
2665static u8 *
2666format_policer_rate_type (u8 * s, va_list * va)
2667{
2668 u32 i = va_arg (*va, u32);
2669
2670 if (i == SSE2_QOS_RATE_KBPS)
2671 s = format (s, "kbps");
2672 else if (i == SSE2_QOS_RATE_PPS)
2673 s = format (s, "pps");
2674 else
2675 s = format (s, "ILLEGAL");
2676 return s;
2677}
2678
2679static u8 *
2680format_policer_round_type (u8 * s, va_list * va)
2681{
2682 u32 i = va_arg (*va, u32);
2683
2684 if (i == SSE2_QOS_ROUND_TO_CLOSEST)
2685 s = format (s, "closest");
2686 else if (i == SSE2_QOS_ROUND_TO_UP)
2687 s = format (s, "up");
2688 else if (i == SSE2_QOS_ROUND_TO_DOWN)
2689 s = format (s, "down");
2690 else
2691 s = format (s, "ILLEGAL");
2692 return s;
2693}
2694
2695static u8 *
2696format_policer_action_type (u8 * s, va_list * va)
2697{
2698 u32 i = va_arg (*va, u32);
2699
2700 if (i == SSE2_QOS_ACTION_DROP)
2701 s = format (s, "drop");
2702 else if (i == SSE2_QOS_ACTION_TRANSMIT)
2703 s = format (s, "transmit");
2704 else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2705 s = format (s, "mark-and-transmit");
2706 else
2707 s = format (s, "ILLEGAL");
2708 return s;
2709}
2710
2711static u8 *
2712format_dscp (u8 * s, va_list * va)
2713{
2714 u32 i = va_arg (*va, u32);
2715 char *t = 0;
2716
2717 switch (i)
2718 {
2719#define _(v,f,str) case VNET_DSCP_##f: t = str; break;
2720 foreach_vnet_dscp
2721#undef _
2722 default:
2723 return format (s, "ILLEGAL");
2724 }
2725 s = format (s, "%s", t);
2726 return s;
2727}
2728
2729static void
2730vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
2731{
2732 vat_main_t *vam = &vat_main;
2733 u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
2734
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002735 if (mp->conform_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
2736 conform_dscp_str = format (0, "%U", format_dscp, mp->conform_action.dscp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002737 else
2738 conform_dscp_str = format (0, "");
2739
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002740 if (mp->exceed_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
2741 exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_action.dscp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002742 else
2743 exceed_dscp_str = format (0, "");
2744
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002745 if (mp->violate_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
2746 violate_dscp_str = format (0, "%U", format_dscp, mp->violate_action.dscp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002747 else
2748 violate_dscp_str = format (0, "");
2749
2750 print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
2751 "rate type %U, round type %U, %s rate, %s color-aware, "
2752 "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
2753 "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
2754 "conform action %U%s, exceed action %U%s, violate action %U%s",
2755 mp->name,
2756 format_policer_type, mp->type,
2757 ntohl (mp->cir),
2758 ntohl (mp->eir),
2759 clib_net_to_host_u64 (mp->cb),
2760 clib_net_to_host_u64 (mp->eb),
2761 format_policer_rate_type, mp->rate_type,
2762 format_policer_round_type, mp->round_type,
2763 mp->single_rate ? "single" : "dual",
2764 mp->color_aware ? "is" : "not",
2765 ntohl (mp->cir_tokens_per_period),
2766 ntohl (mp->pir_tokens_per_period),
2767 ntohl (mp->scale),
2768 ntohl (mp->current_limit),
2769 ntohl (mp->current_bucket),
2770 ntohl (mp->extended_limit),
2771 ntohl (mp->extended_bucket),
2772 clib_net_to_host_u64 (mp->last_update_time),
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002773 format_policer_action_type, mp->conform_action.type,
Damjan Marion7cd468a2016-12-19 23:05:39 +01002774 conform_dscp_str,
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002775 format_policer_action_type, mp->exceed_action.type,
Damjan Marion7cd468a2016-12-19 23:05:39 +01002776 exceed_dscp_str,
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002777 format_policer_action_type, mp->violate_action.type,
Damjan Marion7cd468a2016-12-19 23:05:39 +01002778 violate_dscp_str);
2779
2780 vec_free (conform_dscp_str);
2781 vec_free (exceed_dscp_str);
2782 vec_free (violate_dscp_str);
2783}
2784
2785static void vl_api_policer_details_t_handler_json
2786 (vl_api_policer_details_t * mp)
2787{
2788 vat_main_t *vam = &vat_main;
2789 vat_json_node_t *node;
2790 u8 *rate_type_str, *round_type_str, *type_str;
2791 u8 *conform_action_str, *exceed_action_str, *violate_action_str;
2792
2793 rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
2794 round_type_str =
2795 format (0, "%U", format_policer_round_type, mp->round_type);
2796 type_str = format (0, "%U", format_policer_type, mp->type);
2797 conform_action_str = format (0, "%U", format_policer_action_type,
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002798 mp->conform_action.type);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002799 exceed_action_str = format (0, "%U", format_policer_action_type,
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002800 mp->exceed_action.type);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002801 violate_action_str = format (0, "%U", format_policer_action_type,
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002802 mp->violate_action.type);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002803
2804 if (VAT_JSON_ARRAY != vam->json_tree.type)
2805 {
2806 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2807 vat_json_init_array (&vam->json_tree);
2808 }
2809 node = vat_json_array_add (&vam->json_tree);
2810
2811 vat_json_init_object (node);
2812 vat_json_object_add_string_copy (node, "name", mp->name);
2813 vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
2814 vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
Marek Gradzki59ed4902017-03-21 11:51:54 +01002815 vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
2816 vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
Damjan Marion7cd468a2016-12-19 23:05:39 +01002817 vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
2818 vat_json_object_add_string_copy (node, "round_type", round_type_str);
2819 vat_json_object_add_string_copy (node, "type", type_str);
2820 vat_json_object_add_uint (node, "single_rate", mp->single_rate);
2821 vat_json_object_add_uint (node, "color_aware", mp->color_aware);
2822 vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
2823 vat_json_object_add_uint (node, "cir_tokens_per_period",
2824 ntohl (mp->cir_tokens_per_period));
2825 vat_json_object_add_uint (node, "eir_tokens_per_period",
2826 ntohl (mp->pir_tokens_per_period));
2827 vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
2828 vat_json_object_add_uint (node, "current_bucket",
2829 ntohl (mp->current_bucket));
2830 vat_json_object_add_uint (node, "extended_limit",
2831 ntohl (mp->extended_limit));
2832 vat_json_object_add_uint (node, "extended_bucket",
2833 ntohl (mp->extended_bucket));
2834 vat_json_object_add_uint (node, "last_update_time",
2835 ntohl (mp->last_update_time));
2836 vat_json_object_add_string_copy (node, "conform_action",
2837 conform_action_str);
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002838 if (mp->conform_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002839 {
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002840 u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_action.dscp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002841 vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
2842 vec_free (dscp_str);
2843 }
2844 vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002845 if (mp->exceed_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002846 {
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002847 u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_action.dscp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002848 vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
2849 vec_free (dscp_str);
2850 }
2851 vat_json_object_add_string_copy (node, "violate_action",
2852 violate_action_str);
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002853 if (mp->violate_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002854 {
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002855 u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_action.dscp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002856 vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
2857 vec_free (dscp_str);
2858 }
2859
2860 vec_free (rate_type_str);
2861 vec_free (round_type_str);
2862 vec_free (type_str);
2863 vec_free (conform_action_str);
2864 vec_free (exceed_action_str);
2865 vec_free (violate_action_str);
2866}
2867
2868static void
2869vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
2870 mp)
2871{
2872 vat_main_t *vam = &vat_main;
2873 int i, count = ntohl (mp->count);
2874
2875 if (count > 0)
2876 print (vam->ofp, "classify table ids (%d) : ", count);
2877 for (i = 0; i < count; i++)
2878 {
2879 print (vam->ofp, "%d", ntohl (mp->ids[i]));
2880 print (vam->ofp, (i < count - 1) ? "," : "");
2881 }
2882 vam->retval = ntohl (mp->retval);
2883 vam->result_ready = 1;
2884}
2885
2886static void
2887 vl_api_classify_table_ids_reply_t_handler_json
2888 (vl_api_classify_table_ids_reply_t * mp)
2889{
2890 vat_main_t *vam = &vat_main;
2891 int i, count = ntohl (mp->count);
2892
2893 if (count > 0)
2894 {
2895 vat_json_node_t node;
2896
2897 vat_json_init_object (&node);
2898 for (i = 0; i < count; i++)
2899 {
2900 vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
2901 }
2902 vat_json_print (vam->ofp, &node);
2903 vat_json_free (&node);
2904 }
2905 vam->retval = ntohl (mp->retval);
2906 vam->result_ready = 1;
2907}
2908
2909static void
2910 vl_api_classify_table_by_interface_reply_t_handler
2911 (vl_api_classify_table_by_interface_reply_t * mp)
2912{
2913 vat_main_t *vam = &vat_main;
2914 u32 table_id;
2915
2916 table_id = ntohl (mp->l2_table_id);
2917 if (table_id != ~0)
2918 print (vam->ofp, "l2 table id : %d", table_id);
2919 else
2920 print (vam->ofp, "l2 table id : No input ACL tables configured");
2921 table_id = ntohl (mp->ip4_table_id);
2922 if (table_id != ~0)
2923 print (vam->ofp, "ip4 table id : %d", table_id);
2924 else
2925 print (vam->ofp, "ip4 table id : No input ACL tables configured");
2926 table_id = ntohl (mp->ip6_table_id);
2927 if (table_id != ~0)
2928 print (vam->ofp, "ip6 table id : %d", table_id);
2929 else
2930 print (vam->ofp, "ip6 table id : No input ACL tables configured");
2931 vam->retval = ntohl (mp->retval);
2932 vam->result_ready = 1;
2933}
2934
2935static void
2936 vl_api_classify_table_by_interface_reply_t_handler_json
2937 (vl_api_classify_table_by_interface_reply_t * mp)
2938{
2939 vat_main_t *vam = &vat_main;
2940 vat_json_node_t node;
2941
2942 vat_json_init_object (&node);
2943
2944 vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
2945 vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
2946 vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
2947
2948 vat_json_print (vam->ofp, &node);
2949 vat_json_free (&node);
2950
2951 vam->retval = ntohl (mp->retval);
2952 vam->result_ready = 1;
2953}
2954
2955static void vl_api_policer_add_del_reply_t_handler
2956 (vl_api_policer_add_del_reply_t * mp)
2957{
2958 vat_main_t *vam = &vat_main;
2959 i32 retval = ntohl (mp->retval);
2960 if (vam->async_mode)
2961 {
2962 vam->async_errors += (retval < 0);
2963 }
2964 else
2965 {
2966 vam->retval = retval;
2967 vam->result_ready = 1;
2968 if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
2969 /*
2970 * Note: this is just barely thread-safe, depends on
2971 * the main thread spinning waiting for an answer...
2972 */
2973 errmsg ("policer index %d", ntohl (mp->policer_index));
2974 }
2975}
2976
2977static void vl_api_policer_add_del_reply_t_handler_json
2978 (vl_api_policer_add_del_reply_t * mp)
2979{
2980 vat_main_t *vam = &vat_main;
2981 vat_json_node_t node;
2982
2983 vat_json_init_object (&node);
2984 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2985 vat_json_object_add_uint (&node, "policer_index",
2986 ntohl (mp->policer_index));
2987
2988 vat_json_print (vam->ofp, &node);
2989 vat_json_free (&node);
2990
2991 vam->retval = ntohl (mp->retval);
2992 vam->result_ready = 1;
2993}
2994
2995/* Format hex dump. */
2996u8 *
2997format_hex_bytes (u8 * s, va_list * va)
2998{
2999 u8 *bytes = va_arg (*va, u8 *);
3000 int n_bytes = va_arg (*va, int);
3001 uword i;
3002
3003 /* Print short or long form depending on byte count. */
3004 uword short_form = n_bytes <= 32;
Christophe Fontained3c008d2017-10-02 18:10:54 +02003005 u32 indent = format_get_indent (s);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003006
3007 if (n_bytes == 0)
3008 return s;
3009
3010 for (i = 0; i < n_bytes; i++)
3011 {
3012 if (!short_form && (i % 32) == 0)
3013 s = format (s, "%08x: ", i);
3014 s = format (s, "%02x", bytes[i]);
3015 if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3016 s = format (s, "\n%U", format_white_space, indent);
3017 }
3018
3019 return s;
3020}
3021
3022static void
3023vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3024 * mp)
3025{
3026 vat_main_t *vam = &vat_main;
3027 i32 retval = ntohl (mp->retval);
3028 if (retval == 0)
3029 {
3030 print (vam->ofp, "classify table info :");
3031 print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
3032 ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3033 ntohl (mp->miss_next_index));
3034 print (vam->ofp, "nbuckets: %d skip: %d match: %d",
3035 ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3036 ntohl (mp->match_n_vectors));
3037 print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
3038 ntohl (mp->mask_length));
3039 }
3040 vam->retval = retval;
3041 vam->result_ready = 1;
3042}
3043
3044static void
3045 vl_api_classify_table_info_reply_t_handler_json
3046 (vl_api_classify_table_info_reply_t * mp)
3047{
3048 vat_main_t *vam = &vat_main;
3049 vat_json_node_t node;
3050
3051 i32 retval = ntohl (mp->retval);
3052 if (retval == 0)
3053 {
3054 vat_json_init_object (&node);
3055
3056 vat_json_object_add_int (&node, "sessions",
3057 ntohl (mp->active_sessions));
3058 vat_json_object_add_int (&node, "nexttbl",
3059 ntohl (mp->next_table_index));
3060 vat_json_object_add_int (&node, "nextnode",
3061 ntohl (mp->miss_next_index));
3062 vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3063 vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3064 vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3065 u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3066 ntohl (mp->mask_length), 0);
3067 vat_json_object_add_string_copy (&node, "mask", s);
3068
3069 vat_json_print (vam->ofp, &node);
3070 vat_json_free (&node);
3071 }
3072 vam->retval = ntohl (mp->retval);
3073 vam->result_ready = 1;
3074}
3075
3076static void
3077vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3078 mp)
3079{
3080 vat_main_t *vam = &vat_main;
3081
3082 print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3083 ntohl (mp->hit_next_index), ntohl (mp->advance),
3084 ntohl (mp->opaque_index));
3085 print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
3086 ntohl (mp->match_length));
3087}
3088
3089static void
3090 vl_api_classify_session_details_t_handler_json
3091 (vl_api_classify_session_details_t * mp)
3092{
3093 vat_main_t *vam = &vat_main;
3094 vat_json_node_t *node = NULL;
3095
3096 if (VAT_JSON_ARRAY != vam->json_tree.type)
3097 {
3098 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3099 vat_json_init_array (&vam->json_tree);
3100 }
3101 node = vat_json_array_add (&vam->json_tree);
3102
3103 vat_json_init_object (node);
3104 vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3105 vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3106 vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3107 u8 *s =
3108 format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3109 0);
3110 vat_json_object_add_string_copy (node, "match", s);
3111}
3112
3113static void vl_api_pg_create_interface_reply_t_handler
3114 (vl_api_pg_create_interface_reply_t * mp)
3115{
3116 vat_main_t *vam = &vat_main;
3117
3118 vam->retval = ntohl (mp->retval);
3119 vam->result_ready = 1;
3120}
3121
3122static void vl_api_pg_create_interface_reply_t_handler_json
3123 (vl_api_pg_create_interface_reply_t * mp)
3124{
3125 vat_main_t *vam = &vat_main;
3126 vat_json_node_t node;
3127
3128 i32 retval = ntohl (mp->retval);
3129 if (retval == 0)
3130 {
3131 vat_json_init_object (&node);
3132
3133 vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3134
3135 vat_json_print (vam->ofp, &node);
3136 vat_json_free (&node);
3137 }
3138 vam->retval = ntohl (mp->retval);
3139 vam->result_ready = 1;
3140}
3141
3142static void vl_api_policer_classify_details_t_handler
3143 (vl_api_policer_classify_details_t * mp)
3144{
3145 vat_main_t *vam = &vat_main;
3146
3147 print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3148 ntohl (mp->table_index));
3149}
3150
3151static void vl_api_policer_classify_details_t_handler_json
3152 (vl_api_policer_classify_details_t * mp)
3153{
3154 vat_main_t *vam = &vat_main;
3155 vat_json_node_t *node;
3156
3157 if (VAT_JSON_ARRAY != vam->json_tree.type)
3158 {
3159 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3160 vat_json_init_array (&vam->json_tree);
3161 }
3162 node = vat_json_array_add (&vam->json_tree);
3163
3164 vat_json_init_object (node);
3165 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3166 vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3167}
3168
Damjan Marion7cd468a2016-12-19 23:05:39 +01003169static void vl_api_flow_classify_details_t_handler
3170 (vl_api_flow_classify_details_t * mp)
3171{
3172 vat_main_t *vam = &vat_main;
3173
3174 print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3175 ntohl (mp->table_index));
3176}
3177
3178static void vl_api_flow_classify_details_t_handler_json
3179 (vl_api_flow_classify_details_t * mp)
3180{
3181 vat_main_t *vam = &vat_main;
3182 vat_json_node_t *node;
3183
3184 if (VAT_JSON_ARRAY != vam->json_tree.type)
3185 {
3186 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3187 vat_json_init_array (&vam->json_tree);
3188 }
3189 node = vat_json_array_add (&vam->json_tree);
3190
3191 vat_json_init_object (node);
3192 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3193 vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3194}
3195
Damjan Marion7cd468a2016-12-19 23:05:39 +01003196/*
3197 * Generate boilerplate reply handlers, which
3198 * dig the return value out of the xxx_reply_t API message,
3199 * stick it into vam->retval, and set vam->result_ready
3200 *
3201 * Could also do this by pointing N message decode slots at
3202 * a single function, but that could break in subtle ways.
3203 */
3204
3205#define foreach_standard_reply_retval_handler \
3206_(sw_interface_set_flags_reply) \
3207_(sw_interface_add_del_address_reply) \
Stevenad8015b2017-10-29 22:10:46 -07003208_(sw_interface_set_rx_mode_reply) \
Mohsin Kazmi54f7c512018-08-23 18:28:11 +02003209_(sw_interface_set_rx_placement_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003210_(sw_interface_set_table_reply) \
3211_(sw_interface_set_mpls_enable_reply) \
3212_(sw_interface_set_vpath_reply) \
3213_(sw_interface_set_vxlan_bypass_reply) \
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +08003214_(sw_interface_set_vxlan_gpe_bypass_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003215_(sw_interface_set_l2_bridge_reply) \
Steven Luonga1876b82019-08-20 16:58:00 -07003216_(sw_interface_set_bond_weight_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003217_(bridge_domain_add_del_reply) \
3218_(sw_interface_set_l2_xconnect_reply) \
3219_(l2fib_add_del_reply) \
Eyal Barif24991c2017-04-05 05:33:21 +03003220_(l2fib_flush_int_reply) \
3221_(l2fib_flush_bd_reply) \
Neale Ranns097fa662018-05-01 05:17:55 -07003222_(ip_route_add_del_reply) \
Neale Ranns28ab9cc2017-08-14 07:18:42 -07003223_(ip_table_add_del_reply) \
Neale Ranns9db6ada2019-11-08 12:42:31 +00003224_(ip_table_replace_begin_reply) \
3225_(ip_table_flush_reply) \
3226_(ip_table_replace_end_reply) \
Neale Ranns32e1c012016-11-22 17:07:28 +00003227_(ip_mroute_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003228_(mpls_route_add_del_reply) \
Neale Ranns28ab9cc2017-08-14 07:18:42 -07003229_(mpls_table_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003230_(mpls_ip_bind_unbind_reply) \
Neale Rannsd792d9c2017-10-21 10:53:20 -07003231_(bier_route_add_del_reply) \
3232_(bier_table_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003233_(sw_interface_set_unnumbered_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003234_(set_ip_flow_hash_reply) \
3235_(sw_interface_ip6_enable_disable_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003236_(l2_patch_add_del_reply) \
John Loe166fd92018-09-13 14:08:59 -04003237_(sr_mpls_policy_add_reply) \
3238_(sr_mpls_policy_mod_reply) \
3239_(sr_mpls_policy_del_reply) \
Pablo Camarillofb380952016-12-07 18:34:18 +01003240_(sr_policy_add_reply) \
3241_(sr_policy_mod_reply) \
3242_(sr_policy_del_reply) \
3243_(sr_localsid_add_del_reply) \
3244_(sr_steering_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003245_(classify_add_del_session_reply) \
3246_(classify_set_interface_ip_table_reply) \
3247_(classify_set_interface_l2_tables_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003248_(l2_fib_clear_table_reply) \
3249_(l2_interface_efp_filter_reply) \
3250_(l2_interface_vlan_tag_rewrite_reply) \
3251_(modify_vhost_user_if_reply) \
3252_(delete_vhost_user_if_reply) \
John Lo8d00fff2017-08-03 00:35:36 -04003253_(want_l2_macs_events_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003254_(input_acl_set_interface_reply) \
3255_(ipsec_spd_add_del_reply) \
3256_(ipsec_interface_add_del_spd_reply) \
Neale Ranns17dcec02019-01-09 21:22:20 -08003257_(ipsec_spd_entry_add_del_reply) \
3258_(ipsec_sad_entry_add_del_reply) \
Matthew Smithb0972cb2017-05-02 16:20:41 -05003259_(ipsec_tunnel_if_add_del_reply) \
Matthew Smithca514fd2017-10-12 12:06:59 -05003260_(ipsec_tunnel_if_set_sa_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003261_(delete_loopback_reply) \
3262_(bd_ip_mac_add_del_reply) \
John Loe26c81f2019-01-07 15:16:33 -05003263_(bd_ip_mac_flush_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003264_(want_interface_events_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003265_(cop_interface_enable_disable_reply) \
3266_(cop_whitelist_enable_disable_reply) \
3267_(sw_interface_clear_stats_reply) \
Dave Barach65457162017-10-10 17:53:14 -04003268_(ioam_enable_reply) \
3269_(ioam_disable_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003270_(af_packet_delete_reply) \
3271_(policer_classify_set_interface_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003272_(set_ipfix_exporter_reply) \
3273_(set_ipfix_classify_stream_reply) \
3274_(ipfix_classify_table_add_del_reply) \
3275_(flow_classify_set_interface_reply) \
3276_(sw_interface_span_enable_disable_reply) \
3277_(pg_capture_reply) \
3278_(pg_enable_disable_reply) \
Mohsin Kazmif382b062020-08-11 15:00:44 +02003279_(pg_interface_enable_disable_coalesce_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003280_(ip_source_and_port_range_check_add_del_reply) \
3281_(ip_source_and_port_range_check_interface_add_del_reply)\
3282_(delete_subif_reply) \
3283_(l2_interface_pbb_tag_rewrite_reply) \
Pavel Kotuceke88865d2018-11-28 07:42:11 +01003284_(set_punt_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003285_(feature_enable_disable_reply) \
Mohsin Kazmi29467b52019-10-08 19:42:38 +02003286_(feature_gso_enable_disable_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003287_(sw_interface_tag_add_del_reply) \
Matthew Smithe0792fd2019-07-12 11:48:24 -05003288_(sw_interface_add_del_mac_address_reply) \
Ole Troand7231612018-06-07 10:17:57 +02003289_(hw_interface_set_mtu_reply) \
Pavel Kotucek6899a302017-06-08 08:46:10 +02003290_(p2p_ethernet_add_reply) \
Steve Shin99a0e602017-07-01 04:16:20 +00003291_(p2p_ethernet_del_reply) \
Florin Corascea194d2017-10-02 00:18:51 -07003292_(tcp_configure_src_addresses_reply) \
Florin Coras595992c2017-11-06 17:17:08 -08003293_(session_rule_add_del_reply) \
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +01003294_(ip_container_proxy_add_del_reply) \
Igor Mikhailov (imichail)582caa32018-04-26 21:33:02 -07003295_(output_acl_set_interface_reply) \
Chenmin Sund0236f72020-07-27 17:54:40 +08003296_(qos_record_enable_disable_reply) \
3297_(flow_add_reply)
Damjan Marion7cd468a2016-12-19 23:05:39 +01003298
3299#define _(n) \
3300 static void vl_api_##n##_t_handler \
3301 (vl_api_##n##_t * mp) \
3302 { \
3303 vat_main_t * vam = &vat_main; \
3304 i32 retval = ntohl(mp->retval); \
3305 if (vam->async_mode) { \
3306 vam->async_errors += (retval < 0); \
3307 } else { \
3308 vam->retval = retval; \
3309 vam->result_ready = 1; \
3310 } \
3311 }
3312foreach_standard_reply_retval_handler;
3313#undef _
3314
3315#define _(n) \
3316 static void vl_api_##n##_t_handler_json \
3317 (vl_api_##n##_t * mp) \
3318 { \
3319 vat_main_t * vam = &vat_main; \
3320 vat_json_node_t node; \
3321 vat_json_init_object(&node); \
3322 vat_json_object_add_int(&node, "retval", ntohl(mp->retval)); \
3323 vat_json_print(vam->ofp, &node); \
3324 vam->retval = ntohl(mp->retval); \
3325 vam->result_ready = 1; \
3326 }
3327foreach_standard_reply_retval_handler;
3328#undef _
3329
3330/*
3331 * Table of message reply handlers, must include boilerplate handlers
3332 * we just generated
3333 */
3334
3335#define foreach_vpe_api_reply_msg \
3336_(CREATE_LOOPBACK_REPLY, create_loopback_reply) \
Jon Loeligerc83c3b72017-02-23 13:57:35 -06003337_(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003338_(SW_INTERFACE_DETAILS, sw_interface_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003339_(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply) \
3340_(CONTROL_PING_REPLY, control_ping_reply) \
3341_(CLI_REPLY, cli_reply) \
3342_(CLI_INBAND_REPLY, cli_inband_reply) \
3343_(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY, \
3344 sw_interface_add_del_address_reply) \
Stevenad8015b2017-10-29 22:10:46 -07003345_(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply) \
Mohsin Kazmi54f7c512018-08-23 18:28:11 +02003346_(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply) \
Mohsin Kazmif0b42f42018-09-10 18:11:00 +02003347_(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003348_(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply) \
3349_(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
3350_(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply) \
3351_(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +08003352_(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003353_(SW_INTERFACE_SET_L2_XCONNECT_REPLY, \
3354 sw_interface_set_l2_xconnect_reply) \
3355_(SW_INTERFACE_SET_L2_BRIDGE_REPLY, \
3356 sw_interface_set_l2_bridge_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003357_(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply) \
3358_(BRIDGE_DOMAIN_DETAILS, bridge_domain_details) \
Eyal Barifead6702017-04-04 04:46:32 +03003359_(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003360_(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply) \
Eyal Barif24991c2017-04-05 05:33:21 +03003361_(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply) \
3362_(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003363_(L2_FLAGS_REPLY, l2_flags_reply) \
3364_(BRIDGE_FLAGS_REPLY, bridge_flags_reply) \
Damjan Marion8389fb92017-10-13 18:29:53 +02003365_(TAP_CREATE_V2_REPLY, tap_create_v2_reply) \
3366_(TAP_DELETE_V2_REPLY, tap_delete_v2_reply) \
3367_(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details) \
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01003368_(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply) \
Mohsin Kazmi518251b2020-09-01 17:17:44 +00003369_(VIRTIO_PCI_CREATE_V2_REPLY, virtio_pci_create_v2_reply) \
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01003370_(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply) \
3371_(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details) \
Steven9cd2d7a2017-12-20 12:43:01 -08003372_(BOND_CREATE_REPLY, bond_create_reply) \
Steven Luongea717862020-07-30 07:31:40 -07003373_(BOND_CREATE2_REPLY, bond_create2_reply) \
Steven9cd2d7a2017-12-20 12:43:01 -08003374_(BOND_DELETE_REPLY, bond_delete_reply) \
Steven Luong4c4223e2020-07-15 08:44:54 -07003375_(BOND_ADD_MEMBER_REPLY, bond_add_member_reply) \
3376_(BOND_DETACH_MEMBER_REPLY, bond_detach_member_reply) \
Steven Luonga1876b82019-08-20 16:58:00 -07003377_(SW_INTERFACE_SET_BOND_WEIGHT_REPLY, sw_interface_set_bond_weight_reply) \
Steven Luong4c4223e2020-07-15 08:44:54 -07003378_(SW_BOND_INTERFACE_DETAILS, sw_bond_interface_details) \
3379_(SW_MEMBER_INTERFACE_DETAILS, sw_member_interface_details) \
Neale Ranns097fa662018-05-01 05:17:55 -07003380_(IP_ROUTE_ADD_DEL_REPLY, ip_route_add_del_reply) \
Neale Ranns28ab9cc2017-08-14 07:18:42 -07003381_(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply) \
Neale Ranns9db6ada2019-11-08 12:42:31 +00003382_(IP_TABLE_REPLACE_BEGIN_REPLY, ip_table_replace_begin_reply) \
3383_(IP_TABLE_FLUSH_REPLY, ip_table_flush_reply) \
3384_(IP_TABLE_REPLACE_END_REPLY, ip_table_replace_end_reply) \
Neale Ranns32e1c012016-11-22 17:07:28 +00003385_(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply) \
Neale Ranns28ab9cc2017-08-14 07:18:42 -07003386_(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003387_(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply) \
3388_(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply) \
Neale Rannsd792d9c2017-10-21 10:53:20 -07003389_(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply) \
3390_(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003391_(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply) \
3392_(SW_INTERFACE_SET_UNNUMBERED_REPLY, \
3393 sw_interface_set_unnumbered_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003394_(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply) \
3395_(CREATE_SUBIF_REPLY, create_subif_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003396_(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply) \
3397_(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY, \
3398 sw_interface_ip6_enable_disable_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003399_(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply) \
John Loe166fd92018-09-13 14:08:59 -04003400_(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply) \
3401_(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply) \
3402_(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply) \
Pablo Camarillofb380952016-12-07 18:34:18 +01003403_(SR_POLICY_ADD_REPLY, sr_policy_add_reply) \
3404_(SR_POLICY_MOD_REPLY, sr_policy_mod_reply) \
3405_(SR_POLICY_DEL_REPLY, sr_policy_del_reply) \
3406_(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply) \
3407_(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003408_(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply) \
3409_(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply) \
3410_(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY, \
3411classify_set_interface_ip_table_reply) \
3412_(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY, \
3413 classify_set_interface_l2_tables_reply) \
3414_(GET_NODE_INDEX_REPLY, get_node_index_reply) \
3415_(ADD_NODE_NEXT_REPLY, add_node_next_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003416_(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply) \
eyal bariaf86a482018-04-17 11:20:27 +03003417_(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003418_(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003419_(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply) \
3420_(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply) \
3421_(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3422_(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details) \
3423_(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply) \
3424_(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply) \
3425_(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply) \
3426_(SHOW_VERSION_REPLY, show_version_reply) \
Mohsin Kazmi5d64c782018-09-11 20:27:09 +02003427_(SHOW_THREADS_REPLY, show_threads_reply) \
Ole Troan01384fe2017-05-12 11:55:35 +02003428_(L2_FIB_TABLE_DETAILS, l2_fib_table_details) \
John Loc7b43042018-04-13 16:46:22 -04003429_(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003430_(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details) \
3431_(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply) \
John Lo8d00fff2017-08-03 00:35:36 -04003432_(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply) \
3433_(L2_MACS_EVENT, l2_macs_event) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003434_(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply) \
3435_(IP_ADDRESS_DETAILS, ip_address_details) \
3436_(IP_DETAILS, ip_details) \
3437_(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply) \
3438_(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
Neale Ranns17dcec02019-01-09 21:22:20 -08003439_(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply) \
3440_(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply) \
Matthew Smith28029532017-09-26 13:33:44 -05003441_(IPSEC_SA_DETAILS, ipsec_sa_details) \
Matthew Smithb0972cb2017-05-02 16:20:41 -05003442_(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply) \
Matthew Smithca514fd2017-10-12 12:06:59 -05003443_(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003444_(DELETE_LOOPBACK_REPLY, delete_loopback_reply) \
3445_(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply) \
John Loe26c81f2019-01-07 15:16:33 -05003446_(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply) \
Mohsin Kazmi5d82d2f2018-08-13 19:17:54 +02003447_(BD_IP_MAC_DETAILS, bd_ip_mac_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003448_(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003449_(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply) \
3450_(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
3451_(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
3452_(GET_NODE_GRAPH_REPLY, get_node_graph_reply) \
3453_(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply) \
3454_(IOAM_ENABLE_REPLY, ioam_enable_reply) \
3455_(IOAM_DISABLE_REPLY, ioam_disable_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003456_(AF_PACKET_CREATE_REPLY, af_packet_create_reply) \
3457_(AF_PACKET_DELETE_REPLY, af_packet_delete_reply) \
Mohsin Kazmi04e0bb22018-05-28 18:55:37 +02003458_(AF_PACKET_DETAILS, af_packet_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003459_(POLICER_ADD_DEL_REPLY, policer_add_del_reply) \
3460_(POLICER_DETAILS, policer_details) \
3461_(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3462_(POLICER_CLASSIFY_DETAILS, policer_classify_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003463_(MPLS_TUNNEL_DETAILS, mpls_tunnel_details) \
Neale Ranns097fa662018-05-01 05:17:55 -07003464_(MPLS_TABLE_DETAILS, mpls_table_details) \
3465_(MPLS_ROUTE_DETAILS, mpls_route_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003466_(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply) \
3467_(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3468_(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply) \
3469_(CLASSIFY_SESSION_DETAILS, classify_session_details) \
3470_(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply) \
3471_(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details) \
3472_(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply) \
3473_(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details) \
3474_(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
3475_(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details) \
3476_(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
3477_(FLOW_CLASSIFY_DETAILS, flow_classify_details) \
3478_(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
3479_(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details) \
3480_(GET_NEXT_INDEX_REPLY, get_next_index_reply) \
3481_(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply) \
3482_(PG_CAPTURE_REPLY, pg_capture_reply) \
3483_(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply) \
Mohsin Kazmif382b062020-08-11 15:00:44 +02003484_(PG_INTERFACE_ENABLE_DISABLE_COALESCE_REPLY, pg_interface_enable_disable_coalesce_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003485_(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY, \
3486 ip_source_and_port_range_check_add_del_reply) \
3487_(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY, \
3488 ip_source_and_port_range_check_interface_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003489_(DELETE_SUBIF_REPLY, delete_subif_reply) \
3490_(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
Pavel Kotuceke88865d2018-11-28 07:42:11 +01003491_(SET_PUNT_REPLY, set_punt_reply) \
Neale Ranns097fa662018-05-01 05:17:55 -07003492_(IP_TABLE_DETAILS, ip_table_details) \
3493_(IP_ROUTE_DETAILS, ip_route_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003494_(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply) \
Mohsin Kazmi29467b52019-10-08 19:42:38 +02003495_(FEATURE_GSO_ENABLE_DISABLE_REPLY, feature_gso_enable_disable_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003496_(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply) \
Matthew Smithe0792fd2019-07-12 11:48:24 -05003497_(SW_INTERFACE_ADD_DEL_MAC_ADDRESS_REPLY, sw_interface_add_del_mac_address_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003498_(L2_XCONNECT_DETAILS, l2_xconnect_details) \
Ole Troand7231612018-06-07 10:17:57 +02003499_(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply) \
Pavel Kotucek6899a302017-06-08 08:46:10 +02003500_(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply) \
3501_(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply) \
Steve Shin99a0e602017-07-01 04:16:20 +00003502_(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply) \
Florin Corascea194d2017-10-02 00:18:51 -07003503_(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
Dave Barach65457162017-10-10 17:53:14 -04003504_(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply) \
Florin Coras6c36f532017-11-03 18:32:34 -07003505_(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply) \
Florin Coras595992c2017-11-06 17:17:08 -08003506_(SESSION_RULES_DETAILS, session_rules_details) \
3507_(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply) \
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +01003508_(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply) \
Chenmin Sund0236f72020-07-27 17:54:40 +08003509_(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply) \
3510_(FLOW_ADD_REPLY, flow_add_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003511
Dave Baracha1a093d2017-03-02 13:13:23 -05003512#define foreach_standalone_reply_msg \
Ole Troanf49ba0e2018-11-13 14:04:50 +01003513_(SW_INTERFACE_EVENT, sw_interface_event)
Dave Baracha1a093d2017-03-02 13:13:23 -05003514
Damjan Marion7cd468a2016-12-19 23:05:39 +01003515typedef struct
3516{
3517 u8 *name;
3518 u32 value;
3519} name_sort_t;
3520
Damjan Marion7cd468a2016-12-19 23:05:39 +01003521#define STR_VTR_OP_CASE(op) \
3522 case L2_VTR_ ## op: \
3523 return "" # op;
3524
3525static const char *
3526str_vtr_op (u32 vtr_op)
3527{
3528 switch (vtr_op)
3529 {
3530 STR_VTR_OP_CASE (DISABLED);
3531 STR_VTR_OP_CASE (PUSH_1);
3532 STR_VTR_OP_CASE (PUSH_2);
3533 STR_VTR_OP_CASE (POP_1);
3534 STR_VTR_OP_CASE (POP_2);
3535 STR_VTR_OP_CASE (TRANSLATE_1_1);
3536 STR_VTR_OP_CASE (TRANSLATE_1_2);
3537 STR_VTR_OP_CASE (TRANSLATE_2_1);
3538 STR_VTR_OP_CASE (TRANSLATE_2_2);
3539 }
3540
3541 return "UNKNOWN";
3542}
3543
3544static int
3545dump_sub_interface_table (vat_main_t * vam)
3546{
3547 const sw_interface_subif_t *sub = NULL;
3548
3549 if (vam->json_output)
3550 {
3551 clib_warning
3552 ("JSON output supported only for VPE API calls and dump_stats_table");
3553 return -99;
3554 }
3555
3556 print (vam->ofp,
3557 "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
3558 "Interface", "sw_if_index",
3559 "sub id", "dot1ad", "tags", "outer id",
3560 "inner id", "exact", "default", "outer any", "inner any");
3561
3562 vec_foreach (sub, vam->sw_if_subif_table)
3563 {
3564 print (vam->ofp,
3565 "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
3566 sub->interface_name,
3567 sub->sw_if_index,
3568 sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
3569 sub->sub_number_of_tags, sub->sub_outer_vlan_id,
3570 sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
3571 sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
3572 if (sub->vtr_op != L2_VTR_DISABLED)
3573 {
3574 print (vam->ofp,
3575 " vlan-tag-rewrite - op: %-14s [ dot1q: %d "
3576 "tag1: %d tag2: %d ]",
3577 str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
3578 sub->vtr_tag1, sub->vtr_tag2);
3579 }
3580 }
3581
3582 return 0;
3583}
3584
3585static int
3586name_sort_cmp (void *a1, void *a2)
3587{
3588 name_sort_t *n1 = a1;
3589 name_sort_t *n2 = a2;
3590
3591 return strcmp ((char *) n1->name, (char *) n2->name);
3592}
3593
3594static int
3595dump_interface_table (vat_main_t * vam)
3596{
3597 hash_pair_t *p;
3598 name_sort_t *nses = 0, *ns;
3599
3600 if (vam->json_output)
3601 {
3602 clib_warning
3603 ("JSON output supported only for VPE API calls and dump_stats_table");
3604 return -99;
3605 }
3606
3607 /* *INDENT-OFF* */
3608 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3609 ({
3610 vec_add2 (nses, ns, 1);
3611 ns->name = (u8 *)(p->key);
3612 ns->value = (u32) p->value[0];
3613 }));
3614 /* *INDENT-ON* */
3615
3616 vec_sort_with_function (nses, name_sort_cmp);
3617
3618 print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
3619 vec_foreach (ns, nses)
3620 {
3621 print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
3622 }
3623 vec_free (nses);
3624 return 0;
3625}
3626
3627static int
3628dump_ip_table (vat_main_t * vam, int is_ipv6)
3629{
3630 const ip_details_t *det = NULL;
3631 const ip_address_details_t *address = NULL;
3632 u32 i = ~0;
3633
3634 print (vam->ofp, "%-12s", "sw_if_index");
3635
3636 vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
3637 {
3638 i++;
3639 if (!det->present)
3640 {
3641 continue;
3642 }
3643 print (vam->ofp, "%-12d", i);
3644 print (vam->ofp, " %-30s%-13s", "Address", "Prefix length");
3645 if (!det->addr)
3646 {
3647 continue;
3648 }
3649 vec_foreach (address, det->addr)
3650 {
3651 print (vam->ofp,
3652 " %-30U%-13d",
3653 is_ipv6 ? format_ip6_address : format_ip4_address,
3654 address->ip, address->prefix_length);
3655 }
3656 }
3657
3658 return 0;
3659}
3660
3661static int
3662dump_ipv4_table (vat_main_t * vam)
3663{
3664 if (vam->json_output)
3665 {
3666 clib_warning
3667 ("JSON output supported only for VPE API calls and dump_stats_table");
3668 return -99;
3669 }
3670
3671 return dump_ip_table (vam, 0);
3672}
3673
3674static int
3675dump_ipv6_table (vat_main_t * vam)
3676{
3677 if (vam->json_output)
3678 {
3679 clib_warning
3680 ("JSON output supported only for VPE API calls and dump_stats_table");
3681 return -99;
3682 }
3683
3684 return dump_ip_table (vam, 1);
3685}
3686
Damjan Marion7cd468a2016-12-19 23:05:39 +01003687/*
Dave Barach59b25652017-09-10 15:04:27 -04003688 * Pass CLI buffers directly in the CLI_INBAND API message,
3689 * instead of an additional shared memory area.
Damjan Marion7cd468a2016-12-19 23:05:39 +01003690 */
3691static int
3692exec_inband (vat_main_t * vam)
3693{
3694 vl_api_cli_inband_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003695 unformat_input_t *i = vam->input;
Jon Loeliger56c7b012017-02-01 12:31:41 -06003696 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003697
3698 if (vec_len (i->buffer) == 0)
3699 return -1;
3700
3701 if (vam->exec_mode == 0 && unformat (i, "mode"))
3702 {
3703 vam->exec_mode = 1;
3704 return 0;
3705 }
3706 if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
3707 {
3708 vam->exec_mode = 0;
3709 return 0;
3710 }
3711
3712 /*
3713 * In order for the CLI command to work, it
3714 * must be a vector ending in \n, not a C-string ending
3715 * in \n\0.
3716 */
Jakub Grajciar2dbee932020-02-07 11:30:26 +01003717 M2 (CLI_INBAND, mp, vec_len (vam->input->buffer));
3718 vl_api_vec_to_api_string (vam->input->buffer, &mp->cmd);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003719
Jon Loeliger7bc770c2017-01-31 14:03:33 -06003720 S (mp);
Dave Barach59b25652017-09-10 15:04:27 -04003721 W (ret);
3722 /* json responses may or may not include a useful reply... */
3723 if (vec_len (vam->cmd_reply))
Dave Barachcf5e8482017-10-17 11:48:29 -04003724 print (vam->ofp, "%v", (char *) (vam->cmd_reply));
Jon Loeliger56c7b012017-02-01 12:31:41 -06003725 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003726}
3727
Dave Barach59b25652017-09-10 15:04:27 -04003728int
3729exec (vat_main_t * vam)
3730{
3731 return exec_inband (vam);
3732}
3733
Damjan Marion7cd468a2016-12-19 23:05:39 +01003734static int
3735api_create_loopback (vat_main_t * vam)
3736{
3737 unformat_input_t *i = vam->input;
3738 vl_api_create_loopback_t *mp;
Jon Loeligerc83c3b72017-02-23 13:57:35 -06003739 vl_api_create_loopback_instance_t *mp_lbi;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003740 u8 mac_address[6];
3741 u8 mac_set = 0;
Jon Loeligerc83c3b72017-02-23 13:57:35 -06003742 u8 is_specified = 0;
3743 u32 user_instance = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06003744 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003745
Dave Barachb7b92992018-10-17 10:38:51 -04003746 clib_memset (mac_address, 0, sizeof (mac_address));
Damjan Marion7cd468a2016-12-19 23:05:39 +01003747
3748 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3749 {
3750 if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
3751 mac_set = 1;
Jon Loeligerc83c3b72017-02-23 13:57:35 -06003752 if (unformat (i, "instance %d", &user_instance))
3753 is_specified = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003754 else
3755 break;
3756 }
3757
Jon Loeligerc83c3b72017-02-23 13:57:35 -06003758 if (is_specified)
3759 {
3760 M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
3761 mp_lbi->is_specified = is_specified;
3762 if (is_specified)
3763 mp_lbi->user_instance = htonl (user_instance);
3764 if (mac_set)
3765 clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
3766 S (mp_lbi);
3767 }
3768 else
3769 {
3770 /* Construct the API message */
3771 M (CREATE_LOOPBACK, mp);
3772 if (mac_set)
3773 clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
3774 S (mp);
3775 }
Damjan Marion7cd468a2016-12-19 23:05:39 +01003776
Jon Loeliger56c7b012017-02-01 12:31:41 -06003777 W (ret);
3778 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003779}
3780
3781static int
3782api_delete_loopback (vat_main_t * vam)
3783{
3784 unformat_input_t *i = vam->input;
3785 vl_api_delete_loopback_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003786 u32 sw_if_index = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06003787 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003788
3789 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3790 {
3791 if (unformat (i, "sw_if_index %d", &sw_if_index))
3792 ;
3793 else
3794 break;
3795 }
3796
3797 if (sw_if_index == ~0)
3798 {
3799 errmsg ("missing sw_if_index");
3800 return -99;
3801 }
3802
3803 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06003804 M (DELETE_LOOPBACK, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003805 mp->sw_if_index = ntohl (sw_if_index);
3806
Jon Loeliger7bc770c2017-01-31 14:03:33 -06003807 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06003808 W (ret);
3809 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003810}
3811
3812static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01003813api_want_interface_events (vat_main_t * vam)
3814{
3815 unformat_input_t *i = vam->input;
3816 vl_api_want_interface_events_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003817 int enable = -1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06003818 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003819
3820 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3821 {
3822 if (unformat (i, "enable"))
3823 enable = 1;
3824 else if (unformat (i, "disable"))
3825 enable = 0;
3826 else
3827 break;
3828 }
3829
3830 if (enable == -1)
3831 {
3832 errmsg ("missing enable|disable");
3833 return -99;
3834 }
3835
Jon Loeliger8a2aea32017-01-31 13:19:40 -06003836 M (WANT_INTERFACE_EVENTS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003837 mp->enable_disable = enable;
3838
3839 vam->interface_event_display = enable;
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
3846
3847/* Note: non-static, called once to set up the initial intfc table */
3848int
3849api_sw_interface_dump (vat_main_t * vam)
3850{
3851 vl_api_sw_interface_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -06003852 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003853 hash_pair_t *p;
3854 name_sort_t *nses = 0, *ns;
3855 sw_interface_subif_t *sub = NULL;
Jon Loeliger56c7b012017-02-01 12:31:41 -06003856 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003857
3858 /* Toss the old name table */
3859 /* *INDENT-OFF* */
3860 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3861 ({
3862 vec_add2 (nses, ns, 1);
3863 ns->name = (u8 *)(p->key);
3864 ns->value = (u32) p->value[0];
3865 }));
3866 /* *INDENT-ON* */
3867
3868 hash_free (vam->sw_if_index_by_interface_name);
3869
3870 vec_foreach (ns, nses) vec_free (ns->name);
3871
3872 vec_free (nses);
3873
3874 vec_foreach (sub, vam->sw_if_subif_table)
3875 {
3876 vec_free (sub->interface_name);
3877 }
3878 vec_free (vam->sw_if_subif_table);
3879
3880 /* recreate the interface name hash table */
3881 vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
3882
Dave Barachf72212e2018-01-11 10:25:07 -05003883 /*
3884 * Ask for all interface names. Otherwise, the epic catalog of
3885 * name filters becomes ridiculously long, and vat ends up needing
3886 * to be taught about new interface types.
3887 */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06003888 M (SW_INTERFACE_DUMP, mp);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06003889 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003890
3891 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -04003892 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06003893 S (mp_ping);
3894
Jon Loeliger56c7b012017-02-01 12:31:41 -06003895 W (ret);
3896 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003897}
3898
3899static int
3900api_sw_interface_set_flags (vat_main_t * vam)
3901{
3902 unformat_input_t *i = vam->input;
3903 vl_api_sw_interface_set_flags_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003904 u32 sw_if_index;
3905 u8 sw_if_index_set = 0;
Neale Rannsa07bd702017-08-07 07:53:49 -07003906 u8 admin_up = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06003907 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003908
3909 /* Parse args required to build the message */
3910 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3911 {
3912 if (unformat (i, "admin-up"))
3913 admin_up = 1;
3914 else if (unformat (i, "admin-down"))
3915 admin_up = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003916 else
3917 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
3918 sw_if_index_set = 1;
3919 else if (unformat (i, "sw_if_index %d", &sw_if_index))
3920 sw_if_index_set = 1;
3921 else
3922 break;
3923 }
3924
3925 if (sw_if_index_set == 0)
3926 {
3927 errmsg ("missing interface name or sw_if_index");
3928 return -99;
3929 }
3930
3931 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06003932 M (SW_INTERFACE_SET_FLAGS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003933 mp->sw_if_index = ntohl (sw_if_index);
Jakub Grajciar053204a2019-03-18 13:17:53 +01003934 mp->flags = ntohl ((admin_up) ? IF_STATUS_API_FLAG_ADMIN_UP : 0);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003935
3936 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06003937 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003938
3939 /* Wait for a reply, return the good/bad news... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06003940 W (ret);
3941 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003942}
3943
3944static int
Stevenad8015b2017-10-29 22:10:46 -07003945api_sw_interface_set_rx_mode (vat_main_t * vam)
3946{
3947 unformat_input_t *i = vam->input;
3948 vl_api_sw_interface_set_rx_mode_t *mp;
3949 u32 sw_if_index;
3950 u8 sw_if_index_set = 0;
3951 int ret;
3952 u8 queue_id_valid = 0;
3953 u32 queue_id;
Damjan Marioneabd4242020-10-07 20:59:07 +02003954 vnet_hw_if_rx_mode mode = VNET_HW_IF_RX_MODE_UNKNOWN;
Stevenad8015b2017-10-29 22:10:46 -07003955
3956 /* Parse args required to build the message */
3957 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3958 {
3959 if (unformat (i, "queue %d", &queue_id))
3960 queue_id_valid = 1;
3961 else if (unformat (i, "polling"))
Damjan Marioneabd4242020-10-07 20:59:07 +02003962 mode = VNET_HW_IF_RX_MODE_POLLING;
Stevenad8015b2017-10-29 22:10:46 -07003963 else if (unformat (i, "interrupt"))
Damjan Marioneabd4242020-10-07 20:59:07 +02003964 mode = VNET_HW_IF_RX_MODE_INTERRUPT;
Stevenad8015b2017-10-29 22:10:46 -07003965 else if (unformat (i, "adaptive"))
Damjan Marioneabd4242020-10-07 20:59:07 +02003966 mode = VNET_HW_IF_RX_MODE_ADAPTIVE;
Stevenad8015b2017-10-29 22:10:46 -07003967 else
3968 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
3969 sw_if_index_set = 1;
3970 else if (unformat (i, "sw_if_index %d", &sw_if_index))
3971 sw_if_index_set = 1;
3972 else
3973 break;
3974 }
3975
3976 if (sw_if_index_set == 0)
3977 {
3978 errmsg ("missing interface name or sw_if_index");
3979 return -99;
3980 }
Damjan Marioneabd4242020-10-07 20:59:07 +02003981 if (mode == VNET_HW_IF_RX_MODE_UNKNOWN)
Stevenad8015b2017-10-29 22:10:46 -07003982 {
3983 errmsg ("missing rx-mode");
3984 return -99;
3985 }
3986
3987 /* Construct the API message */
3988 M (SW_INTERFACE_SET_RX_MODE, mp);
3989 mp->sw_if_index = ntohl (sw_if_index);
Jakub Grajciar053204a2019-03-18 13:17:53 +01003990 mp->mode = (vl_api_rx_mode_t) mode;
Stevenad8015b2017-10-29 22:10:46 -07003991 mp->queue_id_valid = queue_id_valid;
3992 mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
3993
3994 /* send it... */
3995 S (mp);
3996
3997 /* Wait for a reply, return the good/bad news... */
3998 W (ret);
3999 return ret;
4000}
4001
4002static int
Mohsin Kazmi54f7c512018-08-23 18:28:11 +02004003api_sw_interface_set_rx_placement (vat_main_t * vam)
4004{
4005 unformat_input_t *i = vam->input;
4006 vl_api_sw_interface_set_rx_placement_t *mp;
4007 u32 sw_if_index;
4008 u8 sw_if_index_set = 0;
4009 int ret;
4010 u8 is_main = 0;
4011 u32 queue_id, thread_index;
4012
4013 /* Parse args required to build the message */
4014 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4015 {
4016 if (unformat (i, "queue %d", &queue_id))
4017 ;
4018 else if (unformat (i, "main"))
4019 is_main = 1;
4020 else if (unformat (i, "worker %d", &thread_index))
4021 ;
4022 else
4023 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4024 sw_if_index_set = 1;
4025 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4026 sw_if_index_set = 1;
4027 else
4028 break;
4029 }
4030
4031 if (sw_if_index_set == 0)
4032 {
4033 errmsg ("missing interface name or sw_if_index");
4034 return -99;
4035 }
4036
4037 if (is_main)
4038 thread_index = 0;
4039 /* Construct the API message */
4040 M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
4041 mp->sw_if_index = ntohl (sw_if_index);
4042 mp->worker_id = ntohl (thread_index);
4043 mp->queue_id = ntohl (queue_id);
4044 mp->is_main = is_main;
4045
4046 /* send it... */
4047 S (mp);
4048 /* Wait for a reply, return the good/bad news... */
4049 W (ret);
4050 return ret;
4051}
4052
Mohsin Kazmif0b42f42018-09-10 18:11:00 +02004053static void vl_api_sw_interface_rx_placement_details_t_handler
4054 (vl_api_sw_interface_rx_placement_details_t * mp)
4055{
4056 vat_main_t *vam = &vat_main;
4057 u32 worker_id = ntohl (mp->worker_id);
4058
4059 print (vam->ofp,
4060 "\n%-11d %-11s %-6d %-5d %-9s",
4061 ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
4062 worker_id, ntohl (mp->queue_id),
4063 (mp->mode ==
4064 1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
4065}
4066
4067static void vl_api_sw_interface_rx_placement_details_t_handler_json
4068 (vl_api_sw_interface_rx_placement_details_t * mp)
4069{
4070 vat_main_t *vam = &vat_main;
4071 vat_json_node_t *node = NULL;
4072
4073 if (VAT_JSON_ARRAY != vam->json_tree.type)
4074 {
4075 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4076 vat_json_init_array (&vam->json_tree);
4077 }
4078 node = vat_json_array_add (&vam->json_tree);
4079
4080 vat_json_init_object (node);
4081 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4082 vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
4083 vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
4084 vat_json_object_add_uint (node, "mode", mp->mode);
4085}
4086
4087static int
4088api_sw_interface_rx_placement_dump (vat_main_t * vam)
4089{
4090 unformat_input_t *i = vam->input;
4091 vl_api_sw_interface_rx_placement_dump_t *mp;
4092 vl_api_control_ping_t *mp_ping;
4093 int ret;
4094 u32 sw_if_index;
4095 u8 sw_if_index_set = 0;
4096
4097 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4098 {
4099 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4100 sw_if_index_set++;
4101 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4102 sw_if_index_set++;
4103 else
4104 break;
4105 }
4106
4107 print (vam->ofp,
4108 "\n%-11s %-11s %-6s %-5s %-4s",
4109 "sw_if_index", "main/worker", "thread", "queue", "mode");
4110
4111 /* Dump Interface rx placement */
4112 M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
4113
4114 if (sw_if_index_set)
4115 mp->sw_if_index = htonl (sw_if_index);
4116 else
4117 mp->sw_if_index = ~0;
4118
4119 S (mp);
4120
4121 /* Use a control ping for synchronization */
4122 MPING (CONTROL_PING, mp_ping);
4123 S (mp_ping);
4124
4125 W (ret);
4126 return ret;
4127}
4128
Mohsin Kazmi54f7c512018-08-23 18:28:11 +02004129static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01004130api_sw_interface_clear_stats (vat_main_t * vam)
4131{
4132 unformat_input_t *i = vam->input;
4133 vl_api_sw_interface_clear_stats_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004134 u32 sw_if_index;
4135 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004136 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004137
4138 /* Parse args required to build the message */
4139 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4140 {
4141 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4142 sw_if_index_set = 1;
4143 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4144 sw_if_index_set = 1;
4145 else
4146 break;
4147 }
4148
4149 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004150 M (SW_INTERFACE_CLEAR_STATS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004151
4152 if (sw_if_index_set == 1)
4153 mp->sw_if_index = ntohl (sw_if_index);
4154 else
4155 mp->sw_if_index = ~0;
4156
4157 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004158 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004159
4160 /* Wait for a reply, return the good/bad news... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06004161 W (ret);
4162 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004163}
4164
Damjan Marion7cd468a2016-12-19 23:05:39 +01004165static int
4166api_sw_interface_add_del_address (vat_main_t * vam)
4167{
4168 unformat_input_t *i = vam->input;
4169 vl_api_sw_interface_add_del_address_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004170 u32 sw_if_index;
4171 u8 sw_if_index_set = 0;
4172 u8 is_add = 1, del_all = 0;
4173 u32 address_length = 0;
4174 u8 v4_address_set = 0;
4175 u8 v6_address_set = 0;
4176 ip4_address_t v4address;
4177 ip6_address_t v6address;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004178 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004179
4180 /* Parse args required to build the message */
4181 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4182 {
4183 if (unformat (i, "del-all"))
4184 del_all = 1;
4185 else if (unformat (i, "del"))
4186 is_add = 0;
4187 else
4188 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4189 sw_if_index_set = 1;
4190 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4191 sw_if_index_set = 1;
4192 else if (unformat (i, "%U/%d",
4193 unformat_ip4_address, &v4address, &address_length))
4194 v4_address_set = 1;
4195 else if (unformat (i, "%U/%d",
4196 unformat_ip6_address, &v6address, &address_length))
4197 v6_address_set = 1;
4198 else
4199 break;
4200 }
4201
4202 if (sw_if_index_set == 0)
4203 {
4204 errmsg ("missing interface name or sw_if_index");
4205 return -99;
4206 }
4207 if (v4_address_set && v6_address_set)
4208 {
4209 errmsg ("both v4 and v6 addresses set");
4210 return -99;
4211 }
4212 if (!v4_address_set && !v6_address_set && !del_all)
4213 {
4214 errmsg ("no addresses set");
4215 return -99;
4216 }
4217
4218 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004219 M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004220
4221 mp->sw_if_index = ntohl (sw_if_index);
4222 mp->is_add = is_add;
4223 mp->del_all = del_all;
4224 if (v6_address_set)
4225 {
Jakub Grajciar053204a2019-03-18 13:17:53 +01004226 mp->prefix.address.af = ADDRESS_IP6;
4227 clib_memcpy (mp->prefix.address.un.ip6, &v6address, sizeof (v6address));
Damjan Marion7cd468a2016-12-19 23:05:39 +01004228 }
4229 else
4230 {
Jakub Grajciar053204a2019-03-18 13:17:53 +01004231 mp->prefix.address.af = ADDRESS_IP4;
4232 clib_memcpy (mp->prefix.address.un.ip4, &v4address, sizeof (v4address));
Damjan Marion7cd468a2016-12-19 23:05:39 +01004233 }
Jakub Grajciar053204a2019-03-18 13:17:53 +01004234 mp->prefix.len = address_length;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004235
4236 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004237 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004238
4239 /* Wait for a reply, return good/bad news */
Jon Loeliger56c7b012017-02-01 12:31:41 -06004240 W (ret);
4241 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004242}
4243
4244static int
4245api_sw_interface_set_mpls_enable (vat_main_t * vam)
4246{
4247 unformat_input_t *i = vam->input;
4248 vl_api_sw_interface_set_mpls_enable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004249 u32 sw_if_index;
4250 u8 sw_if_index_set = 0;
4251 u8 enable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004252 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004253
4254 /* Parse args required to build the message */
4255 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4256 {
4257 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4258 sw_if_index_set = 1;
4259 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4260 sw_if_index_set = 1;
4261 else if (unformat (i, "disable"))
4262 enable = 0;
4263 else if (unformat (i, "dis"))
4264 enable = 0;
4265 else
4266 break;
4267 }
4268
4269 if (sw_if_index_set == 0)
4270 {
4271 errmsg ("missing interface name or sw_if_index");
4272 return -99;
4273 }
4274
4275 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004276 M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004277
4278 mp->sw_if_index = ntohl (sw_if_index);
4279 mp->enable = enable;
4280
4281 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004282 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004283
4284 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06004285 W (ret);
4286 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004287}
4288
4289static int
4290api_sw_interface_set_table (vat_main_t * vam)
4291{
4292 unformat_input_t *i = vam->input;
4293 vl_api_sw_interface_set_table_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004294 u32 sw_if_index, vrf_id = 0;
4295 u8 sw_if_index_set = 0;
4296 u8 is_ipv6 = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004297 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004298
4299 /* Parse args required to build the message */
4300 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4301 {
4302 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4303 sw_if_index_set = 1;
4304 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4305 sw_if_index_set = 1;
4306 else if (unformat (i, "vrf %d", &vrf_id))
4307 ;
4308 else if (unformat (i, "ipv6"))
4309 is_ipv6 = 1;
4310 else
4311 break;
4312 }
4313
4314 if (sw_if_index_set == 0)
4315 {
4316 errmsg ("missing interface name or sw_if_index");
4317 return -99;
4318 }
4319
4320 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004321 M (SW_INTERFACE_SET_TABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004322
4323 mp->sw_if_index = ntohl (sw_if_index);
4324 mp->is_ipv6 = is_ipv6;
4325 mp->vrf_id = ntohl (vrf_id);
4326
4327 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004328 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004329
4330 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06004331 W (ret);
4332 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004333}
4334
4335static void vl_api_sw_interface_get_table_reply_t_handler
4336 (vl_api_sw_interface_get_table_reply_t * mp)
4337{
4338 vat_main_t *vam = &vat_main;
4339
4340 print (vam->ofp, "%d", ntohl (mp->vrf_id));
4341
4342 vam->retval = ntohl (mp->retval);
4343 vam->result_ready = 1;
4344
4345}
4346
4347static void vl_api_sw_interface_get_table_reply_t_handler_json
4348 (vl_api_sw_interface_get_table_reply_t * mp)
4349{
4350 vat_main_t *vam = &vat_main;
4351 vat_json_node_t node;
4352
4353 vat_json_init_object (&node);
4354 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4355 vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
4356
4357 vat_json_print (vam->ofp, &node);
4358 vat_json_free (&node);
4359
4360 vam->retval = ntohl (mp->retval);
4361 vam->result_ready = 1;
4362}
4363
4364static int
4365api_sw_interface_get_table (vat_main_t * vam)
4366{
4367 unformat_input_t *i = vam->input;
4368 vl_api_sw_interface_get_table_t *mp;
4369 u32 sw_if_index;
4370 u8 sw_if_index_set = 0;
4371 u8 is_ipv6 = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004372 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004373
4374 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4375 {
4376 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4377 sw_if_index_set = 1;
4378 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4379 sw_if_index_set = 1;
4380 else if (unformat (i, "ipv6"))
4381 is_ipv6 = 1;
4382 else
4383 break;
4384 }
4385
4386 if (sw_if_index_set == 0)
4387 {
4388 errmsg ("missing interface name or sw_if_index");
4389 return -99;
4390 }
4391
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004392 M (SW_INTERFACE_GET_TABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004393 mp->sw_if_index = htonl (sw_if_index);
4394 mp->is_ipv6 = is_ipv6;
4395
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004396 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06004397 W (ret);
4398 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004399}
4400
4401static int
4402api_sw_interface_set_vpath (vat_main_t * vam)
4403{
4404 unformat_input_t *i = vam->input;
4405 vl_api_sw_interface_set_vpath_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004406 u32 sw_if_index = 0;
4407 u8 sw_if_index_set = 0;
4408 u8 is_enable = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004409 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004410
4411 /* Parse args required to build the message */
4412 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4413 {
4414 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4415 sw_if_index_set = 1;
4416 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4417 sw_if_index_set = 1;
4418 else if (unformat (i, "enable"))
4419 is_enable = 1;
4420 else if (unformat (i, "disable"))
4421 is_enable = 0;
4422 else
4423 break;
4424 }
4425
4426 if (sw_if_index_set == 0)
4427 {
4428 errmsg ("missing interface name or sw_if_index");
4429 return -99;
4430 }
4431
4432 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004433 M (SW_INTERFACE_SET_VPATH, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004434
4435 mp->sw_if_index = ntohl (sw_if_index);
4436 mp->enable = is_enable;
4437
4438 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004439 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004440
4441 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06004442 W (ret);
4443 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004444}
4445
4446static int
4447api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
4448{
4449 unformat_input_t *i = vam->input;
4450 vl_api_sw_interface_set_vxlan_bypass_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004451 u32 sw_if_index = 0;
4452 u8 sw_if_index_set = 0;
John Lo2b81eb82017-01-30 13:12:10 -05004453 u8 is_enable = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004454 u8 is_ipv6 = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004455 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004456
4457 /* Parse args required to build the message */
4458 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4459 {
4460 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4461 sw_if_index_set = 1;
4462 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4463 sw_if_index_set = 1;
4464 else if (unformat (i, "enable"))
4465 is_enable = 1;
4466 else if (unformat (i, "disable"))
4467 is_enable = 0;
4468 else if (unformat (i, "ip4"))
4469 is_ipv6 = 0;
4470 else if (unformat (i, "ip6"))
4471 is_ipv6 = 1;
4472 else
4473 break;
4474 }
4475
4476 if (sw_if_index_set == 0)
4477 {
4478 errmsg ("missing interface name or sw_if_index");
4479 return -99;
4480 }
4481
4482 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004483 M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004484
4485 mp->sw_if_index = ntohl (sw_if_index);
4486 mp->enable = is_enable;
4487 mp->is_ipv6 = is_ipv6;
4488
4489 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004490 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004491
4492 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06004493 W (ret);
4494 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004495}
4496
Marco Varleseb598f1d2017-09-19 14:25:28 +02004497static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01004498api_sw_interface_set_l2_xconnect (vat_main_t * vam)
4499{
4500 unformat_input_t *i = vam->input;
4501 vl_api_sw_interface_set_l2_xconnect_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004502 u32 rx_sw_if_index;
4503 u8 rx_sw_if_index_set = 0;
4504 u32 tx_sw_if_index;
4505 u8 tx_sw_if_index_set = 0;
4506 u8 enable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004507 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004508
4509 /* Parse args required to build the message */
4510 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4511 {
4512 if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
4513 rx_sw_if_index_set = 1;
4514 else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
4515 tx_sw_if_index_set = 1;
4516 else if (unformat (i, "rx"))
4517 {
4518 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4519 {
4520 if (unformat (i, "%U", api_unformat_sw_if_index, vam,
4521 &rx_sw_if_index))
4522 rx_sw_if_index_set = 1;
4523 }
4524 else
4525 break;
4526 }
4527 else if (unformat (i, "tx"))
4528 {
4529 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4530 {
4531 if (unformat (i, "%U", api_unformat_sw_if_index, vam,
4532 &tx_sw_if_index))
4533 tx_sw_if_index_set = 1;
4534 }
4535 else
4536 break;
4537 }
4538 else if (unformat (i, "enable"))
4539 enable = 1;
4540 else if (unformat (i, "disable"))
4541 enable = 0;
4542 else
4543 break;
4544 }
4545
4546 if (rx_sw_if_index_set == 0)
4547 {
4548 errmsg ("missing rx interface name or rx_sw_if_index");
4549 return -99;
4550 }
4551
4552 if (enable && (tx_sw_if_index_set == 0))
4553 {
4554 errmsg ("missing tx interface name or tx_sw_if_index");
4555 return -99;
4556 }
4557
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004558 M (SW_INTERFACE_SET_L2_XCONNECT, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004559
4560 mp->rx_sw_if_index = ntohl (rx_sw_if_index);
4561 mp->tx_sw_if_index = ntohl (tx_sw_if_index);
4562 mp->enable = enable;
4563
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004564 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06004565 W (ret);
4566 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004567}
4568
4569static int
4570api_sw_interface_set_l2_bridge (vat_main_t * vam)
4571{
4572 unformat_input_t *i = vam->input;
4573 vl_api_sw_interface_set_l2_bridge_t *mp;
Neale Rannsb4743802018-09-05 09:13:57 -07004574 vl_api_l2_port_type_t port_type;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004575 u32 rx_sw_if_index;
4576 u8 rx_sw_if_index_set = 0;
4577 u32 bd_id;
4578 u8 bd_id_set = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004579 u32 shg = 0;
4580 u8 enable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004581 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004582
Neale Rannsb4743802018-09-05 09:13:57 -07004583 port_type = L2_API_PORT_TYPE_NORMAL;
4584
Damjan Marion7cd468a2016-12-19 23:05:39 +01004585 /* Parse args required to build the message */
4586 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4587 {
4588 if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
4589 rx_sw_if_index_set = 1;
4590 else if (unformat (i, "bd_id %d", &bd_id))
4591 bd_id_set = 1;
4592 else
4593 if (unformat
4594 (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
4595 rx_sw_if_index_set = 1;
4596 else if (unformat (i, "shg %d", &shg))
4597 ;
4598 else if (unformat (i, "bvi"))
Neale Rannsb4743802018-09-05 09:13:57 -07004599 port_type = L2_API_PORT_TYPE_BVI;
4600 else if (unformat (i, "uu-fwd"))
4601 port_type = L2_API_PORT_TYPE_UU_FWD;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004602 else if (unformat (i, "enable"))
4603 enable = 1;
4604 else if (unformat (i, "disable"))
4605 enable = 0;
4606 else
4607 break;
4608 }
4609
4610 if (rx_sw_if_index_set == 0)
4611 {
4612 errmsg ("missing rx interface name or sw_if_index");
4613 return -99;
4614 }
4615
4616 if (enable && (bd_id_set == 0))
4617 {
4618 errmsg ("missing bridge domain");
4619 return -99;
4620 }
4621
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004622 M (SW_INTERFACE_SET_L2_BRIDGE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004623
4624 mp->rx_sw_if_index = ntohl (rx_sw_if_index);
4625 mp->bd_id = ntohl (bd_id);
4626 mp->shg = (u8) shg;
Neale Rannsb4743802018-09-05 09:13:57 -07004627 mp->port_type = ntohl (port_type);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004628 mp->enable = enable;
4629
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004630 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06004631 W (ret);
4632 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004633}
4634
4635static int
4636api_bridge_domain_dump (vat_main_t * vam)
4637{
4638 unformat_input_t *i = vam->input;
4639 vl_api_bridge_domain_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -06004640 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004641 u32 bd_id = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004642 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004643
4644 /* Parse args required to build the message */
4645 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4646 {
4647 if (unformat (i, "bd_id %d", &bd_id))
4648 ;
4649 else
4650 break;
4651 }
4652
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004653 M (BRIDGE_DOMAIN_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004654 mp->bd_id = ntohl (bd_id);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004655 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004656
4657 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -04004658 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06004659 S (mp_ping);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004660
Jon Loeliger56c7b012017-02-01 12:31:41 -06004661 W (ret);
4662 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004663}
4664
4665static int
4666api_bridge_domain_add_del (vat_main_t * vam)
4667{
4668 unformat_input_t *i = vam->input;
4669 vl_api_bridge_domain_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004670 u32 bd_id = ~0;
4671 u8 is_add = 1;
4672 u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
Jerome Tollet50570ec2017-09-14 12:53:56 +01004673 u8 *bd_tag = NULL;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004674 u32 mac_age = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004675 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004676
4677 /* Parse args required to build the message */
4678 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4679 {
4680 if (unformat (i, "bd_id %d", &bd_id))
4681 ;
4682 else if (unformat (i, "flood %d", &flood))
4683 ;
4684 else if (unformat (i, "uu-flood %d", &uu_flood))
4685 ;
4686 else if (unformat (i, "forward %d", &forward))
4687 ;
4688 else if (unformat (i, "learn %d", &learn))
4689 ;
4690 else if (unformat (i, "arp-term %d", &arp_term))
4691 ;
4692 else if (unformat (i, "mac-age %d", &mac_age))
4693 ;
Jerome Tollet50570ec2017-09-14 12:53:56 +01004694 else if (unformat (i, "bd-tag %s", &bd_tag))
4695 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004696 else if (unformat (i, "del"))
4697 {
4698 is_add = 0;
4699 flood = uu_flood = forward = learn = 0;
4700 }
4701 else
4702 break;
4703 }
4704
4705 if (bd_id == ~0)
4706 {
4707 errmsg ("missing bridge domain");
Jerome Tollet50570ec2017-09-14 12:53:56 +01004708 ret = -99;
4709 goto done;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004710 }
4711
4712 if (mac_age > 255)
4713 {
4714 errmsg ("mac age must be less than 256 ");
Jerome Tollet50570ec2017-09-14 12:53:56 +01004715 ret = -99;
4716 goto done;
4717 }
4718
John Lo70bfcaf2017-11-14 13:19:26 -05004719 if ((bd_tag) && (vec_len (bd_tag) > 63))
Jerome Tollet50570ec2017-09-14 12:53:56 +01004720 {
4721 errmsg ("bd-tag cannot be longer than 63");
4722 ret = -99;
4723 goto done;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004724 }
4725
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004726 M (BRIDGE_DOMAIN_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004727
4728 mp->bd_id = ntohl (bd_id);
4729 mp->flood = flood;
4730 mp->uu_flood = uu_flood;
4731 mp->forward = forward;
4732 mp->learn = learn;
4733 mp->arp_term = arp_term;
4734 mp->is_add = is_add;
4735 mp->mac_age = (u8) mac_age;
Jerome Tollet50570ec2017-09-14 12:53:56 +01004736 if (bd_tag)
John Lo70bfcaf2017-11-14 13:19:26 -05004737 {
4738 clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
4739 mp->bd_tag[vec_len (bd_tag)] = 0;
4740 }
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004741 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06004742 W (ret);
Jerome Tollet50570ec2017-09-14 12:53:56 +01004743
4744done:
4745 vec_free (bd_tag);
Jon Loeliger56c7b012017-02-01 12:31:41 -06004746 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004747}
4748
4749static int
Eyal Barif24991c2017-04-05 05:33:21 +03004750api_l2fib_flush_bd (vat_main_t * vam)
4751{
4752 unformat_input_t *i = vam->input;
4753 vl_api_l2fib_flush_bd_t *mp;
4754 u32 bd_id = ~0;
4755 int ret;
4756
4757 /* Parse args required to build the message */
4758 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4759 {
4760 if (unformat (i, "bd_id %d", &bd_id));
4761 else
4762 break;
4763 }
4764
4765 if (bd_id == ~0)
4766 {
4767 errmsg ("missing bridge domain");
4768 return -99;
4769 }
4770
4771 M (L2FIB_FLUSH_BD, mp);
4772
4773 mp->bd_id = htonl (bd_id);
4774
4775 S (mp);
4776 W (ret);
4777 return ret;
4778}
4779
4780static int
4781api_l2fib_flush_int (vat_main_t * vam)
4782{
4783 unformat_input_t *i = vam->input;
4784 vl_api_l2fib_flush_int_t *mp;
4785 u32 sw_if_index = ~0;
4786 int ret;
4787
4788 /* Parse args required to build the message */
4789 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4790 {
4791 if (unformat (i, "sw_if_index %d", &sw_if_index));
4792 else
4793 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
4794 else
4795 break;
4796 }
4797
4798 if (sw_if_index == ~0)
4799 {
4800 errmsg ("missing interface name or sw_if_index");
4801 return -99;
4802 }
4803
4804 M (L2FIB_FLUSH_INT, mp);
4805
4806 mp->sw_if_index = ntohl (sw_if_index);
4807
4808 S (mp);
4809 W (ret);
4810 return ret;
4811}
4812
4813static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01004814api_l2fib_add_del (vat_main_t * vam)
4815{
4816 unformat_input_t *i = vam->input;
4817 vl_api_l2fib_add_del_t *mp;
4818 f64 timeout;
Mohsin Kazmi57938f62017-10-27 21:28:07 +02004819 u8 mac[6] = { 0 };
Damjan Marion7cd468a2016-12-19 23:05:39 +01004820 u8 mac_set = 0;
4821 u32 bd_id;
4822 u8 bd_id_set = 0;
John Lo7dbd7262018-05-31 10:25:18 -04004823 u32 sw_if_index = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004824 u8 sw_if_index_set = 0;
4825 u8 is_add = 1;
4826 u8 static_mac = 0;
4827 u8 filter_mac = 0;
4828 u8 bvi_mac = 0;
4829 int count = 1;
4830 f64 before = 0;
4831 int j;
4832
4833 /* Parse args required to build the message */
4834 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4835 {
Mohsin Kazmi57938f62017-10-27 21:28:07 +02004836 if (unformat (i, "mac %U", unformat_ethernet_address, mac))
Damjan Marion7cd468a2016-12-19 23:05:39 +01004837 mac_set = 1;
4838 else if (unformat (i, "bd_id %d", &bd_id))
4839 bd_id_set = 1;
4840 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4841 sw_if_index_set = 1;
4842 else if (unformat (i, "sw_if"))
4843 {
4844 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4845 {
4846 if (unformat
4847 (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4848 sw_if_index_set = 1;
4849 }
4850 else
4851 break;
4852 }
4853 else if (unformat (i, "static"))
4854 static_mac = 1;
4855 else if (unformat (i, "filter"))
4856 {
4857 filter_mac = 1;
4858 static_mac = 1;
4859 }
4860 else if (unformat (i, "bvi"))
4861 {
4862 bvi_mac = 1;
4863 static_mac = 1;
4864 }
4865 else if (unformat (i, "del"))
4866 is_add = 0;
4867 else if (unformat (i, "count %d", &count))
4868 ;
4869 else
4870 break;
4871 }
4872
4873 if (mac_set == 0)
4874 {
4875 errmsg ("missing mac address");
4876 return -99;
4877 }
4878
4879 if (bd_id_set == 0)
4880 {
4881 errmsg ("missing bridge domain");
4882 return -99;
4883 }
4884
4885 if (is_add && sw_if_index_set == 0 && filter_mac == 0)
4886 {
4887 errmsg ("missing interface name or sw_if_index");
4888 return -99;
4889 }
4890
4891 if (count > 1)
4892 {
4893 /* Turn on async mode */
4894 vam->async_mode = 1;
4895 vam->async_errors = 0;
4896 before = vat_time_now (vam);
4897 }
4898
4899 for (j = 0; j < count; j++)
4900 {
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004901 M (L2FIB_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004902
Mohsin Kazmi57938f62017-10-27 21:28:07 +02004903 clib_memcpy (mp->mac, mac, 6);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004904 mp->bd_id = ntohl (bd_id);
4905 mp->is_add = is_add;
John Lo7dbd7262018-05-31 10:25:18 -04004906 mp->sw_if_index = ntohl (sw_if_index);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004907
4908 if (is_add)
4909 {
Damjan Marion7cd468a2016-12-19 23:05:39 +01004910 mp->static_mac = static_mac;
4911 mp->filter_mac = filter_mac;
4912 mp->bvi_mac = bvi_mac;
4913 }
Mohsin Kazmi57938f62017-10-27 21:28:07 +02004914 increment_mac_address (mac);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004915 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004916 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004917 }
4918
4919 if (count > 1)
4920 {
Jon Loeliger2d23eca2017-02-01 13:09:58 -06004921 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004922 f64 after;
4923
4924 /* Shut off async mode */
4925 vam->async_mode = 0;
4926
Dave Barach59b25652017-09-10 15:04:27 -04004927 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06004928 S (mp_ping);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004929
4930 timeout = vat_time_now (vam) + 1.0;
4931 while (vat_time_now (vam) < timeout)
4932 if (vam->result_ready == 1)
4933 goto out;
4934 vam->retval = -99;
4935
4936 out:
4937 if (vam->retval == -99)
4938 errmsg ("timeout");
4939
4940 if (vam->async_errors > 0)
4941 {
4942 errmsg ("%d asynchronous errors", vam->async_errors);
4943 vam->retval = -98;
4944 }
4945 vam->async_errors = 0;
4946 after = vat_time_now (vam);
4947
4948 print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
4949 count, after - before, count / (after - before));
4950 }
4951 else
4952 {
Jon Loeliger56c7b012017-02-01 12:31:41 -06004953 int ret;
4954
Damjan Marion7cd468a2016-12-19 23:05:39 +01004955 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06004956 W (ret);
4957 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004958 }
4959 /* Return the good/bad news */
4960 return (vam->retval);
4961}
4962
4963static int
Eyal Barifead6702017-04-04 04:46:32 +03004964api_bridge_domain_set_mac_age (vat_main_t * vam)
4965{
4966 unformat_input_t *i = vam->input;
4967 vl_api_bridge_domain_set_mac_age_t *mp;
4968 u32 bd_id = ~0;
4969 u32 mac_age = 0;
4970 int ret;
4971
4972 /* Parse args required to build the message */
4973 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4974 {
4975 if (unformat (i, "bd_id %d", &bd_id));
4976 else if (unformat (i, "mac-age %d", &mac_age));
4977 else
4978 break;
4979 }
4980
4981 if (bd_id == ~0)
4982 {
4983 errmsg ("missing bridge domain");
4984 return -99;
4985 }
4986
4987 if (mac_age > 255)
4988 {
4989 errmsg ("mac age must be less than 256 ");
4990 return -99;
4991 }
4992
4993 M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
4994
4995 mp->bd_id = htonl (bd_id);
4996 mp->mac_age = (u8) mac_age;
4997
4998 S (mp);
4999 W (ret);
5000 return ret;
5001}
5002
5003static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01005004api_l2_flags (vat_main_t * vam)
5005{
5006 unformat_input_t *i = vam->input;
5007 vl_api_l2_flags_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005008 u32 sw_if_index;
John Lo8d00fff2017-08-03 00:35:36 -04005009 u32 flags = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005010 u8 sw_if_index_set = 0;
John Lo8d00fff2017-08-03 00:35:36 -04005011 u8 is_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005012 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005013
5014 /* Parse args required to build the message */
5015 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5016 {
5017 if (unformat (i, "sw_if_index %d", &sw_if_index))
5018 sw_if_index_set = 1;
5019 else if (unformat (i, "sw_if"))
5020 {
5021 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5022 {
5023 if (unformat
5024 (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5025 sw_if_index_set = 1;
5026 }
5027 else
5028 break;
5029 }
5030 else if (unformat (i, "learn"))
John Lo8d00fff2017-08-03 00:35:36 -04005031 flags |= L2_LEARN;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005032 else if (unformat (i, "forward"))
John Lo8d00fff2017-08-03 00:35:36 -04005033 flags |= L2_FWD;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005034 else if (unformat (i, "flood"))
John Lo8d00fff2017-08-03 00:35:36 -04005035 flags |= L2_FLOOD;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005036 else if (unformat (i, "uu-flood"))
John Lo8d00fff2017-08-03 00:35:36 -04005037 flags |= L2_UU_FLOOD;
5038 else if (unformat (i, "arp-term"))
5039 flags |= L2_ARP_TERM;
5040 else if (unformat (i, "off"))
5041 is_set = 0;
5042 else if (unformat (i, "disable"))
5043 is_set = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005044 else
5045 break;
5046 }
5047
5048 if (sw_if_index_set == 0)
5049 {
5050 errmsg ("missing interface name or sw_if_index");
5051 return -99;
5052 }
5053
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005054 M (L2_FLAGS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005055
5056 mp->sw_if_index = ntohl (sw_if_index);
John Lo8d00fff2017-08-03 00:35:36 -04005057 mp->feature_bitmap = ntohl (flags);
5058 mp->is_set = is_set;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005059
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005060 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06005061 W (ret);
5062 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005063}
5064
5065static int
5066api_bridge_flags (vat_main_t * vam)
5067{
5068 unformat_input_t *i = vam->input;
5069 vl_api_bridge_flags_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005070 u32 bd_id;
5071 u8 bd_id_set = 0;
5072 u8 is_set = 1;
Neale Rannsb4743802018-09-05 09:13:57 -07005073 bd_flags_t flags = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005074 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005075
5076 /* Parse args required to build the message */
5077 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5078 {
5079 if (unformat (i, "bd_id %d", &bd_id))
5080 bd_id_set = 1;
5081 else if (unformat (i, "learn"))
Neale Rannsb4743802018-09-05 09:13:57 -07005082 flags |= BRIDGE_API_FLAG_LEARN;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005083 else if (unformat (i, "forward"))
Neale Rannsb4743802018-09-05 09:13:57 -07005084 flags |= BRIDGE_API_FLAG_FWD;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005085 else if (unformat (i, "flood"))
Neale Rannsb4743802018-09-05 09:13:57 -07005086 flags |= BRIDGE_API_FLAG_FLOOD;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005087 else if (unformat (i, "uu-flood"))
Neale Rannsb4743802018-09-05 09:13:57 -07005088 flags |= BRIDGE_API_FLAG_UU_FLOOD;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005089 else if (unformat (i, "arp-term"))
Neale Rannsb4743802018-09-05 09:13:57 -07005090 flags |= BRIDGE_API_FLAG_ARP_TERM;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005091 else if (unformat (i, "off"))
5092 is_set = 0;
5093 else if (unformat (i, "disable"))
5094 is_set = 0;
5095 else
5096 break;
5097 }
5098
5099 if (bd_id_set == 0)
5100 {
5101 errmsg ("missing bridge domain");
5102 return -99;
5103 }
5104
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005105 M (BRIDGE_FLAGS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005106
5107 mp->bd_id = ntohl (bd_id);
Neale Rannsb4743802018-09-05 09:13:57 -07005108 mp->flags = ntohl (flags);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005109 mp->is_set = is_set;
5110
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005111 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06005112 W (ret);
5113 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005114}
5115
5116static int
5117api_bd_ip_mac_add_del (vat_main_t * vam)
5118{
Neale Ranns4d5b9172018-10-24 02:57:49 -07005119 vl_api_address_t ip = VL_API_ZERO_ADDRESS;
Ole Troan8006c6a2018-12-17 12:02:26 +01005120 vl_api_mac_address_t mac = { 0 };
Damjan Marion7cd468a2016-12-19 23:05:39 +01005121 unformat_input_t *i = vam->input;
5122 vl_api_bd_ip_mac_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005123 u32 bd_id;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005124 u8 is_add = 1;
5125 u8 bd_id_set = 0;
5126 u8 ip_set = 0;
5127 u8 mac_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005128 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005129
5130
5131 /* Parse args required to build the message */
5132 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5133 {
5134 if (unformat (i, "bd_id %d", &bd_id))
5135 {
5136 bd_id_set++;
5137 }
Neale Ranns4d5b9172018-10-24 02:57:49 -07005138 else if (unformat (i, "%U", unformat_vl_api_address, &ip))
Damjan Marion7cd468a2016-12-19 23:05:39 +01005139 {
5140 ip_set++;
5141 }
Neale Ranns4d5b9172018-10-24 02:57:49 -07005142 else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
Damjan Marion7cd468a2016-12-19 23:05:39 +01005143 {
5144 mac_set++;
5145 }
5146 else if (unformat (i, "del"))
5147 is_add = 0;
5148 else
5149 break;
5150 }
5151
5152 if (bd_id_set == 0)
5153 {
5154 errmsg ("missing bridge domain");
5155 return -99;
5156 }
5157 else if (ip_set == 0)
5158 {
5159 errmsg ("missing IP address");
5160 return -99;
5161 }
5162 else if (mac_set == 0)
5163 {
5164 errmsg ("missing MAC address");
5165 return -99;
5166 }
5167
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005168 M (BD_IP_MAC_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005169
Neale Rannsbc764c82019-06-19 07:07:13 -07005170 mp->entry.bd_id = ntohl (bd_id);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005171 mp->is_add = is_add;
Neale Ranns4d5b9172018-10-24 02:57:49 -07005172
Neale Rannsbc764c82019-06-19 07:07:13 -07005173 clib_memcpy (&mp->entry.ip, &ip, sizeof (ip));
5174 clib_memcpy (&mp->entry.mac, &mac, sizeof (mac));
Neale Ranns4d5b9172018-10-24 02:57:49 -07005175
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005176 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06005177 W (ret);
5178 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005179}
5180
John Loe26c81f2019-01-07 15:16:33 -05005181static int
5182api_bd_ip_mac_flush (vat_main_t * vam)
5183{
5184 unformat_input_t *i = vam->input;
5185 vl_api_bd_ip_mac_flush_t *mp;
5186 u32 bd_id;
5187 u8 bd_id_set = 0;
5188 int ret;
5189
5190 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5191 {
5192 if (unformat (i, "bd_id %d", &bd_id))
5193 {
5194 bd_id_set++;
5195 }
5196 else
5197 break;
5198 }
5199
5200 if (bd_id_set == 0)
5201 {
5202 errmsg ("missing bridge domain");
5203 return -99;
5204 }
5205
5206 M (BD_IP_MAC_FLUSH, mp);
5207
5208 mp->bd_id = ntohl (bd_id);
5209
5210 S (mp);
5211 W (ret);
5212 return ret;
5213}
5214
Mohsin Kazmi5d82d2f2018-08-13 19:17:54 +02005215static void vl_api_bd_ip_mac_details_t_handler
5216 (vl_api_bd_ip_mac_details_t * mp)
5217{
5218 vat_main_t *vam = &vat_main;
Mohsin Kazmi5d82d2f2018-08-13 19:17:54 +02005219
5220 print (vam->ofp,
Neale Rannsbc764c82019-06-19 07:07:13 -07005221 "\n%-5d %U %U",
5222 ntohl (mp->entry.bd_id),
5223 format_vl_api_mac_address, mp->entry.mac,
5224 format_vl_api_address, &mp->entry.ip);
Mohsin Kazmi5d82d2f2018-08-13 19:17:54 +02005225}
5226
5227static void vl_api_bd_ip_mac_details_t_handler_json
5228 (vl_api_bd_ip_mac_details_t * mp)
5229{
5230 vat_main_t *vam = &vat_main;
5231 vat_json_node_t *node = NULL;
5232
5233 if (VAT_JSON_ARRAY != vam->json_tree.type)
5234 {
5235 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5236 vat_json_init_array (&vam->json_tree);
5237 }
5238 node = vat_json_array_add (&vam->json_tree);
5239
5240 vat_json_init_object (node);
Neale Rannsbc764c82019-06-19 07:07:13 -07005241 vat_json_object_add_uint (node, "bd_id", ntohl (mp->entry.bd_id));
Mohsin Kazmi5d82d2f2018-08-13 19:17:54 +02005242 vat_json_object_add_string_copy (node, "mac_address",
Neale Rannsbc764c82019-06-19 07:07:13 -07005243 format (0, "%U", format_vl_api_mac_address,
5244 &mp->entry.mac));
Mohsin Kazmi5d82d2f2018-08-13 19:17:54 +02005245 u8 *ip = 0;
5246
Neale Rannsbc764c82019-06-19 07:07:13 -07005247 ip = format (0, "%U", format_vl_api_address, &mp->entry.ip);
Mohsin Kazmi5d82d2f2018-08-13 19:17:54 +02005248 vat_json_object_add_string_copy (node, "ip_address", ip);
5249 vec_free (ip);
5250}
5251
5252static int
5253api_bd_ip_mac_dump (vat_main_t * vam)
5254{
5255 unformat_input_t *i = vam->input;
5256 vl_api_bd_ip_mac_dump_t *mp;
5257 vl_api_control_ping_t *mp_ping;
5258 int ret;
5259 u32 bd_id;
5260 u8 bd_id_set = 0;
5261
5262 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5263 {
5264 if (unformat (i, "bd_id %d", &bd_id))
5265 {
5266 bd_id_set++;
5267 }
5268 else
5269 break;
5270 }
5271
5272 print (vam->ofp,
5273 "\n%-5s %-7s %-20s %-30s",
5274 "bd_id", "is_ipv6", "mac_address", "ip_address");
5275
5276 /* Dump Bridge Domain Ip to Mac entries */
5277 M (BD_IP_MAC_DUMP, mp);
5278
5279 if (bd_id_set)
5280 mp->bd_id = htonl (bd_id);
5281 else
5282 mp->bd_id = ~0;
5283
5284 S (mp);
5285
5286 /* Use a control ping for synchronization */
5287 MPING (CONTROL_PING, mp_ping);
5288 S (mp_ping);
5289
5290 W (ret);
5291 return ret;
5292}
5293
Damjan Marion7cd468a2016-12-19 23:05:39 +01005294static int
Damjan Marion8389fb92017-10-13 18:29:53 +02005295api_tap_create_v2 (vat_main_t * vam)
5296{
5297 unformat_input_t *i = vam->input;
5298 vl_api_tap_create_v2_t *mp;
5299 u8 mac_address[6];
5300 u8 random_mac = 1;
Damjan Marion2df39092017-12-04 20:03:37 +01005301 u32 id = ~0;
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005302 u32 num_rx_queues = 0;
Damjan Marion2df39092017-12-04 20:03:37 +01005303 u8 *host_if_name = 0;
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005304 u8 host_if_name_set = 0;
Damjan Marion2df39092017-12-04 20:03:37 +01005305 u8 *host_ns = 0;
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005306 u8 host_ns_set = 0;
Damjan Marion2df39092017-12-04 20:03:37 +01005307 u8 host_mac_addr[6];
5308 u8 host_mac_addr_set = 0;
Damjan Marion91c6ef72017-12-01 13:34:24 +01005309 u8 *host_bridge = 0;
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005310 u8 host_bridge_set = 0;
5311 u8 host_ip4_prefix_set = 0;
5312 u8 host_ip6_prefix_set = 0;
Damjan Marion91c6ef72017-12-01 13:34:24 +01005313 ip4_address_t host_ip4_addr;
Damjan Marion7866c452018-01-18 13:35:11 +01005314 ip4_address_t host_ip4_gw;
5315 u8 host_ip4_gw_set = 0;
Damjan Marion91c6ef72017-12-01 13:34:24 +01005316 u32 host_ip4_prefix_len = 0;
5317 ip6_address_t host_ip6_addr;
Damjan Marion7866c452018-01-18 13:35:11 +01005318 ip6_address_t host_ip6_gw;
5319 u8 host_ip6_gw_set = 0;
Damjan Marion91c6ef72017-12-01 13:34:24 +01005320 u32 host_ip6_prefix_len = 0;
Mohsin Kazmi97d54ed2019-06-10 11:20:15 +02005321 u32 host_mtu_size = 0;
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005322 u8 host_mtu_set = 0;
Mohsin Kazmi97d54ed2019-06-10 11:20:15 +02005323 u32 tap_flags = 0;
Damjan Marion8389fb92017-10-13 18:29:53 +02005324 int ret;
Steven9e635692018-03-01 09:36:01 -08005325 u32 rx_ring_sz = 0, tx_ring_sz = 0;
Damjan Marion8389fb92017-10-13 18:29:53 +02005326
Dave Barachb7b92992018-10-17 10:38:51 -04005327 clib_memset (mac_address, 0, sizeof (mac_address));
Damjan Marion8389fb92017-10-13 18:29:53 +02005328
5329 /* Parse args required to build the message */
5330 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5331 {
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005332 if (unformat (i, "id %u", &id))
Damjan Marion91c6ef72017-12-01 13:34:24 +01005333 ;
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005334 else
5335 if (unformat
5336 (i, "hw-addr %U", unformat_ethernet_address, mac_address))
5337 random_mac = 0;
Damjan Marion2df39092017-12-04 20:03:37 +01005338 else if (unformat (i, "host-if-name %s", &host_if_name))
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005339 host_if_name_set = 1;
5340 else if (unformat (i, "num-rx-queues %u", &num_rx_queues))
Damjan Marion91c6ef72017-12-01 13:34:24 +01005341 ;
Damjan Marion2df39092017-12-04 20:03:37 +01005342 else if (unformat (i, "host-ns %s", &host_ns))
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005343 host_ns_set = 1;
Damjan Marion2df39092017-12-04 20:03:37 +01005344 else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
5345 host_mac_addr))
5346 host_mac_addr_set = 1;
Damjan Marion91c6ef72017-12-01 13:34:24 +01005347 else if (unformat (i, "host-bridge %s", &host_bridge))
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005348 host_bridge_set = 1;
5349 else if (unformat (i, "host-ip4-addr %U/%u", unformat_ip4_address,
Damjan Marion91c6ef72017-12-01 13:34:24 +01005350 &host_ip4_addr, &host_ip4_prefix_len))
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005351 host_ip4_prefix_set = 1;
5352 else if (unformat (i, "host-ip6-addr %U/%u", unformat_ip6_address,
Damjan Marion91c6ef72017-12-01 13:34:24 +01005353 &host_ip6_addr, &host_ip6_prefix_len))
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005354 host_ip6_prefix_set = 1;
Damjan Marion7866c452018-01-18 13:35:11 +01005355 else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
5356 &host_ip4_gw))
5357 host_ip4_gw_set = 1;
5358 else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
5359 &host_ip6_gw))
5360 host_ip6_gw_set = 1;
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005361 else if (unformat (i, "rx-ring-size %u", &rx_ring_sz))
Damjan Marion8389fb92017-10-13 18:29:53 +02005362 ;
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005363 else if (unformat (i, "tx-ring-size %u", &tx_ring_sz))
Damjan Marion8389fb92017-10-13 18:29:53 +02005364 ;
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005365 else if (unformat (i, "host-mtu-size %u", &host_mtu_size))
Mohsin Kazmi97d54ed2019-06-10 11:20:15 +02005366 host_mtu_set = 1;
5367 else if (unformat (i, "no-gso"))
Mohsin Kazmid88fc0f2020-04-30 19:05:56 +02005368 tap_flags &= ~TAP_API_FLAG_GSO;
Mohsin Kazmi97d54ed2019-06-10 11:20:15 +02005369 else if (unformat (i, "gso"))
Mohsin Kazmid88fc0f2020-04-30 19:05:56 +02005370 tap_flags |= TAP_API_FLAG_GSO;
Mohsin Kazmiba0061f2019-12-18 17:08:54 +01005371 else if (unformat (i, "csum-offload"))
Mohsin Kazmid88fc0f2020-04-30 19:05:56 +02005372 tap_flags |= TAP_API_FLAG_CSUM_OFFLOAD;
Mohsin Kazmib49bc1a2020-02-14 17:51:04 +00005373 else if (unformat (i, "persist"))
Mohsin Kazmid88fc0f2020-04-30 19:05:56 +02005374 tap_flags |= TAP_API_FLAG_PERSIST;
Mohsin Kazmib49bc1a2020-02-14 17:51:04 +00005375 else if (unformat (i, "attach"))
Mohsin Kazmid88fc0f2020-04-30 19:05:56 +02005376 tap_flags |= TAP_API_FLAG_ATTACH;
5377 else if (unformat (i, "tun"))
5378 tap_flags |= TAP_API_FLAG_TUN;
5379 else if (unformat (i, "gro-coalesce"))
5380 tap_flags |= TAP_API_FLAG_GRO_COALESCE;
Mohsin Kazmi50bd1652020-08-26 11:07:48 +02005381 else if (unformat (i, "packed"))
5382 tap_flags |= TAP_API_FLAG_PACKED;
5383 else if (unformat (i, "in-order"))
5384 tap_flags |= TAP_API_FLAG_IN_ORDER;
Damjan Marion8389fb92017-10-13 18:29:53 +02005385 else
5386 break;
5387 }
5388
Damjan Marion2df39092017-12-04 20:03:37 +01005389 if (vec_len (host_if_name) > 63)
Damjan Marion8389fb92017-10-13 18:29:53 +02005390 {
5391 errmsg ("tap name too long. ");
5392 return -99;
5393 }
Damjan Marion2df39092017-12-04 20:03:37 +01005394 if (vec_len (host_ns) > 63)
Damjan Marion8389fb92017-10-13 18:29:53 +02005395 {
5396 errmsg ("host name space too long. ");
5397 return -99;
5398 }
Damjan Marion91c6ef72017-12-01 13:34:24 +01005399 if (vec_len (host_bridge) > 63)
5400 {
5401 errmsg ("host bridge name too long. ");
5402 return -99;
5403 }
5404 if (host_ip4_prefix_len > 32)
5405 {
5406 errmsg ("host ip4 prefix length not valid. ");
5407 return -99;
5408 }
5409 if (host_ip6_prefix_len > 128)
5410 {
5411 errmsg ("host ip6 prefix length not valid. ");
5412 return -99;
5413 }
Damjan Marion8389fb92017-10-13 18:29:53 +02005414 if (!is_pow2 (rx_ring_sz))
5415 {
5416 errmsg ("rx ring size must be power of 2. ");
5417 return -99;
5418 }
5419 if (rx_ring_sz > 32768)
5420 {
5421 errmsg ("rx ring size must be 32768 or lower. ");
5422 return -99;
5423 }
5424 if (!is_pow2 (tx_ring_sz))
5425 {
5426 errmsg ("tx ring size must be power of 2. ");
5427 return -99;
5428 }
5429 if (tx_ring_sz > 32768)
5430 {
5431 errmsg ("tx ring size must be 32768 or lower. ");
5432 return -99;
5433 }
Mohsin Kazmi97d54ed2019-06-10 11:20:15 +02005434 if (host_mtu_set && (host_mtu_size < 64 || host_mtu_size > 65355))
5435 {
5436 errmsg ("host MTU size must be in between 64 and 65355. ");
5437 return -99;
5438 }
Damjan Marion8389fb92017-10-13 18:29:53 +02005439
Damjan Marion8389fb92017-10-13 18:29:53 +02005440 /* Construct the API message */
5441 M (TAP_CREATE_V2, mp);
5442
Steven9e635692018-03-01 09:36:01 -08005443 mp->id = ntohl (id);
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005444 mp->use_random_mac = random_mac;
5445 mp->num_rx_queues = (u8) num_rx_queues;
Steven9e635692018-03-01 09:36:01 -08005446 mp->tx_ring_sz = ntohs (tx_ring_sz);
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005447 mp->rx_ring_sz = ntohs (rx_ring_sz);
Mohsin Kazmi97d54ed2019-06-10 11:20:15 +02005448 mp->host_mtu_set = host_mtu_set;
5449 mp->host_mtu_size = ntohl (host_mtu_size);
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005450 mp->host_mac_addr_set = host_mac_addr_set;
5451 mp->host_ip4_prefix_set = host_ip4_prefix_set;
5452 mp->host_ip6_prefix_set = host_ip6_prefix_set;
5453 mp->host_ip4_gw_set = host_ip4_gw_set;
5454 mp->host_ip6_gw_set = host_ip6_gw_set;
Mohsin Kazmi97d54ed2019-06-10 11:20:15 +02005455 mp->tap_flags = ntohl (tap_flags);
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005456 mp->host_namespace_set = host_ns_set;
5457 mp->host_if_name_set = host_if_name_set;
5458 mp->host_bridge_set = host_bridge_set;
Damjan Marion2df39092017-12-04 20:03:37 +01005459
Steven9e635692018-03-01 09:36:01 -08005460 if (random_mac == 0)
Damjan Marion2df39092017-12-04 20:03:37 +01005461 clib_memcpy (mp->mac_address, mac_address, 6);
5462 if (host_mac_addr_set)
5463 clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005464 if (host_if_name_set)
Damjan Marion2df39092017-12-04 20:03:37 +01005465 clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005466 if (host_ns_set)
Damjan Marion2df39092017-12-04 20:03:37 +01005467 clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005468 if (host_bridge_set)
Damjan Marion91c6ef72017-12-01 13:34:24 +01005469 clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005470 if (host_ip4_prefix_set)
5471 {
5472 clib_memcpy (mp->host_ip4_prefix.address, &host_ip4_addr, 4);
5473 mp->host_ip4_prefix.len = (u8) host_ip4_prefix_len;
5474 }
5475 if (host_ip6_prefix_set)
5476 {
5477 clib_memcpy (mp->host_ip6_prefix.address, &host_ip6_addr, 16);
5478 mp->host_ip6_prefix.len = (u8) host_ip6_prefix_len;
5479 }
Damjan Marion7866c452018-01-18 13:35:11 +01005480 if (host_ip4_gw_set)
5481 clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
5482 if (host_ip6_gw_set)
5483 clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
Damjan Marion8389fb92017-10-13 18:29:53 +02005484
Damjan Marion2df39092017-12-04 20:03:37 +01005485 vec_free (host_ns);
5486 vec_free (host_if_name);
5487 vec_free (host_bridge);
Damjan Marion8389fb92017-10-13 18:29:53 +02005488
5489 /* send it... */
5490 S (mp);
5491
5492 /* Wait for a reply... */
5493 W (ret);
5494 return ret;
5495}
5496
5497static int
5498api_tap_delete_v2 (vat_main_t * vam)
5499{
5500 unformat_input_t *i = vam->input;
5501 vl_api_tap_delete_v2_t *mp;
5502 u32 sw_if_index = ~0;
5503 u8 sw_if_index_set = 0;
5504 int ret;
5505
5506 /* Parse args required to build the message */
5507 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5508 {
5509 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5510 sw_if_index_set = 1;
5511 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5512 sw_if_index_set = 1;
5513 else
5514 break;
5515 }
5516
5517 if (sw_if_index_set == 0)
5518 {
5519 errmsg ("missing vpp interface name. ");
5520 return -99;
5521 }
5522
5523 /* Construct the API message */
5524 M (TAP_DELETE_V2, mp);
5525
5526 mp->sw_if_index = ntohl (sw_if_index);
5527
5528 /* send it... */
5529 S (mp);
5530
5531 /* Wait for a reply... */
5532 W (ret);
5533 return ret;
5534}
5535
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005536uword
jialv01082ebeb2019-09-10 00:23:55 +08005537unformat_vlib_pci_addr (unformat_input_t * input, va_list * args)
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005538{
jialv01082ebeb2019-09-10 00:23:55 +08005539 vlib_pci_addr_t *addr = va_arg (*args, vlib_pci_addr_t *);
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005540 u32 x[4];
5541
5542 if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
5543 return 0;
5544
5545 addr->domain = x[0];
5546 addr->bus = x[1];
5547 addr->slot = x[2];
5548 addr->function = x[3];
5549
5550 return 1;
5551}
5552
5553static int
Mohsin Kazmi518251b2020-09-01 17:17:44 +00005554api_virtio_pci_create_v2 (vat_main_t * vam)
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005555{
5556 unformat_input_t *i = vam->input;
Mohsin Kazmi518251b2020-09-01 17:17:44 +00005557 vl_api_virtio_pci_create_v2_t *mp;
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005558 u8 mac_address[6];
5559 u8 random_mac = 1;
5560 u32 pci_addr = 0;
5561 u64 features = (u64) ~ (0ULL);
Mohsin Kazmi518251b2020-09-01 17:17:44 +00005562 u32 virtio_flags = 0;
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005563 int ret;
5564
5565 clib_memset (mac_address, 0, sizeof (mac_address));
5566
5567 /* Parse args required to build the message */
5568 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5569 {
5570 if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
5571 {
5572 random_mac = 0;
5573 }
jialv01082ebeb2019-09-10 00:23:55 +08005574 else if (unformat (i, "pci-addr %U", unformat_vlib_pci_addr, &pci_addr))
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005575 ;
5576 else if (unformat (i, "features 0x%llx", &features))
5577 ;
Mohsin Kazmibbd6b742019-05-02 13:54:59 +02005578 else if (unformat (i, "gso-enabled"))
Mohsin Kazmi518251b2020-09-01 17:17:44 +00005579 virtio_flags |= VIRTIO_API_FLAG_GSO;
Mohsin Kazmi6d4af892020-01-03 15:11:53 +00005580 else if (unformat (i, "csum-offload-enabled"))
Mohsin Kazmi518251b2020-09-01 17:17:44 +00005581 virtio_flags |= VIRTIO_API_FLAG_CSUM_OFFLOAD;
5582 else if (unformat (i, "gro-coalesce"))
5583 virtio_flags |= VIRTIO_API_FLAG_GRO_COALESCE;
5584 else if (unformat (i, "packed"))
5585 virtio_flags |= VIRTIO_API_FLAG_PACKED;
5586 else if (unformat (i, "in-order"))
5587 virtio_flags |= VIRTIO_API_FLAG_IN_ORDER;
Mohsin Kazmie347acb2020-09-28 10:26:33 +00005588 else if (unformat (i, "buffering"))
5589 virtio_flags |= VIRTIO_API_FLAG_BUFFERING;
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005590 else
5591 break;
5592 }
5593
5594 if (pci_addr == 0)
5595 {
5596 errmsg ("pci address must be non zero. ");
5597 return -99;
5598 }
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005599
5600 /* Construct the API message */
Mohsin Kazmi518251b2020-09-01 17:17:44 +00005601 M (VIRTIO_PCI_CREATE_V2, mp);
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005602
5603 mp->use_random_mac = random_mac;
5604
Jakub Grajciar2c504f82019-09-26 10:34:41 +02005605 mp->pci_addr.domain = htons (((vlib_pci_addr_t) pci_addr).domain);
5606 mp->pci_addr.bus = ((vlib_pci_addr_t) pci_addr).bus;
5607 mp->pci_addr.slot = ((vlib_pci_addr_t) pci_addr).slot;
5608 mp->pci_addr.function = ((vlib_pci_addr_t) pci_addr).function;
5609
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005610 mp->features = clib_host_to_net_u64 (features);
Mohsin Kazmi518251b2020-09-01 17:17:44 +00005611 mp->virtio_flags = clib_host_to_net_u32 (virtio_flags);
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005612
5613 if (random_mac == 0)
5614 clib_memcpy (mp->mac_address, mac_address, 6);
5615
5616 /* send it... */
5617 S (mp);
5618
5619 /* Wait for a reply... */
5620 W (ret);
5621 return ret;
5622}
5623
5624static int
5625api_virtio_pci_delete (vat_main_t * vam)
5626{
5627 unformat_input_t *i = vam->input;
5628 vl_api_virtio_pci_delete_t *mp;
5629 u32 sw_if_index = ~0;
5630 u8 sw_if_index_set = 0;
5631 int ret;
5632
5633 /* Parse args required to build the message */
5634 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5635 {
5636 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5637 sw_if_index_set = 1;
5638 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5639 sw_if_index_set = 1;
5640 else
5641 break;
5642 }
5643
5644 if (sw_if_index_set == 0)
5645 {
5646 errmsg ("missing vpp interface name. ");
5647 return -99;
5648 }
5649
5650 /* Construct the API message */
5651 M (VIRTIO_PCI_DELETE, mp);
5652
5653 mp->sw_if_index = htonl (sw_if_index);
5654
5655 /* send it... */
5656 S (mp);
5657
5658 /* Wait for a reply... */
5659 W (ret);
5660 return ret;
5661}
5662
Damjan Marion8389fb92017-10-13 18:29:53 +02005663static int
Steven9cd2d7a2017-12-20 12:43:01 -08005664api_bond_create (vat_main_t * vam)
5665{
5666 unformat_input_t *i = vam->input;
5667 vl_api_bond_create_t *mp;
5668 u8 mac_address[6];
5669 u8 custom_mac = 0;
5670 int ret;
5671 u8 mode;
5672 u8 lb;
5673 u8 mode_is_set = 0;
Alexander Chernavinad9d5282018-12-13 09:08:09 -05005674 u32 id = ~0;
Zhiyong Yang751e3f32019-06-26 05:49:14 -04005675 u8 numa_only = 0;
Steven9cd2d7a2017-12-20 12:43:01 -08005676
Dave Barachb7b92992018-10-17 10:38:51 -04005677 clib_memset (mac_address, 0, sizeof (mac_address));
Steven9cd2d7a2017-12-20 12:43:01 -08005678 lb = BOND_LB_L2;
5679
5680 /* Parse args required to build the message */
5681 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5682 {
5683 if (unformat (i, "mode %U", unformat_bond_mode, &mode))
5684 mode_is_set = 1;
5685 else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
5686 && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
5687 ;
5688 else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
5689 mac_address))
5690 custom_mac = 1;
Zhiyong Yang751e3f32019-06-26 05:49:14 -04005691 else if (unformat (i, "numa-only"))
5692 numa_only = 1;
Alexander Chernavinad9d5282018-12-13 09:08:09 -05005693 else if (unformat (i, "id %u", &id))
5694 ;
Steven9cd2d7a2017-12-20 12:43:01 -08005695 else
5696 break;
5697 }
5698
5699 if (mode_is_set == 0)
5700 {
5701 errmsg ("Missing bond mode. ");
5702 return -99;
5703 }
5704
5705 /* Construct the API message */
5706 M (BOND_CREATE, mp);
5707
5708 mp->use_custom_mac = custom_mac;
5709
Jakub Grajciar3d1ef872019-08-26 12:55:15 +02005710 mp->mode = htonl (mode);
5711 mp->lb = htonl (lb);
Alexander Chernavinad9d5282018-12-13 09:08:09 -05005712 mp->id = htonl (id);
Zhiyong Yang751e3f32019-06-26 05:49:14 -04005713 mp->numa_only = numa_only;
Steven9cd2d7a2017-12-20 12:43:01 -08005714
5715 if (custom_mac)
5716 clib_memcpy (mp->mac_address, mac_address, 6);
5717
5718 /* send it... */
5719 S (mp);
5720
5721 /* Wait for a reply... */
5722 W (ret);
5723 return ret;
5724}
5725
5726static int
Steven Luongea717862020-07-30 07:31:40 -07005727api_bond_create2 (vat_main_t * vam)
5728{
5729 unformat_input_t *i = vam->input;
5730 vl_api_bond_create2_t *mp;
5731 u8 mac_address[6];
5732 u8 custom_mac = 0;
5733 int ret;
5734 u8 mode;
5735 u8 lb;
5736 u8 mode_is_set = 0;
5737 u32 id = ~0;
5738 u8 numa_only = 0;
5739 u8 gso = 0;
5740
5741 clib_memset (mac_address, 0, sizeof (mac_address));
5742 lb = BOND_LB_L2;
5743
5744 /* Parse args required to build the message */
5745 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5746 {
5747 if (unformat (i, "mode %U", unformat_bond_mode, &mode))
5748 mode_is_set = 1;
5749 else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
5750 && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
5751 ;
5752 else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
5753 mac_address))
5754 custom_mac = 1;
5755 else if (unformat (i, "numa-only"))
5756 numa_only = 1;
5757 else if (unformat (i, "gso"))
5758 gso = 1;
5759 else if (unformat (i, "id %u", &id))
5760 ;
5761 else
5762 break;
5763 }
5764
5765 if (mode_is_set == 0)
5766 {
5767 errmsg ("Missing bond mode. ");
5768 return -99;
5769 }
5770
5771 /* Construct the API message */
5772 M (BOND_CREATE2, mp);
5773
5774 mp->use_custom_mac = custom_mac;
5775
5776 mp->mode = htonl (mode);
5777 mp->lb = htonl (lb);
5778 mp->id = htonl (id);
5779 mp->numa_only = numa_only;
5780 mp->enable_gso = gso;
5781
5782 if (custom_mac)
5783 clib_memcpy (mp->mac_address, mac_address, 6);
5784
5785 /* send it... */
5786 S (mp);
5787
5788 /* Wait for a reply... */
5789 W (ret);
5790 return ret;
5791}
5792
5793static int
Steven9cd2d7a2017-12-20 12:43:01 -08005794api_bond_delete (vat_main_t * vam)
5795{
5796 unformat_input_t *i = vam->input;
5797 vl_api_bond_delete_t *mp;
5798 u32 sw_if_index = ~0;
5799 u8 sw_if_index_set = 0;
5800 int ret;
5801
5802 /* Parse args required to build the message */
5803 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5804 {
5805 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5806 sw_if_index_set = 1;
5807 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5808 sw_if_index_set = 1;
5809 else
5810 break;
5811 }
5812
5813 if (sw_if_index_set == 0)
5814 {
5815 errmsg ("missing vpp interface name. ");
5816 return -99;
5817 }
5818
5819 /* Construct the API message */
5820 M (BOND_DELETE, mp);
5821
5822 mp->sw_if_index = ntohl (sw_if_index);
5823
5824 /* send it... */
5825 S (mp);
5826
5827 /* Wait for a reply... */
5828 W (ret);
5829 return ret;
5830}
5831
5832static int
Steven Luong4c4223e2020-07-15 08:44:54 -07005833api_bond_add_member (vat_main_t * vam)
Steven9cd2d7a2017-12-20 12:43:01 -08005834{
5835 unformat_input_t *i = vam->input;
Steven Luong4c4223e2020-07-15 08:44:54 -07005836 vl_api_bond_add_member_t *mp;
Steven9cd2d7a2017-12-20 12:43:01 -08005837 u32 bond_sw_if_index;
5838 int ret;
5839 u8 is_passive;
5840 u8 is_long_timeout;
5841 u32 bond_sw_if_index_is_set = 0;
5842 u32 sw_if_index;
5843 u8 sw_if_index_is_set = 0;
5844
5845 /* Parse args required to build the message */
5846 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5847 {
5848 if (unformat (i, "sw_if_index %d", &sw_if_index))
5849 sw_if_index_is_set = 1;
5850 else if (unformat (i, "bond %u", &bond_sw_if_index))
5851 bond_sw_if_index_is_set = 1;
5852 else if (unformat (i, "passive %d", &is_passive))
5853 ;
5854 else if (unformat (i, "long-timeout %d", &is_long_timeout))
5855 ;
5856 else
5857 break;
5858 }
5859
5860 if (bond_sw_if_index_is_set == 0)
5861 {
5862 errmsg ("Missing bond sw_if_index. ");
5863 return -99;
5864 }
5865 if (sw_if_index_is_set == 0)
5866 {
Steven Luong4c4223e2020-07-15 08:44:54 -07005867 errmsg ("Missing member sw_if_index. ");
Steven9cd2d7a2017-12-20 12:43:01 -08005868 return -99;
5869 }
5870
5871 /* Construct the API message */
Steven Luong4c4223e2020-07-15 08:44:54 -07005872 M (BOND_ADD_MEMBER, mp);
Steven9cd2d7a2017-12-20 12:43:01 -08005873
5874 mp->bond_sw_if_index = ntohl (bond_sw_if_index);
5875 mp->sw_if_index = ntohl (sw_if_index);
5876 mp->is_long_timeout = is_long_timeout;
5877 mp->is_passive = is_passive;
5878
5879 /* send it... */
5880 S (mp);
5881
5882 /* Wait for a reply... */
5883 W (ret);
5884 return ret;
5885}
5886
5887static int
Steven Luong4c4223e2020-07-15 08:44:54 -07005888api_bond_detach_member (vat_main_t * vam)
Steven9cd2d7a2017-12-20 12:43:01 -08005889{
5890 unformat_input_t *i = vam->input;
Steven Luong4c4223e2020-07-15 08:44:54 -07005891 vl_api_bond_detach_member_t *mp;
Steven9cd2d7a2017-12-20 12:43:01 -08005892 u32 sw_if_index = ~0;
5893 u8 sw_if_index_set = 0;
5894 int ret;
5895
5896 /* Parse args required to build the message */
5897 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5898 {
5899 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5900 sw_if_index_set = 1;
5901 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5902 sw_if_index_set = 1;
5903 else
5904 break;
5905 }
5906
5907 if (sw_if_index_set == 0)
5908 {
5909 errmsg ("missing vpp interface name. ");
5910 return -99;
5911 }
5912
5913 /* Construct the API message */
Steven Luong4c4223e2020-07-15 08:44:54 -07005914 M (BOND_DETACH_MEMBER, mp);
Steven9cd2d7a2017-12-20 12:43:01 -08005915
5916 mp->sw_if_index = ntohl (sw_if_index);
5917
5918 /* send it... */
5919 S (mp);
5920
5921 /* Wait for a reply... */
5922 W (ret);
5923 return ret;
5924}
5925
5926static int
Neale Ranns28ab9cc2017-08-14 07:18:42 -07005927api_ip_table_add_del (vat_main_t * vam)
5928{
5929 unformat_input_t *i = vam->input;
5930 vl_api_ip_table_add_del_t *mp;
5931 u32 table_id = ~0;
5932 u8 is_ipv6 = 0;
5933 u8 is_add = 1;
5934 int ret = 0;
5935
5936 /* Parse args required to build the message */
5937 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5938 {
5939 if (unformat (i, "ipv6"))
5940 is_ipv6 = 1;
5941 else if (unformat (i, "del"))
5942 is_add = 0;
5943 else if (unformat (i, "add"))
5944 is_add = 1;
5945 else if (unformat (i, "table %d", &table_id))
5946 ;
5947 else
5948 {
5949 clib_warning ("parse error '%U'", format_unformat_error, i);
5950 return -99;
5951 }
5952 }
5953
5954 if (~0 == table_id)
5955 {
5956 errmsg ("missing table-ID");
5957 return -99;
5958 }
5959
5960 /* Construct the API message */
5961 M (IP_TABLE_ADD_DEL, mp);
5962
Neale Ranns097fa662018-05-01 05:17:55 -07005963 mp->table.table_id = ntohl (table_id);
5964 mp->table.is_ip6 = is_ipv6;
Neale Ranns28ab9cc2017-08-14 07:18:42 -07005965 mp->is_add = is_add;
5966
5967 /* send it... */
5968 S (mp);
5969
5970 /* Wait for a reply... */
5971 W (ret);
5972
5973 return ret;
5974}
5975
Neale Ranns097fa662018-05-01 05:17:55 -07005976uword
5977unformat_fib_path (unformat_input_t * input, va_list * args)
5978{
5979 vat_main_t *vam = va_arg (*args, vat_main_t *);
5980 vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
5981 u32 weight, preference;
5982 mpls_label_t out_label;
5983
5984 clib_memset (path, 0, sizeof (*path));
5985 path->weight = 1;
5986 path->sw_if_index = ~0;
5987 path->rpf_id = ~0;
5988 path->n_labels = 0;
5989
5990 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
5991 {
5992 if (unformat (input, "%U %U",
5993 unformat_vl_api_ip4_address,
5994 &path->nh.address.ip4,
5995 api_unformat_sw_if_index, vam, &path->sw_if_index))
5996 {
5997 path->proto = FIB_API_PATH_NH_PROTO_IP4;
5998 }
5999 else if (unformat (input, "%U %U",
6000 unformat_vl_api_ip6_address,
6001 &path->nh.address.ip6,
6002 api_unformat_sw_if_index, vam, &path->sw_if_index))
6003 {
6004 path->proto = FIB_API_PATH_NH_PROTO_IP6;
6005 }
6006 else if (unformat (input, "weight %u", &weight))
6007 {
6008 path->weight = weight;
6009 }
6010 else if (unformat (input, "preference %u", &preference))
6011 {
6012 path->preference = preference;
6013 }
6014 else if (unformat (input, "%U next-hop-table %d",
6015 unformat_vl_api_ip4_address,
6016 &path->nh.address.ip4, &path->table_id))
6017 {
6018 path->proto = FIB_API_PATH_NH_PROTO_IP4;
6019 }
6020 else if (unformat (input, "%U next-hop-table %d",
6021 unformat_vl_api_ip6_address,
6022 &path->nh.address.ip6, &path->table_id))
6023 {
6024 path->proto = FIB_API_PATH_NH_PROTO_IP6;
6025 }
6026 else if (unformat (input, "%U",
6027 unformat_vl_api_ip4_address, &path->nh.address.ip4))
6028 {
6029 /*
6030 * the recursive next-hops are by default in the default table
6031 */
6032 path->table_id = 0;
6033 path->sw_if_index = ~0;
6034 path->proto = FIB_API_PATH_NH_PROTO_IP4;
6035 }
6036 else if (unformat (input, "%U",
6037 unformat_vl_api_ip6_address, &path->nh.address.ip6))
6038 {
6039 /*
6040 * the recursive next-hops are by default in the default table
6041 */
6042 path->table_id = 0;
6043 path->sw_if_index = ~0;
6044 path->proto = FIB_API_PATH_NH_PROTO_IP6;
6045 }
6046 else if (unformat (input, "resolve-via-host"))
6047 {
6048 path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
6049 }
6050 else if (unformat (input, "resolve-via-attached"))
6051 {
6052 path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
6053 }
6054 else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
6055 {
6056 path->type = FIB_API_PATH_TYPE_LOCAL;
6057 path->sw_if_index = ~0;
6058 path->proto = FIB_API_PATH_NH_PROTO_IP4;
6059 }
6060 else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
6061 {
6062 path->type = FIB_API_PATH_TYPE_LOCAL;
6063 path->sw_if_index = ~0;
6064 path->proto = FIB_API_PATH_NH_PROTO_IP6;
6065 }
6066 else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
6067 ;
6068 else if (unformat (input, "via-label %d", &path->nh.via_label))
6069 {
6070 path->proto = FIB_API_PATH_NH_PROTO_MPLS;
6071 path->sw_if_index = ~0;
6072 }
6073 else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
6074 {
6075 path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
6076 path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
6077 }
6078 else if (unformat (input, "local"))
6079 {
6080 path->type = FIB_API_PATH_TYPE_LOCAL;
6081 }
6082 else if (unformat (input, "out-labels"))
6083 {
6084 while (unformat (input, "%d", &out_label))
6085 {
6086 path->label_stack[path->n_labels].label = out_label;
6087 path->label_stack[path->n_labels].is_uniform = 0;
6088 path->label_stack[path->n_labels].ttl = 64;
6089 path->n_labels++;
6090 }
6091 }
6092 else if (unformat (input, "via"))
6093 {
6094 /* new path, back up and return */
6095 unformat_put_input (input);
6096 unformat_put_input (input);
6097 unformat_put_input (input);
6098 unformat_put_input (input);
6099 break;
6100 }
6101 else
6102 {
6103 return (0);
6104 }
6105 }
6106
6107 path->proto = ntohl (path->proto);
6108 path->type = ntohl (path->type);
6109 path->flags = ntohl (path->flags);
6110 path->table_id = ntohl (path->table_id);
6111 path->sw_if_index = ntohl (path->sw_if_index);
6112
6113 return (1);
6114}
6115
Neale Ranns28ab9cc2017-08-14 07:18:42 -07006116static int
Neale Ranns097fa662018-05-01 05:17:55 -07006117api_ip_route_add_del (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +01006118{
6119 unformat_input_t *i = vam->input;
Neale Ranns097fa662018-05-01 05:17:55 -07006120 vl_api_ip_route_add_del_t *mp;
6121 u32 vrf_id = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006122 u8 is_add = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006123 u8 is_multipath = 0;
Neale Ranns097fa662018-05-01 05:17:55 -07006124 u8 prefix_set = 0;
6125 u8 path_count = 0;
6126 vl_api_prefix_t pfx = { };
6127 vl_api_fib_path_t paths[8];
Damjan Marion7cd468a2016-12-19 23:05:39 +01006128 int count = 1;
6129 int j;
6130 f64 before = 0;
6131 u32 random_add_del = 0;
6132 u32 *random_vector = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006133 u32 random_seed = 0xdeaddabe;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006134
6135 /* Parse args required to build the message */
6136 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6137 {
Neale Ranns097fa662018-05-01 05:17:55 -07006138 if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
6139 prefix_set = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006140 else if (unformat (i, "del"))
6141 is_add = 0;
6142 else if (unformat (i, "add"))
6143 is_add = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006144 else if (unformat (i, "vrf %d", &vrf_id))
6145 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006146 else if (unformat (i, "count %d", &count))
6147 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006148 else if (unformat (i, "random"))
6149 random_add_del = 1;
Neale Ranns097fa662018-05-01 05:17:55 -07006150 else if (unformat (i, "multipath"))
6151 is_multipath = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006152 else if (unformat (i, "seed %d", &random_seed))
6153 ;
6154 else
Neale Ranns097fa662018-05-01 05:17:55 -07006155 if (unformat
6156 (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
6157 {
6158 path_count++;
6159 if (8 == path_count)
6160 {
6161 errmsg ("max 8 paths");
6162 return -99;
6163 }
6164 }
6165 else
Damjan Marion7cd468a2016-12-19 23:05:39 +01006166 {
6167 clib_warning ("parse error '%U'", format_unformat_error, i);
6168 return -99;
6169 }
6170 }
6171
Neale Ranns097fa662018-05-01 05:17:55 -07006172 if (!path_count)
Damjan Marion7cd468a2016-12-19 23:05:39 +01006173 {
Neale Ranns097fa662018-05-01 05:17:55 -07006174 errmsg ("specify a path; via ...");
Damjan Marion7cd468a2016-12-19 23:05:39 +01006175 return -99;
6176 }
Neale Ranns097fa662018-05-01 05:17:55 -07006177 if (prefix_set == 0)
Damjan Marion7cd468a2016-12-19 23:05:39 +01006178 {
Neale Ranns097fa662018-05-01 05:17:55 -07006179 errmsg ("missing prefix");
Damjan Marion7cd468a2016-12-19 23:05:39 +01006180 return -99;
6181 }
6182
6183 /* Generate a pile of unique, random routes */
6184 if (random_add_del)
6185 {
Neale Ranns097fa662018-05-01 05:17:55 -07006186 ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006187 u32 this_random_address;
Neale Ranns097fa662018-05-01 05:17:55 -07006188 uword *random_hash;
6189
Damjan Marion7cd468a2016-12-19 23:05:39 +01006190 random_hash = hash_create (count, sizeof (uword));
6191
Neale Ranns097fa662018-05-01 05:17:55 -07006192 hash_set (random_hash, i->as_u32, 1);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006193 for (j = 0; j <= count; j++)
6194 {
6195 do
6196 {
6197 this_random_address = random_u32 (&random_seed);
6198 this_random_address =
6199 clib_host_to_net_u32 (this_random_address);
6200 }
6201 while (hash_get (random_hash, this_random_address));
6202 vec_add1 (random_vector, this_random_address);
6203 hash_set (random_hash, this_random_address, 1);
6204 }
6205 hash_free (random_hash);
Neale Ranns097fa662018-05-01 05:17:55 -07006206 set_ip4_address (&pfx.address, random_vector[0]);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006207 }
6208
6209 if (count > 1)
6210 {
6211 /* Turn on async mode */
6212 vam->async_mode = 1;
6213 vam->async_errors = 0;
6214 before = vat_time_now (vam);
6215 }
6216
6217 for (j = 0; j < count; j++)
6218 {
6219 /* Construct the API message */
Neale Ranns097fa662018-05-01 05:17:55 -07006220 M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006221
6222 mp->is_add = is_add;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006223 mp->is_multipath = is_multipath;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006224
Neale Ranns097fa662018-05-01 05:17:55 -07006225 clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
6226 mp->route.table_id = ntohl (vrf_id);
6227 mp->route.n_paths = path_count;
6228
6229 clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
6230
6231 if (random_add_del)
6232 set_ip4_address (&pfx.address, random_vector[j + 1]);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006233 else
Neale Ranns097fa662018-05-01 05:17:55 -07006234 increment_address (&pfx.address);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006235 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006236 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006237 /* If we receive SIGTERM, stop now... */
6238 if (vam->do_exit)
6239 break;
6240 }
6241
6242 /* When testing multiple add/del ops, use a control-ping to sync */
6243 if (count > 1)
6244 {
Jon Loeliger2d23eca2017-02-01 13:09:58 -06006245 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006246 f64 after;
Jon Loeliger1f9191f2017-01-31 15:27:19 -06006247 f64 timeout;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006248
6249 /* Shut off async mode */
6250 vam->async_mode = 0;
6251
Dave Barach59b25652017-09-10 15:04:27 -04006252 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06006253 S (mp_ping);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006254
6255 timeout = vat_time_now (vam) + 1.0;
6256 while (vat_time_now (vam) < timeout)
6257 if (vam->result_ready == 1)
6258 goto out;
6259 vam->retval = -99;
6260
6261 out:
6262 if (vam->retval == -99)
6263 errmsg ("timeout");
6264
6265 if (vam->async_errors > 0)
6266 {
6267 errmsg ("%d asynchronous errors", vam->async_errors);
6268 vam->retval = -98;
6269 }
6270 vam->async_errors = 0;
6271 after = vat_time_now (vam);
6272
6273 /* slim chance, but we might have eaten SIGTERM on the first iteration */
6274 if (j > 0)
6275 count = j;
6276
6277 print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6278 count, after - before, count / (after - before));
6279 }
6280 else
6281 {
Jon Loeliger56c7b012017-02-01 12:31:41 -06006282 int ret;
6283
Damjan Marion7cd468a2016-12-19 23:05:39 +01006284 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06006285 W (ret);
6286 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006287 }
6288
6289 /* Return the good/bad news */
6290 return (vam->retval);
6291}
6292
6293static int
Neale Ranns32e1c012016-11-22 17:07:28 +00006294api_ip_mroute_add_del (vat_main_t * vam)
6295{
6296 unformat_input_t *i = vam->input;
Neale Ranns097fa662018-05-01 05:17:55 -07006297 u8 path_set = 0, prefix_set = 0, is_add = 1;
Neale Ranns32e1c012016-11-22 17:07:28 +00006298 vl_api_ip_mroute_add_del_t *mp;
Neale Ranns32e1c012016-11-22 17:07:28 +00006299 mfib_entry_flags_t eflags = 0;
Neale Ranns097fa662018-05-01 05:17:55 -07006300 vl_api_mfib_path_t path;
6301 vl_api_mprefix_t pfx = { };
6302 u32 vrf_id = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006303 int ret;
Neale Ranns32e1c012016-11-22 17:07:28 +00006304
6305 /* Parse args required to build the message */
6306 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6307 {
Neale Ranns097fa662018-05-01 05:17:55 -07006308 if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
Neale Ranns32e1c012016-11-22 17:07:28 +00006309 {
Neale Ranns097fa662018-05-01 05:17:55 -07006310 prefix_set = 1;
6311 pfx.grp_address_length = htons (pfx.grp_address_length);
Neale Ranns32e1c012016-11-22 17:07:28 +00006312 }
6313 else if (unformat (i, "del"))
6314 is_add = 0;
6315 else if (unformat (i, "add"))
6316 is_add = 1;
6317 else if (unformat (i, "vrf %d", &vrf_id))
6318 ;
Neale Ranns097fa662018-05-01 05:17:55 -07006319 else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
6320 path.itf_flags = htonl (path.itf_flags);
Neale Ranns32e1c012016-11-22 17:07:28 +00006321 else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
6322 ;
Neale Ranns097fa662018-05-01 05:17:55 -07006323 else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
6324 path_set = 1;
Neale Ranns32e1c012016-11-22 17:07:28 +00006325 else
6326 {
6327 clib_warning ("parse error '%U'", format_unformat_error, i);
6328 return -99;
6329 }
6330 }
6331
Neale Ranns097fa662018-05-01 05:17:55 -07006332 if (prefix_set == 0)
Neale Ranns32e1c012016-11-22 17:07:28 +00006333 {
6334 errmsg ("missing addresses\n");
6335 return -99;
6336 }
Neale Ranns097fa662018-05-01 05:17:55 -07006337 if (path_set == 0)
6338 {
6339 errmsg ("missing path\n");
6340 return -99;
6341 }
Neale Ranns32e1c012016-11-22 17:07:28 +00006342
6343 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006344 M (IP_MROUTE_ADD_DEL, mp);
Neale Ranns32e1c012016-11-22 17:07:28 +00006345
Neale Ranns32e1c012016-11-22 17:07:28 +00006346 mp->is_add = is_add;
Neale Ranns097fa662018-05-01 05:17:55 -07006347 mp->is_multipath = 1;
Neale Ranns32e1c012016-11-22 17:07:28 +00006348
Neale Ranns097fa662018-05-01 05:17:55 -07006349 clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
6350 mp->route.table_id = htonl (vrf_id);
6351 mp->route.n_paths = 1;
6352 mp->route.entry_flags = htonl (eflags);
Neale Ranns32e1c012016-11-22 17:07:28 +00006353
Neale Ranns097fa662018-05-01 05:17:55 -07006354 clib_memcpy (&mp->route.paths, &path, sizeof (path));
Neale Ranns32e1c012016-11-22 17:07:28 +00006355
6356 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006357 S (mp);
Neale Ranns32e1c012016-11-22 17:07:28 +00006358 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06006359 W (ret);
6360 return ret;
Neale Ranns32e1c012016-11-22 17:07:28 +00006361}
6362
6363static int
Neale Ranns28ab9cc2017-08-14 07:18:42 -07006364api_mpls_table_add_del (vat_main_t * vam)
6365{
6366 unformat_input_t *i = vam->input;
6367 vl_api_mpls_table_add_del_t *mp;
6368 u32 table_id = ~0;
6369 u8 is_add = 1;
6370 int ret = 0;
6371
6372 /* Parse args required to build the message */
6373 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6374 {
Florin Corasd0a59722017-10-15 17:41:21 +00006375 if (unformat (i, "table %d", &table_id))
6376 ;
6377 else if (unformat (i, "del"))
Neale Ranns28ab9cc2017-08-14 07:18:42 -07006378 is_add = 0;
6379 else if (unformat (i, "add"))
6380 is_add = 1;
6381 else
6382 {
6383 clib_warning ("parse error '%U'", format_unformat_error, i);
6384 return -99;
6385 }
6386 }
6387
6388 if (~0 == table_id)
6389 {
6390 errmsg ("missing table-ID");
6391 return -99;
6392 }
6393
6394 /* Construct the API message */
6395 M (MPLS_TABLE_ADD_DEL, mp);
6396
Neale Ranns097fa662018-05-01 05:17:55 -07006397 mp->mt_table.mt_table_id = ntohl (table_id);
Neale Ranns28ab9cc2017-08-14 07:18:42 -07006398 mp->mt_is_add = is_add;
6399
6400 /* send it... */
6401 S (mp);
6402
6403 /* Wait for a reply... */
6404 W (ret);
6405
6406 return ret;
6407}
6408
6409static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01006410api_mpls_route_add_del (vat_main_t * vam)
6411{
Neale Ranns097fa662018-05-01 05:17:55 -07006412 u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
6413 mpls_label_t local_label = MPLS_LABEL_INVALID;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006414 unformat_input_t *i = vam->input;
6415 vl_api_mpls_route_add_del_t *mp;
Neale Ranns097fa662018-05-01 05:17:55 -07006416 vl_api_fib_path_t paths[8];
6417 int count = 1, j;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006418 f64 before = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006419
6420 /* Parse args required to build the message */
6421 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6422 {
Neale Ranns097fa662018-05-01 05:17:55 -07006423 if (unformat (i, "%d", &local_label))
Damjan Marion7cd468a2016-12-19 23:05:39 +01006424 ;
6425 else if (unformat (i, "eos"))
6426 is_eos = 1;
6427 else if (unformat (i, "non-eos"))
6428 is_eos = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006429 else if (unformat (i, "del"))
6430 is_add = 0;
6431 else if (unformat (i, "add"))
6432 is_add = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006433 else if (unformat (i, "multipath"))
6434 is_multipath = 1;
6435 else if (unformat (i, "count %d", &count))
6436 ;
John Loe166fd92018-09-13 14:08:59 -04006437 else
6438 if (unformat
Neale Ranns097fa662018-05-01 05:17:55 -07006439 (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
John Loe166fd92018-09-13 14:08:59 -04006440 {
Neale Ranns097fa662018-05-01 05:17:55 -07006441 path_count++;
6442 if (8 == path_count)
6443 {
6444 errmsg ("max 8 paths");
6445 return -99;
6446 }
John Loe166fd92018-09-13 14:08:59 -04006447 }
Damjan Marion7cd468a2016-12-19 23:05:39 +01006448 else
6449 {
6450 clib_warning ("parse error '%U'", format_unformat_error, i);
6451 return -99;
6452 }
6453 }
6454
Neale Ranns097fa662018-05-01 05:17:55 -07006455 if (!path_count)
Damjan Marion7cd468a2016-12-19 23:05:39 +01006456 {
Neale Ranns097fa662018-05-01 05:17:55 -07006457 errmsg ("specify a path; via ...");
Damjan Marion7cd468a2016-12-19 23:05:39 +01006458 return -99;
6459 }
6460
6461 if (MPLS_LABEL_INVALID == local_label)
6462 {
6463 errmsg ("missing label");
6464 return -99;
6465 }
6466
6467 if (count > 1)
6468 {
6469 /* Turn on async mode */
6470 vam->async_mode = 1;
6471 vam->async_errors = 0;
6472 before = vat_time_now (vam);
6473 }
6474
6475 for (j = 0; j < count; j++)
6476 {
6477 /* Construct the API message */
Neale Ranns097fa662018-05-01 05:17:55 -07006478 M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006479
6480 mp->mr_is_add = is_add;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006481 mp->mr_is_multipath = is_multipath;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006482
Neale Ranns097fa662018-05-01 05:17:55 -07006483 mp->mr_route.mr_label = local_label;
6484 mp->mr_route.mr_eos = is_eos;
6485 mp->mr_route.mr_table_id = 0;
6486 mp->mr_route.mr_n_paths = path_count;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006487
Neale Ranns097fa662018-05-01 05:17:55 -07006488 clib_memcpy (&mp->mr_route.mr_paths, paths,
6489 sizeof (paths[0]) * path_count);
Neale Rannsda78f952017-05-24 09:15:43 -07006490
Damjan Marion7cd468a2016-12-19 23:05:39 +01006491 local_label++;
6492
6493 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006494 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006495 /* If we receive SIGTERM, stop now... */
6496 if (vam->do_exit)
6497 break;
6498 }
6499
6500 /* When testing multiple add/del ops, use a control-ping to sync */
6501 if (count > 1)
6502 {
Jon Loeliger2d23eca2017-02-01 13:09:58 -06006503 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006504 f64 after;
Jon Loeliger1f9191f2017-01-31 15:27:19 -06006505 f64 timeout;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006506
6507 /* Shut off async mode */
6508 vam->async_mode = 0;
6509
Dave Barach59b25652017-09-10 15:04:27 -04006510 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06006511 S (mp_ping);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006512
6513 timeout = vat_time_now (vam) + 1.0;
6514 while (vat_time_now (vam) < timeout)
6515 if (vam->result_ready == 1)
6516 goto out;
6517 vam->retval = -99;
6518
6519 out:
6520 if (vam->retval == -99)
6521 errmsg ("timeout");
6522
6523 if (vam->async_errors > 0)
6524 {
6525 errmsg ("%d asynchronous errors", vam->async_errors);
6526 vam->retval = -98;
6527 }
6528 vam->async_errors = 0;
6529 after = vat_time_now (vam);
6530
6531 /* slim chance, but we might have eaten SIGTERM on the first iteration */
6532 if (j > 0)
6533 count = j;
6534
6535 print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6536 count, after - before, count / (after - before));
6537 }
6538 else
6539 {
Jon Loeliger56c7b012017-02-01 12:31:41 -06006540 int ret;
6541
Damjan Marion7cd468a2016-12-19 23:05:39 +01006542 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06006543 W (ret);
6544 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006545 }
6546
6547 /* Return the good/bad news */
6548 return (vam->retval);
Neale Ranns097fa662018-05-01 05:17:55 -07006549 return (0);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006550}
6551
6552static int
6553api_mpls_ip_bind_unbind (vat_main_t * vam)
6554{
6555 unformat_input_t *i = vam->input;
6556 vl_api_mpls_ip_bind_unbind_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006557 u32 ip_table_id = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006558 u8 is_bind = 1;
Neale Ranns097fa662018-05-01 05:17:55 -07006559 vl_api_prefix_t pfx;
6560 u8 prefix_set = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006561 mpls_label_t local_label = MPLS_LABEL_INVALID;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006562 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006563
6564 /* Parse args required to build the message */
6565 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6566 {
Neale Ranns097fa662018-05-01 05:17:55 -07006567 if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
6568 prefix_set = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006569 else if (unformat (i, "%d", &local_label))
6570 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006571 else if (unformat (i, "table-id %d", &ip_table_id))
6572 ;
6573 else if (unformat (i, "unbind"))
6574 is_bind = 0;
6575 else if (unformat (i, "bind"))
6576 is_bind = 1;
6577 else
6578 {
6579 clib_warning ("parse error '%U'", format_unformat_error, i);
6580 return -99;
6581 }
6582 }
6583
Neale Ranns097fa662018-05-01 05:17:55 -07006584 if (!prefix_set)
Damjan Marion7cd468a2016-12-19 23:05:39 +01006585 {
Neale Ranns097fa662018-05-01 05:17:55 -07006586 errmsg ("IP prefix not set");
Damjan Marion7cd468a2016-12-19 23:05:39 +01006587 return -99;
6588 }
6589
6590 if (MPLS_LABEL_INVALID == local_label)
6591 {
6592 errmsg ("missing label");
6593 return -99;
6594 }
6595
6596 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006597 M (MPLS_IP_BIND_UNBIND, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006598
Damjan Marion7cd468a2016-12-19 23:05:39 +01006599 mp->mb_is_bind = is_bind;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006600 mp->mb_ip_table_id = ntohl (ip_table_id);
6601 mp->mb_mpls_table_id = 0;
6602 mp->mb_label = ntohl (local_label);
Neale Ranns097fa662018-05-01 05:17:55 -07006603 clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
Damjan Marion7cd468a2016-12-19 23:05:39 +01006604
6605 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006606 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006607
6608 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06006609 W (ret);
6610 return ret;
Neale Ranns097fa662018-05-01 05:17:55 -07006611 return (0);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006612}
6613
6614static int
John Loe166fd92018-09-13 14:08:59 -04006615api_sr_mpls_policy_add (vat_main_t * vam)
6616{
6617 unformat_input_t *i = vam->input;
6618 vl_api_sr_mpls_policy_add_t *mp;
6619 u32 bsid = 0;
6620 u32 weight = 1;
6621 u8 type = 0;
6622 u8 n_segments = 0;
6623 u32 sid;
6624 u32 *segments = NULL;
6625 int ret;
6626
6627 /* Parse args required to build the message */
6628 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6629 {
6630 if (unformat (i, "bsid %d", &bsid))
6631 ;
6632 else if (unformat (i, "weight %d", &weight))
6633 ;
6634 else if (unformat (i, "spray"))
6635 type = 1;
6636 else if (unformat (i, "next %d", &sid))
6637 {
6638 n_segments += 1;
6639 vec_add1 (segments, htonl (sid));
6640 }
6641 else
6642 {
6643 clib_warning ("parse error '%U'", format_unformat_error, i);
6644 return -99;
6645 }
6646 }
6647
6648 if (bsid == 0)
6649 {
6650 errmsg ("bsid not set");
6651 return -99;
6652 }
6653
6654 if (n_segments == 0)
6655 {
6656 errmsg ("no sid in segment stack");
6657 return -99;
6658 }
6659
6660 /* Construct the API message */
6661 M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
6662
6663 mp->bsid = htonl (bsid);
6664 mp->weight = htonl (weight);
Jakub Grajciar00ec4012020-01-31 10:17:29 +01006665 mp->is_spray = type;
John Loe166fd92018-09-13 14:08:59 -04006666 mp->n_segments = n_segments;
6667 memcpy (mp->segments, segments, sizeof (u32) * n_segments);
6668 vec_free (segments);
6669
6670 /* send it... */
6671 S (mp);
6672
6673 /* Wait for a reply... */
6674 W (ret);
6675 return ret;
6676}
6677
6678static int
6679api_sr_mpls_policy_del (vat_main_t * vam)
6680{
6681 unformat_input_t *i = vam->input;
6682 vl_api_sr_mpls_policy_del_t *mp;
6683 u32 bsid = 0;
6684 int ret;
6685
6686 /* Parse args required to build the message */
6687 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6688 {
6689 if (unformat (i, "bsid %d", &bsid))
6690 ;
6691 else
6692 {
6693 clib_warning ("parse error '%U'", format_unformat_error, i);
6694 return -99;
6695 }
6696 }
6697
6698 if (bsid == 0)
6699 {
6700 errmsg ("bsid not set");
6701 return -99;
6702 }
6703
6704 /* Construct the API message */
6705 M (SR_MPLS_POLICY_DEL, mp);
6706
6707 mp->bsid = htonl (bsid);
6708
6709 /* send it... */
6710 S (mp);
6711
6712 /* Wait for a reply... */
6713 W (ret);
6714 return ret;
6715}
6716
6717static int
Neale Rannsd792d9c2017-10-21 10:53:20 -07006718api_bier_table_add_del (vat_main_t * vam)
6719{
6720 unformat_input_t *i = vam->input;
6721 vl_api_bier_table_add_del_t *mp;
6722 u8 is_add = 1;
6723 u32 set = 0, sub_domain = 0, hdr_len = 3;
6724 mpls_label_t local_label = MPLS_LABEL_INVALID;
6725 int ret;
6726
6727 /* Parse args required to build the message */
6728 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6729 {
6730 if (unformat (i, "sub-domain %d", &sub_domain))
6731 ;
6732 else if (unformat (i, "set %d", &set))
6733 ;
6734 else if (unformat (i, "label %d", &local_label))
6735 ;
6736 else if (unformat (i, "hdr-len %d", &hdr_len))
6737 ;
6738 else if (unformat (i, "add"))
6739 is_add = 1;
6740 else if (unformat (i, "del"))
6741 is_add = 0;
6742 else
6743 {
6744 clib_warning ("parse error '%U'", format_unformat_error, i);
6745 return -99;
6746 }
6747 }
6748
6749 if (MPLS_LABEL_INVALID == local_label)
6750 {
6751 errmsg ("missing label\n");
6752 return -99;
6753 }
6754
6755 /* Construct the API message */
6756 M (BIER_TABLE_ADD_DEL, mp);
6757
6758 mp->bt_is_add = is_add;
6759 mp->bt_label = ntohl (local_label);
6760 mp->bt_tbl_id.bt_set = set;
6761 mp->bt_tbl_id.bt_sub_domain = sub_domain;
6762 mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
6763
6764 /* send it... */
6765 S (mp);
6766
6767 /* Wait for a reply... */
6768 W (ret);
6769
6770 return (ret);
6771}
6772
6773static int
6774api_bier_route_add_del (vat_main_t * vam)
6775{
6776 unformat_input_t *i = vam->input;
6777 vl_api_bier_route_add_del_t *mp;
6778 u8 is_add = 1;
6779 u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
6780 ip4_address_t v4_next_hop_address;
6781 ip6_address_t v6_next_hop_address;
6782 u8 next_hop_set = 0;
6783 u8 next_hop_proto_is_ip4 = 1;
6784 mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6785 int ret;
6786
6787 /* Parse args required to build the message */
6788 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6789 {
6790 if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
6791 {
6792 next_hop_proto_is_ip4 = 1;
6793 next_hop_set = 1;
6794 }
6795 else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
6796 {
6797 next_hop_proto_is_ip4 = 0;
6798 next_hop_set = 1;
6799 }
6800 if (unformat (i, "sub-domain %d", &sub_domain))
6801 ;
6802 else if (unformat (i, "set %d", &set))
6803 ;
6804 else if (unformat (i, "hdr-len %d", &hdr_len))
6805 ;
6806 else if (unformat (i, "bp %d", &bp))
6807 ;
6808 else if (unformat (i, "add"))
6809 is_add = 1;
6810 else if (unformat (i, "del"))
6811 is_add = 0;
6812 else if (unformat (i, "out-label %d", &next_hop_out_label))
6813 ;
6814 else
6815 {
6816 clib_warning ("parse error '%U'", format_unformat_error, i);
6817 return -99;
6818 }
6819 }
6820
6821 if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
6822 {
6823 errmsg ("next hop / label set\n");
6824 return -99;
6825 }
6826 if (0 == bp)
6827 {
6828 errmsg ("bit=position not set\n");
6829 return -99;
6830 }
6831
6832 /* Construct the API message */
Neale Ranns31ed7442018-02-23 05:29:09 -08006833 M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
Neale Rannsd792d9c2017-10-21 10:53:20 -07006834
6835 mp->br_is_add = is_add;
Neale Ranns097fa662018-05-01 05:17:55 -07006836 mp->br_route.br_tbl_id.bt_set = set;
6837 mp->br_route.br_tbl_id.bt_sub_domain = sub_domain;
6838 mp->br_route.br_tbl_id.bt_hdr_len_id = hdr_len;
6839 mp->br_route.br_bp = ntohs (bp);
6840 mp->br_route.br_n_paths = 1;
6841 mp->br_route.br_paths[0].n_labels = 1;
6842 mp->br_route.br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
6843 mp->br_route.br_paths[0].proto = (next_hop_proto_is_ip4 ?
6844 FIB_API_PATH_NH_PROTO_IP4 :
6845 FIB_API_PATH_NH_PROTO_IP6);
Neale Rannsd792d9c2017-10-21 10:53:20 -07006846
6847 if (next_hop_proto_is_ip4)
6848 {
Neale Ranns097fa662018-05-01 05:17:55 -07006849 clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip4,
Neale Rannsd792d9c2017-10-21 10:53:20 -07006850 &v4_next_hop_address, sizeof (v4_next_hop_address));
6851 }
6852 else
6853 {
Neale Ranns097fa662018-05-01 05:17:55 -07006854 clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip6,
Neale Rannsd792d9c2017-10-21 10:53:20 -07006855 &v6_next_hop_address, sizeof (v6_next_hop_address));
6856 }
6857
6858 /* send it... */
6859 S (mp);
6860
6861 /* Wait for a reply... */
6862 W (ret);
6863
6864 return (ret);
6865}
6866
6867static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01006868api_mpls_tunnel_add_del (vat_main_t * vam)
6869{
6870 unformat_input_t *i = vam->input;
6871 vl_api_mpls_tunnel_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006872
Neale Ranns097fa662018-05-01 05:17:55 -07006873 vl_api_fib_path_t paths[8];
Damjan Marion7cd468a2016-12-19 23:05:39 +01006874 u32 sw_if_index = ~0;
Neale Ranns097fa662018-05-01 05:17:55 -07006875 u8 path_count = 0;
6876 u8 l2_only = 0;
6877 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006878 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006879
6880 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6881 {
6882 if (unformat (i, "add"))
6883 is_add = 1;
John Lo06fda9c2018-10-03 16:32:44 -04006884 else
6885 if (unformat
6886 (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
6887 is_add = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006888 else if (unformat (i, "del sw_if_index %d", &sw_if_index))
6889 is_add = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006890 else if (unformat (i, "l2-only"))
6891 l2_only = 1;
Neale Ranns097fa662018-05-01 05:17:55 -07006892 else
6893 if (unformat
6894 (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
John Lo06fda9c2018-10-03 16:32:44 -04006895 {
Neale Ranns097fa662018-05-01 05:17:55 -07006896 path_count++;
6897 if (8 == path_count)
6898 {
6899 errmsg ("max 8 paths");
6900 return -99;
6901 }
John Lo06fda9c2018-10-03 16:32:44 -04006902 }
Damjan Marion7cd468a2016-12-19 23:05:39 +01006903 else
6904 {
6905 clib_warning ("parse error '%U'", format_unformat_error, i);
6906 return -99;
6907 }
6908 }
6909
Neale Ranns097fa662018-05-01 05:17:55 -07006910 M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006911
Damjan Marion7cd468a2016-12-19 23:05:39 +01006912 mp->mt_is_add = is_add;
Neale Ranns097fa662018-05-01 05:17:55 -07006913 mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
6914 mp->mt_tunnel.mt_l2_only = l2_only;
6915 mp->mt_tunnel.mt_is_multicast = 0;
6916 mp->mt_tunnel.mt_n_paths = path_count;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006917
Neale Ranns097fa662018-05-01 05:17:55 -07006918 clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
6919 sizeof (paths[0]) * path_count);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006920
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006921 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06006922 W (ret);
6923 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006924}
6925
6926static int
6927api_sw_interface_set_unnumbered (vat_main_t * vam)
6928{
6929 unformat_input_t *i = vam->input;
6930 vl_api_sw_interface_set_unnumbered_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006931 u32 sw_if_index;
6932 u32 unnum_sw_index = ~0;
6933 u8 is_add = 1;
6934 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006935 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006936
6937 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6938 {
6939 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6940 sw_if_index_set = 1;
6941 else if (unformat (i, "sw_if_index %d", &sw_if_index))
6942 sw_if_index_set = 1;
6943 else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
6944 ;
6945 else if (unformat (i, "del"))
6946 is_add = 0;
6947 else
6948 {
6949 clib_warning ("parse error '%U'", format_unformat_error, i);
6950 return -99;
6951 }
6952 }
6953
6954 if (sw_if_index_set == 0)
6955 {
6956 errmsg ("missing interface name or sw_if_index");
6957 return -99;
6958 }
6959
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006960 M (SW_INTERFACE_SET_UNNUMBERED, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006961
6962 mp->sw_if_index = ntohl (sw_if_index);
6963 mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
6964 mp->is_add = is_add;
6965
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006966 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06006967 W (ret);
6968 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006969}
6970
Damjan Marion7cd468a2016-12-19 23:05:39 +01006971
6972static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01006973api_create_vlan_subif (vat_main_t * vam)
6974{
6975 unformat_input_t *i = vam->input;
6976 vl_api_create_vlan_subif_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006977 u32 sw_if_index;
6978 u8 sw_if_index_set = 0;
6979 u32 vlan_id;
6980 u8 vlan_id_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006981 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006982
6983 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6984 {
6985 if (unformat (i, "sw_if_index %d", &sw_if_index))
6986 sw_if_index_set = 1;
6987 else
6988 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6989 sw_if_index_set = 1;
6990 else if (unformat (i, "vlan %d", &vlan_id))
6991 vlan_id_set = 1;
6992 else
6993 {
6994 clib_warning ("parse error '%U'", format_unformat_error, i);
6995 return -99;
6996 }
6997 }
6998
6999 if (sw_if_index_set == 0)
7000 {
7001 errmsg ("missing interface name or sw_if_index");
7002 return -99;
7003 }
7004
7005 if (vlan_id_set == 0)
7006 {
7007 errmsg ("missing vlan_id");
7008 return -99;
7009 }
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007010 M (CREATE_VLAN_SUBIF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007011
7012 mp->sw_if_index = ntohl (sw_if_index);
7013 mp->vlan_id = ntohl (vlan_id);
7014
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007015 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007016 W (ret);
7017 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007018}
7019
7020#define foreach_create_subif_bit \
7021_(no_tags) \
7022_(one_tag) \
7023_(two_tags) \
7024_(dot1ad) \
7025_(exact_match) \
7026_(default_sub) \
7027_(outer_vlan_id_any) \
7028_(inner_vlan_id_any)
7029
Jakub Grajciar053204a2019-03-18 13:17:53 +01007030#define foreach_create_subif_flag \
7031_(0, "no_tags") \
7032_(1, "one_tag") \
7033_(2, "two_tags") \
7034_(3, "dot1ad") \
7035_(4, "exact_match") \
7036_(5, "default_sub") \
7037_(6, "outer_vlan_id_any") \
7038_(7, "inner_vlan_id_any")
7039
Damjan Marion7cd468a2016-12-19 23:05:39 +01007040static int
7041api_create_subif (vat_main_t * vam)
7042{
7043 unformat_input_t *i = vam->input;
7044 vl_api_create_subif_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007045 u32 sw_if_index;
7046 u8 sw_if_index_set = 0;
7047 u32 sub_id;
7048 u8 sub_id_set = 0;
Jakub Grajciar053204a2019-03-18 13:17:53 +01007049 u32 __attribute__ ((unused)) no_tags = 0;
7050 u32 __attribute__ ((unused)) one_tag = 0;
7051 u32 __attribute__ ((unused)) two_tags = 0;
7052 u32 __attribute__ ((unused)) dot1ad = 0;
7053 u32 __attribute__ ((unused)) exact_match = 0;
7054 u32 __attribute__ ((unused)) default_sub = 0;
7055 u32 __attribute__ ((unused)) outer_vlan_id_any = 0;
7056 u32 __attribute__ ((unused)) inner_vlan_id_any = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007057 u32 tmp;
7058 u16 outer_vlan_id = 0;
7059 u16 inner_vlan_id = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007060 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007061
7062 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7063 {
7064 if (unformat (i, "sw_if_index %d", &sw_if_index))
7065 sw_if_index_set = 1;
7066 else
7067 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7068 sw_if_index_set = 1;
7069 else if (unformat (i, "sub_id %d", &sub_id))
7070 sub_id_set = 1;
7071 else if (unformat (i, "outer_vlan_id %d", &tmp))
7072 outer_vlan_id = tmp;
7073 else if (unformat (i, "inner_vlan_id %d", &tmp))
7074 inner_vlan_id = tmp;
7075
7076#define _(a) else if (unformat (i, #a)) a = 1 ;
7077 foreach_create_subif_bit
7078#undef _
7079 else
7080 {
7081 clib_warning ("parse error '%U'", format_unformat_error, i);
7082 return -99;
7083 }
7084 }
7085
7086 if (sw_if_index_set == 0)
7087 {
7088 errmsg ("missing interface name or sw_if_index");
7089 return -99;
7090 }
7091
7092 if (sub_id_set == 0)
7093 {
7094 errmsg ("missing sub_id");
7095 return -99;
7096 }
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007097 M (CREATE_SUBIF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007098
7099 mp->sw_if_index = ntohl (sw_if_index);
7100 mp->sub_id = ntohl (sub_id);
7101
Jakub Grajciar053204a2019-03-18 13:17:53 +01007102#define _(a,b) mp->sub_if_flags |= (1 << a);
7103 foreach_create_subif_flag;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007104#undef _
7105
7106 mp->outer_vlan_id = ntohs (outer_vlan_id);
7107 mp->inner_vlan_id = ntohs (inner_vlan_id);
7108
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007109 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007110 W (ret);
7111 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007112}
7113
7114static int
Neale Ranns9db6ada2019-11-08 12:42:31 +00007115api_ip_table_replace_begin (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +01007116{
7117 unformat_input_t *i = vam->input;
Neale Ranns9db6ada2019-11-08 12:42:31 +00007118 vl_api_ip_table_replace_begin_t *mp;
7119 u32 table_id = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007120 u8 is_ipv6 = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007121
Jon Loeliger56c7b012017-02-01 12:31:41 -06007122 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007123 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7124 {
Neale Ranns9db6ada2019-11-08 12:42:31 +00007125 if (unformat (i, "table %d", &table_id))
7126 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007127 else if (unformat (i, "ipv6"))
7128 is_ipv6 = 1;
7129 else
7130 {
7131 clib_warning ("parse error '%U'", format_unformat_error, i);
7132 return -99;
7133 }
7134 }
7135
Neale Ranns9db6ada2019-11-08 12:42:31 +00007136 M (IP_TABLE_REPLACE_BEGIN, mp);
7137
7138 mp->table.table_id = ntohl (table_id);
7139 mp->table.is_ip6 = is_ipv6;
7140
7141 S (mp);
7142 W (ret);
7143 return ret;
7144}
7145
7146static int
7147api_ip_table_flush (vat_main_t * vam)
7148{
7149 unformat_input_t *i = vam->input;
7150 vl_api_ip_table_flush_t *mp;
7151 u32 table_id = 0;
7152 u8 is_ipv6 = 0;
7153
7154 int ret;
7155 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
Damjan Marion7cd468a2016-12-19 23:05:39 +01007156 {
Neale Ranns9db6ada2019-11-08 12:42:31 +00007157 if (unformat (i, "table %d", &table_id))
7158 ;
7159 else if (unformat (i, "ipv6"))
7160 is_ipv6 = 1;
7161 else
7162 {
7163 clib_warning ("parse error '%U'", format_unformat_error, i);
7164 return -99;
7165 }
Damjan Marion7cd468a2016-12-19 23:05:39 +01007166 }
7167
Neale Ranns9db6ada2019-11-08 12:42:31 +00007168 M (IP_TABLE_FLUSH, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007169
Neale Ranns9db6ada2019-11-08 12:42:31 +00007170 mp->table.table_id = ntohl (table_id);
7171 mp->table.is_ip6 = is_ipv6;
7172
7173 S (mp);
7174 W (ret);
7175 return ret;
7176}
7177
7178static int
7179api_ip_table_replace_end (vat_main_t * vam)
7180{
7181 unformat_input_t *i = vam->input;
7182 vl_api_ip_table_replace_end_t *mp;
7183 u32 table_id = 0;
7184 u8 is_ipv6 = 0;
7185
7186 int ret;
7187 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7188 {
7189 if (unformat (i, "table %d", &table_id))
7190 ;
7191 else if (unformat (i, "ipv6"))
7192 is_ipv6 = 1;
7193 else
7194 {
7195 clib_warning ("parse error '%U'", format_unformat_error, i);
7196 return -99;
7197 }
7198 }
7199
7200 M (IP_TABLE_REPLACE_END, mp);
7201
7202 mp->table.table_id = ntohl (table_id);
7203 mp->table.is_ip6 = is_ipv6;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007204
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007205 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007206 W (ret);
7207 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007208}
7209
7210static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01007211api_set_ip_flow_hash (vat_main_t * vam)
7212{
7213 unformat_input_t *i = vam->input;
7214 vl_api_set_ip_flow_hash_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007215 u32 vrf_id = 0;
7216 u8 is_ipv6 = 0;
7217 u8 vrf_id_set = 0;
7218 u8 src = 0;
7219 u8 dst = 0;
7220 u8 sport = 0;
7221 u8 dport = 0;
7222 u8 proto = 0;
7223 u8 reverse = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007224 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007225
7226 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7227 {
7228 if (unformat (i, "vrf %d", &vrf_id))
7229 vrf_id_set = 1;
7230 else if (unformat (i, "ipv6"))
7231 is_ipv6 = 1;
7232 else if (unformat (i, "src"))
7233 src = 1;
7234 else if (unformat (i, "dst"))
7235 dst = 1;
7236 else if (unformat (i, "sport"))
7237 sport = 1;
7238 else if (unformat (i, "dport"))
7239 dport = 1;
7240 else if (unformat (i, "proto"))
7241 proto = 1;
7242 else if (unformat (i, "reverse"))
7243 reverse = 1;
7244
7245 else
7246 {
7247 clib_warning ("parse error '%U'", format_unformat_error, i);
7248 return -99;
7249 }
7250 }
7251
7252 if (vrf_id_set == 0)
7253 {
7254 errmsg ("missing vrf id");
7255 return -99;
7256 }
7257
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007258 M (SET_IP_FLOW_HASH, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007259 mp->src = src;
7260 mp->dst = dst;
7261 mp->sport = sport;
7262 mp->dport = dport;
7263 mp->proto = proto;
7264 mp->reverse = reverse;
7265 mp->vrf_id = ntohl (vrf_id);
7266 mp->is_ipv6 = is_ipv6;
7267
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007268 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007269 W (ret);
7270 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007271}
7272
7273static int
7274api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7275{
7276 unformat_input_t *i = vam->input;
7277 vl_api_sw_interface_ip6_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007278 u32 sw_if_index;
7279 u8 sw_if_index_set = 0;
7280 u8 enable = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007281 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007282
7283 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7284 {
7285 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7286 sw_if_index_set = 1;
7287 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7288 sw_if_index_set = 1;
7289 else if (unformat (i, "enable"))
7290 enable = 1;
7291 else if (unformat (i, "disable"))
7292 enable = 0;
7293 else
7294 {
7295 clib_warning ("parse error '%U'", format_unformat_error, i);
7296 return -99;
7297 }
7298 }
7299
7300 if (sw_if_index_set == 0)
7301 {
7302 errmsg ("missing interface name or sw_if_index");
7303 return -99;
7304 }
7305
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007306 M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007307
7308 mp->sw_if_index = ntohl (sw_if_index);
7309 mp->enable = enable;
7310
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007311 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007312 W (ret);
7313 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007314}
7315
Damjan Marion7cd468a2016-12-19 23:05:39 +01007316
7317static int
7318api_l2_patch_add_del (vat_main_t * vam)
7319{
7320 unformat_input_t *i = vam->input;
7321 vl_api_l2_patch_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007322 u32 rx_sw_if_index;
7323 u8 rx_sw_if_index_set = 0;
7324 u32 tx_sw_if_index;
7325 u8 tx_sw_if_index_set = 0;
7326 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007327 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007328
7329 /* Parse args required to build the message */
7330 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7331 {
7332 if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7333 rx_sw_if_index_set = 1;
7334 else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7335 tx_sw_if_index_set = 1;
7336 else if (unformat (i, "rx"))
7337 {
7338 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7339 {
7340 if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7341 &rx_sw_if_index))
7342 rx_sw_if_index_set = 1;
7343 }
7344 else
7345 break;
7346 }
7347 else if (unformat (i, "tx"))
7348 {
7349 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7350 {
7351 if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7352 &tx_sw_if_index))
7353 tx_sw_if_index_set = 1;
7354 }
7355 else
7356 break;
7357 }
7358 else if (unformat (i, "del"))
7359 is_add = 0;
7360 else
7361 break;
7362 }
7363
7364 if (rx_sw_if_index_set == 0)
7365 {
7366 errmsg ("missing rx interface name or rx_sw_if_index");
7367 return -99;
7368 }
7369
7370 if (tx_sw_if_index_set == 0)
7371 {
7372 errmsg ("missing tx interface name or tx_sw_if_index");
7373 return -99;
7374 }
7375
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007376 M (L2_PATCH_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007377
7378 mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7379 mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7380 mp->is_add = is_add;
7381
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007382 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007383 W (ret);
7384 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007385}
7386
Pablo Camarillofb380952016-12-07 18:34:18 +01007387u8 is_del;
7388u8 localsid_addr[16];
7389u8 end_psp;
7390u8 behavior;
7391u32 sw_if_index;
7392u32 vlan_index;
7393u32 fib_table;
7394u8 nh_addr[16];
7395
7396static int
7397api_sr_localsid_add_del (vat_main_t * vam)
7398{
7399 unformat_input_t *i = vam->input;
7400 vl_api_sr_localsid_add_del_t *mp;
7401
7402 u8 is_del;
7403 ip6_address_t localsid;
7404 u8 end_psp = 0;
7405 u8 behavior = ~0;
7406 u32 sw_if_index;
7407 u32 fib_table = ~(u32) 0;
Jakub Grajciar0938eba2020-03-04 13:08:27 +01007408 ip46_address_t nh_addr;
7409 clib_memset (&nh_addr, 0, sizeof (ip46_address_t));
Pablo Camarillofb380952016-12-07 18:34:18 +01007410
7411 bool nexthop_set = 0;
7412
7413 int ret;
7414
7415 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7416 {
7417 if (unformat (i, "del"))
7418 is_del = 1;
7419 else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
Jakub Grajciar0938eba2020-03-04 13:08:27 +01007420 else if (unformat (i, "next-hop %U", unformat_ip46_address, &nh_addr))
Pablo Camarillofb380952016-12-07 18:34:18 +01007421 nexthop_set = 1;
7422 else if (unformat (i, "behavior %u", &behavior));
7423 else if (unformat (i, "sw_if_index %u", &sw_if_index));
7424 else if (unformat (i, "fib-table %u", &fib_table));
7425 else if (unformat (i, "end.psp %u", &behavior));
7426 else
7427 break;
7428 }
7429
7430 M (SR_LOCALSID_ADD_DEL, mp);
7431
Jakub Grajciar0938eba2020-03-04 13:08:27 +01007432 clib_memcpy (mp->localsid, &localsid, sizeof (mp->localsid));
Tetsuya Murakami1b81e6e2019-11-06 11:05:51 -08007433
Pablo Camarillofb380952016-12-07 18:34:18 +01007434 if (nexthop_set)
Pablo Camarillo3337bd22018-06-19 15:49:02 +02007435 {
Jakub Grajciar0938eba2020-03-04 13:08:27 +01007436 clib_memcpy (&mp->nh_addr.un, &nh_addr, sizeof (mp->nh_addr.un));
Pablo Camarillo3337bd22018-06-19 15:49:02 +02007437 }
Pablo Camarillofb380952016-12-07 18:34:18 +01007438 mp->behavior = behavior;
7439 mp->sw_if_index = ntohl (sw_if_index);
7440 mp->fib_table = ntohl (fib_table);
7441 mp->end_psp = end_psp;
7442 mp->is_del = is_del;
7443
7444 S (mp);
7445 W (ret);
7446 return ret;
7447}
7448
Damjan Marion7cd468a2016-12-19 23:05:39 +01007449static int
7450api_ioam_enable (vat_main_t * vam)
7451{
7452 unformat_input_t *input = vam->input;
7453 vl_api_ioam_enable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007454 u32 id = 0;
7455 int has_trace_option = 0;
7456 int has_pot_option = 0;
7457 int has_seqno_option = 0;
7458 int has_analyse_option = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007459 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007460
7461 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7462 {
7463 if (unformat (input, "trace"))
7464 has_trace_option = 1;
7465 else if (unformat (input, "pot"))
7466 has_pot_option = 1;
7467 else if (unformat (input, "seqno"))
7468 has_seqno_option = 1;
7469 else if (unformat (input, "analyse"))
7470 has_analyse_option = 1;
7471 else
7472 break;
7473 }
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007474 M (IOAM_ENABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007475 mp->id = htons (id);
7476 mp->seqno = has_seqno_option;
7477 mp->analyse = has_analyse_option;
7478 mp->pot_enable = has_pot_option;
7479 mp->trace_enable = has_trace_option;
7480
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007481 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007482 W (ret);
7483 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007484}
7485
7486
7487static int
7488api_ioam_disable (vat_main_t * vam)
7489{
7490 vl_api_ioam_disable_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007491 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007492
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007493 M (IOAM_DISABLE, mp);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007494 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007495 W (ret);
7496 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007497}
7498
Damjan Marion7cd468a2016-12-19 23:05:39 +01007499#define foreach_tcp_proto_field \
7500_(src_port) \
7501_(dst_port)
7502
7503#define foreach_udp_proto_field \
7504_(src_port) \
7505_(dst_port)
7506
7507#define foreach_ip4_proto_field \
7508_(src_address) \
7509_(dst_address) \
7510_(tos) \
7511_(length) \
7512_(fragment_id) \
7513_(ttl) \
7514_(protocol) \
7515_(checksum)
7516
Dave Barach4a3f69c2017-02-22 12:44:56 -05007517typedef struct
7518{
7519 u16 src_port, dst_port;
7520} tcpudp_header_t;
7521
7522#if VPP_API_TEST_BUILTIN == 0
Damjan Marion7cd468a2016-12-19 23:05:39 +01007523uword
7524unformat_tcp_mask (unformat_input_t * input, va_list * args)
7525{
7526 u8 **maskp = va_arg (*args, u8 **);
7527 u8 *mask = 0;
7528 u8 found_something = 0;
7529 tcp_header_t *tcp;
7530
7531#define _(a) u8 a=0;
7532 foreach_tcp_proto_field;
7533#undef _
7534
7535 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7536 {
7537 if (0);
7538#define _(a) else if (unformat (input, #a)) a=1;
7539 foreach_tcp_proto_field
7540#undef _
7541 else
7542 break;
7543 }
7544
7545#define _(a) found_something += a;
7546 foreach_tcp_proto_field;
7547#undef _
7548
7549 if (found_something == 0)
7550 return 0;
7551
7552 vec_validate (mask, sizeof (*tcp) - 1);
7553
7554 tcp = (tcp_header_t *) mask;
7555
Dave Barachb7b92992018-10-17 10:38:51 -04007556#define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
Damjan Marion7cd468a2016-12-19 23:05:39 +01007557 foreach_tcp_proto_field;
7558#undef _
7559
7560 *maskp = mask;
7561 return 1;
7562}
7563
7564uword
7565unformat_udp_mask (unformat_input_t * input, va_list * args)
7566{
7567 u8 **maskp = va_arg (*args, u8 **);
7568 u8 *mask = 0;
7569 u8 found_something = 0;
7570 udp_header_t *udp;
7571
7572#define _(a) u8 a=0;
7573 foreach_udp_proto_field;
7574#undef _
7575
7576 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7577 {
7578 if (0);
7579#define _(a) else if (unformat (input, #a)) a=1;
7580 foreach_udp_proto_field
7581#undef _
7582 else
7583 break;
7584 }
7585
7586#define _(a) found_something += a;
7587 foreach_udp_proto_field;
7588#undef _
7589
7590 if (found_something == 0)
7591 return 0;
7592
7593 vec_validate (mask, sizeof (*udp) - 1);
7594
7595 udp = (udp_header_t *) mask;
7596
Dave Barachb7b92992018-10-17 10:38:51 -04007597#define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
Damjan Marion7cd468a2016-12-19 23:05:39 +01007598 foreach_udp_proto_field;
7599#undef _
7600
7601 *maskp = mask;
7602 return 1;
7603}
7604
Damjan Marion7cd468a2016-12-19 23:05:39 +01007605uword
7606unformat_l4_mask (unformat_input_t * input, va_list * args)
7607{
7608 u8 **maskp = va_arg (*args, u8 **);
7609 u16 src_port = 0, dst_port = 0;
7610 tcpudp_header_t *tcpudp;
7611
7612 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7613 {
7614 if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
7615 return 1;
7616 else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
7617 return 1;
7618 else if (unformat (input, "src_port"))
7619 src_port = 0xFFFF;
7620 else if (unformat (input, "dst_port"))
7621 dst_port = 0xFFFF;
7622 else
7623 return 0;
7624 }
7625
7626 if (!src_port && !dst_port)
7627 return 0;
7628
7629 u8 *mask = 0;
7630 vec_validate (mask, sizeof (tcpudp_header_t) - 1);
7631
7632 tcpudp = (tcpudp_header_t *) mask;
7633 tcpudp->src_port = src_port;
7634 tcpudp->dst_port = dst_port;
7635
7636 *maskp = mask;
7637
7638 return 1;
7639}
7640
7641uword
7642unformat_ip4_mask (unformat_input_t * input, va_list * args)
7643{
7644 u8 **maskp = va_arg (*args, u8 **);
7645 u8 *mask = 0;
7646 u8 found_something = 0;
7647 ip4_header_t *ip;
7648
7649#define _(a) u8 a=0;
7650 foreach_ip4_proto_field;
7651#undef _
7652 u8 version = 0;
7653 u8 hdr_length = 0;
7654
7655
7656 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7657 {
7658 if (unformat (input, "version"))
7659 version = 1;
7660 else if (unformat (input, "hdr_length"))
7661 hdr_length = 1;
7662 else if (unformat (input, "src"))
7663 src_address = 1;
7664 else if (unformat (input, "dst"))
7665 dst_address = 1;
7666 else if (unformat (input, "proto"))
7667 protocol = 1;
7668
7669#define _(a) else if (unformat (input, #a)) a=1;
7670 foreach_ip4_proto_field
7671#undef _
7672 else
7673 break;
7674 }
7675
7676#define _(a) found_something += a;
7677 foreach_ip4_proto_field;
7678#undef _
7679
7680 if (found_something == 0)
7681 return 0;
7682
7683 vec_validate (mask, sizeof (*ip) - 1);
7684
7685 ip = (ip4_header_t *) mask;
7686
Dave Barachb7b92992018-10-17 10:38:51 -04007687#define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
Damjan Marion7cd468a2016-12-19 23:05:39 +01007688 foreach_ip4_proto_field;
7689#undef _
7690
7691 ip->ip_version_and_header_length = 0;
7692
7693 if (version)
7694 ip->ip_version_and_header_length |= 0xF0;
7695
7696 if (hdr_length)
7697 ip->ip_version_and_header_length |= 0x0F;
7698
7699 *maskp = mask;
7700 return 1;
7701}
7702
7703#define foreach_ip6_proto_field \
7704_(src_address) \
7705_(dst_address) \
7706_(payload_length) \
7707_(hop_limit) \
7708_(protocol)
7709
7710uword
7711unformat_ip6_mask (unformat_input_t * input, va_list * args)
7712{
7713 u8 **maskp = va_arg (*args, u8 **);
7714 u8 *mask = 0;
7715 u8 found_something = 0;
7716 ip6_header_t *ip;
7717 u32 ip_version_traffic_class_and_flow_label;
7718
7719#define _(a) u8 a=0;
7720 foreach_ip6_proto_field;
7721#undef _
7722 u8 version = 0;
7723 u8 traffic_class = 0;
7724 u8 flow_label = 0;
7725
7726 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7727 {
7728 if (unformat (input, "version"))
7729 version = 1;
7730 else if (unformat (input, "traffic-class"))
7731 traffic_class = 1;
7732 else if (unformat (input, "flow-label"))
7733 flow_label = 1;
7734 else if (unformat (input, "src"))
7735 src_address = 1;
7736 else if (unformat (input, "dst"))
7737 dst_address = 1;
7738 else if (unformat (input, "proto"))
7739 protocol = 1;
7740
7741#define _(a) else if (unformat (input, #a)) a=1;
7742 foreach_ip6_proto_field
7743#undef _
7744 else
7745 break;
7746 }
7747
7748#define _(a) found_something += a;
7749 foreach_ip6_proto_field;
7750#undef _
7751
7752 if (found_something == 0)
7753 return 0;
7754
7755 vec_validate (mask, sizeof (*ip) - 1);
7756
7757 ip = (ip6_header_t *) mask;
7758
Dave Barachb7b92992018-10-17 10:38:51 -04007759#define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
Damjan Marion7cd468a2016-12-19 23:05:39 +01007760 foreach_ip6_proto_field;
7761#undef _
7762
7763 ip_version_traffic_class_and_flow_label = 0;
7764
7765 if (version)
7766 ip_version_traffic_class_and_flow_label |= 0xF0000000;
7767
7768 if (traffic_class)
7769 ip_version_traffic_class_and_flow_label |= 0x0FF00000;
7770
7771 if (flow_label)
7772 ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
7773
7774 ip->ip_version_traffic_class_and_flow_label =
7775 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
7776
7777 *maskp = mask;
7778 return 1;
7779}
7780
7781uword
7782unformat_l3_mask (unformat_input_t * input, va_list * args)
7783{
7784 u8 **maskp = va_arg (*args, u8 **);
7785
7786 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7787 {
7788 if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
7789 return 1;
7790 else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
7791 return 1;
7792 else
7793 break;
7794 }
7795 return 0;
7796}
7797
7798uword
7799unformat_l2_mask (unformat_input_t * input, va_list * args)
7800{
7801 u8 **maskp = va_arg (*args, u8 **);
7802 u8 *mask = 0;
7803 u8 src = 0;
7804 u8 dst = 0;
7805 u8 proto = 0;
7806 u8 tag1 = 0;
7807 u8 tag2 = 0;
7808 u8 ignore_tag1 = 0;
7809 u8 ignore_tag2 = 0;
7810 u8 cos1 = 0;
7811 u8 cos2 = 0;
7812 u8 dot1q = 0;
7813 u8 dot1ad = 0;
7814 int len = 14;
7815
7816 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7817 {
7818 if (unformat (input, "src"))
7819 src = 1;
7820 else if (unformat (input, "dst"))
7821 dst = 1;
7822 else if (unformat (input, "proto"))
7823 proto = 1;
7824 else if (unformat (input, "tag1"))
7825 tag1 = 1;
7826 else if (unformat (input, "tag2"))
7827 tag2 = 1;
7828 else if (unformat (input, "ignore-tag1"))
7829 ignore_tag1 = 1;
7830 else if (unformat (input, "ignore-tag2"))
7831 ignore_tag2 = 1;
7832 else if (unformat (input, "cos1"))
7833 cos1 = 1;
7834 else if (unformat (input, "cos2"))
7835 cos2 = 1;
7836 else if (unformat (input, "dot1q"))
7837 dot1q = 1;
7838 else if (unformat (input, "dot1ad"))
7839 dot1ad = 1;
7840 else
7841 break;
7842 }
7843 if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
7844 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
7845 return 0;
7846
7847 if (tag1 || ignore_tag1 || cos1 || dot1q)
7848 len = 18;
7849 if (tag2 || ignore_tag2 || cos2 || dot1ad)
7850 len = 22;
7851
7852 vec_validate (mask, len - 1);
7853
7854 if (dst)
Dave Barachb7b92992018-10-17 10:38:51 -04007855 clib_memset (mask, 0xff, 6);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007856
7857 if (src)
Dave Barachb7b92992018-10-17 10:38:51 -04007858 clib_memset (mask + 6, 0xff, 6);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007859
7860 if (tag2 || dot1ad)
7861 {
7862 /* inner vlan tag */
7863 if (tag2)
7864 {
7865 mask[19] = 0xff;
7866 mask[18] = 0x0f;
7867 }
7868 if (cos2)
7869 mask[18] |= 0xe0;
7870 if (proto)
7871 mask[21] = mask[20] = 0xff;
7872 if (tag1)
7873 {
7874 mask[15] = 0xff;
7875 mask[14] = 0x0f;
7876 }
7877 if (cos1)
7878 mask[14] |= 0xe0;
7879 *maskp = mask;
7880 return 1;
7881 }
7882 if (tag1 | dot1q)
7883 {
7884 if (tag1)
7885 {
7886 mask[15] = 0xff;
7887 mask[14] = 0x0f;
7888 }
7889 if (cos1)
7890 mask[14] |= 0xe0;
7891 if (proto)
7892 mask[16] = mask[17] = 0xff;
7893
7894 *maskp = mask;
7895 return 1;
7896 }
7897 if (cos2)
7898 mask[18] |= 0xe0;
7899 if (cos1)
7900 mask[14] |= 0xe0;
7901 if (proto)
7902 mask[12] = mask[13] = 0xff;
7903
7904 *maskp = mask;
7905 return 1;
7906}
7907
7908uword
7909unformat_classify_mask (unformat_input_t * input, va_list * args)
7910{
7911 u8 **maskp = va_arg (*args, u8 **);
7912 u32 *skipp = va_arg (*args, u32 *);
7913 u32 *matchp = va_arg (*args, u32 *);
7914 u32 match;
7915 u8 *mask = 0;
7916 u8 *l2 = 0;
7917 u8 *l3 = 0;
7918 u8 *l4 = 0;
7919 int i;
7920
7921 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7922 {
7923 if (unformat (input, "hex %U", unformat_hex_string, &mask))
7924 ;
7925 else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
7926 ;
7927 else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
7928 ;
7929 else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
7930 ;
7931 else
7932 break;
7933 }
7934
7935 if (l4 && !l3)
7936 {
7937 vec_free (mask);
7938 vec_free (l2);
7939 vec_free (l4);
7940 return 0;
7941 }
7942
7943 if (mask || l2 || l3 || l4)
7944 {
7945 if (l2 || l3 || l4)
7946 {
7947 /* "With a free Ethernet header in every package" */
7948 if (l2 == 0)
7949 vec_validate (l2, 13);
7950 mask = l2;
7951 if (vec_len (l3))
7952 {
7953 vec_append (mask, l3);
7954 vec_free (l3);
7955 }
7956 if (vec_len (l4))
7957 {
7958 vec_append (mask, l4);
7959 vec_free (l4);
7960 }
7961 }
7962
7963 /* Scan forward looking for the first significant mask octet */
7964 for (i = 0; i < vec_len (mask); i++)
7965 if (mask[i])
7966 break;
7967
7968 /* compute (skip, match) params */
7969 *skipp = i / sizeof (u32x4);
7970 vec_delete (mask, *skipp * sizeof (u32x4), 0);
7971
7972 /* Pad mask to an even multiple of the vector size */
7973 while (vec_len (mask) % sizeof (u32x4))
7974 vec_add1 (mask, 0);
7975
7976 match = vec_len (mask) / sizeof (u32x4);
7977
7978 for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
7979 {
7980 u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
7981 if (*tmp || *(tmp + 1))
7982 break;
7983 match--;
7984 }
7985 if (match == 0)
7986 clib_warning ("BUG: match 0");
7987
7988 _vec_len (mask) = match * sizeof (u32x4);
7989
7990 *matchp = match;
7991 *maskp = mask;
7992
7993 return 1;
7994 }
7995
7996 return 0;
7997}
Dave Barach4a3f69c2017-02-22 12:44:56 -05007998#endif /* VPP_API_TEST_BUILTIN */
Damjan Marion7cd468a2016-12-19 23:05:39 +01007999
8000#define foreach_l2_next \
8001_(drop, DROP) \
8002_(ethernet, ETHERNET_INPUT) \
8003_(ip4, IP4_INPUT) \
8004_(ip6, IP6_INPUT)
8005
8006uword
8007unformat_l2_next_index (unformat_input_t * input, va_list * args)
8008{
8009 u32 *miss_next_indexp = va_arg (*args, u32 *);
8010 u32 next_index = 0;
8011 u32 tmp;
8012
8013#define _(n,N) \
8014 if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
8015 foreach_l2_next;
8016#undef _
8017
8018 if (unformat (input, "%d", &tmp))
8019 {
8020 next_index = tmp;
8021 goto out;
8022 }
8023
8024 return 0;
8025
8026out:
8027 *miss_next_indexp = next_index;
8028 return 1;
8029}
8030
8031#define foreach_ip_next \
8032_(drop, DROP) \
8033_(local, LOCAL) \
8034_(rewrite, REWRITE)
8035
8036uword
Dave Barach4a3f69c2017-02-22 12:44:56 -05008037api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
Damjan Marion7cd468a2016-12-19 23:05:39 +01008038{
8039 u32 *miss_next_indexp = va_arg (*args, u32 *);
8040 u32 next_index = 0;
8041 u32 tmp;
8042
8043#define _(n,N) \
8044 if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
8045 foreach_ip_next;
8046#undef _
8047
8048 if (unformat (input, "%d", &tmp))
8049 {
8050 next_index = tmp;
8051 goto out;
8052 }
8053
8054 return 0;
8055
8056out:
8057 *miss_next_indexp = next_index;
8058 return 1;
8059}
8060
8061#define foreach_acl_next \
8062_(deny, DENY)
8063
8064uword
Dave Barach4a3f69c2017-02-22 12:44:56 -05008065api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
Damjan Marion7cd468a2016-12-19 23:05:39 +01008066{
8067 u32 *miss_next_indexp = va_arg (*args, u32 *);
8068 u32 next_index = 0;
8069 u32 tmp;
8070
8071#define _(n,N) \
8072 if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
8073 foreach_acl_next;
8074#undef _
8075
8076 if (unformat (input, "permit"))
8077 {
8078 next_index = ~0;
8079 goto out;
8080 }
8081 else if (unformat (input, "%d", &tmp))
8082 {
8083 next_index = tmp;
8084 goto out;
8085 }
8086
8087 return 0;
8088
8089out:
8090 *miss_next_indexp = next_index;
8091 return 1;
8092}
8093
8094uword
8095unformat_policer_precolor (unformat_input_t * input, va_list * args)
8096{
8097 u32 *r = va_arg (*args, u32 *);
8098
8099 if (unformat (input, "conform-color"))
8100 *r = POLICE_CONFORM;
8101 else if (unformat (input, "exceed-color"))
8102 *r = POLICE_EXCEED;
8103 else
8104 return 0;
8105
8106 return 1;
8107}
8108
8109static int
8110api_classify_add_del_table (vat_main_t * vam)
8111{
8112 unformat_input_t *i = vam->input;
8113 vl_api_classify_add_del_table_t *mp;
8114
8115 u32 nbuckets = 2;
8116 u32 skip = ~0;
8117 u32 match = ~0;
8118 int is_add = 1;
8119 int del_chain = 0;
8120 u32 table_index = ~0;
8121 u32 next_table_index = ~0;
8122 u32 miss_next_index = ~0;
8123 u32 memory_size = 32 << 20;
8124 u8 *mask = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008125 u32 current_data_flag = 0;
8126 int current_data_offset = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008127 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008128
8129 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8130 {
8131 if (unformat (i, "del"))
8132 is_add = 0;
8133 else if (unformat (i, "del-chain"))
8134 {
8135 is_add = 0;
8136 del_chain = 1;
8137 }
8138 else if (unformat (i, "buckets %d", &nbuckets))
8139 ;
8140 else if (unformat (i, "memory_size %d", &memory_size))
8141 ;
8142 else if (unformat (i, "skip %d", &skip))
8143 ;
8144 else if (unformat (i, "match %d", &match))
8145 ;
8146 else if (unformat (i, "table %d", &table_index))
8147 ;
8148 else if (unformat (i, "mask %U", unformat_classify_mask,
8149 &mask, &skip, &match))
8150 ;
8151 else if (unformat (i, "next-table %d", &next_table_index))
8152 ;
Dave Barach4a3f69c2017-02-22 12:44:56 -05008153 else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
Damjan Marion7cd468a2016-12-19 23:05:39 +01008154 &miss_next_index))
8155 ;
8156 else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
8157 &miss_next_index))
8158 ;
Dave Barach4a3f69c2017-02-22 12:44:56 -05008159 else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
Damjan Marion7cd468a2016-12-19 23:05:39 +01008160 &miss_next_index))
8161 ;
8162 else if (unformat (i, "current-data-flag %d", &current_data_flag))
8163 ;
8164 else if (unformat (i, "current-data-offset %d", &current_data_offset))
8165 ;
8166 else
8167 break;
8168 }
8169
8170 if (is_add && mask == 0)
8171 {
8172 errmsg ("Mask required");
8173 return -99;
8174 }
8175
8176 if (is_add && skip == ~0)
8177 {
8178 errmsg ("skip count required");
8179 return -99;
8180 }
8181
8182 if (is_add && match == ~0)
8183 {
8184 errmsg ("match count required");
8185 return -99;
8186 }
8187
8188 if (!is_add && table_index == ~0)
8189 {
8190 errmsg ("table index required for delete");
8191 return -99;
8192 }
8193
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008194 M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
Damjan Marion7cd468a2016-12-19 23:05:39 +01008195
8196 mp->is_add = is_add;
8197 mp->del_chain = del_chain;
8198 mp->table_index = ntohl (table_index);
8199 mp->nbuckets = ntohl (nbuckets);
8200 mp->memory_size = ntohl (memory_size);
8201 mp->skip_n_vectors = ntohl (skip);
8202 mp->match_n_vectors = ntohl (match);
8203 mp->next_table_index = ntohl (next_table_index);
8204 mp->miss_next_index = ntohl (miss_next_index);
8205 mp->current_data_flag = ntohl (current_data_flag);
8206 mp->current_data_offset = ntohl (current_data_offset);
Juraj Sloboda75282452018-06-12 14:20:49 +02008207 mp->mask_len = ntohl (vec_len (mask));
Damjan Marion7cd468a2016-12-19 23:05:39 +01008208 clib_memcpy (mp->mask, mask, vec_len (mask));
8209
8210 vec_free (mask);
8211
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008212 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008213 W (ret);
8214 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008215}
8216
Dave Barach4a3f69c2017-02-22 12:44:56 -05008217#if VPP_API_TEST_BUILTIN == 0
Damjan Marion7cd468a2016-12-19 23:05:39 +01008218uword
8219unformat_l4_match (unformat_input_t * input, va_list * args)
8220{
8221 u8 **matchp = va_arg (*args, u8 **);
8222
8223 u8 *proto_header = 0;
8224 int src_port = 0;
8225 int dst_port = 0;
8226
8227 tcpudp_header_t h;
8228
8229 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8230 {
8231 if (unformat (input, "src_port %d", &src_port))
8232 ;
8233 else if (unformat (input, "dst_port %d", &dst_port))
8234 ;
8235 else
8236 return 0;
8237 }
8238
8239 h.src_port = clib_host_to_net_u16 (src_port);
8240 h.dst_port = clib_host_to_net_u16 (dst_port);
8241 vec_validate (proto_header, sizeof (h) - 1);
8242 memcpy (proto_header, &h, sizeof (h));
8243
8244 *matchp = proto_header;
8245
8246 return 1;
8247}
8248
8249uword
8250unformat_ip4_match (unformat_input_t * input, va_list * args)
8251{
8252 u8 **matchp = va_arg (*args, u8 **);
8253 u8 *match = 0;
8254 ip4_header_t *ip;
8255 int version = 0;
8256 u32 version_val;
8257 int hdr_length = 0;
8258 u32 hdr_length_val;
8259 int src = 0, dst = 0;
8260 ip4_address_t src_val, dst_val;
8261 int proto = 0;
8262 u32 proto_val;
8263 int tos = 0;
8264 u32 tos_val;
8265 int length = 0;
8266 u32 length_val;
8267 int fragment_id = 0;
8268 u32 fragment_id_val;
8269 int ttl = 0;
8270 int ttl_val;
8271 int checksum = 0;
8272 u32 checksum_val;
8273
8274 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8275 {
8276 if (unformat (input, "version %d", &version_val))
8277 version = 1;
8278 else if (unformat (input, "hdr_length %d", &hdr_length_val))
8279 hdr_length = 1;
8280 else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
8281 src = 1;
8282 else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
8283 dst = 1;
8284 else if (unformat (input, "proto %d", &proto_val))
8285 proto = 1;
8286 else if (unformat (input, "tos %d", &tos_val))
8287 tos = 1;
8288 else if (unformat (input, "length %d", &length_val))
8289 length = 1;
8290 else if (unformat (input, "fragment_id %d", &fragment_id_val))
8291 fragment_id = 1;
8292 else if (unformat (input, "ttl %d", &ttl_val))
8293 ttl = 1;
8294 else if (unformat (input, "checksum %d", &checksum_val))
8295 checksum = 1;
8296 else
8297 break;
8298 }
8299
8300 if (version + hdr_length + src + dst + proto + tos + length + fragment_id
8301 + ttl + checksum == 0)
8302 return 0;
8303
8304 /*
8305 * Aligned because we use the real comparison functions
8306 */
8307 vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8308
8309 ip = (ip4_header_t *) match;
8310
8311 /* These are realistically matched in practice */
8312 if (src)
8313 ip->src_address.as_u32 = src_val.as_u32;
8314
8315 if (dst)
8316 ip->dst_address.as_u32 = dst_val.as_u32;
8317
8318 if (proto)
8319 ip->protocol = proto_val;
8320
8321
8322 /* These are not, but they're included for completeness */
8323 if (version)
8324 ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
8325
8326 if (hdr_length)
8327 ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
8328
8329 if (tos)
8330 ip->tos = tos_val;
8331
8332 if (length)
8333 ip->length = clib_host_to_net_u16 (length_val);
8334
8335 if (ttl)
8336 ip->ttl = ttl_val;
8337
8338 if (checksum)
8339 ip->checksum = clib_host_to_net_u16 (checksum_val);
8340
8341 *matchp = match;
8342 return 1;
8343}
8344
8345uword
8346unformat_ip6_match (unformat_input_t * input, va_list * args)
8347{
8348 u8 **matchp = va_arg (*args, u8 **);
8349 u8 *match = 0;
8350 ip6_header_t *ip;
8351 int version = 0;
8352 u32 version_val;
8353 u8 traffic_class = 0;
8354 u32 traffic_class_val = 0;
8355 u8 flow_label = 0;
8356 u8 flow_label_val;
8357 int src = 0, dst = 0;
8358 ip6_address_t src_val, dst_val;
8359 int proto = 0;
8360 u32 proto_val;
8361 int payload_length = 0;
8362 u32 payload_length_val;
8363 int hop_limit = 0;
8364 int hop_limit_val;
8365 u32 ip_version_traffic_class_and_flow_label;
8366
8367 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8368 {
8369 if (unformat (input, "version %d", &version_val))
8370 version = 1;
8371 else if (unformat (input, "traffic_class %d", &traffic_class_val))
8372 traffic_class = 1;
8373 else if (unformat (input, "flow_label %d", &flow_label_val))
8374 flow_label = 1;
8375 else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
8376 src = 1;
8377 else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
8378 dst = 1;
8379 else if (unformat (input, "proto %d", &proto_val))
8380 proto = 1;
8381 else if (unformat (input, "payload_length %d", &payload_length_val))
8382 payload_length = 1;
8383 else if (unformat (input, "hop_limit %d", &hop_limit_val))
8384 hop_limit = 1;
8385 else
8386 break;
8387 }
8388
8389 if (version + traffic_class + flow_label + src + dst + proto +
8390 payload_length + hop_limit == 0)
8391 return 0;
8392
8393 /*
8394 * Aligned because we use the real comparison functions
8395 */
8396 vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8397
8398 ip = (ip6_header_t *) match;
8399
8400 if (src)
8401 clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
8402
8403 if (dst)
8404 clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
8405
8406 if (proto)
8407 ip->protocol = proto_val;
8408
8409 ip_version_traffic_class_and_flow_label = 0;
8410
8411 if (version)
8412 ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
8413
8414 if (traffic_class)
8415 ip_version_traffic_class_and_flow_label |=
8416 (traffic_class_val & 0xFF) << 20;
8417
8418 if (flow_label)
8419 ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
8420
8421 ip->ip_version_traffic_class_and_flow_label =
8422 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8423
8424 if (payload_length)
8425 ip->payload_length = clib_host_to_net_u16 (payload_length_val);
8426
8427 if (hop_limit)
8428 ip->hop_limit = hop_limit_val;
8429
8430 *matchp = match;
8431 return 1;
8432}
8433
8434uword
8435unformat_l3_match (unformat_input_t * input, va_list * args)
8436{
8437 u8 **matchp = va_arg (*args, u8 **);
8438
8439 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8440 {
8441 if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
8442 return 1;
8443 else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
8444 return 1;
8445 else
8446 break;
8447 }
8448 return 0;
8449}
8450
8451uword
8452unformat_vlan_tag (unformat_input_t * input, va_list * args)
8453{
8454 u8 *tagp = va_arg (*args, u8 *);
8455 u32 tag;
8456
8457 if (unformat (input, "%d", &tag))
8458 {
8459 tagp[0] = (tag >> 8) & 0x0F;
8460 tagp[1] = tag & 0xFF;
8461 return 1;
8462 }
8463
8464 return 0;
8465}
8466
8467uword
8468unformat_l2_match (unformat_input_t * input, va_list * args)
8469{
8470 u8 **matchp = va_arg (*args, u8 **);
8471 u8 *match = 0;
8472 u8 src = 0;
8473 u8 src_val[6];
8474 u8 dst = 0;
8475 u8 dst_val[6];
8476 u8 proto = 0;
8477 u16 proto_val;
8478 u8 tag1 = 0;
8479 u8 tag1_val[2];
8480 u8 tag2 = 0;
8481 u8 tag2_val[2];
8482 int len = 14;
8483 u8 ignore_tag1 = 0;
8484 u8 ignore_tag2 = 0;
8485 u8 cos1 = 0;
8486 u8 cos2 = 0;
8487 u32 cos1_val = 0;
8488 u32 cos2_val = 0;
8489
8490 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8491 {
8492 if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
8493 src = 1;
8494 else
8495 if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
8496 dst = 1;
8497 else if (unformat (input, "proto %U",
8498 unformat_ethernet_type_host_byte_order, &proto_val))
8499 proto = 1;
8500 else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
8501 tag1 = 1;
8502 else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
8503 tag2 = 1;
8504 else if (unformat (input, "ignore-tag1"))
8505 ignore_tag1 = 1;
8506 else if (unformat (input, "ignore-tag2"))
8507 ignore_tag2 = 1;
8508 else if (unformat (input, "cos1 %d", &cos1_val))
8509 cos1 = 1;
8510 else if (unformat (input, "cos2 %d", &cos2_val))
8511 cos2 = 1;
8512 else
8513 break;
8514 }
8515 if ((src + dst + proto + tag1 + tag2 +
8516 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8517 return 0;
8518
8519 if (tag1 || ignore_tag1 || cos1)
8520 len = 18;
8521 if (tag2 || ignore_tag2 || cos2)
8522 len = 22;
8523
8524 vec_validate_aligned (match, len - 1, sizeof (u32x4));
8525
8526 if (dst)
8527 clib_memcpy (match, dst_val, 6);
8528
8529 if (src)
8530 clib_memcpy (match + 6, src_val, 6);
8531
8532 if (tag2)
8533 {
8534 /* inner vlan tag */
8535 match[19] = tag2_val[1];
8536 match[18] = tag2_val[0];
8537 if (cos2)
8538 match[18] |= (cos2_val & 0x7) << 5;
8539 if (proto)
8540 {
8541 match[21] = proto_val & 0xff;
8542 match[20] = proto_val >> 8;
8543 }
8544 if (tag1)
8545 {
8546 match[15] = tag1_val[1];
8547 match[14] = tag1_val[0];
8548 }
8549 if (cos1)
8550 match[14] |= (cos1_val & 0x7) << 5;
8551 *matchp = match;
8552 return 1;
8553 }
8554 if (tag1)
8555 {
8556 match[15] = tag1_val[1];
8557 match[14] = tag1_val[0];
8558 if (proto)
8559 {
8560 match[17] = proto_val & 0xff;
8561 match[16] = proto_val >> 8;
8562 }
8563 if (cos1)
8564 match[14] |= (cos1_val & 0x7) << 5;
8565
8566 *matchp = match;
8567 return 1;
8568 }
8569 if (cos2)
8570 match[18] |= (cos2_val & 0x7) << 5;
8571 if (cos1)
8572 match[14] |= (cos1_val & 0x7) << 5;
8573 if (proto)
8574 {
8575 match[13] = proto_val & 0xff;
8576 match[12] = proto_val >> 8;
8577 }
8578
8579 *matchp = match;
8580 return 1;
8581}
Igor Mikhailov (imichail)582caa32018-04-26 21:33:02 -07008582
8583uword
8584unformat_qos_source (unformat_input_t * input, va_list * args)
8585{
8586 int *qs = va_arg (*args, int *);
8587
8588 if (unformat (input, "ip"))
8589 *qs = QOS_SOURCE_IP;
8590 else if (unformat (input, "mpls"))
8591 *qs = QOS_SOURCE_MPLS;
8592 else if (unformat (input, "ext"))
8593 *qs = QOS_SOURCE_EXT;
8594 else if (unformat (input, "vlan"))
8595 *qs = QOS_SOURCE_VLAN;
8596 else
8597 return 0;
8598
8599 return 1;
8600}
Dave Barach4a3f69c2017-02-22 12:44:56 -05008601#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +01008602
8603uword
Dave Barach4a3f69c2017-02-22 12:44:56 -05008604api_unformat_classify_match (unformat_input_t * input, va_list * args)
Damjan Marion7cd468a2016-12-19 23:05:39 +01008605{
8606 u8 **matchp = va_arg (*args, u8 **);
8607 u32 skip_n_vectors = va_arg (*args, u32);
8608 u32 match_n_vectors = va_arg (*args, u32);
8609
8610 u8 *match = 0;
8611 u8 *l2 = 0;
8612 u8 *l3 = 0;
8613 u8 *l4 = 0;
8614
8615 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8616 {
8617 if (unformat (input, "hex %U", unformat_hex_string, &match))
8618 ;
8619 else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
8620 ;
8621 else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
8622 ;
8623 else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
8624 ;
8625 else
8626 break;
8627 }
8628
8629 if (l4 && !l3)
8630 {
8631 vec_free (match);
8632 vec_free (l2);
8633 vec_free (l4);
8634 return 0;
8635 }
8636
8637 if (match || l2 || l3 || l4)
8638 {
8639 if (l2 || l3 || l4)
8640 {
8641 /* "Win a free Ethernet header in every packet" */
8642 if (l2 == 0)
8643 vec_validate_aligned (l2, 13, sizeof (u32x4));
8644 match = l2;
8645 if (vec_len (l3))
8646 {
8647 vec_append_aligned (match, l3, sizeof (u32x4));
8648 vec_free (l3);
8649 }
8650 if (vec_len (l4))
8651 {
8652 vec_append_aligned (match, l4, sizeof (u32x4));
8653 vec_free (l4);
8654 }
8655 }
8656
8657 /* Make sure the vector is big enough even if key is all 0's */
8658 vec_validate_aligned
8659 (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
8660 sizeof (u32x4));
8661
8662 /* Set size, include skipped vectors */
8663 _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
8664
8665 *matchp = match;
8666
8667 return 1;
8668 }
8669
8670 return 0;
8671}
8672
8673static int
8674api_classify_add_del_session (vat_main_t * vam)
8675{
8676 unformat_input_t *i = vam->input;
8677 vl_api_classify_add_del_session_t *mp;
8678 int is_add = 1;
8679 u32 table_index = ~0;
8680 u32 hit_next_index = ~0;
8681 u32 opaque_index = ~0;
8682 u8 *match = 0;
8683 i32 advance = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008684 u32 skip_n_vectors = 0;
8685 u32 match_n_vectors = 0;
8686 u32 action = 0;
8687 u32 metadata = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008688 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008689
8690 /*
8691 * Warning: you have to supply skip_n and match_n
8692 * because the API client cant simply look at the classify
8693 * table object.
8694 */
8695
8696 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8697 {
8698 if (unformat (i, "del"))
8699 is_add = 0;
Dave Barach4a3f69c2017-02-22 12:44:56 -05008700 else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
Damjan Marion7cd468a2016-12-19 23:05:39 +01008701 &hit_next_index))
8702 ;
8703 else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
8704 &hit_next_index))
8705 ;
Dave Barach4a3f69c2017-02-22 12:44:56 -05008706 else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
Damjan Marion7cd468a2016-12-19 23:05:39 +01008707 &hit_next_index))
8708 ;
8709 else if (unformat (i, "policer-hit-next %d", &hit_next_index))
8710 ;
8711 else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
8712 ;
8713 else if (unformat (i, "opaque-index %d", &opaque_index))
8714 ;
8715 else if (unformat (i, "skip_n %d", &skip_n_vectors))
8716 ;
8717 else if (unformat (i, "match_n %d", &match_n_vectors))
8718 ;
Dave Barach4a3f69c2017-02-22 12:44:56 -05008719 else if (unformat (i, "match %U", api_unformat_classify_match,
Damjan Marion7cd468a2016-12-19 23:05:39 +01008720 &match, skip_n_vectors, match_n_vectors))
8721 ;
8722 else if (unformat (i, "advance %d", &advance))
8723 ;
8724 else if (unformat (i, "table-index %d", &table_index))
8725 ;
8726 else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
8727 action = 1;
8728 else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
8729 action = 2;
8730 else if (unformat (i, "action %d", &action))
8731 ;
8732 else if (unformat (i, "metadata %d", &metadata))
8733 ;
8734 else
8735 break;
8736 }
8737
8738 if (table_index == ~0)
8739 {
8740 errmsg ("Table index required");
8741 return -99;
8742 }
8743
8744 if (is_add && match == 0)
8745 {
8746 errmsg ("Match value required");
8747 return -99;
8748 }
8749
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008750 M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
Damjan Marion7cd468a2016-12-19 23:05:39 +01008751
8752 mp->is_add = is_add;
8753 mp->table_index = ntohl (table_index);
8754 mp->hit_next_index = ntohl (hit_next_index);
8755 mp->opaque_index = ntohl (opaque_index);
8756 mp->advance = ntohl (advance);
8757 mp->action = action;
8758 mp->metadata = ntohl (metadata);
Juraj Sloboda75282452018-06-12 14:20:49 +02008759 mp->match_len = ntohl (vec_len (match));
Damjan Marion7cd468a2016-12-19 23:05:39 +01008760 clib_memcpy (mp->match, match, vec_len (match));
8761 vec_free (match);
8762
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008763 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008764 W (ret);
8765 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008766}
8767
8768static int
8769api_classify_set_interface_ip_table (vat_main_t * vam)
8770{
8771 unformat_input_t *i = vam->input;
8772 vl_api_classify_set_interface_ip_table_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008773 u32 sw_if_index;
8774 int sw_if_index_set;
8775 u32 table_index = ~0;
8776 u8 is_ipv6 = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008777 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008778
8779 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8780 {
8781 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8782 sw_if_index_set = 1;
8783 else if (unformat (i, "sw_if_index %d", &sw_if_index))
8784 sw_if_index_set = 1;
8785 else if (unformat (i, "table %d", &table_index))
8786 ;
8787 else
8788 {
8789 clib_warning ("parse error '%U'", format_unformat_error, i);
8790 return -99;
8791 }
8792 }
8793
8794 if (sw_if_index_set == 0)
8795 {
8796 errmsg ("missing interface name or sw_if_index");
8797 return -99;
8798 }
8799
8800
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008801 M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008802
8803 mp->sw_if_index = ntohl (sw_if_index);
8804 mp->table_index = ntohl (table_index);
8805 mp->is_ipv6 = is_ipv6;
8806
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008807 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008808 W (ret);
8809 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008810}
8811
8812static int
8813api_classify_set_interface_l2_tables (vat_main_t * vam)
8814{
8815 unformat_input_t *i = vam->input;
8816 vl_api_classify_set_interface_l2_tables_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008817 u32 sw_if_index;
8818 int sw_if_index_set;
8819 u32 ip4_table_index = ~0;
8820 u32 ip6_table_index = ~0;
8821 u32 other_table_index = ~0;
8822 u32 is_input = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008823 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008824
8825 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8826 {
8827 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8828 sw_if_index_set = 1;
8829 else if (unformat (i, "sw_if_index %d", &sw_if_index))
8830 sw_if_index_set = 1;
8831 else if (unformat (i, "ip4-table %d", &ip4_table_index))
8832 ;
8833 else if (unformat (i, "ip6-table %d", &ip6_table_index))
8834 ;
8835 else if (unformat (i, "other-table %d", &other_table_index))
8836 ;
8837 else if (unformat (i, "is-input %d", &is_input))
8838 ;
8839 else
8840 {
8841 clib_warning ("parse error '%U'", format_unformat_error, i);
8842 return -99;
8843 }
8844 }
8845
8846 if (sw_if_index_set == 0)
8847 {
8848 errmsg ("missing interface name or sw_if_index");
8849 return -99;
8850 }
8851
8852
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008853 M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008854
8855 mp->sw_if_index = ntohl (sw_if_index);
8856 mp->ip4_table_index = ntohl (ip4_table_index);
8857 mp->ip6_table_index = ntohl (ip6_table_index);
8858 mp->other_table_index = ntohl (other_table_index);
8859 mp->is_input = (u8) is_input;
8860
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008861 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008862 W (ret);
8863 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008864}
8865
8866static int
8867api_set_ipfix_exporter (vat_main_t * vam)
8868{
8869 unformat_input_t *i = vam->input;
8870 vl_api_set_ipfix_exporter_t *mp;
8871 ip4_address_t collector_address;
8872 u8 collector_address_set = 0;
8873 u32 collector_port = ~0;
8874 ip4_address_t src_address;
8875 u8 src_address_set = 0;
8876 u32 vrf_id = ~0;
8877 u32 path_mtu = ~0;
8878 u32 template_interval = ~0;
8879 u8 udp_checksum = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008880 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008881
8882 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8883 {
8884 if (unformat (i, "collector_address %U", unformat_ip4_address,
8885 &collector_address))
8886 collector_address_set = 1;
8887 else if (unformat (i, "collector_port %d", &collector_port))
8888 ;
8889 else if (unformat (i, "src_address %U", unformat_ip4_address,
8890 &src_address))
8891 src_address_set = 1;
8892 else if (unformat (i, "vrf_id %d", &vrf_id))
8893 ;
8894 else if (unformat (i, "path_mtu %d", &path_mtu))
8895 ;
8896 else if (unformat (i, "template_interval %d", &template_interval))
8897 ;
8898 else if (unformat (i, "udp_checksum"))
8899 udp_checksum = 1;
8900 else
8901 break;
8902 }
8903
8904 if (collector_address_set == 0)
8905 {
8906 errmsg ("collector_address required");
8907 return -99;
8908 }
8909
8910 if (src_address_set == 0)
8911 {
8912 errmsg ("src_address required");
8913 return -99;
8914 }
8915
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008916 M (SET_IPFIX_EXPORTER, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008917
Jakub Grajciar2f71a882019-10-10 14:21:22 +02008918 memcpy (mp->collector_address.un.ip4, collector_address.data,
Damjan Marion7cd468a2016-12-19 23:05:39 +01008919 sizeof (collector_address.data));
8920 mp->collector_port = htons ((u16) collector_port);
Jakub Grajciar2f71a882019-10-10 14:21:22 +02008921 memcpy (mp->src_address.un.ip4, src_address.data,
8922 sizeof (src_address.data));
Damjan Marion7cd468a2016-12-19 23:05:39 +01008923 mp->vrf_id = htonl (vrf_id);
8924 mp->path_mtu = htonl (path_mtu);
8925 mp->template_interval = htonl (template_interval);
8926 mp->udp_checksum = udp_checksum;
8927
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008928 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008929 W (ret);
8930 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008931}
8932
8933static int
8934api_set_ipfix_classify_stream (vat_main_t * vam)
8935{
8936 unformat_input_t *i = vam->input;
8937 vl_api_set_ipfix_classify_stream_t *mp;
8938 u32 domain_id = 0;
8939 u32 src_port = UDP_DST_PORT_ipfix;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008940 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008941
8942 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8943 {
8944 if (unformat (i, "domain %d", &domain_id))
8945 ;
8946 else if (unformat (i, "src_port %d", &src_port))
8947 ;
8948 else
8949 {
8950 errmsg ("unknown input `%U'", format_unformat_error, i);
8951 return -99;
8952 }
8953 }
8954
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008955 M (SET_IPFIX_CLASSIFY_STREAM, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008956
8957 mp->domain_id = htonl (domain_id);
8958 mp->src_port = htons ((u16) src_port);
8959
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008960 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008961 W (ret);
8962 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008963}
8964
8965static int
8966api_ipfix_classify_table_add_del (vat_main_t * vam)
8967{
8968 unformat_input_t *i = vam->input;
8969 vl_api_ipfix_classify_table_add_del_t *mp;
8970 int is_add = -1;
8971 u32 classify_table_index = ~0;
8972 u8 ip_version = 0;
8973 u8 transport_protocol = 255;
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, "add"))
8979 is_add = 1;
8980 else if (unformat (i, "del"))
8981 is_add = 0;
8982 else if (unformat (i, "table %d", &classify_table_index))
8983 ;
8984 else if (unformat (i, "ip4"))
8985 ip_version = 4;
8986 else if (unformat (i, "ip6"))
8987 ip_version = 6;
8988 else if (unformat (i, "tcp"))
8989 transport_protocol = 6;
8990 else if (unformat (i, "udp"))
8991 transport_protocol = 17;
8992 else
8993 {
8994 errmsg ("unknown input `%U'", format_unformat_error, i);
8995 return -99;
8996 }
8997 }
8998
8999 if (is_add == -1)
9000 {
9001 errmsg ("expecting: add|del");
9002 return -99;
9003 }
9004 if (classify_table_index == ~0)
9005 {
9006 errmsg ("classifier table not specified");
9007 return -99;
9008 }
9009 if (ip_version == 0)
9010 {
9011 errmsg ("IP version not specified");
9012 return -99;
9013 }
9014
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009015 M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009016
9017 mp->is_add = is_add;
9018 mp->table_id = htonl (classify_table_index);
9019 mp->ip_version = ip_version;
9020 mp->transport_protocol = transport_protocol;
9021
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009022 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06009023 W (ret);
9024 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009025}
9026
9027static int
9028api_get_node_index (vat_main_t * vam)
9029{
9030 unformat_input_t *i = vam->input;
9031 vl_api_get_node_index_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009032 u8 *name = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009033 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009034
9035 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9036 {
9037 if (unformat (i, "node %s", &name))
9038 ;
9039 else
9040 break;
9041 }
9042 if (name == 0)
9043 {
9044 errmsg ("node name required");
9045 return -99;
9046 }
9047 if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9048 {
9049 errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9050 return -99;
9051 }
9052
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009053 M (GET_NODE_INDEX, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009054 clib_memcpy (mp->node_name, name, vec_len (name));
9055 vec_free (name);
9056
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009057 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06009058 W (ret);
9059 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009060}
9061
9062static int
9063api_get_next_index (vat_main_t * vam)
9064{
9065 unformat_input_t *i = vam->input;
9066 vl_api_get_next_index_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009067 u8 *node_name = 0, *next_node_name = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009068 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009069
9070 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9071 {
9072 if (unformat (i, "node-name %s", &node_name))
9073 ;
9074 else if (unformat (i, "next-node-name %s", &next_node_name))
9075 break;
9076 }
9077
9078 if (node_name == 0)
9079 {
9080 errmsg ("node name required");
9081 return -99;
9082 }
9083 if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
9084 {
9085 errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9086 return -99;
9087 }
9088
9089 if (next_node_name == 0)
9090 {
9091 errmsg ("next node name required");
9092 return -99;
9093 }
9094 if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
9095 {
9096 errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
9097 return -99;
9098 }
9099
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009100 M (GET_NEXT_INDEX, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009101 clib_memcpy (mp->node_name, node_name, vec_len (node_name));
9102 clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
9103 vec_free (node_name);
9104 vec_free (next_node_name);
9105
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009106 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06009107 W (ret);
9108 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009109}
9110
9111static int
9112api_add_node_next (vat_main_t * vam)
9113{
9114 unformat_input_t *i = vam->input;
9115 vl_api_add_node_next_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009116 u8 *name = 0;
9117 u8 *next = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009118 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009119
9120 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9121 {
9122 if (unformat (i, "node %s", &name))
9123 ;
9124 else if (unformat (i, "next %s", &next))
9125 ;
9126 else
9127 break;
9128 }
9129 if (name == 0)
9130 {
9131 errmsg ("node name required");
9132 return -99;
9133 }
9134 if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9135 {
9136 errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9137 return -99;
9138 }
9139 if (next == 0)
9140 {
9141 errmsg ("next node required");
9142 return -99;
9143 }
9144 if (vec_len (next) >= ARRAY_LEN (mp->next_name))
9145 {
9146 errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
9147 return -99;
9148 }
9149
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009150 M (ADD_NODE_NEXT, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009151 clib_memcpy (mp->node_name, name, vec_len (name));
9152 clib_memcpy (mp->next_name, next, vec_len (next));
9153 vec_free (name);
9154 vec_free (next);
9155
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009156 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06009157 W (ret);
9158 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009159}
9160
Damjan Marion8389fb92017-10-13 18:29:53 +02009161static void vl_api_sw_interface_tap_v2_details_t_handler
9162 (vl_api_sw_interface_tap_v2_details_t * mp)
9163{
9164 vat_main_t *vam = &vat_main;
9165
Jakub Grajciar5de4fb72019-09-03 10:40:01 +02009166 u8 *ip4 =
9167 format (0, "%U/%d", format_ip4_address, mp->host_ip4_prefix.address,
9168 mp->host_ip4_prefix.len);
9169 u8 *ip6 =
9170 format (0, "%U/%d", format_ip6_address, mp->host_ip6_prefix.address,
9171 mp->host_ip6_prefix.len);
Milan Lenco73e7f422017-12-14 10:04:25 +01009172
9173 print (vam->ofp,
Andrew Yourtchenko754f24b2019-01-07 20:56:46 +01009174 "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
Milan Lenco73e7f422017-12-14 10:04:25 +01009175 mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
9176 ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
9177 format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
Andrew Yourtchenko754f24b2019-01-07 20:56:46 +01009178 mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
Milan Lenco73e7f422017-12-14 10:04:25 +01009179
9180 vec_free (ip4);
9181 vec_free (ip6);
Damjan Marion8389fb92017-10-13 18:29:53 +02009182}
9183
9184static void vl_api_sw_interface_tap_v2_details_t_handler_json
9185 (vl_api_sw_interface_tap_v2_details_t * mp)
9186{
9187 vat_main_t *vam = &vat_main;
9188 vat_json_node_t *node = NULL;
9189
9190 if (VAT_JSON_ARRAY != vam->json_tree.type)
9191 {
9192 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9193 vat_json_init_array (&vam->json_tree);
9194 }
9195 node = vat_json_array_add (&vam->json_tree);
9196
9197 vat_json_init_object (node);
Milan Lenco73e7f422017-12-14 10:04:25 +01009198 vat_json_object_add_uint (node, "id", ntohl (mp->id));
Damjan Marion8389fb92017-10-13 18:29:53 +02009199 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
Andrew Yourtchenko754f24b2019-01-07 20:56:46 +01009200 vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
Damjan Marion8389fb92017-10-13 18:29:53 +02009201 vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
Milan Lenco73e7f422017-12-14 10:04:25 +01009202 vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
9203 vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
9204 vat_json_object_add_string_copy (node, "host_mac_addr",
9205 format (0, "%U", format_ethernet_address,
9206 &mp->host_mac_addr));
9207 vat_json_object_add_string_copy (node, "host_namespace",
9208 mp->host_namespace);
9209 vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
9210 vat_json_object_add_string_copy (node, "host_ip4_addr",
9211 format (0, "%U/%d", format_ip4_address,
Jakub Grajciar5de4fb72019-09-03 10:40:01 +02009212 mp->host_ip4_prefix.address,
9213 mp->host_ip4_prefix.len));
9214 vat_json_object_add_string_copy (node, "host_ip6_prefix",
Milan Lenco73e7f422017-12-14 10:04:25 +01009215 format (0, "%U/%d", format_ip6_address,
Jakub Grajciar5de4fb72019-09-03 10:40:01 +02009216 mp->host_ip6_prefix.address,
9217 mp->host_ip6_prefix.len));
Milan Lenco73e7f422017-12-14 10:04:25 +01009218
Damjan Marion8389fb92017-10-13 18:29:53 +02009219}
9220
9221static int
9222api_sw_interface_tap_v2_dump (vat_main_t * vam)
9223{
9224 vl_api_sw_interface_tap_v2_dump_t *mp;
9225 vl_api_control_ping_t *mp_ping;
9226 int ret;
9227
Milan Lenco73e7f422017-12-14 10:04:25 +01009228 print (vam->ofp,
9229 "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
9230 "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
9231 "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
9232 "host_ip6_addr");
9233
Damjan Marion8389fb92017-10-13 18:29:53 +02009234 /* Get list of tap interfaces */
9235 M (SW_INTERFACE_TAP_V2_DUMP, mp);
9236 S (mp);
9237
9238 /* Use a control ping for synchronization */
9239 MPING (CONTROL_PING, mp_ping);
9240 S (mp_ping);
9241
9242 W (ret);
9243 return ret;
9244}
9245
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01009246static void vl_api_sw_interface_virtio_pci_details_t_handler
9247 (vl_api_sw_interface_virtio_pci_details_t * mp)
9248{
9249 vat_main_t *vam = &vat_main;
9250
9251 typedef union
9252 {
9253 struct
9254 {
9255 u16 domain;
9256 u8 bus;
9257 u8 slot:5;
9258 u8 function:3;
9259 };
9260 u32 as_u32;
9261 } pci_addr_t;
9262 pci_addr_t addr;
Jakub Grajciar2c504f82019-09-26 10:34:41 +02009263
9264 addr.domain = ntohs (mp->pci_addr.domain);
9265 addr.bus = mp->pci_addr.bus;
9266 addr.slot = mp->pci_addr.slot;
9267 addr.function = mp->pci_addr.function;
9268
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01009269 u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
9270 addr.slot, addr.function);
9271
9272 print (vam->ofp,
9273 "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
9274 pci_addr, ntohl (mp->sw_if_index),
9275 ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
9276 format_ethernet_address, mp->mac_addr,
9277 clib_net_to_host_u64 (mp->features));
9278 vec_free (pci_addr);
9279}
9280
9281static void vl_api_sw_interface_virtio_pci_details_t_handler_json
9282 (vl_api_sw_interface_virtio_pci_details_t * mp)
9283{
9284 vat_main_t *vam = &vat_main;
9285 vat_json_node_t *node = NULL;
Jakub Grajciar2c504f82019-09-26 10:34:41 +02009286 vlib_pci_addr_t pci_addr;
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01009287
9288 if (VAT_JSON_ARRAY != vam->json_tree.type)
9289 {
9290 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9291 vat_json_init_array (&vam->json_tree);
9292 }
9293 node = vat_json_array_add (&vam->json_tree);
9294
Jakub Grajciar2c504f82019-09-26 10:34:41 +02009295 pci_addr.domain = ntohs (mp->pci_addr.domain);
9296 pci_addr.bus = mp->pci_addr.bus;
9297 pci_addr.slot = mp->pci_addr.slot;
9298 pci_addr.function = mp->pci_addr.function;
9299
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01009300 vat_json_init_object (node);
Jakub Grajciar2c504f82019-09-26 10:34:41 +02009301 vat_json_object_add_uint (node, "pci-addr", pci_addr.as_u32);
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01009302 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9303 vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
9304 vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
9305 vat_json_object_add_uint (node, "features",
9306 clib_net_to_host_u64 (mp->features));
9307 vat_json_object_add_string_copy (node, "mac_addr",
9308 format (0, "%U", format_ethernet_address,
9309 &mp->mac_addr));
9310}
9311
9312static int
9313api_sw_interface_virtio_pci_dump (vat_main_t * vam)
9314{
9315 vl_api_sw_interface_virtio_pci_dump_t *mp;
9316 vl_api_control_ping_t *mp_ping;
9317 int ret;
9318
9319 print (vam->ofp,
9320 "\n%-12s %-12s %-12s %-12s %-17s %-08s",
9321 "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
9322 "mac_addr", "features");
9323
9324 /* Get list of tap interfaces */
9325 M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
9326 S (mp);
9327
9328 /* Use a control ping for synchronization */
9329 MPING (CONTROL_PING, mp_ping);
9330 S (mp_ping);
9331
9332 W (ret);
9333 return ret;
9334}
9335
eyal bariaf86a482018-04-17 11:20:27 +03009336static int
9337api_vxlan_offload_rx (vat_main_t * vam)
9338{
9339 unformat_input_t *line_input = vam->input;
9340 vl_api_vxlan_offload_rx_t *mp;
9341 u32 hw_if_index = ~0, rx_if_index = ~0;
9342 u8 is_add = 1;
9343 int ret;
9344
9345 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9346 {
9347 if (unformat (line_input, "del"))
9348 is_add = 0;
9349 else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
9350 &hw_if_index))
9351 ;
9352 else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
9353 ;
9354 else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
9355 &rx_if_index))
9356 ;
9357 else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
9358 ;
9359 else
9360 {
9361 errmsg ("parse error '%U'", format_unformat_error, line_input);
9362 return -99;
9363 }
9364 }
9365
9366 if (hw_if_index == ~0)
9367 {
9368 errmsg ("no hw interface");
9369 return -99;
9370 }
9371
9372 if (rx_if_index == ~0)
9373 {
9374 errmsg ("no rx tunnel");
9375 return -99;
9376 }
9377
9378 M (VXLAN_OFFLOAD_RX, mp);
9379
9380 mp->hw_if_index = ntohl (hw_if_index);
9381 mp->sw_if_index = ntohl (rx_if_index);
9382 mp->enable = is_add;
9383
9384 S (mp);
9385 W (ret);
9386 return ret;
9387}
9388
Damjan Marion7cd468a2016-12-19 23:05:39 +01009389static uword unformat_vxlan_decap_next
9390 (unformat_input_t * input, va_list * args)
9391{
9392 u32 *result = va_arg (*args, u32 *);
9393 u32 tmp;
9394
9395 if (unformat (input, "l2"))
9396 *result = VXLAN_INPUT_NEXT_L2_INPUT;
9397 else if (unformat (input, "%d", &tmp))
9398 *result = tmp;
9399 else
9400 return 0;
9401 return 1;
9402}
9403
9404static int
9405api_vxlan_add_del_tunnel (vat_main_t * vam)
9406{
9407 unformat_input_t *line_input = vam->input;
9408 vl_api_vxlan_add_del_tunnel_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009409 ip46_address_t src, dst;
9410 u8 is_add = 1;
9411 u8 ipv4_set = 0, ipv6_set = 0;
9412 u8 src_set = 0;
9413 u8 dst_set = 0;
9414 u8 grp_set = 0;
Jon Loeliger3d460bd2018-02-01 16:36:12 -06009415 u32 instance = ~0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009416 u32 mcast_sw_if_index = ~0;
9417 u32 encap_vrf_id = 0;
9418 u32 decap_next_index = ~0;
9419 u32 vni = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009420 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009421
9422 /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
Dave Barachb7b92992018-10-17 10:38:51 -04009423 clib_memset (&src, 0, sizeof src);
9424 clib_memset (&dst, 0, sizeof dst);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009425
9426 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9427 {
9428 if (unformat (line_input, "del"))
9429 is_add = 0;
Jon Loeliger3d460bd2018-02-01 16:36:12 -06009430 else if (unformat (line_input, "instance %d", &instance))
9431 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009432 else
9433 if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
9434 {
9435 ipv4_set = 1;
9436 src_set = 1;
9437 }
9438 else
9439 if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
9440 {
9441 ipv4_set = 1;
9442 dst_set = 1;
9443 }
9444 else
9445 if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
9446 {
9447 ipv6_set = 1;
9448 src_set = 1;
9449 }
9450 else
9451 if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
9452 {
9453 ipv6_set = 1;
9454 dst_set = 1;
9455 }
9456 else if (unformat (line_input, "group %U %U",
9457 unformat_ip4_address, &dst.ip4,
9458 api_unformat_sw_if_index, vam, &mcast_sw_if_index))
9459 {
9460 grp_set = dst_set = 1;
9461 ipv4_set = 1;
9462 }
9463 else if (unformat (line_input, "group %U",
9464 unformat_ip4_address, &dst.ip4))
9465 {
9466 grp_set = dst_set = 1;
9467 ipv4_set = 1;
9468 }
9469 else if (unformat (line_input, "group %U %U",
9470 unformat_ip6_address, &dst.ip6,
9471 api_unformat_sw_if_index, vam, &mcast_sw_if_index))
9472 {
9473 grp_set = dst_set = 1;
9474 ipv6_set = 1;
9475 }
9476 else if (unformat (line_input, "group %U",
9477 unformat_ip6_address, &dst.ip6))
9478 {
9479 grp_set = dst_set = 1;
9480 ipv6_set = 1;
9481 }
9482 else
9483 if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
9484 ;
9485 else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
9486 ;
9487 else if (unformat (line_input, "decap-next %U",
9488 unformat_vxlan_decap_next, &decap_next_index))
9489 ;
9490 else if (unformat (line_input, "vni %d", &vni))
9491 ;
9492 else
9493 {
9494 errmsg ("parse error '%U'", format_unformat_error, line_input);
9495 return -99;
9496 }
9497 }
9498
9499 if (src_set == 0)
9500 {
9501 errmsg ("tunnel src address not specified");
9502 return -99;
9503 }
9504 if (dst_set == 0)
9505 {
9506 errmsg ("tunnel dst address not specified");
9507 return -99;
9508 }
9509
9510 if (grp_set && !ip46_address_is_multicast (&dst))
9511 {
9512 errmsg ("tunnel group address not multicast");
9513 return -99;
9514 }
9515 if (grp_set && mcast_sw_if_index == ~0)
9516 {
9517 errmsg ("tunnel nonexistent multicast device");
9518 return -99;
9519 }
9520 if (grp_set == 0 && ip46_address_is_multicast (&dst))
9521 {
9522 errmsg ("tunnel dst address must be unicast");
9523 return -99;
9524 }
9525
9526
9527 if (ipv4_set && ipv6_set)
9528 {
9529 errmsg ("both IPv4 and IPv6 addresses specified");
9530 return -99;
9531 }
9532
9533 if ((vni == 0) || (vni >> 24))
9534 {
9535 errmsg ("vni not specified or out of range");
9536 return -99;
9537 }
9538
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009539 M (VXLAN_ADD_DEL_TUNNEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009540
9541 if (ipv6_set)
9542 {
Jakub Grajciar7c0eb562020-03-02 13:55:31 +01009543 clib_memcpy (mp->src_address.un.ip6, &src.ip6, sizeof (src.ip6));
9544 clib_memcpy (mp->dst_address.un.ip6, &dst.ip6, sizeof (dst.ip6));
Damjan Marion7cd468a2016-12-19 23:05:39 +01009545 }
9546 else
9547 {
Jakub Grajciar7c0eb562020-03-02 13:55:31 +01009548 clib_memcpy (mp->src_address.un.ip4, &src.ip4, sizeof (src.ip4));
9549 clib_memcpy (mp->dst_address.un.ip4, &dst.ip4, sizeof (dst.ip4));
Damjan Marion7cd468a2016-12-19 23:05:39 +01009550 }
Jakub Grajciar7c0eb562020-03-02 13:55:31 +01009551 mp->src_address.af = ipv6_set;
9552 mp->dst_address.af = ipv6_set;
Jon Loeliger3d460bd2018-02-01 16:36:12 -06009553
9554 mp->instance = htonl (instance);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009555 mp->encap_vrf_id = ntohl (encap_vrf_id);
9556 mp->decap_next_index = ntohl (decap_next_index);
9557 mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
9558 mp->vni = ntohl (vni);
9559 mp->is_add = is_add;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009560
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009561 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06009562 W (ret);
9563 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009564}
9565
9566static void vl_api_vxlan_tunnel_details_t_handler
9567 (vl_api_vxlan_tunnel_details_t * mp)
9568{
9569 vat_main_t *vam = &vat_main;
Jakub Grajciar7c0eb562020-03-02 13:55:31 +01009570 ip46_address_t src =
9571 to_ip46 (mp->dst_address.af, (u8 *) & mp->dst_address.un);
9572 ip46_address_t dst =
9573 to_ip46 (mp->dst_address.af, (u8 *) & mp->src_address.un);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009574
Jon Loeliger3d460bd2018-02-01 16:36:12 -06009575 print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
Damjan Marion7cd468a2016-12-19 23:05:39 +01009576 ntohl (mp->sw_if_index),
Jon Loeliger3d460bd2018-02-01 16:36:12 -06009577 ntohl (mp->instance),
Damjan Marion7cd468a2016-12-19 23:05:39 +01009578 format_ip46_address, &src, IP46_TYPE_ANY,
9579 format_ip46_address, &dst, IP46_TYPE_ANY,
9580 ntohl (mp->encap_vrf_id),
9581 ntohl (mp->decap_next_index), ntohl (mp->vni),
9582 ntohl (mp->mcast_sw_if_index));
9583}
9584
9585static void vl_api_vxlan_tunnel_details_t_handler_json
9586 (vl_api_vxlan_tunnel_details_t * mp)
9587{
9588 vat_main_t *vam = &vat_main;
9589 vat_json_node_t *node = NULL;
9590
9591 if (VAT_JSON_ARRAY != vam->json_tree.type)
9592 {
9593 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9594 vat_json_init_array (&vam->json_tree);
9595 }
9596 node = vat_json_array_add (&vam->json_tree);
9597
9598 vat_json_init_object (node);
9599 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
Jon Loeliger3d460bd2018-02-01 16:36:12 -06009600
9601 vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
9602
Jakub Grajciar7c0eb562020-03-02 13:55:31 +01009603 if (mp->src_address.af)
Damjan Marion7cd468a2016-12-19 23:05:39 +01009604 {
9605 struct in6_addr ip6;
9606
Jakub Grajciar7c0eb562020-03-02 13:55:31 +01009607 clib_memcpy (&ip6, mp->src_address.un.ip6, sizeof (ip6));
Damjan Marion7cd468a2016-12-19 23:05:39 +01009608 vat_json_object_add_ip6 (node, "src_address", ip6);
Jakub Grajciar7c0eb562020-03-02 13:55:31 +01009609 clib_memcpy (&ip6, mp->dst_address.un.ip6, sizeof (ip6));
Damjan Marion7cd468a2016-12-19 23:05:39 +01009610 vat_json_object_add_ip6 (node, "dst_address", ip6);
9611 }
9612 else
9613 {
9614 struct in_addr ip4;
9615
Jakub Grajciar7c0eb562020-03-02 13:55:31 +01009616 clib_memcpy (&ip4, mp->src_address.un.ip4, sizeof (ip4));
Damjan Marion7cd468a2016-12-19 23:05:39 +01009617 vat_json_object_add_ip4 (node, "src_address", ip4);
Jakub Grajciar7c0eb562020-03-02 13:55:31 +01009618 clib_memcpy (&ip4, mp->dst_address.un.ip4, sizeof (ip4));
Damjan Marion7cd468a2016-12-19 23:05:39 +01009619 vat_json_object_add_ip4 (node, "dst_address", ip4);
9620 }
9621 vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
9622 vat_json_object_add_uint (node, "decap_next_index",
9623 ntohl (mp->decap_next_index));
9624 vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
Damjan Marion7cd468a2016-12-19 23:05:39 +01009625 vat_json_object_add_uint (node, "mcast_sw_if_index",
9626 ntohl (mp->mcast_sw_if_index));
9627}
9628
9629static int
9630api_vxlan_tunnel_dump (vat_main_t * vam)
9631{
9632 unformat_input_t *i = vam->input;
9633 vl_api_vxlan_tunnel_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -06009634 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009635 u32 sw_if_index;
9636 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009637 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009638
9639 /* Parse args required to build the message */
9640 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9641 {
9642 if (unformat (i, "sw_if_index %d", &sw_if_index))
9643 sw_if_index_set = 1;
9644 else
9645 break;
9646 }
9647
9648 if (sw_if_index_set == 0)
9649 {
9650 sw_if_index = ~0;
9651 }
9652
9653 if (!vam->json_output)
9654 {
Jon Loeliger3d460bd2018-02-01 16:36:12 -06009655 print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
9656 "sw_if_index", "instance", "src_address", "dst_address",
Damjan Marion7cd468a2016-12-19 23:05:39 +01009657 "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
9658 }
9659
9660 /* Get list of vxlan-tunnel interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009661 M (VXLAN_TUNNEL_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009662
9663 mp->sw_if_index = htonl (sw_if_index);
9664
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009665 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009666
9667 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -04009668 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06009669 S (mp_ping);
9670
Jon Loeliger56c7b012017-02-01 12:31:41 -06009671 W (ret);
9672 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009673}
9674
9675static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01009676api_l2_fib_clear_table (vat_main_t * vam)
9677{
9678// unformat_input_t * i = vam->input;
9679 vl_api_l2_fib_clear_table_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009680 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009681
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009682 M (L2_FIB_CLEAR_TABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009683
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009684 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06009685 W (ret);
9686 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009687}
9688
9689static int
9690api_l2_interface_efp_filter (vat_main_t * vam)
9691{
9692 unformat_input_t *i = vam->input;
9693 vl_api_l2_interface_efp_filter_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009694 u32 sw_if_index;
9695 u8 enable = 1;
9696 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009697 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009698
9699 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9700 {
9701 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9702 sw_if_index_set = 1;
9703 else if (unformat (i, "sw_if_index %d", &sw_if_index))
9704 sw_if_index_set = 1;
9705 else if (unformat (i, "enable"))
9706 enable = 1;
9707 else if (unformat (i, "disable"))
9708 enable = 0;
9709 else
9710 {
9711 clib_warning ("parse error '%U'", format_unformat_error, i);
9712 return -99;
9713 }
9714 }
9715
9716 if (sw_if_index_set == 0)
9717 {
9718 errmsg ("missing sw_if_index");
9719 return -99;
9720 }
9721
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009722 M (L2_INTERFACE_EFP_FILTER, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009723
9724 mp->sw_if_index = ntohl (sw_if_index);
9725 mp->enable_disable = enable;
9726
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009727 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06009728 W (ret);
9729 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009730}
9731
9732#define foreach_vtr_op \
9733_("disable", L2_VTR_DISABLED) \
9734_("push-1", L2_VTR_PUSH_1) \
9735_("push-2", L2_VTR_PUSH_2) \
9736_("pop-1", L2_VTR_POP_1) \
9737_("pop-2", L2_VTR_POP_2) \
9738_("translate-1-1", L2_VTR_TRANSLATE_1_1) \
9739_("translate-1-2", L2_VTR_TRANSLATE_1_2) \
9740_("translate-2-1", L2_VTR_TRANSLATE_2_1) \
9741_("translate-2-2", L2_VTR_TRANSLATE_2_2)
9742
9743static int
9744api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
9745{
9746 unformat_input_t *i = vam->input;
9747 vl_api_l2_interface_vlan_tag_rewrite_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009748 u32 sw_if_index;
9749 u8 sw_if_index_set = 0;
9750 u8 vtr_op_set = 0;
9751 u32 vtr_op = 0;
9752 u32 push_dot1q = 1;
9753 u32 tag1 = ~0;
9754 u32 tag2 = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009755 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009756
9757 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9758 {
9759 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9760 sw_if_index_set = 1;
9761 else if (unformat (i, "sw_if_index %d", &sw_if_index))
9762 sw_if_index_set = 1;
9763 else if (unformat (i, "vtr_op %d", &vtr_op))
9764 vtr_op_set = 1;
9765#define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
9766 foreach_vtr_op
9767#undef _
9768 else if (unformat (i, "push_dot1q %d", &push_dot1q))
9769 ;
9770 else if (unformat (i, "tag1 %d", &tag1))
9771 ;
9772 else if (unformat (i, "tag2 %d", &tag2))
9773 ;
9774 else
9775 {
9776 clib_warning ("parse error '%U'", format_unformat_error, i);
9777 return -99;
9778 }
9779 }
9780
9781 if ((sw_if_index_set == 0) || (vtr_op_set == 0))
9782 {
9783 errmsg ("missing vtr operation or sw_if_index");
9784 return -99;
9785 }
9786
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009787 M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
9788 mp->sw_if_index = ntohl (sw_if_index);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009789 mp->vtr_op = ntohl (vtr_op);
9790 mp->push_dot1q = ntohl (push_dot1q);
9791 mp->tag1 = ntohl (tag1);
9792 mp->tag2 = ntohl (tag2);
9793
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009794 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06009795 W (ret);
9796 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009797}
9798
9799static int
9800api_create_vhost_user_if (vat_main_t * vam)
9801{
9802 unformat_input_t *i = vam->input;
9803 vl_api_create_vhost_user_if_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009804 u8 *file_name;
9805 u8 is_server = 0;
9806 u8 file_name_set = 0;
9807 u32 custom_dev_instance = ~0;
9808 u8 hwaddr[6];
9809 u8 use_custom_mac = 0;
Mohsin Kazmiee2e58f2018-08-21 16:07:03 +02009810 u8 disable_mrg_rxbuf = 0;
9811 u8 disable_indirect_desc = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009812 u8 *tag = 0;
Steven Luong4208a4c2019-05-06 08:51:56 -07009813 u8 enable_gso = 0;
Steven Luongbc0d9ff2020-03-23 09:34:59 -07009814 u8 enable_packed = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009815 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009816
9817 /* Shut up coverity */
Dave Barachb7b92992018-10-17 10:38:51 -04009818 clib_memset (hwaddr, 0, sizeof (hwaddr));
Damjan Marion7cd468a2016-12-19 23:05:39 +01009819
9820 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9821 {
9822 if (unformat (i, "socket %s", &file_name))
9823 {
9824 file_name_set = 1;
9825 }
9826 else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
9827 ;
9828 else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
9829 use_custom_mac = 1;
9830 else if (unformat (i, "server"))
9831 is_server = 1;
Mohsin Kazmiee2e58f2018-08-21 16:07:03 +02009832 else if (unformat (i, "disable_mrg_rxbuf"))
9833 disable_mrg_rxbuf = 1;
9834 else if (unformat (i, "disable_indirect_desc"))
9835 disable_indirect_desc = 1;
Steven Luong4208a4c2019-05-06 08:51:56 -07009836 else if (unformat (i, "gso"))
9837 enable_gso = 1;
Steven Luongbc0d9ff2020-03-23 09:34:59 -07009838 else if (unformat (i, "packed"))
9839 enable_packed = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009840 else if (unformat (i, "tag %s", &tag))
9841 ;
9842 else
9843 break;
9844 }
9845
9846 if (file_name_set == 0)
9847 {
9848 errmsg ("missing socket file name");
9849 return -99;
9850 }
9851
9852 if (vec_len (file_name) > 255)
9853 {
9854 errmsg ("socket file name too long");
9855 return -99;
9856 }
9857 vec_add1 (file_name, 0);
9858
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009859 M (CREATE_VHOST_USER_IF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009860
9861 mp->is_server = is_server;
Mohsin Kazmiee2e58f2018-08-21 16:07:03 +02009862 mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
9863 mp->disable_indirect_desc = disable_indirect_desc;
Steven Luong4208a4c2019-05-06 08:51:56 -07009864 mp->enable_gso = enable_gso;
Steven Luongbc0d9ff2020-03-23 09:34:59 -07009865 mp->enable_packed = enable_packed;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009866 clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
9867 vec_free (file_name);
9868 if (custom_dev_instance != ~0)
9869 {
9870 mp->renumber = 1;
9871 mp->custom_dev_instance = ntohl (custom_dev_instance);
9872 }
Mohsin Kazmiee2e58f2018-08-21 16:07:03 +02009873
Damjan Marion7cd468a2016-12-19 23:05:39 +01009874 mp->use_custom_mac = use_custom_mac;
9875 clib_memcpy (mp->mac_address, hwaddr, 6);
9876 if (tag)
9877 strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
9878 vec_free (tag);
9879
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009880 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06009881 W (ret);
9882 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009883}
9884
9885static int
9886api_modify_vhost_user_if (vat_main_t * vam)
9887{
9888 unformat_input_t *i = vam->input;
9889 vl_api_modify_vhost_user_if_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009890 u8 *file_name;
9891 u8 is_server = 0;
9892 u8 file_name_set = 0;
9893 u32 custom_dev_instance = ~0;
9894 u8 sw_if_index_set = 0;
9895 u32 sw_if_index = (u32) ~ 0;
Steven Luong4208a4c2019-05-06 08:51:56 -07009896 u8 enable_gso = 0;
Steven Luongbc0d9ff2020-03-23 09:34:59 -07009897 u8 enable_packed = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009898 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009899
9900 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9901 {
9902 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9903 sw_if_index_set = 1;
9904 else if (unformat (i, "sw_if_index %d", &sw_if_index))
9905 sw_if_index_set = 1;
9906 else if (unformat (i, "socket %s", &file_name))
9907 {
9908 file_name_set = 1;
9909 }
9910 else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
9911 ;
9912 else if (unformat (i, "server"))
9913 is_server = 1;
Steven Luong4208a4c2019-05-06 08:51:56 -07009914 else if (unformat (i, "gso"))
9915 enable_gso = 1;
Steven Luongbc0d9ff2020-03-23 09:34:59 -07009916 else if (unformat (i, "packed"))
9917 enable_packed = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009918 else
9919 break;
9920 }
9921
9922 if (sw_if_index_set == 0)
9923 {
9924 errmsg ("missing sw_if_index or interface name");
9925 return -99;
9926 }
9927
9928 if (file_name_set == 0)
9929 {
9930 errmsg ("missing socket file name");
9931 return -99;
9932 }
9933
9934 if (vec_len (file_name) > 255)
9935 {
9936 errmsg ("socket file name too long");
9937 return -99;
9938 }
9939 vec_add1 (file_name, 0);
9940
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009941 M (MODIFY_VHOST_USER_IF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009942
9943 mp->sw_if_index = ntohl (sw_if_index);
9944 mp->is_server = is_server;
Steven Luong4208a4c2019-05-06 08:51:56 -07009945 mp->enable_gso = enable_gso;
Steven Luongbc0d9ff2020-03-23 09:34:59 -07009946 mp->enable_packed = enable_packed;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009947 clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
9948 vec_free (file_name);
9949 if (custom_dev_instance != ~0)
9950 {
9951 mp->renumber = 1;
9952 mp->custom_dev_instance = ntohl (custom_dev_instance);
9953 }
9954
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009955 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06009956 W (ret);
9957 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009958}
9959
9960static int
9961api_delete_vhost_user_if (vat_main_t * vam)
9962{
9963 unformat_input_t *i = vam->input;
9964 vl_api_delete_vhost_user_if_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009965 u32 sw_if_index = ~0;
9966 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009967 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009968
9969 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9970 {
9971 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9972 sw_if_index_set = 1;
9973 else if (unformat (i, "sw_if_index %d", &sw_if_index))
9974 sw_if_index_set = 1;
9975 else
9976 break;
9977 }
9978
9979 if (sw_if_index_set == 0)
9980 {
9981 errmsg ("missing sw_if_index or interface name");
9982 return -99;
9983 }
9984
9985
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009986 M (DELETE_VHOST_USER_IF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009987
9988 mp->sw_if_index = ntohl (sw_if_index);
9989
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009990 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06009991 W (ret);
9992 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009993}
9994
9995static void vl_api_sw_interface_vhost_user_details_t_handler
9996 (vl_api_sw_interface_vhost_user_details_t * mp)
9997{
9998 vat_main_t *vam = &vat_main;
Jakub Grajciar5d4c99f2019-09-26 10:21:59 +02009999 u64 features;
10000
10001 features =
10002 clib_net_to_host_u32 (mp->features_first_32) | ((u64)
10003 clib_net_to_host_u32
10004 (mp->features_last_32) <<
10005 32);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010006
Stevenf3b53642017-05-01 14:03:02 -070010007 print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
Damjan Marion7cd468a2016-12-19 23:05:39 +010010008 (char *) mp->interface_name,
10009 ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
Jakub Grajciar5d4c99f2019-09-26 10:21:59 +020010010 features, mp->is_server,
Stevenf3b53642017-05-01 14:03:02 -070010011 ntohl (mp->num_regions), (char *) mp->sock_filename);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010012 print (vam->ofp, " Status: '%s'", strerror (ntohl (mp->sock_errno)));
10013}
10014
10015static void vl_api_sw_interface_vhost_user_details_t_handler_json
10016 (vl_api_sw_interface_vhost_user_details_t * mp)
10017{
10018 vat_main_t *vam = &vat_main;
10019 vat_json_node_t *node = NULL;
10020
10021 if (VAT_JSON_ARRAY != vam->json_tree.type)
10022 {
10023 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10024 vat_json_init_array (&vam->json_tree);
10025 }
10026 node = vat_json_array_add (&vam->json_tree);
10027
10028 vat_json_init_object (node);
10029 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10030 vat_json_object_add_string_copy (node, "interface_name",
10031 mp->interface_name);
10032 vat_json_object_add_uint (node, "virtio_net_hdr_sz",
10033 ntohl (mp->virtio_net_hdr_sz));
Jakub Grajciar5d4c99f2019-09-26 10:21:59 +020010034 vat_json_object_add_uint (node, "features_first_32",
10035 clib_net_to_host_u32 (mp->features_first_32));
10036 vat_json_object_add_uint (node, "features_last_32",
10037 clib_net_to_host_u32 (mp->features_last_32));
Damjan Marion7cd468a2016-12-19 23:05:39 +010010038 vat_json_object_add_uint (node, "is_server", mp->is_server);
10039 vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
10040 vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
10041 vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
10042}
10043
10044static int
10045api_sw_interface_vhost_user_dump (vat_main_t * vam)
10046{
Steven Luonga0e8d962020-05-18 17:12:56 -070010047 unformat_input_t *i = vam->input;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010048 vl_api_sw_interface_vhost_user_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010049 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010050 int ret;
Steven Luonga0e8d962020-05-18 17:12:56 -070010051 u32 sw_if_index = ~0;
10052
10053 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10054 {
10055 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10056 ;
10057 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10058 ;
10059 else
10060 break;
10061 }
10062
Damjan Marion7cd468a2016-12-19 23:05:39 +010010063 print (vam->ofp,
Stevenf3b53642017-05-01 14:03:02 -070010064 "Interface name idx hdr_sz features server regions filename");
Damjan Marion7cd468a2016-12-19 23:05:39 +010010065
10066 /* Get list of vhost-user interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010067 M (SW_INTERFACE_VHOST_USER_DUMP, mp);
Steven Luonga0e8d962020-05-18 17:12:56 -070010068 mp->sw_if_index = ntohl (sw_if_index);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010069 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010070
10071 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040010072 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010073 S (mp_ping);
10074
Jon Loeliger56c7b012017-02-01 12:31:41 -060010075 W (ret);
10076 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010077}
10078
10079static int
10080api_show_version (vat_main_t * vam)
10081{
10082 vl_api_show_version_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010083 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010084
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010085 M (SHOW_VERSION, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010086
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010087 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010088 W (ret);
10089 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010090}
10091
10092
10093static int
10094api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
10095{
10096 unformat_input_t *line_input = vam->input;
10097 vl_api_vxlan_gpe_add_del_tunnel_t *mp;
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010098 ip46_address_t local, remote;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010099 u8 is_add = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010100 u8 local_set = 0;
10101 u8 remote_set = 0;
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010102 u8 grp_set = 0;
10103 u32 mcast_sw_if_index = ~0;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010104 u32 encap_vrf_id = 0;
10105 u32 decap_vrf_id = 0;
10106 u8 protocol = ~0;
10107 u32 vni;
10108 u8 vni_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010109 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010110
10111 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10112 {
10113 if (unformat (line_input, "del"))
10114 is_add = 0;
10115 else if (unformat (line_input, "local %U",
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010116 unformat_ip46_address, &local))
Damjan Marion7cd468a2016-12-19 23:05:39 +010010117 {
10118 local_set = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010119 }
10120 else if (unformat (line_input, "remote %U",
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010121 unformat_ip46_address, &remote))
Damjan Marion7cd468a2016-12-19 23:05:39 +010010122 {
10123 remote_set = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010124 }
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010125 else if (unformat (line_input, "group %U %U",
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010126 unformat_ip46_address, &remote,
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010127 api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10128 {
10129 grp_set = remote_set = 1;
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010130 }
10131 else if (unformat (line_input, "group %U",
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010132 unformat_ip46_address, &remote))
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010133 {
10134 grp_set = remote_set = 1;
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010135 }
10136 else
10137 if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10138 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010139 else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10140 ;
10141 else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
10142 ;
10143 else if (unformat (line_input, "vni %d", &vni))
10144 vni_set = 1;
10145 else if (unformat (line_input, "next-ip4"))
10146 protocol = 1;
10147 else if (unformat (line_input, "next-ip6"))
10148 protocol = 2;
10149 else if (unformat (line_input, "next-ethernet"))
10150 protocol = 3;
10151 else if (unformat (line_input, "next-nsh"))
10152 protocol = 4;
10153 else
10154 {
10155 errmsg ("parse error '%U'", format_unformat_error, line_input);
10156 return -99;
10157 }
10158 }
10159
10160 if (local_set == 0)
10161 {
10162 errmsg ("tunnel local address not specified");
10163 return -99;
10164 }
10165 if (remote_set == 0)
10166 {
10167 errmsg ("tunnel remote address not specified");
10168 return -99;
10169 }
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010170 if (grp_set && mcast_sw_if_index == ~0)
10171 {
10172 errmsg ("tunnel nonexistent multicast device");
10173 return -99;
10174 }
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010175 if (ip46_address_is_ip4 (&local) != ip46_address_is_ip4 (&remote))
Damjan Marion7cd468a2016-12-19 23:05:39 +010010176 {
10177 errmsg ("both IPv4 and IPv6 addresses specified");
10178 return -99;
10179 }
10180
10181 if (vni_set == 0)
10182 {
10183 errmsg ("vni not specified");
10184 return -99;
10185 }
10186
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010187 M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010188
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010189 ip_address_encode (&local,
10190 ip46_address_is_ip4 (&local) ? IP46_TYPE_IP4 :
10191 IP46_TYPE_IP6, &mp->local);
10192 ip_address_encode (&remote,
10193 ip46_address_is_ip4 (&remote) ? IP46_TYPE_IP4 :
10194 IP46_TYPE_IP6, &mp->remote);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010195
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010196 mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010197 mp->encap_vrf_id = ntohl (encap_vrf_id);
10198 mp->decap_vrf_id = ntohl (decap_vrf_id);
10199 mp->protocol = protocol;
10200 mp->vni = ntohl (vni);
10201 mp->is_add = is_add;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010202
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010203 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010204 W (ret);
10205 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010206}
10207
10208static void vl_api_vxlan_gpe_tunnel_details_t_handler
10209 (vl_api_vxlan_gpe_tunnel_details_t * mp)
10210{
10211 vat_main_t *vam = &vat_main;
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010212 ip46_address_t local, remote;
10213
10214 ip_address_decode (&mp->local, &local);
10215 ip_address_decode (&mp->remote, &remote);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010216
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010217 print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
Damjan Marion7cd468a2016-12-19 23:05:39 +010010218 ntohl (mp->sw_if_index),
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010219 format_ip46_address, &local, IP46_TYPE_ANY,
10220 format_ip46_address, &remote, IP46_TYPE_ANY,
10221 ntohl (mp->vni), mp->protocol,
10222 ntohl (mp->mcast_sw_if_index),
Damjan Marion7cd468a2016-12-19 23:05:39 +010010223 ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
10224}
10225
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010226
Damjan Marion7cd468a2016-12-19 23:05:39 +010010227static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
10228 (vl_api_vxlan_gpe_tunnel_details_t * mp)
10229{
10230 vat_main_t *vam = &vat_main;
10231 vat_json_node_t *node = NULL;
10232 struct in_addr ip4;
10233 struct in6_addr ip6;
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010234 ip46_address_t local, remote;
10235
10236 ip_address_decode (&mp->local, &local);
10237 ip_address_decode (&mp->remote, &remote);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010238
10239 if (VAT_JSON_ARRAY != vam->json_tree.type)
10240 {
10241 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10242 vat_json_init_array (&vam->json_tree);
10243 }
10244 node = vat_json_array_add (&vam->json_tree);
10245
10246 vat_json_init_object (node);
10247 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010248 if (ip46_address_is_ip4 (&local))
Damjan Marion7cd468a2016-12-19 23:05:39 +010010249 {
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010250 clib_memcpy (&ip4, &local.ip4, sizeof (ip4));
10251 vat_json_object_add_ip4 (node, "local", ip4);
10252 clib_memcpy (&ip4, &remote.ip4, sizeof (ip4));
10253 vat_json_object_add_ip4 (node, "remote", ip4);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010254 }
10255 else
10256 {
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010257 clib_memcpy (&ip6, &local.ip6, sizeof (ip6));
10258 vat_json_object_add_ip6 (node, "local", ip6);
10259 clib_memcpy (&ip6, &remote.ip6, sizeof (ip6));
10260 vat_json_object_add_ip6 (node, "remote", ip6);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010261 }
10262 vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10263 vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010264 vat_json_object_add_uint (node, "mcast_sw_if_index",
10265 ntohl (mp->mcast_sw_if_index));
Damjan Marion7cd468a2016-12-19 23:05:39 +010010266 vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10267 vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
10268 vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10269}
10270
10271static int
10272api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
10273{
10274 unformat_input_t *i = vam->input;
10275 vl_api_vxlan_gpe_tunnel_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010276 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010277 u32 sw_if_index;
10278 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010279 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010280
10281 /* Parse args required to build the message */
10282 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10283 {
10284 if (unformat (i, "sw_if_index %d", &sw_if_index))
10285 sw_if_index_set = 1;
10286 else
10287 break;
10288 }
10289
10290 if (sw_if_index_set == 0)
10291 {
10292 sw_if_index = ~0;
10293 }
10294
10295 if (!vam->json_output)
10296 {
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010297 print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
Damjan Marion7cd468a2016-12-19 23:05:39 +010010298 "sw_if_index", "local", "remote", "vni",
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010299 "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
Damjan Marion7cd468a2016-12-19 23:05:39 +010010300 }
10301
10302 /* Get list of vxlan-tunnel interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010303 M (VXLAN_GPE_TUNNEL_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010304
10305 mp->sw_if_index = htonl (sw_if_index);
10306
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010307 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010308
10309 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040010310 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010311 S (mp_ping);
10312
Jon Loeliger56c7b012017-02-01 12:31:41 -060010313 W (ret);
10314 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010315}
10316
Ole Troan01384fe2017-05-12 11:55:35 +020010317static void vl_api_l2_fib_table_details_t_handler
10318 (vl_api_l2_fib_table_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010010319{
10320 vat_main_t *vam = &vat_main;
10321
10322 print (vam->ofp, "%3" PRIu32 " %U %3" PRIu32
10323 " %d %d %d",
Mohsin Kazmi57938f62017-10-27 21:28:07 +020010324 ntohl (mp->bd_id), format_ethernet_address, mp->mac,
Damjan Marion7cd468a2016-12-19 23:05:39 +010010325 ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
10326 mp->bvi_mac);
10327}
10328
Ole Troan01384fe2017-05-12 11:55:35 +020010329static void vl_api_l2_fib_table_details_t_handler_json
10330 (vl_api_l2_fib_table_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010010331{
10332 vat_main_t *vam = &vat_main;
10333 vat_json_node_t *node = NULL;
10334
10335 if (VAT_JSON_ARRAY != vam->json_tree.type)
10336 {
10337 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10338 vat_json_init_array (&vam->json_tree);
10339 }
10340 node = vat_json_array_add (&vam->json_tree);
10341
10342 vat_json_init_object (node);
10343 vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
Mohsin Kazmi57938f62017-10-27 21:28:07 +020010344 vat_json_object_add_bytes (node, "mac", mp->mac, 6);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010345 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10346 vat_json_object_add_uint (node, "static_mac", mp->static_mac);
10347 vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
10348 vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
10349}
10350
10351static int
10352api_l2_fib_table_dump (vat_main_t * vam)
10353{
10354 unformat_input_t *i = vam->input;
10355 vl_api_l2_fib_table_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010356 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010357 u32 bd_id;
10358 u8 bd_id_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010359 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010360
10361 /* Parse args required to build the message */
10362 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10363 {
10364 if (unformat (i, "bd_id %d", &bd_id))
10365 bd_id_set = 1;
10366 else
10367 break;
10368 }
10369
10370 if (bd_id_set == 0)
10371 {
10372 errmsg ("missing bridge domain");
10373 return -99;
10374 }
10375
10376 print (vam->ofp, "BD-ID Mac Address sw-ndx Static Filter BVI");
10377
10378 /* Get list of l2 fib entries */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010379 M (L2_FIB_TABLE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010380
10381 mp->bd_id = ntohl (bd_id);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010382 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010383
10384 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040010385 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010386 S (mp_ping);
10387
Jon Loeliger56c7b012017-02-01 12:31:41 -060010388 W (ret);
10389 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010390}
10391
10392
10393static int
10394api_interface_name_renumber (vat_main_t * vam)
10395{
10396 unformat_input_t *line_input = vam->input;
10397 vl_api_interface_name_renumber_t *mp;
10398 u32 sw_if_index = ~0;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010399 u32 new_show_dev_instance = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010400 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010401
10402 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10403 {
10404 if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
10405 &sw_if_index))
10406 ;
10407 else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
10408 ;
10409 else if (unformat (line_input, "new_show_dev_instance %d",
10410 &new_show_dev_instance))
10411 ;
10412 else
10413 break;
10414 }
10415
10416 if (sw_if_index == ~0)
10417 {
10418 errmsg ("missing interface name or sw_if_index");
10419 return -99;
10420 }
10421
10422 if (new_show_dev_instance == ~0)
10423 {
10424 errmsg ("missing new_show_dev_instance");
10425 return -99;
10426 }
10427
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010428 M (INTERFACE_NAME_RENUMBER, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010429
10430 mp->sw_if_index = ntohl (sw_if_index);
10431 mp->new_show_dev_instance = ntohl (new_show_dev_instance);
10432
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010433 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010434 W (ret);
10435 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010436}
10437
10438static int
John Lo8d00fff2017-08-03 00:35:36 -040010439api_want_l2_macs_events (vat_main_t * vam)
10440{
10441 unformat_input_t *line_input = vam->input;
10442 vl_api_want_l2_macs_events_t *mp;
10443 u8 enable_disable = 1;
10444 u32 scan_delay = 0;
10445 u32 max_macs_in_event = 0;
10446 u32 learn_limit = 0;
10447 int ret;
10448
10449 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10450 {
10451 if (unformat (line_input, "learn-limit %d", &learn_limit))
10452 ;
10453 else if (unformat (line_input, "scan-delay %d", &scan_delay))
10454 ;
10455 else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
10456 ;
10457 else if (unformat (line_input, "disable"))
10458 enable_disable = 0;
10459 else
10460 break;
10461 }
10462
10463 M (WANT_L2_MACS_EVENTS, mp);
10464 mp->enable_disable = enable_disable;
10465 mp->pid = htonl (getpid ());
10466 mp->learn_limit = htonl (learn_limit);
10467 mp->scan_delay = (u8) scan_delay;
10468 mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
10469 S (mp);
10470 W (ret);
10471 return ret;
10472}
10473
10474static int
Damjan Marion7cd468a2016-12-19 23:05:39 +010010475api_input_acl_set_interface (vat_main_t * vam)
10476{
10477 unformat_input_t *i = vam->input;
10478 vl_api_input_acl_set_interface_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010479 u32 sw_if_index;
10480 int sw_if_index_set;
10481 u32 ip4_table_index = ~0;
10482 u32 ip6_table_index = ~0;
10483 u32 l2_table_index = ~0;
10484 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010485 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010486
10487 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10488 {
10489 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10490 sw_if_index_set = 1;
10491 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10492 sw_if_index_set = 1;
10493 else if (unformat (i, "del"))
10494 is_add = 0;
10495 else if (unformat (i, "ip4-table %d", &ip4_table_index))
10496 ;
10497 else if (unformat (i, "ip6-table %d", &ip6_table_index))
10498 ;
10499 else if (unformat (i, "l2-table %d", &l2_table_index))
10500 ;
10501 else
10502 {
10503 clib_warning ("parse error '%U'", format_unformat_error, i);
10504 return -99;
10505 }
10506 }
10507
10508 if (sw_if_index_set == 0)
10509 {
10510 errmsg ("missing interface name or sw_if_index");
10511 return -99;
10512 }
10513
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010514 M (INPUT_ACL_SET_INTERFACE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010515
10516 mp->sw_if_index = ntohl (sw_if_index);
10517 mp->ip4_table_index = ntohl (ip4_table_index);
10518 mp->ip6_table_index = ntohl (ip6_table_index);
10519 mp->l2_table_index = ntohl (l2_table_index);
10520 mp->is_add = is_add;
10521
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010522 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010523 W (ret);
10524 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010525}
10526
10527static int
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +010010528api_output_acl_set_interface (vat_main_t * vam)
10529{
10530 unformat_input_t *i = vam->input;
10531 vl_api_output_acl_set_interface_t *mp;
10532 u32 sw_if_index;
10533 int sw_if_index_set;
10534 u32 ip4_table_index = ~0;
10535 u32 ip6_table_index = ~0;
10536 u32 l2_table_index = ~0;
10537 u8 is_add = 1;
10538 int ret;
10539
10540 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10541 {
10542 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10543 sw_if_index_set = 1;
10544 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10545 sw_if_index_set = 1;
10546 else if (unformat (i, "del"))
10547 is_add = 0;
10548 else if (unformat (i, "ip4-table %d", &ip4_table_index))
10549 ;
10550 else if (unformat (i, "ip6-table %d", &ip6_table_index))
10551 ;
10552 else if (unformat (i, "l2-table %d", &l2_table_index))
10553 ;
10554 else
10555 {
10556 clib_warning ("parse error '%U'", format_unformat_error, i);
10557 return -99;
10558 }
10559 }
10560
10561 if (sw_if_index_set == 0)
10562 {
10563 errmsg ("missing interface name or sw_if_index");
10564 return -99;
10565 }
10566
10567 M (OUTPUT_ACL_SET_INTERFACE, mp);
10568
10569 mp->sw_if_index = ntohl (sw_if_index);
10570 mp->ip4_table_index = ntohl (ip4_table_index);
10571 mp->ip6_table_index = ntohl (ip6_table_index);
10572 mp->l2_table_index = ntohl (l2_table_index);
10573 mp->is_add = is_add;
10574
10575 S (mp);
10576 W (ret);
10577 return ret;
10578}
10579
10580static int
Damjan Marion7cd468a2016-12-19 23:05:39 +010010581api_ip_address_dump (vat_main_t * vam)
10582{
10583 unformat_input_t *i = vam->input;
10584 vl_api_ip_address_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010585 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010586 u32 sw_if_index = ~0;
10587 u8 sw_if_index_set = 0;
10588 u8 ipv4_set = 0;
10589 u8 ipv6_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010590 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010591
10592 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10593 {
10594 if (unformat (i, "sw_if_index %d", &sw_if_index))
10595 sw_if_index_set = 1;
10596 else
10597 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10598 sw_if_index_set = 1;
10599 else if (unformat (i, "ipv4"))
10600 ipv4_set = 1;
10601 else if (unformat (i, "ipv6"))
10602 ipv6_set = 1;
10603 else
10604 break;
10605 }
10606
10607 if (ipv4_set && ipv6_set)
10608 {
10609 errmsg ("ipv4 and ipv6 flags cannot be both set");
10610 return -99;
10611 }
10612
10613 if ((!ipv4_set) && (!ipv6_set))
10614 {
10615 errmsg ("no ipv4 nor ipv6 flag set");
10616 return -99;
10617 }
10618
10619 if (sw_if_index_set == 0)
10620 {
10621 errmsg ("missing interface name or sw_if_index");
10622 return -99;
10623 }
10624
10625 vam->current_sw_if_index = sw_if_index;
10626 vam->is_ipv6 = ipv6_set;
10627
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010628 M (IP_ADDRESS_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010629 mp->sw_if_index = ntohl (sw_if_index);
10630 mp->is_ipv6 = ipv6_set;
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010631 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010632
10633 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040010634 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010635 S (mp_ping);
10636
Jon Loeliger56c7b012017-02-01 12:31:41 -060010637 W (ret);
10638 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010639}
10640
10641static int
10642api_ip_dump (vat_main_t * vam)
10643{
10644 vl_api_ip_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010645 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010646 unformat_input_t *in = vam->input;
10647 int ipv4_set = 0;
10648 int ipv6_set = 0;
10649 int is_ipv6;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010650 int i;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010651 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010652
10653 while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
10654 {
10655 if (unformat (in, "ipv4"))
10656 ipv4_set = 1;
10657 else if (unformat (in, "ipv6"))
10658 ipv6_set = 1;
10659 else
10660 break;
10661 }
10662
10663 if (ipv4_set && ipv6_set)
10664 {
10665 errmsg ("ipv4 and ipv6 flags cannot be both set");
10666 return -99;
10667 }
10668
10669 if ((!ipv4_set) && (!ipv6_set))
10670 {
10671 errmsg ("no ipv4 nor ipv6 flag set");
10672 return -99;
10673 }
10674
10675 is_ipv6 = ipv6_set;
10676 vam->is_ipv6 = is_ipv6;
10677
10678 /* free old data */
10679 for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
10680 {
10681 vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
10682 }
10683 vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
10684
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010685 M (IP_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010686 mp->is_ipv6 = ipv6_set;
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010687 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010688
10689 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040010690 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010691 S (mp_ping);
10692
Jon Loeliger56c7b012017-02-01 12:31:41 -060010693 W (ret);
10694 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010695}
10696
10697static int
10698api_ipsec_spd_add_del (vat_main_t * vam)
10699{
10700 unformat_input_t *i = vam->input;
10701 vl_api_ipsec_spd_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010702 u32 spd_id = ~0;
10703 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010704 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010705
10706 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10707 {
10708 if (unformat (i, "spd_id %d", &spd_id))
10709 ;
10710 else if (unformat (i, "del"))
10711 is_add = 0;
10712 else
10713 {
10714 clib_warning ("parse error '%U'", format_unformat_error, i);
10715 return -99;
10716 }
10717 }
10718 if (spd_id == ~0)
10719 {
10720 errmsg ("spd_id must be set");
10721 return -99;
10722 }
10723
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010724 M (IPSEC_SPD_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010725
10726 mp->spd_id = ntohl (spd_id);
10727 mp->is_add = is_add;
10728
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010729 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010730 W (ret);
10731 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010732}
10733
10734static int
10735api_ipsec_interface_add_del_spd (vat_main_t * vam)
10736{
10737 unformat_input_t *i = vam->input;
10738 vl_api_ipsec_interface_add_del_spd_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010739 u32 sw_if_index;
10740 u8 sw_if_index_set = 0;
10741 u32 spd_id = (u32) ~ 0;
10742 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010743 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010744
10745 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10746 {
10747 if (unformat (i, "del"))
10748 is_add = 0;
10749 else if (unformat (i, "spd_id %d", &spd_id))
10750 ;
10751 else
10752 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10753 sw_if_index_set = 1;
10754 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10755 sw_if_index_set = 1;
10756 else
10757 {
10758 clib_warning ("parse error '%U'", format_unformat_error, i);
10759 return -99;
10760 }
10761
10762 }
10763
10764 if (spd_id == (u32) ~ 0)
10765 {
10766 errmsg ("spd_id must be set");
10767 return -99;
10768 }
10769
10770 if (sw_if_index_set == 0)
10771 {
10772 errmsg ("missing interface name or sw_if_index");
10773 return -99;
10774 }
10775
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010776 M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010777
10778 mp->spd_id = ntohl (spd_id);
10779 mp->sw_if_index = ntohl (sw_if_index);
10780 mp->is_add = is_add;
10781
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010782 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010783 W (ret);
10784 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010785}
10786
10787static int
Neale Ranns17dcec02019-01-09 21:22:20 -080010788api_ipsec_spd_entry_add_del (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010010789{
10790 unformat_input_t *i = vam->input;
Neale Ranns17dcec02019-01-09 21:22:20 -080010791 vl_api_ipsec_spd_entry_add_del_t *mp;
Benoît Ganne49ee6842019-04-30 11:50:46 +020010792 u8 is_add = 1, is_outbound = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010793 u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
10794 i32 priority = 0;
10795 u32 rport_start = 0, rport_stop = (u32) ~ 0;
10796 u32 lport_start = 0, lport_stop = (u32) ~ 0;
Neale Ranns17dcec02019-01-09 21:22:20 -080010797 vl_api_address_t laddr_start = { }, laddr_stop =
10798 {
10799 }, raddr_start =
10800 {
10801 }, raddr_stop =
10802 {
10803 };
Jon Loeliger56c7b012017-02-01 12:31:41 -060010804 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010805
Damjan Marion7cd468a2016-12-19 23:05:39 +010010806 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10807 {
10808 if (unformat (i, "del"))
10809 is_add = 0;
10810 if (unformat (i, "outbound"))
10811 is_outbound = 1;
10812 if (unformat (i, "inbound"))
10813 is_outbound = 0;
10814 else if (unformat (i, "spd_id %d", &spd_id))
10815 ;
10816 else if (unformat (i, "sa_id %d", &sa_id))
10817 ;
10818 else if (unformat (i, "priority %d", &priority))
10819 ;
10820 else if (unformat (i, "protocol %d", &protocol))
10821 ;
10822 else if (unformat (i, "lport_start %d", &lport_start))
10823 ;
10824 else if (unformat (i, "lport_stop %d", &lport_stop))
10825 ;
10826 else if (unformat (i, "rport_start %d", &rport_start))
10827 ;
10828 else if (unformat (i, "rport_stop %d", &rport_stop))
10829 ;
Neale Ranns17dcec02019-01-09 21:22:20 -080010830 else if (unformat (i, "laddr_start %U",
10831 unformat_vl_api_address, &laddr_start))
Benoît Ganne49ee6842019-04-30 11:50:46 +020010832 ;
Neale Ranns17dcec02019-01-09 21:22:20 -080010833 else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
10834 &laddr_stop))
Benoît Ganne49ee6842019-04-30 11:50:46 +020010835 ;
Neale Ranns17dcec02019-01-09 21:22:20 -080010836 else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
10837 &raddr_start))
Benoît Ganne49ee6842019-04-30 11:50:46 +020010838 ;
Neale Ranns17dcec02019-01-09 21:22:20 -080010839 else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
10840 &raddr_stop))
Benoît Ganne49ee6842019-04-30 11:50:46 +020010841 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010842 else
10843 if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
10844 {
10845 if (policy == IPSEC_POLICY_ACTION_RESOLVE)
10846 {
10847 clib_warning ("unsupported action: 'resolve'");
10848 return -99;
10849 }
10850 }
10851 else
10852 {
10853 clib_warning ("parse error '%U'", format_unformat_error, i);
10854 return -99;
10855 }
10856
10857 }
10858
Neale Ranns17dcec02019-01-09 21:22:20 -080010859 M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010860
Damjan Marion7cd468a2016-12-19 23:05:39 +010010861 mp->is_add = is_add;
Neale Ranns17dcec02019-01-09 21:22:20 -080010862
10863 mp->entry.spd_id = ntohl (spd_id);
10864 mp->entry.priority = ntohl (priority);
10865 mp->entry.is_outbound = is_outbound;
10866
10867 clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
10868 sizeof (vl_api_address_t));
10869 clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
10870 sizeof (vl_api_address_t));
10871 clib_memcpy (&mp->entry.local_address_start, &laddr_start,
10872 sizeof (vl_api_address_t));
10873 clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
10874 sizeof (vl_api_address_t));
10875
10876 mp->entry.protocol = (u8) protocol;
10877 mp->entry.local_port_start = ntohs ((u16) lport_start);
10878 mp->entry.local_port_stop = ntohs ((u16) lport_stop);
10879 mp->entry.remote_port_start = ntohs ((u16) rport_start);
10880 mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
10881 mp->entry.policy = (u8) policy;
10882 mp->entry.sa_id = ntohl (sa_id);
Neale Ranns17dcec02019-01-09 21:22:20 -080010883
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010884 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010885 W (ret);
10886 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010887}
10888
10889static int
Neale Ranns17dcec02019-01-09 21:22:20 -080010890api_ipsec_sad_entry_add_del (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010010891{
10892 unformat_input_t *i = vam->input;
Neale Ranns17dcec02019-01-09 21:22:20 -080010893 vl_api_ipsec_sad_entry_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010894 u32 sad_id = 0, spi = 0;
10895 u8 *ck = 0, *ik = 0;
10896 u8 is_add = 1;
10897
Neale Ranns17dcec02019-01-09 21:22:20 -080010898 vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
10899 vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
10900 vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
10901 vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
10902 vl_api_address_t tun_src, tun_dst;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010903 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010904
10905 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10906 {
10907 if (unformat (i, "del"))
10908 is_add = 0;
10909 else if (unformat (i, "sad_id %d", &sad_id))
10910 ;
10911 else if (unformat (i, "spi %d", &spi))
10912 ;
10913 else if (unformat (i, "esp"))
Neale Ranns17dcec02019-01-09 21:22:20 -080010914 protocol = IPSEC_API_PROTO_ESP;
10915 else
10916 if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
Damjan Marion7cd468a2016-12-19 23:05:39 +010010917 {
Neale Ranns17dcec02019-01-09 21:22:20 -080010918 flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
10919 if (ADDRESS_IP6 == tun_src.af)
10920 flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010921 }
10922 else
Neale Ranns17dcec02019-01-09 21:22:20 -080010923 if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
Damjan Marion7cd468a2016-12-19 23:05:39 +010010924 {
Neale Ranns17dcec02019-01-09 21:22:20 -080010925 flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
10926 if (ADDRESS_IP6 == tun_src.af)
10927 flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010928 }
Neale Ranns17dcec02019-01-09 21:22:20 -080010929 else
10930 if (unformat (i, "crypto_alg %U",
10931 unformat_ipsec_api_crypto_alg, &crypto_alg))
10932 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010933 else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
10934 ;
Neale Ranns17dcec02019-01-09 21:22:20 -080010935 else if (unformat (i, "integ_alg %U",
10936 unformat_ipsec_api_integ_alg, &integ_alg))
10937 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010938 else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
10939 ;
10940 else
10941 {
10942 clib_warning ("parse error '%U'", format_unformat_error, i);
10943 return -99;
10944 }
10945
10946 }
10947
Neale Ranns17dcec02019-01-09 21:22:20 -080010948 M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010949
Damjan Marion7cd468a2016-12-19 23:05:39 +010010950 mp->is_add = is_add;
Neale Ranns17dcec02019-01-09 21:22:20 -080010951 mp->entry.sad_id = ntohl (sad_id);
10952 mp->entry.protocol = protocol;
10953 mp->entry.spi = ntohl (spi);
10954 mp->entry.flags = flags;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010955
Neale Ranns17dcec02019-01-09 21:22:20 -080010956 mp->entry.crypto_algorithm = crypto_alg;
10957 mp->entry.integrity_algorithm = integ_alg;
10958 mp->entry.crypto_key.length = vec_len (ck);
10959 mp->entry.integrity_key.length = vec_len (ik);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010960
Neale Ranns17dcec02019-01-09 21:22:20 -080010961 if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
10962 mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
10963
10964 if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
10965 mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010966
10967 if (ck)
Neale Ranns17dcec02019-01-09 21:22:20 -080010968 clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010969 if (ik)
Neale Ranns17dcec02019-01-09 21:22:20 -080010970 clib_memcpy (mp->entry.integrity_key.data, ik,
10971 mp->entry.integrity_key.length);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010972
Neale Ranns17dcec02019-01-09 21:22:20 -080010973 if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
Damjan Marion7cd468a2016-12-19 23:05:39 +010010974 {
Neale Ranns17dcec02019-01-09 21:22:20 -080010975 clib_memcpy (&mp->entry.tunnel_src, &tun_src,
10976 sizeof (mp->entry.tunnel_src));
10977 clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
10978 sizeof (mp->entry.tunnel_dst));
Damjan Marion7cd468a2016-12-19 23:05:39 +010010979 }
10980
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010981 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010982 W (ret);
10983 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010984}
10985
10986static int
Matthew Smithb0972cb2017-05-02 16:20:41 -050010987api_ipsec_tunnel_if_add_del (vat_main_t * vam)
10988{
10989 unformat_input_t *i = vam->input;
10990 vl_api_ipsec_tunnel_if_add_del_t *mp;
10991 u32 local_spi = 0, remote_spi = 0;
10992 u32 crypto_alg = 0, integ_alg = 0;
10993 u8 *lck = NULL, *rck = NULL;
10994 u8 *lik = NULL, *rik = NULL;
Kingwel Xie1ba5bc82019-03-20 07:21:58 -040010995 vl_api_address_t local_ip = { 0 };
10996 vl_api_address_t remote_ip = { 0 };
Neale Ranns2b5ba952019-04-02 10:15:40 +000010997 f64 before = 0;
Matthew Smithb0972cb2017-05-02 16:20:41 -050010998 u8 is_add = 1;
10999 u8 esn = 0;
11000 u8 anti_replay = 0;
Matthew Smith8e1039a2018-04-12 07:32:56 -050011001 u8 renumber = 0;
11002 u32 instance = ~0;
Neale Ranns2b5ba952019-04-02 10:15:40 +000011003 u32 count = 1, jj;
Benoît Ganne49ee6842019-04-30 11:50:46 +020011004 int ret = -1;
Matthew Smithb0972cb2017-05-02 16:20:41 -050011005
11006 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11007 {
11008 if (unformat (i, "del"))
11009 is_add = 0;
11010 else if (unformat (i, "esn"))
11011 esn = 1;
Neale Ranns2b5ba952019-04-02 10:15:40 +000011012 else if (unformat (i, "anti-replay"))
Matthew Smithb0972cb2017-05-02 16:20:41 -050011013 anti_replay = 1;
Neale Ranns2b5ba952019-04-02 10:15:40 +000011014 else if (unformat (i, "count %d", &count))
11015 ;
Matthew Smithb0972cb2017-05-02 16:20:41 -050011016 else if (unformat (i, "local_spi %d", &local_spi))
11017 ;
11018 else if (unformat (i, "remote_spi %d", &remote_spi))
11019 ;
Kingwel Xie1ba5bc82019-03-20 07:21:58 -040011020 else
11021 if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
Matthew Smithb0972cb2017-05-02 16:20:41 -050011022 ;
Kingwel Xie1ba5bc82019-03-20 07:21:58 -040011023 else
11024 if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
Matthew Smithb0972cb2017-05-02 16:20:41 -050011025 ;
11026 else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
11027 ;
11028 else
11029 if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
11030 ;
11031 else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
11032 ;
11033 else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
11034 ;
11035 else
11036 if (unformat
Neale Ranns17dcec02019-01-09 21:22:20 -080011037 (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
Matthew Smithb0972cb2017-05-02 16:20:41 -050011038 {
Dave Baracha8d47642018-07-13 11:22:23 -040011039 if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
Matthew Smithb0972cb2017-05-02 16:20:41 -050011040 {
11041 errmsg ("unsupported crypto-alg: '%U'\n",
11042 format_ipsec_crypto_alg, crypto_alg);
11043 return -99;
11044 }
11045 }
11046 else
11047 if (unformat
Neale Ranns17dcec02019-01-09 21:22:20 -080011048 (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
Matthew Smithb0972cb2017-05-02 16:20:41 -050011049 {
Dave Baracha8d47642018-07-13 11:22:23 -040011050 if (integ_alg >= IPSEC_INTEG_N_ALG)
Matthew Smithb0972cb2017-05-02 16:20:41 -050011051 {
11052 errmsg ("unsupported integ-alg: '%U'\n",
11053 format_ipsec_integ_alg, integ_alg);
11054 return -99;
11055 }
11056 }
Matthew Smith8e1039a2018-04-12 07:32:56 -050011057 else if (unformat (i, "instance %u", &instance))
11058 renumber = 1;
Matthew Smithb0972cb2017-05-02 16:20:41 -050011059 else
11060 {
11061 errmsg ("parse error '%U'\n", format_unformat_error, i);
11062 return -99;
11063 }
11064 }
11065
Neale Ranns2b5ba952019-04-02 10:15:40 +000011066 if (count > 1)
Matthew Smithb0972cb2017-05-02 16:20:41 -050011067 {
Neale Ranns2b5ba952019-04-02 10:15:40 +000011068 /* Turn on async mode */
11069 vam->async_mode = 1;
11070 vam->async_errors = 0;
11071 before = vat_time_now (vam);
Matthew Smithb0972cb2017-05-02 16:20:41 -050011072 }
11073
Neale Ranns2b5ba952019-04-02 10:15:40 +000011074 for (jj = 0; jj < count; jj++)
Matthew Smithb0972cb2017-05-02 16:20:41 -050011075 {
Neale Ranns2b5ba952019-04-02 10:15:40 +000011076 M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
11077
11078 mp->is_add = is_add;
11079 mp->esn = esn;
11080 mp->anti_replay = anti_replay;
11081
11082 if (jj > 0)
Neale Ranns097fa662018-05-01 05:17:55 -070011083 increment_address (&remote_ip);
Neale Ranns2b5ba952019-04-02 10:15:40 +000011084
11085 clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
11086 clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
11087
11088 mp->local_spi = htonl (local_spi + jj);
11089 mp->remote_spi = htonl (remote_spi + jj);
11090 mp->crypto_alg = (u8) crypto_alg;
11091
11092 mp->local_crypto_key_len = 0;
11093 if (lck)
11094 {
11095 mp->local_crypto_key_len = vec_len (lck);
11096 if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
11097 mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
11098 clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
11099 }
11100
11101 mp->remote_crypto_key_len = 0;
11102 if (rck)
11103 {
11104 mp->remote_crypto_key_len = vec_len (rck);
11105 if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
11106 mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
11107 clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
11108 }
11109
11110 mp->integ_alg = (u8) integ_alg;
11111
11112 mp->local_integ_key_len = 0;
11113 if (lik)
11114 {
11115 mp->local_integ_key_len = vec_len (lik);
11116 if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
11117 mp->local_integ_key_len = sizeof (mp->local_integ_key);
11118 clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
11119 }
11120
11121 mp->remote_integ_key_len = 0;
11122 if (rik)
11123 {
11124 mp->remote_integ_key_len = vec_len (rik);
11125 if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
11126 mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
11127 clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
11128 }
11129
11130 if (renumber)
11131 {
11132 mp->renumber = renumber;
11133 mp->show_instance = ntohl (instance);
11134 }
11135 S (mp);
Matthew Smithb0972cb2017-05-02 16:20:41 -050011136 }
11137
Neale Ranns2b5ba952019-04-02 10:15:40 +000011138 /* When testing multiple add/del ops, use a control-ping to sync */
11139 if (count > 1)
Matthew Smithb0972cb2017-05-02 16:20:41 -050011140 {
Neale Ranns2b5ba952019-04-02 10:15:40 +000011141 vl_api_control_ping_t *mp_ping;
11142 f64 after;
11143 f64 timeout;
11144
11145 /* Shut off async mode */
11146 vam->async_mode = 0;
11147
11148 MPING (CONTROL_PING, mp_ping);
11149 S (mp_ping);
11150
11151 timeout = vat_time_now (vam) + 1.0;
11152 while (vat_time_now (vam) < timeout)
11153 if (vam->result_ready == 1)
11154 goto out;
11155 vam->retval = -99;
11156
11157 out:
11158 if (vam->retval == -99)
11159 errmsg ("timeout");
11160
11161 if (vam->async_errors > 0)
11162 {
11163 errmsg ("%d asynchronous errors", vam->async_errors);
11164 vam->retval = -98;
11165 }
11166 vam->async_errors = 0;
11167 after = vat_time_now (vam);
11168
11169 /* slim chance, but we might have eaten SIGTERM on the first iteration */
11170 if (jj > 0)
11171 count = jj;
11172
11173 print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
11174 count, after - before, count / (after - before));
11175 }
11176 else
11177 {
11178 /* Wait for a reply... */
11179 W (ret);
11180 return ret;
Matthew Smithb0972cb2017-05-02 16:20:41 -050011181 }
11182
Matthew Smithb0972cb2017-05-02 16:20:41 -050011183 return ret;
11184}
11185
Matthew Smith28029532017-09-26 13:33:44 -050011186static void
11187vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
11188{
11189 vat_main_t *vam = &vat_main;
11190
11191 print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
Neale Ranns8d7c5022019-02-06 01:41:05 -080011192 "crypto_key %U integ_alg %u integ_key %U flags %x "
Matthew Smith28029532017-09-26 13:33:44 -050011193 "tunnel_src_addr %U tunnel_dst_addr %U "
11194 "salt %u seq_outbound %lu last_seq_inbound %lu "
Matthew Smith48d32b42020-04-02 07:45:49 -050011195 "replay_window %lu stat_index %u\n",
Neale Ranns8d7c5022019-02-06 01:41:05 -080011196 ntohl (mp->entry.sad_id),
11197 ntohl (mp->sw_if_index),
11198 ntohl (mp->entry.spi),
11199 ntohl (mp->entry.protocol),
11200 ntohl (mp->entry.crypto_algorithm),
11201 format_hex_bytes, mp->entry.crypto_key.data,
11202 mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
11203 format_hex_bytes, mp->entry.integrity_key.data,
11204 mp->entry.integrity_key.length, ntohl (mp->entry.flags),
11205 format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
11206 &mp->entry.tunnel_dst, ntohl (mp->salt),
Matthew Smith28029532017-09-26 13:33:44 -050011207 clib_net_to_host_u64 (mp->seq_outbound),
11208 clib_net_to_host_u64 (mp->last_seq_inbound),
Matthew Smith48d32b42020-04-02 07:45:49 -050011209 clib_net_to_host_u64 (mp->replay_window), ntohl (mp->stat_index));
Matthew Smith28029532017-09-26 13:33:44 -050011210}
11211
11212#define vl_api_ipsec_sa_details_t_endian vl_noop_handler
11213#define vl_api_ipsec_sa_details_t_print vl_noop_handler
11214
11215static void vl_api_ipsec_sa_details_t_handler_json
11216 (vl_api_ipsec_sa_details_t * mp)
11217{
11218 vat_main_t *vam = &vat_main;
11219 vat_json_node_t *node = NULL;
Neale Ranns8d7c5022019-02-06 01:41:05 -080011220 vl_api_ipsec_sad_flags_t flags;
Matthew Smith28029532017-09-26 13:33:44 -050011221
11222 if (VAT_JSON_ARRAY != vam->json_tree.type)
11223 {
11224 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11225 vat_json_init_array (&vam->json_tree);
11226 }
11227 node = vat_json_array_add (&vam->json_tree);
11228
11229 vat_json_init_object (node);
Neale Ranns8d7c5022019-02-06 01:41:05 -080011230 vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
Matthew Smith28029532017-09-26 13:33:44 -050011231 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
Neale Ranns8d7c5022019-02-06 01:41:05 -080011232 vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
11233 vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
11234 vat_json_object_add_uint (node, "crypto_alg",
11235 ntohl (mp->entry.crypto_algorithm));
11236 vat_json_object_add_uint (node, "integ_alg",
11237 ntohl (mp->entry.integrity_algorithm));
11238 flags = ntohl (mp->entry.flags);
11239 vat_json_object_add_uint (node, "use_esn",
Damjan Marion1e3aa5e2019-03-28 10:58:59 +010011240 ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
Neale Ranns8d7c5022019-02-06 01:41:05 -080011241 vat_json_object_add_uint (node, "use_anti_replay",
11242 ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
11243 vat_json_object_add_uint (node, "is_tunnel",
11244 ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
11245 vat_json_object_add_uint (node, "is_tunnel_ip6",
11246 ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
11247 vat_json_object_add_uint (node, "udp_encap",
11248 ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
11249 vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
11250 mp->entry.crypto_key.length);
11251 vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
11252 mp->entry.integrity_key.length);
Neale Ranns5a8844b2019-04-16 07:15:35 +000011253 vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
11254 vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
Matthew Smith28029532017-09-26 13:33:44 -050011255 vat_json_object_add_uint (node, "replay_window",
11256 clib_net_to_host_u64 (mp->replay_window));
Matthew Smith48d32b42020-04-02 07:45:49 -050011257 vat_json_object_add_uint (node, "stat_index", ntohl (mp->stat_index));
Matthew Smith28029532017-09-26 13:33:44 -050011258}
11259
11260static int
11261api_ipsec_sa_dump (vat_main_t * vam)
11262{
11263 unformat_input_t *i = vam->input;
11264 vl_api_ipsec_sa_dump_t *mp;
11265 vl_api_control_ping_t *mp_ping;
11266 u32 sa_id = ~0;
11267 int ret;
11268
11269 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11270 {
11271 if (unformat (i, "sa_id %d", &sa_id))
11272 ;
11273 else
11274 {
11275 clib_warning ("parse error '%U'", format_unformat_error, i);
11276 return -99;
11277 }
11278 }
11279
11280 M (IPSEC_SA_DUMP, mp);
11281
11282 mp->sa_id = ntohl (sa_id);
11283
11284 S (mp);
11285
11286 /* Use a control ping for synchronization */
11287 M (CONTROL_PING, mp_ping);
11288 S (mp_ping);
11289
11290 W (ret);
11291 return ret;
11292}
11293
Matthew Smithb0972cb2017-05-02 16:20:41 -050011294static int
Matthew Smithca514fd2017-10-12 12:06:59 -050011295api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
11296{
11297 unformat_input_t *i = vam->input;
11298 vl_api_ipsec_tunnel_if_set_sa_t *mp;
11299 u32 sw_if_index = ~0;
11300 u32 sa_id = ~0;
11301 u8 is_outbound = (u8) ~ 0;
11302 int ret;
11303
11304 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11305 {
11306 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11307 ;
11308 else if (unformat (i, "sa_id %d", &sa_id))
11309 ;
11310 else if (unformat (i, "outbound"))
11311 is_outbound = 1;
11312 else if (unformat (i, "inbound"))
11313 is_outbound = 0;
11314 else
11315 {
11316 clib_warning ("parse error '%U'", format_unformat_error, i);
11317 return -99;
11318 }
11319 }
11320
11321 if (sw_if_index == ~0)
11322 {
11323 errmsg ("interface must be specified");
11324 return -99;
11325 }
11326
11327 if (sa_id == ~0)
11328 {
11329 errmsg ("SA ID must be specified");
11330 return -99;
11331 }
11332
11333 M (IPSEC_TUNNEL_IF_SET_SA, mp);
11334
11335 mp->sw_if_index = htonl (sw_if_index);
11336 mp->sa_id = htonl (sa_id);
11337 mp->is_outbound = is_outbound;
11338
11339 S (mp);
11340 W (ret);
11341
11342 return ret;
11343}
11344
11345static int
Damjan Marion7cd468a2016-12-19 23:05:39 +010011346api_get_first_msg_id (vat_main_t * vam)
11347{
11348 vl_api_get_first_msg_id_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011349 unformat_input_t *i = vam->input;
11350 u8 *name;
11351 u8 name_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011352 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011353
11354 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11355 {
11356 if (unformat (i, "client %s", &name))
11357 name_set = 1;
11358 else
11359 break;
11360 }
11361
11362 if (name_set == 0)
11363 {
11364 errmsg ("missing client name");
11365 return -99;
11366 }
11367 vec_add1 (name, 0);
11368
11369 if (vec_len (name) > 63)
11370 {
11371 errmsg ("client name too long");
11372 return -99;
11373 }
11374
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011375 M (GET_FIRST_MSG_ID, mp);
Ole Troan7adaa222019-08-27 15:05:27 +020011376 clib_memcpy (mp->name, name, vec_len (name));
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011377 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011378 W (ret);
11379 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011380}
11381
11382static int
11383api_cop_interface_enable_disable (vat_main_t * vam)
11384{
11385 unformat_input_t *line_input = vam->input;
11386 vl_api_cop_interface_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011387 u32 sw_if_index = ~0;
11388 u8 enable_disable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011389 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011390
11391 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11392 {
11393 if (unformat (line_input, "disable"))
11394 enable_disable = 0;
11395 if (unformat (line_input, "enable"))
11396 enable_disable = 1;
11397 else if (unformat (line_input, "%U", api_unformat_sw_if_index,
11398 vam, &sw_if_index))
11399 ;
11400 else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11401 ;
11402 else
11403 break;
11404 }
11405
11406 if (sw_if_index == ~0)
11407 {
11408 errmsg ("missing interface name or sw_if_index");
11409 return -99;
11410 }
11411
11412 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011413 M (COP_INTERFACE_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011414 mp->sw_if_index = ntohl (sw_if_index);
11415 mp->enable_disable = enable_disable;
11416
11417 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011418 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011419 /* Wait for the reply */
Jon Loeliger56c7b012017-02-01 12:31:41 -060011420 W (ret);
11421 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011422}
11423
11424static int
11425api_cop_whitelist_enable_disable (vat_main_t * vam)
11426{
11427 unformat_input_t *line_input = vam->input;
11428 vl_api_cop_whitelist_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011429 u32 sw_if_index = ~0;
11430 u8 ip4 = 0, ip6 = 0, default_cop = 0;
11431 u32 fib_id = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011432 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011433
11434 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11435 {
11436 if (unformat (line_input, "ip4"))
11437 ip4 = 1;
11438 else if (unformat (line_input, "ip6"))
11439 ip6 = 1;
11440 else if (unformat (line_input, "default"))
11441 default_cop = 1;
11442 else if (unformat (line_input, "%U", api_unformat_sw_if_index,
11443 vam, &sw_if_index))
11444 ;
11445 else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11446 ;
11447 else if (unformat (line_input, "fib-id %d", &fib_id))
11448 ;
11449 else
11450 break;
11451 }
11452
11453 if (sw_if_index == ~0)
11454 {
11455 errmsg ("missing interface name or sw_if_index");
11456 return -99;
11457 }
11458
11459 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011460 M (COP_WHITELIST_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011461 mp->sw_if_index = ntohl (sw_if_index);
11462 mp->fib_id = ntohl (fib_id);
11463 mp->ip4 = ip4;
11464 mp->ip6 = ip6;
11465 mp->default_cop = default_cop;
11466
11467 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011468 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011469 /* Wait for the reply */
Jon Loeliger56c7b012017-02-01 12:31:41 -060011470 W (ret);
11471 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011472}
11473
11474static int
11475api_get_node_graph (vat_main_t * vam)
11476{
11477 vl_api_get_node_graph_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011478 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011479
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011480 M (GET_NODE_GRAPH, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011481
11482 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011483 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011484 /* Wait for the reply */
Jon Loeliger56c7b012017-02-01 12:31:41 -060011485 W (ret);
11486 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011487}
11488
Damjan Marion7cd468a2016-12-19 23:05:39 +010011489static int
11490api_af_packet_create (vat_main_t * vam)
11491{
11492 unformat_input_t *i = vam->input;
11493 vl_api_af_packet_create_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011494 u8 *host_if_name = 0;
11495 u8 hw_addr[6];
11496 u8 random_hw_addr = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011497 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011498
Dave Barachb7b92992018-10-17 10:38:51 -040011499 clib_memset (hw_addr, 0, sizeof (hw_addr));
Damjan Marion7cd468a2016-12-19 23:05:39 +010011500
11501 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11502 {
11503 if (unformat (i, "name %s", &host_if_name))
11504 vec_add1 (host_if_name, 0);
11505 else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
11506 random_hw_addr = 0;
11507 else
11508 break;
11509 }
11510
11511 if (!vec_len (host_if_name))
11512 {
11513 errmsg ("host-interface name must be specified");
11514 return -99;
11515 }
11516
11517 if (vec_len (host_if_name) > 64)
11518 {
11519 errmsg ("host-interface name too long");
11520 return -99;
11521 }
11522
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011523 M (AF_PACKET_CREATE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011524
11525 clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
11526 clib_memcpy (mp->hw_addr, hw_addr, 6);
11527 mp->use_random_hw_addr = random_hw_addr;
11528 vec_free (host_if_name);
11529
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011530 S (mp);
Dave Baracha1a093d2017-03-02 13:13:23 -050011531
11532 /* *INDENT-OFF* */
11533 W2 (ret,
11534 ({
11535 if (ret == 0)
11536 fprintf (vam->ofp ? vam->ofp : stderr,
11537 " new sw_if_index = %d\n", vam->sw_if_index);
11538 }));
11539 /* *INDENT-ON* */
Jon Loeliger56c7b012017-02-01 12:31:41 -060011540 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011541}
11542
11543static int
11544api_af_packet_delete (vat_main_t * vam)
11545{
11546 unformat_input_t *i = vam->input;
11547 vl_api_af_packet_delete_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011548 u8 *host_if_name = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011549 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011550
11551 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11552 {
11553 if (unformat (i, "name %s", &host_if_name))
11554 vec_add1 (host_if_name, 0);
11555 else
11556 break;
11557 }
11558
11559 if (!vec_len (host_if_name))
11560 {
11561 errmsg ("host-interface name must be specified");
11562 return -99;
11563 }
11564
11565 if (vec_len (host_if_name) > 64)
11566 {
11567 errmsg ("host-interface name too long");
11568 return -99;
11569 }
11570
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011571 M (AF_PACKET_DELETE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011572
11573 clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
11574 vec_free (host_if_name);
11575
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011576 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011577 W (ret);
11578 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011579}
11580
Mohsin Kazmi04e0bb22018-05-28 18:55:37 +020011581static void vl_api_af_packet_details_t_handler
11582 (vl_api_af_packet_details_t * mp)
11583{
11584 vat_main_t *vam = &vat_main;
11585
11586 print (vam->ofp, "%-16s %d",
11587 mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
11588}
11589
11590static void vl_api_af_packet_details_t_handler_json
11591 (vl_api_af_packet_details_t * mp)
11592{
11593 vat_main_t *vam = &vat_main;
11594 vat_json_node_t *node = NULL;
11595
11596 if (VAT_JSON_ARRAY != vam->json_tree.type)
11597 {
11598 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11599 vat_json_init_array (&vam->json_tree);
11600 }
11601 node = vat_json_array_add (&vam->json_tree);
11602
11603 vat_json_init_object (node);
11604 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11605 vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
11606}
11607
11608static int
11609api_af_packet_dump (vat_main_t * vam)
11610{
11611 vl_api_af_packet_dump_t *mp;
11612 vl_api_control_ping_t *mp_ping;
11613 int ret;
11614
11615 print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
11616 /* Get list of tap interfaces */
11617 M (AF_PACKET_DUMP, mp);
11618 S (mp);
11619
11620 /* Use a control ping for synchronization */
11621 MPING (CONTROL_PING, mp_ping);
11622 S (mp_ping);
11623
11624 W (ret);
11625 return ret;
11626}
11627
Damjan Marion7cd468a2016-12-19 23:05:39 +010011628static int
11629api_policer_add_del (vat_main_t * vam)
11630{
11631 unformat_input_t *i = vam->input;
11632 vl_api_policer_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011633 u8 is_add = 1;
11634 u8 *name = 0;
11635 u32 cir = 0;
11636 u32 eir = 0;
11637 u64 cb = 0;
11638 u64 eb = 0;
11639 u8 rate_type = 0;
11640 u8 round_type = 0;
11641 u8 type = 0;
11642 u8 color_aware = 0;
11643 sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011644 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011645
11646 conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
11647 conform_action.dscp = 0;
11648 exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
11649 exceed_action.dscp = 0;
11650 violate_action.action_type = SSE2_QOS_ACTION_DROP;
11651 violate_action.dscp = 0;
11652
11653 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11654 {
11655 if (unformat (i, "del"))
11656 is_add = 0;
11657 else if (unformat (i, "name %s", &name))
11658 vec_add1 (name, 0);
11659 else if (unformat (i, "cir %u", &cir))
11660 ;
11661 else if (unformat (i, "eir %u", &eir))
11662 ;
11663 else if (unformat (i, "cb %u", &cb))
11664 ;
11665 else if (unformat (i, "eb %u", &eb))
11666 ;
11667 else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
11668 &rate_type))
11669 ;
11670 else if (unformat (i, "round_type %U", unformat_policer_round_type,
11671 &round_type))
11672 ;
11673 else if (unformat (i, "type %U", unformat_policer_type, &type))
11674 ;
11675 else if (unformat (i, "conform_action %U", unformat_policer_action_type,
11676 &conform_action))
11677 ;
11678 else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
11679 &exceed_action))
11680 ;
11681 else if (unformat (i, "violate_action %U", unformat_policer_action_type,
11682 &violate_action))
11683 ;
11684 else if (unformat (i, "color-aware"))
11685 color_aware = 1;
11686 else
11687 break;
11688 }
11689
11690 if (!vec_len (name))
11691 {
11692 errmsg ("policer name must be specified");
11693 return -99;
11694 }
11695
11696 if (vec_len (name) > 64)
11697 {
11698 errmsg ("policer name too long");
11699 return -99;
11700 }
11701
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011702 M (POLICER_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011703
11704 clib_memcpy (mp->name, name, vec_len (name));
11705 vec_free (name);
11706 mp->is_add = is_add;
Neale Rannsd91c1db2017-07-31 02:30:50 -070011707 mp->cir = ntohl (cir);
11708 mp->eir = ntohl (eir);
11709 mp->cb = clib_net_to_host_u64 (cb);
11710 mp->eb = clib_net_to_host_u64 (eb);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011711 mp->rate_type = rate_type;
11712 mp->round_type = round_type;
11713 mp->type = type;
Jakub Grajciarcd01fb42020-03-02 13:16:53 +010011714 mp->conform_action.type = conform_action.action_type;
11715 mp->conform_action.dscp = conform_action.dscp;
11716 mp->exceed_action.type = exceed_action.action_type;
11717 mp->exceed_action.dscp = exceed_action.dscp;
11718 mp->violate_action.type = violate_action.action_type;
11719 mp->violate_action.dscp = violate_action.dscp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011720 mp->color_aware = color_aware;
11721
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011722 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011723 W (ret);
11724 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011725}
11726
11727static int
11728api_policer_dump (vat_main_t * vam)
11729{
11730 unformat_input_t *i = vam->input;
11731 vl_api_policer_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011732 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011733 u8 *match_name = 0;
11734 u8 match_name_valid = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011735 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011736
11737 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11738 {
11739 if (unformat (i, "name %s", &match_name))
11740 {
11741 vec_add1 (match_name, 0);
11742 match_name_valid = 1;
11743 }
11744 else
11745 break;
11746 }
11747
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011748 M (POLICER_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011749 mp->match_name_valid = match_name_valid;
11750 clib_memcpy (mp->match_name, match_name, vec_len (match_name));
11751 vec_free (match_name);
11752 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011753 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011754
11755 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040011756 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011757 S (mp_ping);
11758
Damjan Marion7cd468a2016-12-19 23:05:39 +010011759 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060011760 W (ret);
11761 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011762}
11763
11764static int
11765api_policer_classify_set_interface (vat_main_t * vam)
11766{
11767 unformat_input_t *i = vam->input;
11768 vl_api_policer_classify_set_interface_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011769 u32 sw_if_index;
11770 int sw_if_index_set;
11771 u32 ip4_table_index = ~0;
11772 u32 ip6_table_index = ~0;
11773 u32 l2_table_index = ~0;
11774 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011775 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011776
11777 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11778 {
11779 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11780 sw_if_index_set = 1;
11781 else if (unformat (i, "sw_if_index %d", &sw_if_index))
11782 sw_if_index_set = 1;
11783 else if (unformat (i, "del"))
11784 is_add = 0;
11785 else if (unformat (i, "ip4-table %d", &ip4_table_index))
11786 ;
11787 else if (unformat (i, "ip6-table %d", &ip6_table_index))
11788 ;
11789 else if (unformat (i, "l2-table %d", &l2_table_index))
11790 ;
11791 else
11792 {
11793 clib_warning ("parse error '%U'", format_unformat_error, i);
11794 return -99;
11795 }
11796 }
11797
11798 if (sw_if_index_set == 0)
11799 {
11800 errmsg ("missing interface name or sw_if_index");
11801 return -99;
11802 }
11803
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011804 M (POLICER_CLASSIFY_SET_INTERFACE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011805
11806 mp->sw_if_index = ntohl (sw_if_index);
11807 mp->ip4_table_index = ntohl (ip4_table_index);
11808 mp->ip6_table_index = ntohl (ip6_table_index);
11809 mp->l2_table_index = ntohl (l2_table_index);
11810 mp->is_add = is_add;
11811
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011812 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011813 W (ret);
11814 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011815}
11816
11817static int
11818api_policer_classify_dump (vat_main_t * vam)
11819{
11820 unformat_input_t *i = vam->input;
11821 vl_api_policer_classify_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011822 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011823 u8 type = POLICER_CLASSIFY_N_TABLES;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011824 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011825
11826 if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
11827 ;
11828 else
11829 {
11830 errmsg ("classify table type must be specified");
11831 return -99;
11832 }
11833
11834 if (!vam->json_output)
11835 {
11836 print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
11837 }
11838
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011839 M (POLICER_CLASSIFY_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011840 mp->type = type;
11841 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011842 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011843
11844 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040011845 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011846 S (mp_ping);
11847
Damjan Marion7cd468a2016-12-19 23:05:39 +010011848 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060011849 W (ret);
11850 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011851}
11852
Neale Ranns097fa662018-05-01 05:17:55 -070011853static u8 *
11854format_fib_api_path_nh_proto (u8 * s, va_list * args)
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011855{
Neale Ranns097fa662018-05-01 05:17:55 -070011856 vl_api_fib_path_nh_proto_t proto =
11857 va_arg (*args, vl_api_fib_path_nh_proto_t);
11858
11859 switch (proto)
11860 {
11861 case FIB_API_PATH_NH_PROTO_IP4:
11862 s = format (s, "ip4");
11863 break;
11864 case FIB_API_PATH_NH_PROTO_IP6:
11865 s = format (s, "ip6");
11866 break;
11867 case FIB_API_PATH_NH_PROTO_MPLS:
11868 s = format (s, "mpls");
11869 break;
11870 case FIB_API_PATH_NH_PROTO_BIER:
11871 s = format (s, "bier");
11872 break;
11873 case FIB_API_PATH_NH_PROTO_ETHERNET:
11874 s = format (s, "ethernet");
11875 break;
11876 }
11877
11878 return (s);
11879}
11880
11881static u8 *
11882format_vl_api_ip_address_union (u8 * s, va_list * args)
11883{
Jakub Grajciar7dd63e52020-03-19 08:03:55 +010011884 vl_api_address_family_t af = va_arg (*args, int);
Neale Ranns097fa662018-05-01 05:17:55 -070011885 const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
11886
11887 switch (af)
11888 {
11889 case ADDRESS_IP4:
11890 s = format (s, "%U", format_ip4_address, u->ip4);
11891 break;
11892 case ADDRESS_IP6:
11893 s = format (s, "%U", format_ip6_address, u->ip6);
11894 break;
11895 }
11896 return (s);
11897}
11898
11899static u8 *
11900format_vl_api_fib_path_type (u8 * s, va_list * args)
11901{
11902 vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
11903
11904 switch (t)
11905 {
11906 case FIB_API_PATH_TYPE_NORMAL:
11907 s = format (s, "normal");
11908 break;
11909 case FIB_API_PATH_TYPE_LOCAL:
11910 s = format (s, "local");
11911 break;
11912 case FIB_API_PATH_TYPE_DROP:
11913 s = format (s, "drop");
11914 break;
11915 case FIB_API_PATH_TYPE_UDP_ENCAP:
11916 s = format (s, "udp-encap");
11917 break;
11918 case FIB_API_PATH_TYPE_BIER_IMP:
11919 s = format (s, "bier-imp");
11920 break;
11921 case FIB_API_PATH_TYPE_ICMP_UNREACH:
11922 s = format (s, "unreach");
11923 break;
11924 case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
11925 s = format (s, "prohibit");
11926 break;
11927 case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
11928 s = format (s, "src-lookup");
11929 break;
11930 case FIB_API_PATH_TYPE_DVR:
11931 s = format (s, "dvr");
11932 break;
11933 case FIB_API_PATH_TYPE_INTERFACE_RX:
11934 s = format (s, "interface-rx");
11935 break;
11936 case FIB_API_PATH_TYPE_CLASSIFY:
11937 s = format (s, "classify");
11938 break;
11939 }
11940
11941 return (s);
11942}
11943
11944static void
11945vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
11946{
11947 print (vam->ofp,
11948 " weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
11949 ntohl (fp->weight), ntohl (fp->sw_if_index),
11950 format_vl_api_fib_path_type, fp->type,
11951 format_fib_api_path_nh_proto, fp->proto,
11952 format_vl_api_ip_address_union, &fp->nh.address);
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011953}
11954
11955static void
11956vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
Neale Ranns31ed7442018-02-23 05:29:09 -080011957 vl_api_fib_path_t * fp)
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011958{
11959 struct in_addr ip4;
11960 struct in6_addr ip6;
11961
11962 vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
11963 vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
Neale Ranns097fa662018-05-01 05:17:55 -070011964 vat_json_object_add_uint (node, "type", fp->type);
11965 vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
11966 if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011967 {
Neale Ranns097fa662018-05-01 05:17:55 -070011968 clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011969 vat_json_object_add_ip4 (node, "next_hop", ip4);
11970 }
Dave Barachc35f3e82020-04-02 10:44:09 -040011971 else if (fp->proto == FIB_API_PATH_NH_PROTO_IP6)
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011972 {
Neale Ranns097fa662018-05-01 05:17:55 -070011973 clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011974 vat_json_object_add_ip6 (node, "next_hop", ip6);
11975 }
11976}
11977
11978static void
11979vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010011980{
11981 vat_main_t *vam = &vat_main;
Neale Ranns097fa662018-05-01 05:17:55 -070011982 int count = ntohl (mp->mt_tunnel.mt_n_paths);
Neale Ranns31ed7442018-02-23 05:29:09 -080011983 vl_api_fib_path_t *fp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011984 i32 i;
11985
Neale Ranns097fa662018-05-01 05:17:55 -070011986 print (vam->ofp, "sw_if_index %d via:",
11987 ntohl (mp->mt_tunnel.mt_sw_if_index));
11988 fp = mp->mt_tunnel.mt_paths;
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011989 for (i = 0; i < count; i++)
Damjan Marion7cd468a2016-12-19 23:05:39 +010011990 {
Neale Ranns097fa662018-05-01 05:17:55 -070011991 vl_api_fib_path_print (vam, fp);
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011992 fp++;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011993 }
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011994
Damjan Marion7cd468a2016-12-19 23:05:39 +010011995 print (vam->ofp, "");
11996}
11997
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011998#define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
11999#define vl_api_mpls_tunnel_details_t_print vl_noop_handler
12000
12001static void
12002vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012003{
12004 vat_main_t *vam = &vat_main;
12005 vat_json_node_t *node = NULL;
Neale Ranns097fa662018-05-01 05:17:55 -070012006 int count = ntohl (mp->mt_tunnel.mt_n_paths);
Neale Ranns31ed7442018-02-23 05:29:09 -080012007 vl_api_fib_path_t *fp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012008 i32 i;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012009
12010 if (VAT_JSON_ARRAY != vam->json_tree.type)
12011 {
12012 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12013 vat_json_init_array (&vam->json_tree);
12014 }
12015 node = vat_json_array_add (&vam->json_tree);
12016
12017 vat_json_init_object (node);
Neale Ranns097fa662018-05-01 05:17:55 -070012018 vat_json_object_add_uint (node, "sw_if_index",
12019 ntohl (mp->mt_tunnel.mt_sw_if_index));
Neale Ranns0f26c5a2017-03-01 15:12:11 -080012020
Neale Ranns097fa662018-05-01 05:17:55 -070012021 vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
Neale Ranns0f26c5a2017-03-01 15:12:11 -080012022
Neale Ranns097fa662018-05-01 05:17:55 -070012023 fp = mp->mt_tunnel.mt_paths;
Neale Ranns0f26c5a2017-03-01 15:12:11 -080012024 for (i = 0; i < count; i++)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012025 {
Neale Ranns0f26c5a2017-03-01 15:12:11 -080012026 vl_api_mpls_fib_path_json_print (node, fp);
12027 fp++;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012028 }
12029}
12030
12031static int
12032api_mpls_tunnel_dump (vat_main_t * vam)
12033{
12034 vl_api_mpls_tunnel_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012035 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012036 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012037
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012038 M (MPLS_TUNNEL_DUMP, mp);
Neale Ranns097fa662018-05-01 05:17:55 -070012039
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012040 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012041
12042 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040012043 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012044 S (mp_ping);
12045
Jon Loeliger56c7b012017-02-01 12:31:41 -060012046 W (ret);
12047 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012048}
12049
Neale Ranns097fa662018-05-01 05:17:55 -070012050#define vl_api_mpls_table_details_t_endian vl_noop_handler
12051#define vl_api_mpls_table_details_t_print vl_noop_handler
Damjan Marion7cd468a2016-12-19 23:05:39 +010012052
Neale Ranns0f26c5a2017-03-01 15:12:11 -080012053
Damjan Marion7cd468a2016-12-19 23:05:39 +010012054static void
Neale Ranns097fa662018-05-01 05:17:55 -070012055vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012056{
12057 vat_main_t *vam = &vat_main;
Neale Ranns097fa662018-05-01 05:17:55 -070012058
12059 print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
12060}
12061
12062static void vl_api_mpls_table_details_t_handler_json
12063 (vl_api_mpls_table_details_t * mp)
12064{
12065 vat_main_t *vam = &vat_main;
12066 vat_json_node_t *node = NULL;
12067
12068 if (VAT_JSON_ARRAY != vam->json_tree.type)
12069 {
12070 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12071 vat_json_init_array (&vam->json_tree);
12072 }
12073 node = vat_json_array_add (&vam->json_tree);
12074
12075 vat_json_init_object (node);
12076 vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
12077}
12078
12079static int
12080api_mpls_table_dump (vat_main_t * vam)
12081{
12082 vl_api_mpls_table_dump_t *mp;
12083 vl_api_control_ping_t *mp_ping;
12084 int ret;
12085
12086 M (MPLS_TABLE_DUMP, mp);
12087 S (mp);
12088
12089 /* Use a control ping for synchronization */
12090 MPING (CONTROL_PING, mp_ping);
12091 S (mp_ping);
12092
12093 W (ret);
12094 return ret;
12095}
12096
12097#define vl_api_mpls_route_details_t_endian vl_noop_handler
12098#define vl_api_mpls_route_details_t_print vl_noop_handler
12099
12100static void
12101vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
12102{
12103 vat_main_t *vam = &vat_main;
Dave Barach4bda2d92019-07-03 15:21:50 -040012104 int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
Neale Ranns31ed7442018-02-23 05:29:09 -080012105 vl_api_fib_path_t *fp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012106 int i;
12107
12108 print (vam->ofp,
12109 "table-id %d, label %u, ess_bit %u",
Neale Ranns097fa662018-05-01 05:17:55 -070012110 ntohl (mp->mr_route.mr_table_id),
12111 ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
12112 fp = mp->mr_route.mr_paths;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012113 for (i = 0; i < count; i++)
12114 {
Neale Ranns097fa662018-05-01 05:17:55 -070012115 vl_api_fib_path_print (vam, fp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012116 fp++;
12117 }
12118}
12119
Neale Ranns097fa662018-05-01 05:17:55 -070012120static void vl_api_mpls_route_details_t_handler_json
12121 (vl_api_mpls_route_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012122{
12123 vat_main_t *vam = &vat_main;
Dave Barach4bda2d92019-07-03 15:21:50 -040012124 int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012125 vat_json_node_t *node = NULL;
Neale Ranns31ed7442018-02-23 05:29:09 -080012126 vl_api_fib_path_t *fp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012127 int i;
12128
12129 if (VAT_JSON_ARRAY != vam->json_tree.type)
12130 {
12131 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12132 vat_json_init_array (&vam->json_tree);
12133 }
12134 node = vat_json_array_add (&vam->json_tree);
12135
12136 vat_json_init_object (node);
Neale Ranns097fa662018-05-01 05:17:55 -070012137 vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
12138 vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
12139 vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
Damjan Marion7cd468a2016-12-19 23:05:39 +010012140 vat_json_object_add_uint (node, "path_count", count);
Neale Ranns097fa662018-05-01 05:17:55 -070012141 fp = mp->mr_route.mr_paths;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012142 for (i = 0; i < count; i++)
12143 {
Neale Ranns0f26c5a2017-03-01 15:12:11 -080012144 vl_api_mpls_fib_path_json_print (node, fp);
12145 fp++;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012146 }
12147}
12148
12149static int
Neale Ranns097fa662018-05-01 05:17:55 -070012150api_mpls_route_dump (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012151{
Neale Ranns097fa662018-05-01 05:17:55 -070012152 unformat_input_t *input = vam->input;
12153 vl_api_mpls_route_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012154 vl_api_control_ping_t *mp_ping;
Neale Ranns097fa662018-05-01 05:17:55 -070012155 u32 table_id;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012156 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012157
Neale Ranns097fa662018-05-01 05:17:55 -070012158 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12159 {
12160 if (unformat (input, "table_id %d", &table_id))
12161 ;
12162 else
12163 break;
12164 }
12165 if (table_id == ~0)
12166 {
12167 errmsg ("missing table id");
12168 return -99;
12169 }
12170
12171 M (MPLS_ROUTE_DUMP, mp);
12172
12173 mp->table.mt_table_id = ntohl (table_id);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012174 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012175
12176 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040012177 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012178 S (mp_ping);
12179
Jon Loeliger56c7b012017-02-01 12:31:41 -060012180 W (ret);
12181 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012182}
12183
Neale Ranns097fa662018-05-01 05:17:55 -070012184#define vl_api_ip_table_details_t_endian vl_noop_handler
12185#define vl_api_ip_table_details_t_print vl_noop_handler
Damjan Marion7cd468a2016-12-19 23:05:39 +010012186
12187static void
Neale Ranns097fa662018-05-01 05:17:55 -070012188vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012189{
12190 vat_main_t *vam = &vat_main;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012191
12192 print (vam->ofp,
Neale Ranns097fa662018-05-01 05:17:55 -070012193 "%s; table-id %d, prefix %U/%d",
12194 mp->table.name, ntohl (mp->table.table_id));
Damjan Marion7cd468a2016-12-19 23:05:39 +010012195}
12196
Neale Ranns097fa662018-05-01 05:17:55 -070012197
12198static void vl_api_ip_table_details_t_handler_json
12199 (vl_api_ip_table_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012200{
12201 vat_main_t *vam = &vat_main;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012202 vat_json_node_t *node = NULL;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012203
12204 if (VAT_JSON_ARRAY != vam->json_tree.type)
12205 {
12206 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12207 vat_json_init_array (&vam->json_tree);
12208 }
12209 node = vat_json_array_add (&vam->json_tree);
12210
12211 vat_json_init_object (node);
Neale Ranns097fa662018-05-01 05:17:55 -070012212 vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
Damjan Marion7cd468a2016-12-19 23:05:39 +010012213}
12214
12215static int
Neale Ranns097fa662018-05-01 05:17:55 -070012216api_ip_table_dump (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012217{
Neale Ranns097fa662018-05-01 05:17:55 -070012218 vl_api_ip_table_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012219 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012220 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012221
Neale Ranns097fa662018-05-01 05:17:55 -070012222 M (IP_TABLE_DUMP, mp);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012223 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012224
12225 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040012226 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012227 S (mp_ping);
12228
Jon Loeliger56c7b012017-02-01 12:31:41 -060012229 W (ret);
12230 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012231}
12232
Neale Ranns5a8123b2017-01-26 01:18:23 -080012233static int
Neale Ranns097fa662018-05-01 05:17:55 -070012234api_ip_mtable_dump (vat_main_t * vam)
Neale Ranns5a8123b2017-01-26 01:18:23 -080012235{
Neale Ranns097fa662018-05-01 05:17:55 -070012236 vl_api_ip_mtable_dump_t *mp;
Neale Ranns5a8123b2017-01-26 01:18:23 -080012237 vl_api_control_ping_t *mp_ping;
12238 int ret;
12239
Neale Ranns097fa662018-05-01 05:17:55 -070012240 M (IP_MTABLE_DUMP, mp);
12241 S (mp);
12242
12243 /* Use a control ping for synchronization */
12244 MPING (CONTROL_PING, mp_ping);
12245 S (mp_ping);
12246
12247 W (ret);
12248 return ret;
12249}
12250
12251static int
12252api_ip_mroute_dump (vat_main_t * vam)
12253{
12254 unformat_input_t *input = vam->input;
12255 vl_api_control_ping_t *mp_ping;
12256 vl_api_ip_mroute_dump_t *mp;
12257 int ret, is_ip6;
12258 u32 table_id;
12259
12260 is_ip6 = 0;
12261 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12262 {
12263 if (unformat (input, "table_id %d", &table_id))
12264 ;
12265 else if (unformat (input, "ip6"))
12266 is_ip6 = 1;
12267 else if (unformat (input, "ip4"))
12268 is_ip6 = 0;
12269 else
12270 break;
12271 }
12272 if (table_id == ~0)
12273 {
12274 errmsg ("missing table id");
12275 return -99;
12276 }
12277
12278 M (IP_MROUTE_DUMP, mp);
12279 mp->table.table_id = table_id;
12280 mp->table.is_ip6 = is_ip6;
Neale Ranns5a8123b2017-01-26 01:18:23 -080012281 S (mp);
12282
12283 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040012284 MPING (CONTROL_PING, mp_ping);
Neale Ranns5a8123b2017-01-26 01:18:23 -080012285 S (mp_ping);
12286
12287 W (ret);
12288 return ret;
12289}
12290
Neale Ranns097fa662018-05-01 05:17:55 -070012291#define vl_api_ip_route_details_t_endian vl_noop_handler
12292#define vl_api_ip_route_details_t_print vl_noop_handler
Damjan Marion7cd468a2016-12-19 23:05:39 +010012293
12294static void
Neale Ranns097fa662018-05-01 05:17:55 -070012295vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012296{
12297 vat_main_t *vam = &vat_main;
Neale Ranns097fa662018-05-01 05:17:55 -070012298 u8 count = mp->route.n_paths;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012299 vl_api_fib_path_t *fp;
12300 int i;
12301
12302 print (vam->ofp,
Neale Ranns097fa662018-05-01 05:17:55 -070012303 "table-id %d, prefix %U/%d",
12304 ntohl (mp->route.table_id),
Paul Vinciguerraab055082019-06-06 14:07:55 -040012305 format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012306 for (i = 0; i < count; i++)
12307 {
Neale Ranns097fa662018-05-01 05:17:55 -070012308 fp = &mp->route.paths[i];
12309
12310 vl_api_fib_path_print (vam, fp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012311 fp++;
12312 }
12313}
12314
Neale Ranns097fa662018-05-01 05:17:55 -070012315static void vl_api_ip_route_details_t_handler_json
12316 (vl_api_ip_route_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012317{
12318 vat_main_t *vam = &vat_main;
Neale Ranns097fa662018-05-01 05:17:55 -070012319 u8 count = mp->route.n_paths;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012320 vat_json_node_t *node = NULL;
12321 struct in_addr ip4;
12322 struct in6_addr ip6;
12323 vl_api_fib_path_t *fp;
12324 int i;
12325
12326 if (VAT_JSON_ARRAY != vam->json_tree.type)
12327 {
12328 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12329 vat_json_init_array (&vam->json_tree);
12330 }
12331 node = vat_json_array_add (&vam->json_tree);
12332
12333 vat_json_init_object (node);
Neale Ranns097fa662018-05-01 05:17:55 -070012334 vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
12335 if (ADDRESS_IP6 == mp->route.prefix.address.af)
12336 {
12337 clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
12338 vat_json_object_add_ip6 (node, "prefix", ip6);
12339 }
12340 else
12341 {
12342 clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
12343 vat_json_object_add_ip4 (node, "prefix", ip4);
12344 }
Paul Vinciguerraab055082019-06-06 14:07:55 -040012345 vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012346 vat_json_object_add_uint (node, "path_count", count);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012347 for (i = 0; i < count; i++)
12348 {
Neale Ranns097fa662018-05-01 05:17:55 -070012349 fp = &mp->route.paths[i];
12350 vl_api_mpls_fib_path_json_print (node, fp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012351 }
12352}
12353
12354static int
Neale Ranns097fa662018-05-01 05:17:55 -070012355api_ip_route_dump (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012356{
Neale Ranns097fa662018-05-01 05:17:55 -070012357 unformat_input_t *input = vam->input;
12358 vl_api_ip_route_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012359 vl_api_control_ping_t *mp_ping;
Neale Ranns097fa662018-05-01 05:17:55 -070012360 u32 table_id;
12361 u8 is_ip6;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012362 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012363
Neale Ranns097fa662018-05-01 05:17:55 -070012364 is_ip6 = 0;
12365 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12366 {
12367 if (unformat (input, "table_id %d", &table_id))
12368 ;
12369 else if (unformat (input, "ip6"))
12370 is_ip6 = 1;
12371 else if (unformat (input, "ip4"))
12372 is_ip6 = 0;
12373 else
12374 break;
12375 }
12376 if (table_id == ~0)
12377 {
12378 errmsg ("missing table id");
12379 return -99;
12380 }
Damjan Marion7cd468a2016-12-19 23:05:39 +010012381
Neale Ranns097fa662018-05-01 05:17:55 -070012382 M (IP_ROUTE_DUMP, mp);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012383
Neale Ranns097fa662018-05-01 05:17:55 -070012384 mp->table.table_id = table_id;
12385 mp->table.is_ip6 = is_ip6;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012386
Neale Ranns5a8123b2017-01-26 01:18:23 -080012387 S (mp);
12388
12389 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040012390 MPING (CONTROL_PING, mp_ping);
Neale Ranns5a8123b2017-01-26 01:18:23 -080012391 S (mp_ping);
12392
12393 W (ret);
12394 return ret;
12395}
12396
Damjan Marion7cd468a2016-12-19 23:05:39 +010012397int
12398api_classify_table_ids (vat_main_t * vam)
12399{
12400 vl_api_classify_table_ids_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012401 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012402
12403 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012404 M (CLASSIFY_TABLE_IDS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012405 mp->context = 0;
12406
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012407 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012408 W (ret);
12409 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012410}
12411
12412int
12413api_classify_table_by_interface (vat_main_t * vam)
12414{
12415 unformat_input_t *input = vam->input;
12416 vl_api_classify_table_by_interface_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012417
12418 u32 sw_if_index = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012419 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012420 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12421 {
12422 if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12423 ;
12424 else if (unformat (input, "sw_if_index %d", &sw_if_index))
12425 ;
12426 else
12427 break;
12428 }
12429 if (sw_if_index == ~0)
12430 {
12431 errmsg ("missing interface name or sw_if_index");
12432 return -99;
12433 }
12434
12435 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012436 M (CLASSIFY_TABLE_BY_INTERFACE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012437 mp->context = 0;
12438 mp->sw_if_index = ntohl (sw_if_index);
12439
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012440 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012441 W (ret);
12442 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012443}
12444
12445int
12446api_classify_table_info (vat_main_t * vam)
12447{
12448 unformat_input_t *input = vam->input;
12449 vl_api_classify_table_info_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012450
12451 u32 table_id = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012452 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012453 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12454 {
12455 if (unformat (input, "table_id %d", &table_id))
12456 ;
12457 else
12458 break;
12459 }
12460 if (table_id == ~0)
12461 {
12462 errmsg ("missing table id");
12463 return -99;
12464 }
12465
12466 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012467 M (CLASSIFY_TABLE_INFO, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012468 mp->context = 0;
12469 mp->table_id = ntohl (table_id);
12470
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012471 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012472 W (ret);
12473 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012474}
12475
12476int
12477api_classify_session_dump (vat_main_t * vam)
12478{
12479 unformat_input_t *input = vam->input;
12480 vl_api_classify_session_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012481 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012482
12483 u32 table_id = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012484 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012485 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12486 {
12487 if (unformat (input, "table_id %d", &table_id))
12488 ;
12489 else
12490 break;
12491 }
12492 if (table_id == ~0)
12493 {
12494 errmsg ("missing table id");
12495 return -99;
12496 }
12497
12498 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012499 M (CLASSIFY_SESSION_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012500 mp->context = 0;
12501 mp->table_id = ntohl (table_id);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012502 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012503
12504 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040012505 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012506 S (mp_ping);
12507
Jon Loeliger56c7b012017-02-01 12:31:41 -060012508 W (ret);
12509 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012510}
12511
12512static void
12513vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
12514{
12515 vat_main_t *vam = &vat_main;
12516
12517 print (vam->ofp, "collector_address %U, collector_port %d, "
12518 "src_address %U, vrf_id %d, path_mtu %u, "
12519 "template_interval %u, udp_checksum %d",
12520 format_ip4_address, mp->collector_address,
12521 ntohs (mp->collector_port),
12522 format_ip4_address, mp->src_address,
12523 ntohl (mp->vrf_id), ntohl (mp->path_mtu),
12524 ntohl (mp->template_interval), mp->udp_checksum);
12525
12526 vam->retval = 0;
12527 vam->result_ready = 1;
12528}
12529
12530static void
12531 vl_api_ipfix_exporter_details_t_handler_json
12532 (vl_api_ipfix_exporter_details_t * mp)
12533{
12534 vat_main_t *vam = &vat_main;
12535 vat_json_node_t node;
12536 struct in_addr collector_address;
12537 struct in_addr src_address;
12538
12539 vat_json_init_object (&node);
12540 clib_memcpy (&collector_address, &mp->collector_address,
12541 sizeof (collector_address));
12542 vat_json_object_add_ip4 (&node, "collector_address", collector_address);
12543 vat_json_object_add_uint (&node, "collector_port",
12544 ntohs (mp->collector_port));
12545 clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
12546 vat_json_object_add_ip4 (&node, "src_address", src_address);
12547 vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
12548 vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
12549 vat_json_object_add_uint (&node, "template_interval",
12550 ntohl (mp->template_interval));
12551 vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
12552
12553 vat_json_print (vam->ofp, &node);
12554 vat_json_free (&node);
12555 vam->retval = 0;
12556 vam->result_ready = 1;
12557}
12558
12559int
12560api_ipfix_exporter_dump (vat_main_t * vam)
12561{
12562 vl_api_ipfix_exporter_dump_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012563 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012564
12565 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012566 M (IPFIX_EXPORTER_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012567 mp->context = 0;
12568
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012569 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012570 W (ret);
12571 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012572}
12573
12574static int
12575api_ipfix_classify_stream_dump (vat_main_t * vam)
12576{
12577 vl_api_ipfix_classify_stream_dump_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012578 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012579
12580 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012581 M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012582 mp->context = 0;
12583
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012584 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012585 W (ret);
12586 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012587 /* NOTREACHED */
12588 return 0;
12589}
12590
12591static void
12592 vl_api_ipfix_classify_stream_details_t_handler
12593 (vl_api_ipfix_classify_stream_details_t * mp)
12594{
12595 vat_main_t *vam = &vat_main;
12596 print (vam->ofp, "domain_id %d, src_port %d",
12597 ntohl (mp->domain_id), ntohs (mp->src_port));
12598 vam->retval = 0;
12599 vam->result_ready = 1;
12600}
12601
12602static void
12603 vl_api_ipfix_classify_stream_details_t_handler_json
12604 (vl_api_ipfix_classify_stream_details_t * mp)
12605{
12606 vat_main_t *vam = &vat_main;
12607 vat_json_node_t node;
12608
12609 vat_json_init_object (&node);
12610 vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
12611 vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
12612
12613 vat_json_print (vam->ofp, &node);
12614 vat_json_free (&node);
12615 vam->retval = 0;
12616 vam->result_ready = 1;
12617}
12618
12619static int
12620api_ipfix_classify_table_dump (vat_main_t * vam)
12621{
12622 vl_api_ipfix_classify_table_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012623 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012624 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012625
12626 if (!vam->json_output)
12627 {
12628 print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
12629 "transport_protocol");
12630 }
12631
12632 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012633 M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012634
12635 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012636 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012637
12638 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040012639 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012640 S (mp_ping);
12641
Jon Loeliger56c7b012017-02-01 12:31:41 -060012642 W (ret);
12643 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012644}
12645
12646static void
12647 vl_api_ipfix_classify_table_details_t_handler
12648 (vl_api_ipfix_classify_table_details_t * mp)
12649{
12650 vat_main_t *vam = &vat_main;
12651 print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
12652 mp->transport_protocol);
12653}
12654
12655static void
12656 vl_api_ipfix_classify_table_details_t_handler_json
12657 (vl_api_ipfix_classify_table_details_t * mp)
12658{
12659 vat_json_node_t *node = NULL;
12660 vat_main_t *vam = &vat_main;
12661
12662 if (VAT_JSON_ARRAY != vam->json_tree.type)
12663 {
12664 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12665 vat_json_init_array (&vam->json_tree);
12666 }
12667
12668 node = vat_json_array_add (&vam->json_tree);
12669 vat_json_init_object (node);
12670
12671 vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
12672 vat_json_object_add_uint (node, "ip_version", mp->ip_version);
12673 vat_json_object_add_uint (node, "transport_protocol",
12674 mp->transport_protocol);
12675}
12676
12677static int
12678api_sw_interface_span_enable_disable (vat_main_t * vam)
12679{
12680 unformat_input_t *i = vam->input;
12681 vl_api_sw_interface_span_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012682 u32 src_sw_if_index = ~0;
12683 u32 dst_sw_if_index = ~0;
12684 u8 state = 3;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012685 int ret;
Eyal Bari001fd402017-07-16 09:34:53 +030012686 u8 is_l2 = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012687
12688 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12689 {
12690 if (unformat
12691 (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
12692 ;
12693 else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
12694 ;
12695 else
12696 if (unformat
12697 (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
12698 ;
12699 else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
12700 ;
12701 else if (unformat (i, "disable"))
12702 state = 0;
12703 else if (unformat (i, "rx"))
12704 state = 1;
12705 else if (unformat (i, "tx"))
12706 state = 2;
12707 else if (unformat (i, "both"))
12708 state = 3;
Eyal Bari001fd402017-07-16 09:34:53 +030012709 else if (unformat (i, "l2"))
12710 is_l2 = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012711 else
12712 break;
12713 }
12714
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012715 M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012716
12717 mp->sw_if_index_from = htonl (src_sw_if_index);
12718 mp->sw_if_index_to = htonl (dst_sw_if_index);
12719 mp->state = state;
Eyal Bari001fd402017-07-16 09:34:53 +030012720 mp->is_l2 = is_l2;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012721
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012722 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012723 W (ret);
12724 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012725}
12726
12727static void
12728vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
12729 * mp)
12730{
12731 vat_main_t *vam = &vat_main;
12732 u8 *sw_if_from_name = 0;
12733 u8 *sw_if_to_name = 0;
12734 u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
12735 u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
12736 char *states[] = { "none", "rx", "tx", "both" };
12737 hash_pair_t *p;
12738
12739 /* *INDENT-OFF* */
12740 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
12741 ({
12742 if ((u32) p->value[0] == sw_if_index_from)
12743 {
12744 sw_if_from_name = (u8 *)(p->key);
12745 if (sw_if_to_name)
12746 break;
12747 }
12748 if ((u32) p->value[0] == sw_if_index_to)
12749 {
12750 sw_if_to_name = (u8 *)(p->key);
12751 if (sw_if_from_name)
12752 break;
12753 }
12754 }));
12755 /* *INDENT-ON* */
Jon Loeliger179ab362018-03-12 14:50:08 -050012756 print (vam->ofp, "%20s => %20s (%s) %s",
12757 sw_if_from_name, sw_if_to_name, states[mp->state],
12758 mp->is_l2 ? "l2" : "device");
Damjan Marion7cd468a2016-12-19 23:05:39 +010012759}
12760
12761static void
12762 vl_api_sw_interface_span_details_t_handler_json
12763 (vl_api_sw_interface_span_details_t * mp)
12764{
12765 vat_main_t *vam = &vat_main;
12766 vat_json_node_t *node = NULL;
12767 u8 *sw_if_from_name = 0;
12768 u8 *sw_if_to_name = 0;
12769 u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
12770 u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
12771 hash_pair_t *p;
12772
12773 /* *INDENT-OFF* */
12774 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
12775 ({
12776 if ((u32) p->value[0] == sw_if_index_from)
12777 {
12778 sw_if_from_name = (u8 *)(p->key);
12779 if (sw_if_to_name)
12780 break;
12781 }
12782 if ((u32) p->value[0] == sw_if_index_to)
12783 {
12784 sw_if_to_name = (u8 *)(p->key);
12785 if (sw_if_from_name)
12786 break;
12787 }
12788 }));
12789 /* *INDENT-ON* */
12790
12791 if (VAT_JSON_ARRAY != vam->json_tree.type)
12792 {
12793 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12794 vat_json_init_array (&vam->json_tree);
12795 }
12796 node = vat_json_array_add (&vam->json_tree);
12797
12798 vat_json_init_object (node);
12799 vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
12800 vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
12801 vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
Neale Ranns05b2bf22017-01-30 06:44:58 -080012802 if (0 != sw_if_to_name)
12803 {
12804 vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
12805 }
Damjan Marion7cd468a2016-12-19 23:05:39 +010012806 vat_json_object_add_uint (node, "state", mp->state);
Jon Loeliger179ab362018-03-12 14:50:08 -050012807 vat_json_object_add_uint (node, "is-l2", mp->is_l2);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012808}
12809
12810static int
12811api_sw_interface_span_dump (vat_main_t * vam)
12812{
Eyal Bari5b311202017-07-31 13:12:30 +030012813 unformat_input_t *input = vam->input;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012814 vl_api_sw_interface_span_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012815 vl_api_control_ping_t *mp_ping;
Eyal Bari5b311202017-07-31 13:12:30 +030012816 u8 is_l2 = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012817 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012818
Eyal Bari5b311202017-07-31 13:12:30 +030012819 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12820 {
12821 if (unformat (input, "l2"))
12822 is_l2 = 1;
12823 else
12824 break;
12825 }
12826
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012827 M (SW_INTERFACE_SPAN_DUMP, mp);
Eyal Bari5b311202017-07-31 13:12:30 +030012828 mp->is_l2 = is_l2;
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012829 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012830
12831 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040012832 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012833 S (mp_ping);
12834
Jon Loeliger56c7b012017-02-01 12:31:41 -060012835 W (ret);
12836 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012837}
12838
12839int
12840api_pg_create_interface (vat_main_t * vam)
12841{
12842 unformat_input_t *input = vam->input;
12843 vl_api_pg_create_interface_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012844
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +020012845 u32 if_id = ~0, gso_size = 0;
12846 u8 gso_enabled = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012847 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012848 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12849 {
12850 if (unformat (input, "if_id %d", &if_id))
12851 ;
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +020012852 else if (unformat (input, "gso-enabled"))
12853 {
12854 gso_enabled = 1;
12855 if (unformat (input, "gso-size %u", &gso_size))
12856 ;
12857 else
12858 {
12859 errmsg ("missing gso-size");
12860 return -99;
12861 }
12862 }
Damjan Marion7cd468a2016-12-19 23:05:39 +010012863 else
12864 break;
12865 }
12866 if (if_id == ~0)
12867 {
12868 errmsg ("missing pg interface index");
12869 return -99;
12870 }
12871
12872 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012873 M (PG_CREATE_INTERFACE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012874 mp->context = 0;
12875 mp->interface_id = ntohl (if_id);
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +020012876 mp->gso_enabled = gso_enabled;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012877
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_capture (vat_main_t * vam)
12885{
12886 unformat_input_t *input = vam->input;
12887 vl_api_pg_capture_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012888
12889 u32 if_id = ~0;
12890 u8 enable = 1;
12891 u32 count = 1;
12892 u8 pcap_file_set = 0;
12893 u8 *pcap_file = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012894 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012895 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12896 {
12897 if (unformat (input, "if_id %d", &if_id))
12898 ;
12899 else if (unformat (input, "pcap %s", &pcap_file))
12900 pcap_file_set = 1;
12901 else if (unformat (input, "count %d", &count))
12902 ;
12903 else if (unformat (input, "disable"))
12904 enable = 0;
12905 else
12906 break;
12907 }
12908 if (if_id == ~0)
12909 {
12910 errmsg ("missing pg interface index");
12911 return -99;
12912 }
12913 if (pcap_file_set > 0)
12914 {
12915 if (vec_len (pcap_file) > 255)
12916 {
12917 errmsg ("pcap file name is too long");
12918 return -99;
12919 }
12920 }
12921
Damjan Marion7cd468a2016-12-19 23:05:39 +010012922 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012923 M (PG_CAPTURE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012924 mp->context = 0;
12925 mp->interface_id = ntohl (if_id);
12926 mp->is_enabled = enable;
12927 mp->count = ntohl (count);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012928 if (pcap_file_set != 0)
12929 {
Jakub Grajciardb863292020-01-30 14:14:15 +010012930 vl_api_vec_to_api_string (pcap_file, &mp->pcap_file_name);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012931 }
12932 vec_free (pcap_file);
12933
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012934 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012935 W (ret);
12936 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012937}
12938
12939int
12940api_pg_enable_disable (vat_main_t * vam)
12941{
12942 unformat_input_t *input = vam->input;
12943 vl_api_pg_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012944
12945 u8 enable = 1;
12946 u8 stream_name_set = 0;
12947 u8 *stream_name = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012948 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012949 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12950 {
12951 if (unformat (input, "stream %s", &stream_name))
12952 stream_name_set = 1;
12953 else if (unformat (input, "disable"))
12954 enable = 0;
12955 else
12956 break;
12957 }
12958
12959 if (stream_name_set > 0)
12960 {
12961 if (vec_len (stream_name) > 255)
12962 {
12963 errmsg ("stream name too long");
12964 return -99;
12965 }
12966 }
12967
Damjan Marion7cd468a2016-12-19 23:05:39 +010012968 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012969 M (PG_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012970 mp->context = 0;
12971 mp->is_enabled = enable;
12972 if (stream_name_set != 0)
12973 {
Jakub Grajciardb863292020-01-30 14:14:15 +010012974 vl_api_vec_to_api_string (stream_name, &mp->stream_name);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012975 }
12976 vec_free (stream_name);
12977
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012978 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012979 W (ret);
12980 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012981}
12982
12983int
Mohsin Kazmif382b062020-08-11 15:00:44 +020012984api_pg_interface_enable_disable_coalesce (vat_main_t * vam)
12985{
12986 unformat_input_t *input = vam->input;
12987 vl_api_pg_interface_enable_disable_coalesce_t *mp;
12988
12989 u32 sw_if_index = ~0;
12990 u8 enable = 1;
12991 int ret;
12992 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12993 {
12994 if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12995 ;
12996 else if (unformat (input, "sw_if_index %d", &sw_if_index))
12997 ;
12998 else if (unformat (input, "disable"))
12999 enable = 0;
13000 else
13001 break;
13002 }
13003
13004 if (sw_if_index == ~0)
13005 {
13006 errmsg ("Interface required but not specified");
13007 return -99;
13008 }
13009
13010 /* Construct the API message */
13011 M (PG_INTERFACE_ENABLE_DISABLE_COALESCE, mp);
13012 mp->context = 0;
13013 mp->coalesce_enabled = enable;
13014 mp->sw_if_index = htonl (sw_if_index);
13015
13016 S (mp);
13017 W (ret);
13018 return ret;
13019}
13020
13021int
Damjan Marion7cd468a2016-12-19 23:05:39 +010013022api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
13023{
13024 unformat_input_t *input = vam->input;
13025 vl_api_ip_source_and_port_range_check_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013026
13027 u16 *low_ports = 0;
13028 u16 *high_ports = 0;
13029 u16 this_low;
13030 u16 this_hi;
Neale Ranns37029302018-08-10 05:30:06 -070013031 vl_api_prefix_t prefix;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013032 u32 tmp, tmp2;
13033 u8 prefix_set = 0;
13034 u32 vrf_id = ~0;
13035 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013036 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013037
13038 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13039 {
Neale Ranns37029302018-08-10 05:30:06 -070013040 if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
13041 prefix_set = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013042 else if (unformat (input, "vrf %d", &vrf_id))
13043 ;
13044 else if (unformat (input, "del"))
13045 is_add = 0;
13046 else if (unformat (input, "port %d", &tmp))
13047 {
13048 if (tmp == 0 || tmp > 65535)
13049 {
13050 errmsg ("port %d out of range", tmp);
13051 return -99;
13052 }
13053 this_low = tmp;
13054 this_hi = this_low + 1;
13055 vec_add1 (low_ports, this_low);
13056 vec_add1 (high_ports, this_hi);
13057 }
13058 else if (unformat (input, "range %d - %d", &tmp, &tmp2))
13059 {
13060 if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
13061 {
13062 errmsg ("incorrect range parameters");
13063 return -99;
13064 }
13065 this_low = tmp;
13066 /* Note: in debug CLI +1 is added to high before
13067 passing to real fn that does "the work"
13068 (ip_source_and_port_range_check_add_del).
13069 This fn is a wrapper around the binary API fn a
13070 control plane will call, which expects this increment
13071 to have occurred. Hence letting the binary API control
13072 plane fn do the increment for consistency between VAT
13073 and other control planes.
13074 */
13075 this_hi = tmp2;
13076 vec_add1 (low_ports, this_low);
13077 vec_add1 (high_ports, this_hi);
13078 }
13079 else
13080 break;
13081 }
13082
13083 if (prefix_set == 0)
13084 {
13085 errmsg ("<address>/<mask> not specified");
13086 return -99;
13087 }
13088
13089 if (vrf_id == ~0)
13090 {
13091 errmsg ("VRF ID required, not specified");
13092 return -99;
13093 }
13094
13095 if (vrf_id == 0)
13096 {
13097 errmsg
13098 ("VRF ID should not be default. Should be distinct VRF for this purpose.");
13099 return -99;
13100 }
13101
13102 if (vec_len (low_ports) == 0)
13103 {
13104 errmsg ("At least one port or port range required");
13105 return -99;
13106 }
13107
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013108 M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013109
13110 mp->is_add = is_add;
13111
Neale Ranns37029302018-08-10 05:30:06 -070013112 clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
Damjan Marion7cd468a2016-12-19 23:05:39 +010013113
Damjan Marion7cd468a2016-12-19 23:05:39 +010013114 mp->number_of_ranges = vec_len (low_ports);
13115
13116 clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
13117 vec_free (low_ports);
13118
13119 clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
13120 vec_free (high_ports);
13121
13122 mp->vrf_id = ntohl (vrf_id);
13123
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013124 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013125 W (ret);
13126 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013127}
13128
13129int
13130api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
13131{
13132 unformat_input_t *input = vam->input;
13133 vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013134 u32 sw_if_index = ~0;
13135 int vrf_set = 0;
13136 u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
13137 u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
13138 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013139 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013140
13141 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13142 {
13143 if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13144 ;
13145 else if (unformat (input, "sw_if_index %d", &sw_if_index))
13146 ;
13147 else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
13148 vrf_set = 1;
13149 else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
13150 vrf_set = 1;
13151 else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
13152 vrf_set = 1;
13153 else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
13154 vrf_set = 1;
13155 else if (unformat (input, "del"))
13156 is_add = 0;
13157 else
13158 break;
13159 }
13160
13161 if (sw_if_index == ~0)
13162 {
13163 errmsg ("Interface required but not specified");
13164 return -99;
13165 }
13166
13167 if (vrf_set == 0)
13168 {
13169 errmsg ("VRF ID required but not specified");
13170 return -99;
13171 }
13172
13173 if (tcp_out_vrf_id == 0
13174 || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
13175 {
13176 errmsg
13177 ("VRF ID should not be default. Should be distinct VRF for this purpose.");
13178 return -99;
13179 }
13180
13181 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013182 M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013183
13184 mp->sw_if_index = ntohl (sw_if_index);
13185 mp->is_add = is_add;
13186 mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
13187 mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
13188 mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
13189 mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
13190
13191 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013192 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013193
13194 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060013195 W (ret);
13196 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013197}
13198
13199static int
Pavel Kotuceke88865d2018-11-28 07:42:11 +010013200api_set_punt (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010013201{
13202 unformat_input_t *i = vam->input;
Neale Ranns50f0ac02019-05-15 02:13:37 -070013203 vl_api_address_family_t af;
Pavel Kotuceke88865d2018-11-28 07:42:11 +010013204 vl_api_set_punt_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013205 u32 protocol = ~0;
13206 u32 port = ~0;
13207 int is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013208 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013209
13210 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13211 {
Neale Ranns50f0ac02019-05-15 02:13:37 -070013212 if (unformat (i, "%U", unformat_vl_api_address_family, &af))
Damjan Marion7cd468a2016-12-19 23:05:39 +010013213 ;
13214 else if (unformat (i, "protocol %d", &protocol))
13215 ;
13216 else if (unformat (i, "port %d", &port))
13217 ;
13218 else if (unformat (i, "del"))
13219 is_add = 0;
13220 else
13221 {
13222 clib_warning ("parse error '%U'", format_unformat_error, i);
13223 return -99;
13224 }
13225 }
13226
Pavel Kotuceke88865d2018-11-28 07:42:11 +010013227 M (SET_PUNT, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013228
13229 mp->is_add = (u8) is_add;
Neale Ranns50f0ac02019-05-15 02:13:37 -070013230 mp->punt.type = PUNT_API_TYPE_L4;
13231 mp->punt.punt.l4.af = af;
13232 mp->punt.punt.l4.protocol = (u8) protocol;
13233 mp->punt.punt.l4.port = htons ((u16) port);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013234
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013235 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013236 W (ret);
13237 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013238}
13239
Damjan Marion7cd468a2016-12-19 23:05:39 +010013240static int
13241api_delete_subif (vat_main_t * vam)
13242{
13243 unformat_input_t *i = vam->input;
13244 vl_api_delete_subif_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013245 u32 sw_if_index = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013246 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013247
13248 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13249 {
13250 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13251 ;
13252 if (unformat (i, "sw_if_index %d", &sw_if_index))
13253 ;
13254 else
13255 break;
13256 }
13257
13258 if (sw_if_index == ~0)
13259 {
13260 errmsg ("missing sw_if_index");
13261 return -99;
13262 }
13263
13264 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013265 M (DELETE_SUBIF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013266 mp->sw_if_index = ntohl (sw_if_index);
13267
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013268 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013269 W (ret);
13270 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013271}
13272
13273#define foreach_pbb_vtr_op \
13274_("disable", L2_VTR_DISABLED) \
13275_("pop", L2_VTR_POP_2) \
13276_("push", L2_VTR_PUSH_2)
13277
13278static int
13279api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
13280{
13281 unformat_input_t *i = vam->input;
13282 vl_api_l2_interface_pbb_tag_rewrite_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013283 u32 sw_if_index = ~0, vtr_op = ~0;
13284 u16 outer_tag = ~0;
13285 u8 dmac[6], smac[6];
13286 u8 dmac_set = 0, smac_set = 0;
13287 u16 vlanid = 0;
13288 u32 sid = ~0;
13289 u32 tmp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013290 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013291
13292 /* Shut up coverity */
Dave Barachb7b92992018-10-17 10:38:51 -040013293 clib_memset (dmac, 0, sizeof (dmac));
13294 clib_memset (smac, 0, sizeof (smac));
Damjan Marion7cd468a2016-12-19 23:05:39 +010013295
13296 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13297 {
13298 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13299 ;
13300 else if (unformat (i, "sw_if_index %d", &sw_if_index))
13301 ;
13302 else if (unformat (i, "vtr_op %d", &vtr_op))
13303 ;
13304#define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
13305 foreach_pbb_vtr_op
13306#undef _
13307 else if (unformat (i, "translate_pbb_stag"))
13308 {
13309 if (unformat (i, "%d", &tmp))
13310 {
13311 vtr_op = L2_VTR_TRANSLATE_2_1;
13312 outer_tag = tmp;
13313 }
13314 else
13315 {
13316 errmsg
13317 ("translate_pbb_stag operation requires outer tag definition");
13318 return -99;
13319 }
13320 }
13321 else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
13322 dmac_set++;
13323 else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
13324 smac_set++;
13325 else if (unformat (i, "sid %d", &sid))
13326 ;
13327 else if (unformat (i, "vlanid %d", &tmp))
13328 vlanid = tmp;
13329 else
13330 {
13331 clib_warning ("parse error '%U'", format_unformat_error, i);
13332 return -99;
13333 }
13334 }
13335
13336 if ((sw_if_index == ~0) || (vtr_op == ~0))
13337 {
13338 errmsg ("missing sw_if_index or vtr operation");
13339 return -99;
13340 }
13341 if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
13342 && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
13343 {
13344 errmsg
13345 ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
13346 return -99;
13347 }
13348
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013349 M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013350 mp->sw_if_index = ntohl (sw_if_index);
13351 mp->vtr_op = ntohl (vtr_op);
13352 mp->outer_tag = ntohs (outer_tag);
13353 clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
13354 clib_memcpy (mp->b_smac, smac, sizeof (smac));
13355 mp->b_vlanid = ntohs (vlanid);
13356 mp->i_sid = ntohl (sid);
13357
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013358 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013359 W (ret);
13360 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013361}
13362
13363static int
13364api_flow_classify_set_interface (vat_main_t * vam)
13365{
13366 unformat_input_t *i = vam->input;
13367 vl_api_flow_classify_set_interface_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013368 u32 sw_if_index;
13369 int sw_if_index_set;
13370 u32 ip4_table_index = ~0;
13371 u32 ip6_table_index = ~0;
13372 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013373 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013374
13375 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13376 {
13377 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13378 sw_if_index_set = 1;
13379 else if (unformat (i, "sw_if_index %d", &sw_if_index))
13380 sw_if_index_set = 1;
13381 else if (unformat (i, "del"))
13382 is_add = 0;
13383 else if (unformat (i, "ip4-table %d", &ip4_table_index))
13384 ;
13385 else if (unformat (i, "ip6-table %d", &ip6_table_index))
13386 ;
13387 else
13388 {
13389 clib_warning ("parse error '%U'", format_unformat_error, i);
13390 return -99;
13391 }
13392 }
13393
13394 if (sw_if_index_set == 0)
13395 {
13396 errmsg ("missing interface name or sw_if_index");
13397 return -99;
13398 }
13399
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013400 M (FLOW_CLASSIFY_SET_INTERFACE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013401
13402 mp->sw_if_index = ntohl (sw_if_index);
13403 mp->ip4_table_index = ntohl (ip4_table_index);
13404 mp->ip6_table_index = ntohl (ip6_table_index);
13405 mp->is_add = is_add;
13406
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013407 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013408 W (ret);
13409 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013410}
13411
13412static int
13413api_flow_classify_dump (vat_main_t * vam)
13414{
13415 unformat_input_t *i = vam->input;
13416 vl_api_flow_classify_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060013417 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013418 u8 type = FLOW_CLASSIFY_N_TABLES;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013419 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013420
13421 if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
13422 ;
13423 else
13424 {
13425 errmsg ("classify table type must be specified");
13426 return -99;
13427 }
13428
13429 if (!vam->json_output)
13430 {
13431 print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
13432 }
13433
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013434 M (FLOW_CLASSIFY_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013435 mp->type = type;
13436 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013437 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013438
13439 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040013440 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060013441 S (mp_ping);
13442
Damjan Marion7cd468a2016-12-19 23:05:39 +010013443 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060013444 W (ret);
13445 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013446}
13447
13448static int
13449api_feature_enable_disable (vat_main_t * vam)
13450{
13451 unformat_input_t *i = vam->input;
13452 vl_api_feature_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013453 u8 *arc_name = 0;
13454 u8 *feature_name = 0;
13455 u32 sw_if_index = ~0;
13456 u8 enable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013457 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013458
13459 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13460 {
13461 if (unformat (i, "arc_name %s", &arc_name))
13462 ;
13463 else if (unformat (i, "feature_name %s", &feature_name))
13464 ;
13465 else
13466 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13467 ;
13468 else if (unformat (i, "sw_if_index %d", &sw_if_index))
13469 ;
13470 else if (unformat (i, "disable"))
13471 enable = 0;
13472 else
13473 break;
13474 }
13475
13476 if (arc_name == 0)
13477 {
13478 errmsg ("missing arc name");
13479 return -99;
13480 }
13481 if (vec_len (arc_name) > 63)
13482 {
13483 errmsg ("arc name too long");
13484 }
13485
13486 if (feature_name == 0)
13487 {
13488 errmsg ("missing feature name");
13489 return -99;
13490 }
13491 if (vec_len (feature_name) > 63)
13492 {
13493 errmsg ("feature name too long");
13494 }
13495
13496 if (sw_if_index == ~0)
13497 {
13498 errmsg ("missing interface name or sw_if_index");
13499 return -99;
13500 }
13501
13502 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013503 M (FEATURE_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013504 mp->sw_if_index = ntohl (sw_if_index);
13505 mp->enable = enable;
13506 clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
13507 clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
13508 vec_free (arc_name);
13509 vec_free (feature_name);
13510
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013511 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013512 W (ret);
13513 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013514}
13515
13516static int
Mohsin Kazmi29467b52019-10-08 19:42:38 +020013517api_feature_gso_enable_disable (vat_main_t * vam)
13518{
13519 unformat_input_t *i = vam->input;
13520 vl_api_feature_gso_enable_disable_t *mp;
13521 u32 sw_if_index = ~0;
13522 u8 enable = 1;
13523 int ret;
13524
13525 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13526 {
13527 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13528 ;
13529 else if (unformat (i, "sw_if_index %d", &sw_if_index))
13530 ;
13531 else if (unformat (i, "enable"))
13532 enable = 1;
13533 else if (unformat (i, "disable"))
13534 enable = 0;
13535 else
13536 break;
13537 }
13538
13539 if (sw_if_index == ~0)
13540 {
13541 errmsg ("missing interface name or sw_if_index");
13542 return -99;
13543 }
13544
13545 /* Construct the API message */
13546 M (FEATURE_GSO_ENABLE_DISABLE, mp);
13547 mp->sw_if_index = ntohl (sw_if_index);
13548 mp->enable_disable = enable;
13549
13550 S (mp);
13551 W (ret);
13552 return ret;
13553}
13554
13555static int
Damjan Marion7cd468a2016-12-19 23:05:39 +010013556api_sw_interface_tag_add_del (vat_main_t * vam)
13557{
13558 unformat_input_t *i = vam->input;
13559 vl_api_sw_interface_tag_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013560 u32 sw_if_index = ~0;
13561 u8 *tag = 0;
13562 u8 enable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013563 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013564
13565 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13566 {
13567 if (unformat (i, "tag %s", &tag))
13568 ;
13569 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13570 ;
13571 else if (unformat (i, "sw_if_index %d", &sw_if_index))
13572 ;
13573 else if (unformat (i, "del"))
13574 enable = 0;
13575 else
13576 break;
13577 }
13578
13579 if (sw_if_index == ~0)
13580 {
13581 errmsg ("missing interface name or sw_if_index");
13582 return -99;
13583 }
13584
13585 if (enable && (tag == 0))
13586 {
13587 errmsg ("no tag specified");
13588 return -99;
13589 }
13590
13591 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013592 M (SW_INTERFACE_TAG_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013593 mp->sw_if_index = ntohl (sw_if_index);
13594 mp->is_add = enable;
13595 if (enable)
Ole Troane5ff5a32019-08-23 22:55:18 +020013596 strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013597 vec_free (tag);
13598
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013599 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013600 W (ret);
13601 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013602}
13603
Matthew Smithe0792fd2019-07-12 11:48:24 -050013604static int
13605api_sw_interface_add_del_mac_address (vat_main_t * vam)
13606{
13607 unformat_input_t *i = vam->input;
13608 vl_api_mac_address_t mac = { 0 };
13609 vl_api_sw_interface_add_del_mac_address_t *mp;
13610 u32 sw_if_index = ~0;
13611 u8 is_add = 1;
13612 u8 mac_set = 0;
13613 int ret;
13614
13615 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13616 {
13617 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13618 ;
13619 else if (unformat (i, "sw_if_index %d", &sw_if_index))
13620 ;
13621 else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
13622 mac_set++;
13623 else if (unformat (i, "del"))
13624 is_add = 0;
13625 else
13626 break;
13627 }
13628
13629 if (sw_if_index == ~0)
13630 {
13631 errmsg ("missing interface name or sw_if_index");
13632 return -99;
13633 }
13634
13635 if (!mac_set)
13636 {
13637 errmsg ("missing MAC address");
13638 return -99;
13639 }
13640
13641 /* Construct the API message */
13642 M (SW_INTERFACE_ADD_DEL_MAC_ADDRESS, mp);
13643 mp->sw_if_index = ntohl (sw_if_index);
13644 mp->is_add = is_add;
13645 clib_memcpy (&mp->addr, &mac, sizeof (mac));
13646
13647 S (mp);
13648 W (ret);
13649 return ret;
13650}
13651
Damjan Marion7cd468a2016-12-19 23:05:39 +010013652static void vl_api_l2_xconnect_details_t_handler
13653 (vl_api_l2_xconnect_details_t * mp)
13654{
13655 vat_main_t *vam = &vat_main;
13656
13657 print (vam->ofp, "%15d%15d",
13658 ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
13659}
13660
13661static void vl_api_l2_xconnect_details_t_handler_json
13662 (vl_api_l2_xconnect_details_t * mp)
13663{
13664 vat_main_t *vam = &vat_main;
13665 vat_json_node_t *node = NULL;
13666
13667 if (VAT_JSON_ARRAY != vam->json_tree.type)
13668 {
13669 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13670 vat_json_init_array (&vam->json_tree);
13671 }
13672 node = vat_json_array_add (&vam->json_tree);
13673
13674 vat_json_init_object (node);
13675 vat_json_object_add_uint (node, "rx_sw_if_index",
13676 ntohl (mp->rx_sw_if_index));
13677 vat_json_object_add_uint (node, "tx_sw_if_index",
13678 ntohl (mp->tx_sw_if_index));
13679}
13680
13681static int
13682api_l2_xconnect_dump (vat_main_t * vam)
13683{
13684 vl_api_l2_xconnect_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060013685 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013686 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013687
13688 if (!vam->json_output)
13689 {
13690 print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
13691 }
13692
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013693 M (L2_XCONNECT_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013694
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013695 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013696
13697 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040013698 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060013699 S (mp_ping);
13700
Jon Loeliger56c7b012017-02-01 12:31:41 -060013701 W (ret);
13702 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013703}
13704
13705static int
Ole Troand7231612018-06-07 10:17:57 +020013706api_hw_interface_set_mtu (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010013707{
13708 unformat_input_t *i = vam->input;
Ole Troand7231612018-06-07 10:17:57 +020013709 vl_api_hw_interface_set_mtu_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013710 u32 sw_if_index = ~0;
13711 u32 mtu = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013712 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013713
13714 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13715 {
13716 if (unformat (i, "mtu %d", &mtu))
13717 ;
13718 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13719 ;
13720 else if (unformat (i, "sw_if_index %d", &sw_if_index))
13721 ;
13722 else
13723 break;
13724 }
13725
13726 if (sw_if_index == ~0)
13727 {
13728 errmsg ("missing interface name or sw_if_index");
13729 return -99;
13730 }
13731
13732 if (mtu == 0)
13733 {
13734 errmsg ("no mtu specified");
13735 return -99;
13736 }
13737
13738 /* Construct the API message */
Ole Troand7231612018-06-07 10:17:57 +020013739 M (HW_INTERFACE_SET_MTU, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013740 mp->sw_if_index = ntohl (sw_if_index);
13741 mp->mtu = ntohs ((u16) mtu);
13742
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013743 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013744 W (ret);
13745 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013746}
13747
Pavel Kotucek6899a302017-06-08 08:46:10 +020013748static int
13749api_p2p_ethernet_add (vat_main_t * vam)
13750{
13751 unformat_input_t *i = vam->input;
13752 vl_api_p2p_ethernet_add_t *mp;
13753 u32 parent_if_index = ~0;
Pavel Kotucek15ac81c2017-06-20 14:00:26 +020013754 u32 sub_id = ~0;
Pavel Kotucek6899a302017-06-08 08:46:10 +020013755 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++;
Pavel Kotucek15ac81c2017-06-20 14:00:26 +020013770 else if (unformat (i, "sub_id %d", &sub_id))
13771 ;
Pavel Kotucek6899a302017-06-08 08:46:10 +020013772 else
13773 {
13774 clib_warning ("parse error '%U'", format_unformat_error, i);
13775 return -99;
13776 }
13777 }
13778
13779 if (parent_if_index == ~0)
13780 {
13781 errmsg ("missing interface name or sw_if_index");
13782 return -99;
13783 }
13784 if (mac_set == 0)
13785 {
13786 errmsg ("missing remote mac address");
13787 return -99;
13788 }
Pavel Kotucek15ac81c2017-06-20 14:00:26 +020013789 if (sub_id == ~0)
13790 {
13791 errmsg ("missing sub-interface id");
13792 return -99;
13793 }
Pavel Kotucek6899a302017-06-08 08:46:10 +020013794
13795 M (P2P_ETHERNET_ADD, mp);
13796 mp->parent_if_index = ntohl (parent_if_index);
Pavel Kotucek15ac81c2017-06-20 14:00:26 +020013797 mp->subif_id = ntohl (sub_id);
Pavel Kotucek6899a302017-06-08 08:46:10 +020013798 clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
13799
13800 S (mp);
13801 W (ret);
13802 return ret;
13803}
13804
13805static int
13806api_p2p_ethernet_del (vat_main_t * vam)
13807{
13808 unformat_input_t *i = vam->input;
13809 vl_api_p2p_ethernet_del_t *mp;
13810 u32 parent_if_index = ~0;
13811 u8 remote_mac[6];
13812 u8 mac_set = 0;
13813 int ret;
13814
Dave Barachb7b92992018-10-17 10:38:51 -040013815 clib_memset (remote_mac, 0, sizeof (remote_mac));
Pavel Kotucek6899a302017-06-08 08:46:10 +020013816 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13817 {
13818 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
13819 ;
13820 else if (unformat (i, "sw_if_index %d", &parent_if_index))
13821 ;
13822 else
13823 if (unformat
13824 (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
13825 mac_set++;
13826 else
13827 {
13828 clib_warning ("parse error '%U'", format_unformat_error, i);
13829 return -99;
13830 }
13831 }
13832
13833 if (parent_if_index == ~0)
13834 {
13835 errmsg ("missing interface name or sw_if_index");
13836 return -99;
13837 }
13838 if (mac_set == 0)
13839 {
13840 errmsg ("missing remote mac address");
13841 return -99;
13842 }
13843
13844 M (P2P_ETHERNET_DEL, mp);
13845 mp->parent_if_index = ntohl (parent_if_index);
13846 clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
13847
13848 S (mp);
13849 W (ret);
13850 return ret;
13851}
Damjan Marion7cd468a2016-12-19 23:05:39 +010013852
13853static int
Dave Barach3bbcfab2017-08-15 19:03:44 -040013854api_tcp_configure_src_addresses (vat_main_t * vam)
13855{
13856 vl_api_tcp_configure_src_addresses_t *mp;
13857 unformat_input_t *i = vam->input;
Neale Rannscbe25aa2019-09-30 10:53:31 +000013858 vl_api_address_t first, last;
Dave Barach3bbcfab2017-08-15 19:03:44 -040013859 u8 range_set = 0;
13860 u32 vrf_id = 0;
13861 int ret;
13862
13863 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13864 {
13865 if (unformat (i, "%U - %U",
Neale Rannscbe25aa2019-09-30 10:53:31 +000013866 unformat_vl_api_address, &first,
13867 unformat_vl_api_address, &last))
Dave Barach3bbcfab2017-08-15 19:03:44 -040013868 {
13869 if (range_set)
13870 {
13871 errmsg ("one range per message (range already set)");
13872 return -99;
13873 }
13874 range_set = 1;
13875 }
Dave Barach3bbcfab2017-08-15 19:03:44 -040013876 else if (unformat (i, "vrf %d", &vrf_id))
13877 ;
13878 else
13879 break;
13880 }
13881
13882 if (range_set == 0)
13883 {
13884 errmsg ("address range not set");
13885 return -99;
13886 }
13887
13888 M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
Neale Rannscbe25aa2019-09-30 10:53:31 +000013889
Dave Barach3bbcfab2017-08-15 19:03:44 -040013890 mp->vrf_id = ntohl (vrf_id);
Neale Rannscbe25aa2019-09-30 10:53:31 +000013891 clib_memcpy (&mp->first_address, &first, sizeof (first));
13892 clib_memcpy (&mp->last_address, &last, sizeof (last));
13893
Dave Barach3bbcfab2017-08-15 19:03:44 -040013894 S (mp);
13895 W (ret);
13896 return ret;
13897}
13898
Florin Coras6e8c6672017-11-10 09:03:54 -080013899static void vl_api_app_namespace_add_del_reply_t_handler
13900 (vl_api_app_namespace_add_del_reply_t * mp)
13901{
13902 vat_main_t *vam = &vat_main;
13903 i32 retval = ntohl (mp->retval);
13904 if (vam->async_mode)
13905 {
13906 vam->async_errors += (retval < 0);
13907 }
13908 else
13909 {
13910 vam->retval = retval;
13911 if (retval == 0)
13912 errmsg ("app ns index %d\n", ntohl (mp->appns_index));
13913 vam->result_ready = 1;
13914 }
13915}
13916
13917static void vl_api_app_namespace_add_del_reply_t_handler_json
13918 (vl_api_app_namespace_add_del_reply_t * mp)
13919{
13920 vat_main_t *vam = &vat_main;
13921 vat_json_node_t node;
13922
13923 vat_json_init_object (&node);
13924 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
13925 vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
13926
13927 vat_json_print (vam->ofp, &node);
13928 vat_json_free (&node);
13929
13930 vam->retval = ntohl (mp->retval);
13931 vam->result_ready = 1;
13932}
13933
Dave Barach3bbcfab2017-08-15 19:03:44 -040013934static int
Florin Corascea194d2017-10-02 00:18:51 -070013935api_app_namespace_add_del (vat_main_t * vam)
13936{
13937 vl_api_app_namespace_add_del_t *mp;
13938 unformat_input_t *i = vam->input;
13939 u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
13940 u32 sw_if_index, ip4_fib_id, ip6_fib_id;
13941 u64 secret;
13942 int ret;
13943
13944 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13945 {
13946 if (unformat (i, "id %_%v%_", &ns_id))
13947 ;
13948 else if (unformat (i, "secret %lu", &secret))
13949 secret_set = 1;
13950 else if (unformat (i, "sw_if_index %d", &sw_if_index))
13951 sw_if_index_set = 1;
13952 else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
13953 ;
13954 else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
13955 ;
13956 else
13957 break;
13958 }
13959 if (!ns_id || !secret_set || !sw_if_index_set)
13960 {
13961 errmsg ("namespace id, secret and sw_if_index must be set");
13962 return -99;
13963 }
13964 if (vec_len (ns_id) > 64)
13965 {
13966 errmsg ("namespace id too long");
13967 return -99;
13968 }
13969 M (APP_NAMESPACE_ADD_DEL, mp);
13970
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010013971 vl_api_vec_to_api_string (ns_id, &mp->namespace_id);
Florin Coras9a9adb22017-10-26 08:16:59 -070013972 mp->secret = clib_host_to_net_u64 (secret);
Florin Corascea194d2017-10-02 00:18:51 -070013973 mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
13974 mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
13975 mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
13976 vec_free (ns_id);
13977 S (mp);
13978 W (ret);
13979 return ret;
13980}
13981
13982static int
Florin Coras90a63982017-12-19 04:50:01 -080013983api_sock_init_shm (vat_main_t * vam)
13984{
13985#if VPP_API_TEST_BUILTIN == 0
13986 unformat_input_t *i = vam->input;
13987 vl_api_shm_elem_config_t *config = 0;
13988 u64 size = 64 << 20;
13989 int rv;
13990
13991 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13992 {
13993 if (unformat (i, "size %U", unformat_memory_size, &size))
13994 ;
13995 else
13996 break;
13997 }
13998
Dave Barach78958722018-05-10 16:44:27 -040013999 /*
14000 * Canned custom ring allocator config.
14001 * Should probably parse all of this
14002 */
14003 vec_validate (config, 6);
Florin Coras90a63982017-12-19 04:50:01 -080014004 config[0].type = VL_API_VLIB_RING;
Florin Coras90a63982017-12-19 04:50:01 -080014005 config[0].size = 256;
Dave Barach78958722018-05-10 16:44:27 -040014006 config[0].count = 32;
14007
14008 config[1].type = VL_API_VLIB_RING;
Florin Coras90a63982017-12-19 04:50:01 -080014009 config[1].size = 1024;
Dave Barach78958722018-05-10 16:44:27 -040014010 config[1].count = 16;
14011
14012 config[2].type = VL_API_VLIB_RING;
Florin Coras90a63982017-12-19 04:50:01 -080014013 config[2].size = 4096;
Dave Barach78958722018-05-10 16:44:27 -040014014 config[2].count = 2;
14015
14016 config[3].type = VL_API_CLIENT_RING;
14017 config[3].size = 256;
14018 config[3].count = 32;
14019
14020 config[4].type = VL_API_CLIENT_RING;
14021 config[4].size = 1024;
14022 config[4].count = 16;
14023
14024 config[5].type = VL_API_CLIENT_RING;
14025 config[5].size = 4096;
14026 config[5].count = 2;
14027
14028 config[6].type = VL_API_QUEUE;
14029 config[6].count = 128;
14030 config[6].size = sizeof (uword);
14031
Tomasz Kulasek97dcf5b2019-01-31 18:26:32 +010014032 rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
Florin Coras90a63982017-12-19 04:50:01 -080014033 if (!rv)
14034 vam->client_index_invalid = 1;
14035 return rv;
14036#else
14037 return -99;
14038#endif
14039}
14040
Florin Coras6c36f532017-11-03 18:32:34 -070014041static void
14042vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
14043{
14044 vat_main_t *vam = &vat_main;
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014045 fib_prefix_t lcl, rmt;
Florin Coras6c36f532017-11-03 18:32:34 -070014046
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014047 ip_prefix_decode (&mp->lcl, &lcl);
14048 ip_prefix_decode (&mp->rmt, &rmt);
14049
14050 if (lcl.fp_proto == FIB_PROTOCOL_IP4)
Florin Coras6c36f532017-11-03 18:32:34 -070014051 {
Florin Corasc97a7392017-11-05 23:07:07 -080014052 print (vam->ofp,
14053 "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
Steven85dbac02017-11-07 16:29:53 -080014054 clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014055 mp->scope, format_ip4_address, &lcl.fp_addr.ip4, lcl.fp_len,
Steven85dbac02017-11-07 16:29:53 -080014056 clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014057 &rmt.fp_addr.ip4, rmt.fp_len,
14058 clib_net_to_host_u16 (mp->rmt_port),
Steven85dbac02017-11-07 16:29:53 -080014059 clib_net_to_host_u32 (mp->action_index), mp->tag);
Florin Coras6c36f532017-11-03 18:32:34 -070014060 }
14061 else
14062 {
Florin Corasc97a7392017-11-05 23:07:07 -080014063 print (vam->ofp,
14064 "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
Steven85dbac02017-11-07 16:29:53 -080014065 clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014066 mp->scope, format_ip6_address, &lcl.fp_addr.ip6, lcl.fp_len,
Steven85dbac02017-11-07 16:29:53 -080014067 clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014068 &rmt.fp_addr.ip6, rmt.fp_len,
14069 clib_net_to_host_u16 (mp->rmt_port),
Steven85dbac02017-11-07 16:29:53 -080014070 clib_net_to_host_u32 (mp->action_index), mp->tag);
Florin Coras6c36f532017-11-03 18:32:34 -070014071 }
14072}
14073
14074static void
14075vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
14076 mp)
14077{
14078 vat_main_t *vam = &vat_main;
14079 vat_json_node_t *node = NULL;
14080 struct in6_addr ip6;
14081 struct in_addr ip4;
14082
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014083 fib_prefix_t lcl, rmt;
14084
14085 ip_prefix_decode (&mp->lcl, &lcl);
14086 ip_prefix_decode (&mp->rmt, &rmt);
14087
Florin Coras6c36f532017-11-03 18:32:34 -070014088 if (VAT_JSON_ARRAY != vam->json_tree.type)
14089 {
14090 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14091 vat_json_init_array (&vam->json_tree);
14092 }
14093 node = vat_json_array_add (&vam->json_tree);
14094 vat_json_init_object (node);
14095
Florin Coras6c36f532017-11-03 18:32:34 -070014096 vat_json_object_add_uint (node, "appns_index",
14097 clib_net_to_host_u32 (mp->appns_index));
14098 vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
14099 vat_json_object_add_uint (node, "scope", mp->scope);
14100 vat_json_object_add_uint (node, "action_index",
14101 clib_net_to_host_u32 (mp->action_index));
14102 vat_json_object_add_uint (node, "lcl_port",
14103 clib_net_to_host_u16 (mp->lcl_port));
14104 vat_json_object_add_uint (node, "rmt_port",
14105 clib_net_to_host_u16 (mp->rmt_port));
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014106 vat_json_object_add_uint (node, "lcl_plen", lcl.fp_len);
14107 vat_json_object_add_uint (node, "rmt_plen", rmt.fp_len);
Florin Corasc97a7392017-11-05 23:07:07 -080014108 vat_json_object_add_string_copy (node, "tag", mp->tag);
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014109 if (lcl.fp_proto == FIB_PROTOCOL_IP4)
Florin Coras6c36f532017-11-03 18:32:34 -070014110 {
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014111 clib_memcpy (&ip4, &lcl.fp_addr.ip4, sizeof (ip4));
Florin Coras6c36f532017-11-03 18:32:34 -070014112 vat_json_object_add_ip4 (node, "lcl_ip", ip4);
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014113 clib_memcpy (&ip4, &rmt.fp_addr.ip4, sizeof (ip4));
Florin Coras6c36f532017-11-03 18:32:34 -070014114 vat_json_object_add_ip4 (node, "rmt_ip", ip4);
14115 }
14116 else
14117 {
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014118 clib_memcpy (&ip6, &lcl.fp_addr.ip6, sizeof (ip6));
Florin Coras6c36f532017-11-03 18:32:34 -070014119 vat_json_object_add_ip6 (node, "lcl_ip", ip6);
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014120 clib_memcpy (&ip6, &rmt.fp_addr.ip6, sizeof (ip6));
Florin Coras6c36f532017-11-03 18:32:34 -070014121 vat_json_object_add_ip6 (node, "rmt_ip", ip6);
14122 }
14123}
14124
Florin Coras1c710452017-10-17 00:03:13 -070014125static int
14126api_session_rule_add_del (vat_main_t * vam)
14127{
14128 vl_api_session_rule_add_del_t *mp;
14129 unformat_input_t *i = vam->input;
14130 u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
14131 u32 appns_index = 0, scope = 0;
14132 ip4_address_t lcl_ip4, rmt_ip4;
14133 ip6_address_t lcl_ip6, rmt_ip6;
14134 u8 is_ip4 = 1, conn_set = 0;
Florin Corasc97a7392017-11-05 23:07:07 -080014135 u8 is_add = 1, *tag = 0;
Florin Coras1c710452017-10-17 00:03:13 -070014136 int ret;
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014137 fib_prefix_t lcl, rmt;
Florin Coras1c710452017-10-17 00:03:13 -070014138
14139 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14140 {
14141 if (unformat (i, "del"))
14142 is_add = 0;
14143 else if (unformat (i, "add"))
14144 ;
14145 else if (unformat (i, "proto tcp"))
14146 proto = 0;
14147 else if (unformat (i, "proto udp"))
14148 proto = 1;
14149 else if (unformat (i, "appns %d", &appns_index))
14150 ;
14151 else if (unformat (i, "scope %d", &scope))
14152 ;
Florin Corasc97a7392017-11-05 23:07:07 -080014153 else if (unformat (i, "tag %_%v%_", &tag))
14154 ;
Florin Coras1c710452017-10-17 00:03:13 -070014155 else
14156 if (unformat
14157 (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
14158 &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
14159 &rmt_port))
14160 {
14161 is_ip4 = 1;
14162 conn_set = 1;
14163 }
14164 else
14165 if (unformat
14166 (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
14167 &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
14168 &rmt_port))
14169 {
14170 is_ip4 = 0;
14171 conn_set = 1;
14172 }
14173 else if (unformat (i, "action %d", &action))
14174 ;
14175 else
14176 break;
14177 }
14178 if (proto == ~0 || !conn_set || action == ~0)
14179 {
14180 errmsg ("transport proto, connection and action must be set");
14181 return -99;
14182 }
14183
14184 if (scope > 3)
14185 {
14186 errmsg ("scope should be 0-3");
14187 return -99;
14188 }
14189
14190 M (SESSION_RULE_ADD_DEL, mp);
14191
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014192 clib_memset (&lcl, 0, sizeof (lcl));
14193 clib_memset (&rmt, 0, sizeof (rmt));
14194 if (is_ip4)
14195 {
14196 ip_set (&lcl.fp_addr, &lcl_ip4, 1);
14197 ip_set (&rmt.fp_addr, &rmt_ip4, 1);
14198 lcl.fp_len = lcl_plen;
14199 rmt.fp_len = rmt_plen;
14200 }
14201 else
14202 {
14203 ip_set (&lcl.fp_addr, &lcl_ip6, 0);
14204 ip_set (&rmt.fp_addr, &rmt_ip6, 0);
14205 lcl.fp_len = lcl_plen;
14206 rmt.fp_len = rmt_plen;
14207 }
14208
14209
14210 ip_prefix_encode (&lcl, &mp->lcl);
14211 ip_prefix_encode (&rmt, &mp->rmt);
Florin Corasc97a7392017-11-05 23:07:07 -080014212 mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
14213 mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014214 mp->transport_proto =
14215 proto ? TRANSPORT_PROTO_API_UDP : TRANSPORT_PROTO_API_TCP;
Florin Coras1c710452017-10-17 00:03:13 -070014216 mp->action_index = clib_host_to_net_u32 (action);
14217 mp->appns_index = clib_host_to_net_u32 (appns_index);
14218 mp->scope = scope;
14219 mp->is_add = is_add;
Florin Corasc97a7392017-11-05 23:07:07 -080014220 if (tag)
14221 {
14222 clib_memcpy (mp->tag, tag, vec_len (tag));
14223 vec_free (tag);
14224 }
Florin Coras1c710452017-10-17 00:03:13 -070014225
14226 S (mp);
14227 W (ret);
14228 return ret;
14229}
Dave Barach65457162017-10-10 17:53:14 -040014230
14231static int
Florin Coras6c36f532017-11-03 18:32:34 -070014232api_session_rules_dump (vat_main_t * vam)
14233{
14234 vl_api_session_rules_dump_t *mp;
14235 vl_api_control_ping_t *mp_ping;
14236 int ret;
14237
14238 if (!vam->json_output)
14239 {
14240 print (vam->ofp, "%=20s", "Session Rules");
14241 }
14242
14243 M (SESSION_RULES_DUMP, mp);
14244 /* send it... */
14245 S (mp);
14246
14247 /* Use a control ping for synchronization */
14248 MPING (CONTROL_PING, mp_ping);
14249 S (mp_ping);
14250
14251 /* Wait for a reply... */
14252 W (ret);
14253 return ret;
14254}
14255
14256static int
Florin Coras595992c2017-11-06 17:17:08 -080014257api_ip_container_proxy_add_del (vat_main_t * vam)
14258{
14259 vl_api_ip_container_proxy_add_del_t *mp;
14260 unformat_input_t *i = vam->input;
Neale Ranns37029302018-08-10 05:30:06 -070014261 u32 sw_if_index = ~0;
14262 vl_api_prefix_t pfx = { };
Florin Coras595992c2017-11-06 17:17:08 -080014263 u8 is_add = 1;
14264 int ret;
14265
14266 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14267 {
14268 if (unformat (i, "del"))
14269 is_add = 0;
14270 else if (unformat (i, "add"))
14271 ;
Neale Ranns37029302018-08-10 05:30:06 -070014272 if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
14273 ;
Florin Coras595992c2017-11-06 17:17:08 -080014274 else if (unformat (i, "sw_if_index %u", &sw_if_index))
14275 ;
14276 else
14277 break;
14278 }
Paul Vinciguerraab055082019-06-06 14:07:55 -040014279 if (sw_if_index == ~0 || pfx.len == 0)
Florin Coras595992c2017-11-06 17:17:08 -080014280 {
14281 errmsg ("address and sw_if_index must be set");
14282 return -99;
14283 }
14284
14285 M (IP_CONTAINER_PROXY_ADD_DEL, mp);
14286
Florin Coras595992c2017-11-06 17:17:08 -080014287 mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
Florin Coras595992c2017-11-06 17:17:08 -080014288 mp->is_add = is_add;
Neale Ranns37029302018-08-10 05:30:06 -070014289 clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
Florin Coras595992c2017-11-06 17:17:08 -080014290
14291 S (mp);
14292 W (ret);
14293 return ret;
14294}
14295
14296static int
Igor Mikhailov (imichail)582caa32018-04-26 21:33:02 -070014297api_qos_record_enable_disable (vat_main_t * vam)
14298{
14299 unformat_input_t *i = vam->input;
14300 vl_api_qos_record_enable_disable_t *mp;
14301 u32 sw_if_index, qs = 0xff;
14302 u8 sw_if_index_set = 0;
14303 u8 enable = 1;
14304 int ret;
14305
14306 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14307 {
14308 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14309 sw_if_index_set = 1;
14310 else if (unformat (i, "sw_if_index %d", &sw_if_index))
14311 sw_if_index_set = 1;
14312 else if (unformat (i, "%U", unformat_qos_source, &qs))
14313 ;
14314 else if (unformat (i, "disable"))
14315 enable = 0;
14316 else
14317 {
14318 clib_warning ("parse error '%U'", format_unformat_error, i);
14319 return -99;
14320 }
14321 }
14322
14323 if (sw_if_index_set == 0)
14324 {
14325 errmsg ("missing interface name or sw_if_index");
14326 return -99;
14327 }
14328 if (qs == 0xff)
14329 {
14330 errmsg ("input location must be specified");
14331 return -99;
14332 }
14333
14334 M (QOS_RECORD_ENABLE_DISABLE, mp);
14335
Neale Ranns5281a902019-07-23 08:16:19 -070014336 mp->record.sw_if_index = ntohl (sw_if_index);
14337 mp->record.input_source = qs;
Igor Mikhailov (imichail)582caa32018-04-26 21:33:02 -070014338 mp->enable = enable;
14339
14340 S (mp);
14341 W (ret);
14342 return ret;
14343}
14344
Dave Barach048a4e52018-06-01 18:52:25 -040014345
Igor Mikhailov (imichail)582caa32018-04-26 21:33:02 -070014346static int
Damjan Marion7cd468a2016-12-19 23:05:39 +010014347q_or_quit (vat_main_t * vam)
14348{
Dave Barachdef19da2017-02-22 17:29:20 -050014349#if VPP_API_TEST_BUILTIN == 0
Damjan Marion7cd468a2016-12-19 23:05:39 +010014350 longjmp (vam->jump_buf, 1);
Dave Barachdef19da2017-02-22 17:29:20 -050014351#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +010014352 return 0; /* not so much */
14353}
14354
14355static int
14356q (vat_main_t * vam)
14357{
14358 return q_or_quit (vam);
14359}
14360
14361static int
14362quit (vat_main_t * vam)
14363{
14364 return q_or_quit (vam);
14365}
14366
14367static int
14368comment (vat_main_t * vam)
14369{
14370 return 0;
14371}
14372
14373static int
Dave Barachb09f4d02019-07-15 16:00:03 -040014374elog_save (vat_main_t * vam)
14375{
14376#if VPP_API_TEST_BUILTIN == 0
14377 elog_main_t *em = &vam->elog_main;
14378 unformat_input_t *i = vam->input;
14379 char *file, *chroot_file;
14380 clib_error_t *error;
14381
14382 if (!unformat (i, "%s", &file))
14383 {
14384 errmsg ("expected file name, got `%U'", format_unformat_error, i);
14385 return 0;
14386 }
14387
14388 /* It's fairly hard to get "../oopsie" through unformat; just in case */
14389 if (strstr (file, "..") || index (file, '/'))
14390 {
14391 errmsg ("illegal characters in filename '%s'", file);
14392 return 0;
14393 }
14394
14395 chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
14396
14397 vec_free (file);
14398
14399 errmsg ("Saving %wd of %wd events to %s",
14400 elog_n_events_in_buffer (em),
14401 elog_buffer_capacity (em), chroot_file);
14402
14403 error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
14404 vec_free (chroot_file);
14405
14406 if (error)
14407 clib_error_report (error);
14408#else
14409 errmsg ("Use the vpp event loger...");
14410#endif
14411
14412 return 0;
14413}
14414
14415static int
14416elog_setup (vat_main_t * vam)
14417{
14418#if VPP_API_TEST_BUILTIN == 0
14419 elog_main_t *em = &vam->elog_main;
14420 unformat_input_t *i = vam->input;
14421 u32 nevents = 128 << 10;
14422
14423 (void) unformat (i, "nevents %d", &nevents);
14424
14425 elog_init (em, nevents);
14426 vl_api_set_elog_main (em);
14427 vl_api_set_elog_trace_api_messages (1);
14428 errmsg ("Event logger initialized with %u events", nevents);
14429#else
14430 errmsg ("Use the vpp event loger...");
14431#endif
14432 return 0;
14433}
14434
14435static int
14436elog_enable (vat_main_t * vam)
14437{
14438#if VPP_API_TEST_BUILTIN == 0
14439 elog_main_t *em = &vam->elog_main;
14440
14441 elog_enable_disable (em, 1 /* enable */ );
14442 vl_api_set_elog_trace_api_messages (1);
14443 errmsg ("Event logger enabled...");
14444#else
14445 errmsg ("Use the vpp event loger...");
14446#endif
14447 return 0;
14448}
14449
14450static int
14451elog_disable (vat_main_t * vam)
14452{
14453#if VPP_API_TEST_BUILTIN == 0
14454 elog_main_t *em = &vam->elog_main;
14455
14456 elog_enable_disable (em, 0 /* enable */ );
14457 vl_api_set_elog_trace_api_messages (1);
14458 errmsg ("Event logger disabled...");
14459#else
14460 errmsg ("Use the vpp event loger...");
14461#endif
14462 return 0;
14463}
14464
14465static int
Dave Barach048a4e52018-06-01 18:52:25 -040014466statseg (vat_main_t * vam)
14467{
14468 ssvm_private_t *ssvmp = &vam->stat_segment;
14469 ssvm_shared_header_t *shared_header = ssvmp->sh;
14470 vlib_counter_t **counters;
14471 u64 thread0_index1_packets;
14472 u64 thread0_index1_bytes;
14473 f64 vector_rate, input_rate;
14474 uword *p;
14475
14476 uword *counter_vector_by_name;
14477 if (vam->stat_segment_lockp == 0)
14478 {
14479 errmsg ("Stat segment not mapped...");
14480 return -99;
14481 }
14482
14483 /* look up "/if/rx for sw_if_index 1 as a test */
14484
14485 clib_spinlock_lock (vam->stat_segment_lockp);
14486
14487 counter_vector_by_name = (uword *) shared_header->opaque[1];
14488
14489 p = hash_get_mem (counter_vector_by_name, "/if/rx");
14490 if (p == 0)
14491 {
14492 clib_spinlock_unlock (vam->stat_segment_lockp);
14493 errmsg ("/if/tx not found?");
14494 return -99;
14495 }
14496
14497 /* Fish per-thread vector of combined counters from shared memory */
14498 counters = (vlib_counter_t **) p[0];
14499
14500 if (vec_len (counters[0]) < 2)
14501 {
14502 clib_spinlock_unlock (vam->stat_segment_lockp);
14503 errmsg ("/if/tx vector length %d", vec_len (counters[0]));
14504 return -99;
14505 }
14506
14507 /* Read thread 0 sw_if_index 1 counter */
14508 thread0_index1_packets = counters[0][1].packets;
14509 thread0_index1_bytes = counters[0][1].bytes;
14510
14511 p = hash_get_mem (counter_vector_by_name, "vector_rate");
14512 if (p == 0)
14513 {
14514 clib_spinlock_unlock (vam->stat_segment_lockp);
14515 errmsg ("vector_rate not found?");
14516 return -99;
14517 }
14518
14519 vector_rate = *(f64 *) (p[0]);
14520 p = hash_get_mem (counter_vector_by_name, "input_rate");
14521 if (p == 0)
14522 {
14523 clib_spinlock_unlock (vam->stat_segment_lockp);
14524 errmsg ("input_rate not found?");
14525 return -99;
14526 }
14527 input_rate = *(f64 *) (p[0]);
14528
14529 clib_spinlock_unlock (vam->stat_segment_lockp);
14530
14531 print (vam->ofp, "vector_rate %.2f input_rate %.2f",
14532 vector_rate, input_rate);
14533 print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
14534 thread0_index1_packets, thread0_index1_bytes);
14535
14536 return 0;
14537}
14538
14539static int
Damjan Marion7cd468a2016-12-19 23:05:39 +010014540cmd_cmp (void *a1, void *a2)
14541{
14542 u8 **c1 = a1;
14543 u8 **c2 = a2;
14544
14545 return strcmp ((char *) (c1[0]), (char *) (c2[0]));
14546}
14547
14548static int
14549help (vat_main_t * vam)
14550{
14551 u8 **cmds = 0;
14552 u8 *name = 0;
14553 hash_pair_t *p;
14554 unformat_input_t *i = vam->input;
14555 int j;
14556
14557 if (unformat (i, "%s", &name))
14558 {
14559 uword *hs;
14560
14561 vec_add1 (name, 0);
14562
14563 hs = hash_get_mem (vam->help_by_name, name);
14564 if (hs)
14565 print (vam->ofp, "usage: %s %s", name, hs[0]);
14566 else
14567 print (vam->ofp, "No such msg / command '%s'", name);
14568 vec_free (name);
14569 return 0;
14570 }
14571
14572 print (vam->ofp, "Help is available for the following:");
14573
14574 /* *INDENT-OFF* */
14575 hash_foreach_pair (p, vam->function_by_name,
14576 ({
14577 vec_add1 (cmds, (u8 *)(p->key));
14578 }));
14579 /* *INDENT-ON* */
14580
14581 vec_sort_with_function (cmds, cmd_cmp);
14582
14583 for (j = 0; j < vec_len (cmds); j++)
14584 print (vam->ofp, "%s", cmds[j]);
14585
14586 vec_free (cmds);
14587 return 0;
14588}
14589
14590static int
14591set (vat_main_t * vam)
14592{
14593 u8 *name = 0, *value = 0;
14594 unformat_input_t *i = vam->input;
14595
14596 if (unformat (i, "%s", &name))
14597 {
14598 /* The input buffer is a vector, not a string. */
14599 value = vec_dup (i->buffer);
14600 vec_delete (value, i->index, 0);
14601 /* Almost certainly has a trailing newline */
14602 if (value[vec_len (value) - 1] == '\n')
14603 value[vec_len (value) - 1] = 0;
14604 /* Make sure it's a proper string, one way or the other */
14605 vec_add1 (value, 0);
14606 (void) clib_macro_set_value (&vam->macro_main,
14607 (char *) name, (char *) value);
14608 }
14609 else
14610 errmsg ("usage: set <name> <value>");
14611
14612 vec_free (name);
14613 vec_free (value);
14614 return 0;
14615}
14616
14617static int
14618unset (vat_main_t * vam)
14619{
14620 u8 *name = 0;
14621
14622 if (unformat (vam->input, "%s", &name))
14623 if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
14624 errmsg ("unset: %s wasn't set", name);
14625 vec_free (name);
14626 return 0;
14627}
14628
14629typedef struct
14630{
14631 u8 *name;
14632 u8 *value;
14633} macro_sort_t;
14634
14635
14636static int
14637macro_sort_cmp (void *a1, void *a2)
14638{
14639 macro_sort_t *s1 = a1;
14640 macro_sort_t *s2 = a2;
14641
14642 return strcmp ((char *) (s1->name), (char *) (s2->name));
14643}
14644
14645static int
14646dump_macro_table (vat_main_t * vam)
14647{
14648 macro_sort_t *sort_me = 0, *sm;
14649 int i;
14650 hash_pair_t *p;
14651
14652 /* *INDENT-OFF* */
14653 hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
14654 ({
14655 vec_add2 (sort_me, sm, 1);
14656 sm->name = (u8 *)(p->key);
14657 sm->value = (u8 *) (p->value[0]);
14658 }));
14659 /* *INDENT-ON* */
14660
14661 vec_sort_with_function (sort_me, macro_sort_cmp);
14662
14663 if (vec_len (sort_me))
14664 print (vam->ofp, "%-15s%s", "Name", "Value");
14665 else
14666 print (vam->ofp, "The macro table is empty...");
14667
14668 for (i = 0; i < vec_len (sort_me); i++)
14669 print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
14670 return 0;
14671}
14672
14673static int
14674dump_node_table (vat_main_t * vam)
14675{
14676 int i, j;
14677 vlib_node_t *node, *next_node;
14678
14679 if (vec_len (vam->graph_nodes) == 0)
14680 {
14681 print (vam->ofp, "Node table empty, issue get_node_graph...");
14682 return 0;
14683 }
14684
Dave Barach1ddbc012018-06-13 09:26:05 -040014685 for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
Damjan Marion7cd468a2016-12-19 23:05:39 +010014686 {
Dave Barach1ddbc012018-06-13 09:26:05 -040014687 node = vam->graph_nodes[0][i];
Damjan Marion7cd468a2016-12-19 23:05:39 +010014688 print (vam->ofp, "[%d] %s", i, node->name);
14689 for (j = 0; j < vec_len (node->next_nodes); j++)
14690 {
14691 if (node->next_nodes[j] != ~0)
14692 {
Dave Barach1ddbc012018-06-13 09:26:05 -040014693 next_node = vam->graph_nodes[0][node->next_nodes[j]];
Damjan Marion7cd468a2016-12-19 23:05:39 +010014694 print (vam->ofp, " [%d] %s", j, next_node->name);
14695 }
14696 }
14697 }
14698 return 0;
14699}
14700
14701static int
14702value_sort_cmp (void *a1, void *a2)
14703{
14704 name_sort_t *n1 = a1;
14705 name_sort_t *n2 = a2;
14706
14707 if (n1->value < n2->value)
14708 return -1;
14709 if (n1->value > n2->value)
14710 return 1;
14711 return 0;
14712}
14713
14714
14715static int
14716dump_msg_api_table (vat_main_t * vam)
14717{
Dave Barach39d69112019-11-27 11:42:13 -050014718 api_main_t *am = vlibapi_get_main ();
Damjan Marion7cd468a2016-12-19 23:05:39 +010014719 name_sort_t *nses = 0, *ns;
14720 hash_pair_t *hp;
14721 int i;
14722
14723 /* *INDENT-OFF* */
14724 hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
14725 ({
14726 vec_add2 (nses, ns, 1);
14727 ns->name = (u8 *)(hp->key);
14728 ns->value = (u32) hp->value[0];
14729 }));
14730 /* *INDENT-ON* */
14731
14732 vec_sort_with_function (nses, value_sort_cmp);
14733
14734 for (i = 0; i < vec_len (nses); i++)
14735 print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
14736 vec_free (nses);
14737 return 0;
14738}
14739
14740static int
14741get_msg_id (vat_main_t * vam)
14742{
14743 u8 *name_and_crc;
14744 u32 message_index;
14745
14746 if (unformat (vam->input, "%s", &name_and_crc))
14747 {
Florin Corase86a8ed2018-01-05 03:20:25 -080014748 message_index = vl_msg_api_get_msg_index (name_and_crc);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014749 if (message_index == ~0)
14750 {
14751 print (vam->ofp, " '%s' not found", name_and_crc);
14752 return 0;
14753 }
14754 print (vam->ofp, " '%s' has message index %d",
14755 name_and_crc, message_index);
14756 return 0;
14757 }
14758 errmsg ("name_and_crc required...");
14759 return 0;
14760}
14761
14762static int
14763search_node_table (vat_main_t * vam)
14764{
14765 unformat_input_t *line_input = vam->input;
14766 u8 *node_to_find;
14767 int j;
14768 vlib_node_t *node, *next_node;
14769 uword *p;
14770
14771 if (vam->graph_node_index_by_name == 0)
14772 {
14773 print (vam->ofp, "Node table empty, issue get_node_graph...");
14774 return 0;
14775 }
14776
14777 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14778 {
14779 if (unformat (line_input, "%s", &node_to_find))
14780 {
14781 vec_add1 (node_to_find, 0);
14782 p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
14783 if (p == 0)
14784 {
14785 print (vam->ofp, "%s not found...", node_to_find);
14786 goto out;
14787 }
Dave Barach1ddbc012018-06-13 09:26:05 -040014788 node = vam->graph_nodes[0][p[0]];
Damjan Marion7cd468a2016-12-19 23:05:39 +010014789 print (vam->ofp, "[%d] %s", p[0], node->name);
14790 for (j = 0; j < vec_len (node->next_nodes); j++)
14791 {
14792 if (node->next_nodes[j] != ~0)
14793 {
Dave Barach1ddbc012018-06-13 09:26:05 -040014794 next_node = vam->graph_nodes[0][node->next_nodes[j]];
Damjan Marion7cd468a2016-12-19 23:05:39 +010014795 print (vam->ofp, " [%d] %s", j, next_node->name);
14796 }
14797 }
14798 }
14799
14800 else
14801 {
14802 clib_warning ("parse error '%U'", format_unformat_error,
14803 line_input);
14804 return -99;
14805 }
14806
14807 out:
14808 vec_free (node_to_find);
14809
14810 }
14811
14812 return 0;
14813}
14814
14815
14816static int
14817script (vat_main_t * vam)
14818{
14819#if (VPP_API_TEST_BUILTIN==0)
14820 u8 *s = 0;
14821 char *save_current_file;
14822 unformat_input_t save_input;
14823 jmp_buf save_jump_buf;
14824 u32 save_line_number;
14825
14826 FILE *new_fp, *save_ifp;
14827
14828 if (unformat (vam->input, "%s", &s))
14829 {
14830 new_fp = fopen ((char *) s, "r");
14831 if (new_fp == 0)
14832 {
14833 errmsg ("Couldn't open script file %s", s);
14834 vec_free (s);
14835 return -99;
14836 }
14837 }
14838 else
14839 {
14840 errmsg ("Missing script name");
14841 return -99;
14842 }
14843
14844 clib_memcpy (&save_input, &vam->input, sizeof (save_input));
14845 clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
14846 save_ifp = vam->ifp;
14847 save_line_number = vam->input_line_number;
14848 save_current_file = (char *) vam->current_file;
14849
14850 vam->input_line_number = 0;
14851 vam->ifp = new_fp;
14852 vam->current_file = s;
14853 do_one_file (vam);
14854
Sirshak Dasb0861822018-05-29 21:13:21 -050014855 clib_memcpy (&vam->input, &save_input, sizeof (save_input));
Damjan Marion7cd468a2016-12-19 23:05:39 +010014856 clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
14857 vam->ifp = save_ifp;
14858 vam->input_line_number = save_line_number;
14859 vam->current_file = (u8 *) save_current_file;
14860 vec_free (s);
14861
14862 return 0;
14863#else
14864 clib_warning ("use the exec command...");
14865 return -99;
14866#endif
14867}
14868
14869static int
14870echo (vat_main_t * vam)
14871{
14872 print (vam->ofp, "%v", vam->input->buffer);
14873 return 0;
14874}
14875
14876/* List of API message constructors, CLI names map to api_xxx */
14877#define foreach_vpe_api_msg \
Jon Loeligerc83c3b72017-02-23 13:57:35 -060014878_(create_loopback,"[mac <mac-addr>] [instance <instance>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014879_(sw_interface_dump,"") \
14880_(sw_interface_set_flags, \
14881 "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
14882_(sw_interface_add_del_address, \
14883 "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
Stevenad8015b2017-10-29 22:10:46 -070014884_(sw_interface_set_rx_mode, \
14885 "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
Mohsin Kazmi54f7c512018-08-23 18:28:11 +020014886_(sw_interface_set_rx_placement, \
14887 "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]") \
Mohsin Kazmif0b42f42018-09-10 18:11:00 +020014888_(sw_interface_rx_placement_dump, \
14889 "[<intfc> | sw_if_index <id>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014890_(sw_interface_set_table, \
14891 "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]") \
14892_(sw_interface_set_mpls_enable, \
14893 "<intfc> | sw_if_index [disable | dis]") \
14894_(sw_interface_set_vpath, \
14895 "<intfc> | sw_if_index <id> enable | disable") \
14896_(sw_interface_set_vxlan_bypass, \
John Lo2b81eb82017-01-30 13:12:10 -050014897 "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014898_(sw_interface_set_l2_xconnect, \
14899 "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
14900 "enable | disable") \
14901_(sw_interface_set_l2_bridge, \
Eyal Barif24991c2017-04-05 05:33:21 +030014902 "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n" \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014903 "[shg <split-horizon-group>] [bvi]\n" \
14904 "enable | disable") \
Eyal Barif24991c2017-04-05 05:33:21 +030014905_(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014906_(bridge_domain_add_del, \
John Lo70bfcaf2017-11-14 13:19:26 -050014907 "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 +010014908_(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n") \
14909_(l2fib_add_del, \
14910 "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 +030014911_(l2fib_flush_bd, "bd_id <bridge-domain-id>") \
14912_(l2fib_flush_int, "<intfc> | sw_if_index <id>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014913_(l2_flags, \
John Lo8d00fff2017-08-03 00:35:36 -040014914 "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014915_(bridge_flags, \
14916 "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
Damjan Marion8389fb92017-10-13 18:29:53 +020014917_(tap_create_v2, \
Mohsin Kazmi50bd1652020-08-26 11:07:48 +020014918 "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 +020014919_(tap_delete_v2, \
14920 "<vpp-if-name> | sw_if_index <id>") \
14921_(sw_interface_tap_v2_dump, "") \
Mohsin Kazmi518251b2020-09-01 17:17:44 +000014922_(virtio_pci_create_v2, \
Mohsin Kazmie347acb2020-09-28 10:26:33 +000014923 "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 +010014924_(virtio_pci_delete, \
14925 "<vpp-if-name> | sw_if_index <id>") \
14926_(sw_interface_virtio_pci_dump, "") \
Steven9cd2d7a2017-12-20 12:43:01 -080014927_(bond_create, \
14928 "[hw-addr <mac-addr>] {round-robin | active-backup | " \
Alexander Chernavinad9d5282018-12-13 09:08:09 -050014929 "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} " \
Steven Luonga1876b82019-08-20 16:58:00 -070014930 "[id <if-id>]") \
Steven Luongea717862020-07-30 07:31:40 -070014931_(bond_create2, \
14932 "[hw-addr <mac-addr>] {mode round-robin | active-backup | " \
14933 "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} " \
14934 "[id <if-id>] [gso]") \
Steven9cd2d7a2017-12-20 12:43:01 -080014935_(bond_delete, \
14936 "<vpp-if-name> | sw_if_index <id>") \
Steven Luong4c4223e2020-07-15 08:44:54 -070014937_(bond_add_member, \
Steven Luonga1876b82019-08-20 16:58:00 -070014938 "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]") \
Steven Luong4c4223e2020-07-15 08:44:54 -070014939_(bond_detach_member, \
Steven9cd2d7a2017-12-20 12:43:01 -080014940 "sw_if_index <n>") \
Steven Luonga1876b82019-08-20 16:58:00 -070014941 _(sw_interface_set_bond_weight, "<intfc> | sw_if_index <nn> weight <value>") \
Steven Luong4c4223e2020-07-15 08:44:54 -070014942 _(sw_bond_interface_dump, "<intfc> | sw_if_index <nn>") \
14943 _(sw_member_interface_dump, \
Steven9cd2d7a2017-12-20 12:43:01 -080014944 "<vpp-if-name> | sw_if_index <id>") \
Neale Ranns28ab9cc2017-08-14 07:18:42 -070014945_(ip_table_add_del, \
John Loe166fd92018-09-13 14:08:59 -040014946 "table <n> [ipv6] [add | del]\n") \
Neale Ranns097fa662018-05-01 05:17:55 -070014947_(ip_route_add_del, \
John Lo22030432018-09-20 16:07:00 -040014948 "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
14949 "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
John Lo06fda9c2018-10-03 16:32:44 -040014950 "[weight <n>] [drop] [local] [classify <n>] [out-label <n>]\n" \
14951 "[multipath] [count <n>] [del]") \
Neale Ranns32e1c012016-11-22 17:07:28 +000014952_(ip_mroute_add_del, \
14953 "<src> <grp>/<mask> [table-id <n>]\n" \
14954 "[<intfc> | sw_if_index <id>] [local] [del]") \
Neale Ranns28ab9cc2017-08-14 07:18:42 -070014955_(mpls_table_add_del, \
John Loe166fd92018-09-13 14:08:59 -040014956 "table <n> [add | del]\n") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014957_(mpls_route_add_del, \
John Loe166fd92018-09-13 14:08:59 -040014958 "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n" \
14959 "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n" \
14960 "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n" \
14961 "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n" \
John Lo06fda9c2018-10-03 16:32:44 -040014962 "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n" \
14963 "[count <n>] [del]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014964_(mpls_ip_bind_unbind, \
14965 "<label> <addr/len>") \
14966_(mpls_tunnel_add_del, \
John Lo06fda9c2018-10-03 16:32:44 -040014967 "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
14968 "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n" \
14969 "[l2-only] [out-label <n>]") \
John Loe166fd92018-09-13 14:08:59 -040014970_(sr_mpls_policy_add, \
14971 "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]") \
14972_(sr_mpls_policy_del, \
14973 "bsid <id>") \
Neale Rannsd792d9c2017-10-21 10:53:20 -070014974_(bier_table_add_del, \
14975 "<label> <sub-domain> <set> <bsl> [del]") \
14976_(bier_route_add_del, \
14977 "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
14978 "[<intfc> | sw_if_index <id>]" \
14979 "[weight <n>] [del] [multipath]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014980_(sw_interface_set_unnumbered, \
14981 "<intfc> | sw_if_index <id> unnum_if_index <id> [del]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014982_(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>") \
14983_(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n" \
14984 "[outer_vlan_id <n>][inner_vlan_id <n>]\n" \
14985 "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n" \
14986 "[outer_vlan_id_any][inner_vlan_id_any]") \
Neale Ranns9db6ada2019-11-08 12:42:31 +000014987_(ip_table_replace_begin, "table <n> [ipv6]") \
14988_(ip_table_flush, "table <n> [ipv6]") \
14989_(ip_table_replace_end, "table <n> [ipv6]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014990_(set_ip_flow_hash, \
14991 "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]") \
14992_(sw_interface_ip6_enable_disable, \
14993 "<intfc> | sw_if_index <id> enable | disable") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014994_(l2_patch_add_del, \
14995 "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
14996 "enable | disable") \
Pablo Camarillofb380952016-12-07 18:34:18 +010014997_(sr_localsid_add_del, \
14998 "(del) address <addr> next_hop <addr> behavior <beh>\n" \
14999 "fib-table <num> (end.psp) sw_if_index <num>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015000_(classify_add_del_table, \
15001 "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n" \
15002 " [del] [del-chain] mask <mask-value>\n" \
15003 " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n" \
15004 " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]") \
15005_(classify_add_del_session, \
15006 "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n" \
15007 " table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n" \
15008 " [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n" \
15009 " [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]") \
15010_(classify_set_interface_ip_table, \
15011 "<intfc> | sw_if_index <nn> table <nn>") \
15012_(classify_set_interface_l2_tables, \
15013 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
15014 " [other-table <nn>]") \
15015_(get_node_index, "node <node-name") \
15016_(add_node_next, "node <node-name> next <next-node-name>") \
eyal bariaf86a482018-04-17 11:20:27 +030015017_(vxlan_offload_rx, \
15018 "hw { <interface name> | hw_if_index <nn>} " \
15019 "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015020_(vxlan_add_del_tunnel, \
15021 "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n" \
Jon Loeliger3d460bd2018-02-01 16:36:12 -060015022 "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n" \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015023 "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]") \
15024_(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015025_(l2_fib_clear_table, "") \
15026_(l2_interface_efp_filter, "sw_if_index <nn> enable | disable") \
15027_(l2_interface_vlan_tag_rewrite, \
15028 "<intfc> | sw_if_index <nn> \n" \
15029 "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n" \
15030 "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>") \
15031_(create_vhost_user_if, \
15032 "socket <filename> [server] [renumber <dev_instance>] " \
Steven Luong4208a4c2019-05-06 08:51:56 -070015033 "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] " \
Steven Luongbc0d9ff2020-03-23 09:34:59 -070015034 "[mac <mac_address>] [packed]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015035_(modify_vhost_user_if, \
15036 "<intfc> | sw_if_index <nn> socket <filename>\n" \
Steven Luongbc0d9ff2020-03-23 09:34:59 -070015037 "[server] [renumber <dev_instance>] [gso] [packed]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015038_(delete_vhost_user_if, "<intfc> | sw_if_index <nn>") \
Steven Luonga0e8d962020-05-18 17:12:56 -070015039_(sw_interface_vhost_user_dump, "<intfc> | sw_if_index <nn>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015040_(show_version, "") \
Mohsin Kazmi5d64c782018-09-11 20:27:09 +020015041_(show_threads, "") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015042_(vxlan_gpe_add_del_tunnel, \
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080015043 "local <addr> remote <addr> | group <mcast-ip-addr>\n" \
15044 "{ <intfc> | mcast_sw_if_index <nn> } }\n" \
15045 "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n" \
15046 "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015047_(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]") \
15048_(l2_fib_table_dump, "bd_id <bridge-domain-id>") \
15049_(interface_name_renumber, \
15050 "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>") \
15051_(input_acl_set_interface, \
15052 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
15053 " [l2-table <nn>] [del]") \
John Lo8d00fff2017-08-03 00:35:36 -040015054_(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015055_(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)") \
15056_(ip_dump, "ipv4 | ipv6") \
15057_(ipsec_spd_add_del, "spd_id <n> [del]") \
15058_(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n" \
15059 " spid_id <n> ") \
Neale Ranns17dcec02019-01-09 21:22:20 -080015060_(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n" \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015061 " crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n" \
15062 " integ_alg <alg> integ_key <hex>") \
Neale Ranns17dcec02019-01-09 21:22:20 -080015063_(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n" \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015064 " (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n" \
15065 " laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
15066 " [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
Matthew Smithb0972cb2017-05-02 16:20:41 -050015067_(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n" \
15068 " crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
15069 " integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n" \
Matthew Smith8e1039a2018-04-12 07:32:56 -050015070 " local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n" \
15071 " [instance <n>]") \
Matthew Smith28029532017-09-26 13:33:44 -050015072_(ipsec_sa_dump, "[sa_id <n>]") \
Matthew Smithca514fd2017-10-12 12:06:59 -050015073_(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015074_(delete_loopback,"sw_if_index <nn>") \
15075_(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
John Loe26c81f2019-01-07 15:16:33 -050015076_(bd_ip_mac_flush, "bd_id <bridge-domain-id>") \
15077_(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015078_(want_interface_events, "enable|disable") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015079_(get_first_msg_id, "client <name>") \
15080_(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
15081_(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n" \
15082 "fib-id <nn> [ip4][ip6][default]") \
15083_(get_node_graph, " ") \
15084_(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>") \
15085_(ioam_enable, "[trace] [pow] [ppc <encap|decap>]") \
15086_(ioam_disable, "") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015087_(af_packet_create, "name <host interface name> [hw_addr <mac>]") \
15088_(af_packet_delete, "name <host interface name>") \
Mohsin Kazmi04e0bb22018-05-28 18:55:37 +020015089_(af_packet_dump, "") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015090_(policer_add_del, "name <policer name> <params> [del]") \
15091_(policer_dump, "[name <policer name>]") \
15092_(policer_classify_set_interface, \
15093 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
15094 " [l2-table <nn>] [del]") \
15095_(policer_classify_dump, "type [ip4|ip6|l2]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015096_(mpls_tunnel_dump, "tunnel_index <tunnel-id>") \
Neale Ranns097fa662018-05-01 05:17:55 -070015097_(mpls_table_dump, "") \
15098_(mpls_route_dump, "table-id <ID>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015099_(classify_table_ids, "") \
15100_(classify_table_by_interface, "sw_if_index <sw_if_index>") \
15101_(classify_table_info, "table_id <nn>") \
15102_(classify_session_dump, "table_id <nn>") \
15103_(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] " \
15104 "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] " \
15105 "[template_interval <nn>] [udp_checksum]") \
15106_(ipfix_exporter_dump, "") \
15107_(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
15108_(ipfix_classify_stream_dump, "") \
15109_(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
15110_(ipfix_classify_table_dump, "") \
Eyal Bari001fd402017-07-16 09:34:53 +030015111_(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 +030015112_(sw_interface_span_dump, "[l2]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015113_(get_next_index, "node-name <node-name> next-node-name <node-name>") \
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +020015114_(pg_create_interface, "if_id <nn> [gso-enabled gso-size <size>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015115_(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]") \
15116_(pg_enable_disable, "[stream <id>] disable") \
Mohsin Kazmif382b062020-08-11 15:00:44 +020015117_(pg_interface_enable_disable_coalesce, "<intf> | sw_if_index <nn> enable | disable") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015118_(ip_source_and_port_range_check_add_del, \
15119 "<ip-addr>/<mask> range <nn>-<nn> vrf <id>") \
15120_(ip_source_and_port_range_check_interface_add_del, \
15121 "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]" \
15122 "[udp-in-vrf <id>] [udp-out-vrf <id>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015123_(delete_subif,"<intfc> | sw_if_index <nn>") \
15124_(l2_interface_pbb_tag_rewrite, \
15125 "<intfc> | sw_if_index <nn> \n" \
15126 "[disable | push | pop | translate_pbb_stag <outer_tag>] \n" \
15127 "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]") \
Pavel Kotuceke88865d2018-11-28 07:42:11 +010015128_(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015129_(flow_classify_set_interface, \
15130 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
15131_(flow_classify_dump, "type [ip4|ip6]") \
Neale Ranns097fa662018-05-01 05:17:55 -070015132_(ip_table_dump, "") \
15133_(ip_route_dump, "table-id [ip4|ip6]") \
15134_(ip_mtable_dump, "") \
15135_(ip_mroute_dump, "table-id [ip4|ip6]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015136_(feature_enable_disable, "arc_name <arc_name> " \
15137 "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]") \
Mohsin Kazmi29467b52019-10-08 19:42:38 +020015138_(feature_gso_enable_disable, "<intfc> | sw_if_index <nn> " \
15139 "[enable | disable] ") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015140_(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>" \
15141"[disable]") \
Matthew Smithe0792fd2019-07-12 11:48:24 -050015142_(sw_interface_add_del_mac_address, "<intfc> | sw_if_index <nn> " \
15143 "mac <mac-address> [del]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015144_(l2_xconnect_dump, "") \
Ole Troand7231612018-06-07 10:17:57 +020015145_(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>") \
Pavel Kotucek6899a302017-06-08 08:46:10 +020015146_(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]") \
Pavel Kotucek15ac81c2017-06-20 14:00:26 +020015147_(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
Steve Shin99a0e602017-07-01 04:16:20 +000015148_(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
Dave Barach59b25652017-09-10 15:04:27 -040015149_(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]") \
Florin Coras90a63982017-12-19 04:50:01 -080015150_(sock_init_shm, "size <nnn>") \
Florin Corascea194d2017-10-02 00:18:51 -070015151_(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
Florin Coras1c710452017-10-17 00:03:13 -070015152_(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> " \
15153 "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>") \
Florin Coras6c36f532017-11-03 18:32:34 -070015154_(session_rules_dump, "") \
Florin Coras595992c2017-11-06 17:17:08 -080015155_(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>") \
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +010015156_(output_acl_set_interface, \
15157 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
15158 " [l2-table <nn>] [del]") \
Ole Troane906aac2018-06-14 14:42:14 +020015159_(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
Damjan Marion7cd468a2016-12-19 23:05:39 +010015160
15161/* List of command functions, CLI names map directly to functions */
15162#define foreach_cli_function \
15163_(comment, "usage: comment <ignore-rest-of-line>") \
15164_(dump_interface_table, "usage: dump_interface_table") \
15165_(dump_sub_interface_table, "usage: dump_sub_interface_table") \
15166_(dump_ipv4_table, "usage: dump_ipv4_table") \
15167_(dump_ipv6_table, "usage: dump_ipv6_table") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015168_(dump_macro_table, "usage: dump_macro_table ") \
15169_(dump_node_table, "usage: dump_node_table") \
15170_(dump_msg_api_table, "usage: dump_msg_api_table") \
Dave Barachb09f4d02019-07-15 16:00:03 -040015171_(elog_setup, "usage: elog_setup [nevents, default 128K]") \
15172_(elog_disable, "usage: elog_disable") \
15173_(elog_enable, "usage: elog_enable") \
15174_(elog_save, "usage: elog_save <filename>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015175_(get_msg_id, "usage: get_msg_id name_and_crc") \
15176_(echo, "usage: echo <message>") \
15177_(exec, "usage: exec <vpe-debug-CLI-command>") \
15178_(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>") \
15179_(help, "usage: help") \
15180_(q, "usage: quit") \
15181_(quit, "usage: quit") \
15182_(search_node_table, "usage: search_node_table <name>...") \
15183_(set, "usage: set <variable-name> <value>") \
15184_(script, "usage: script <file-name>") \
Neale Ranns097fa662018-05-01 05:17:55 -070015185_(statseg, "usage: statseg") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015186_(unset, "usage: unset <variable-name>")
Dave Barach048a4e52018-06-01 18:52:25 -040015187
Damjan Marion7cd468a2016-12-19 23:05:39 +010015188#define _(N,n) \
15189 static void vl_api_##n##_t_handler_uni \
15190 (vl_api_##n##_t * mp) \
15191 { \
15192 vat_main_t * vam = &vat_main; \
15193 if (vam->json_output) { \
15194 vl_api_##n##_t_handler_json(mp); \
15195 } else { \
15196 vl_api_##n##_t_handler(mp); \
15197 } \
15198 }
15199foreach_vpe_api_reply_msg;
Dave Baracha1a093d2017-03-02 13:13:23 -050015200#if VPP_API_TEST_BUILTIN == 0
15201foreach_standalone_reply_msg;
15202#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +010015203#undef _
15204
15205void
15206vat_api_hookup (vat_main_t * vam)
15207{
15208#define _(N,n) \
15209 vl_msg_api_set_handlers(VL_API_##N, #n, \
15210 vl_api_##n##_t_handler_uni, \
15211 vl_noop_handler, \
15212 vl_api_##n##_t_endian, \
15213 vl_api_##n##_t_print, \
15214 sizeof(vl_api_##n##_t), 1);
15215 foreach_vpe_api_reply_msg;
Dave Baracha1a093d2017-03-02 13:13:23 -050015216#if VPP_API_TEST_BUILTIN == 0
15217 foreach_standalone_reply_msg;
15218#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +010015219#undef _
15220
15221#if (VPP_API_TEST_BUILTIN==0)
15222 vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015223
15224 vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
15225
15226 vam->function_by_name = hash_create_string (0, sizeof (uword));
15227
15228 vam->help_by_name = hash_create_string (0, sizeof (uword));
Dave Barach45e4f362017-03-07 12:52:31 -050015229#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +010015230
15231 /* API messages we can send */
15232#define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
15233 foreach_vpe_api_msg;
15234#undef _
15235
15236 /* Help strings */
15237#define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
15238 foreach_vpe_api_msg;
15239#undef _
Damjan Marion7cd468a2016-12-19 23:05:39 +010015240
15241 /* CLI functions */
15242#define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
15243 foreach_cli_function;
15244#undef _
15245
15246 /* Help strings */
15247#define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
15248 foreach_cli_function;
15249#undef _
15250}
15251
Dave Baracha1a093d2017-03-02 13:13:23 -050015252#if VPP_API_TEST_BUILTIN
15253static clib_error_t *
15254vat_api_hookup_shim (vlib_main_t * vm)
15255{
15256 vat_api_hookup (&vat_main);
15257 return 0;
15258}
15259
15260VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
15261#endif
15262
Damjan Marion7cd468a2016-12-19 23:05:39 +010015263/*
15264 * fd.io coding-style-patch-verification: ON
15265 *
15266 * Local Variables:
15267 * eval: (c-set-style "gnu")
15268 * End:
15269 */