blob: 4dd3f054ff351f5bdd2b587963c496cd51ac0270 [file] [log] [blame]
Damjan Marion7cd468a2016-12-19 23:05:39 +01001/*
2 *------------------------------------------------------------------
3 * api_format.c
4 *
Dave Barachac0326f2020-07-14 18:30:05 -04005 * Copyright (c) 2014-2020 Cisco and/or its affiliates.
Damjan Marion7cd468a2016-12-19 23:05:39 +01006 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at:
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *------------------------------------------------------------------
18 */
19
20#include <vat/vat.h>
jialv01082ebeb2019-09-10 00:23:55 +080021#include <vlib/pci/pci.h>
Neale Ranns86327be2018-11-02 09:14:01 -070022#include <vpp/api/types.h>
Dave Barach59b25652017-09-10 15:04:27 -040023#include <vppinfra/socket.h>
Damjan Marion7cd468a2016-12-19 23:05:39 +010024#include <vlibapi/api.h>
25#include <vlibmemory/api.h>
Damjan Marion7cd468a2016-12-19 23:05:39 +010026#include <vnet/ip/ip.h>
Neale Rannscbe25aa2019-09-30 10:53:31 +000027#include <vnet/ip-neighbor/ip_neighbor.h>
Neale Ranns37029302018-08-10 05:30:06 -070028#include <vnet/ip/ip_types_api.h>
Damjan Marion7cd468a2016-12-19 23:05:39 +010029#include <vnet/l2/l2_input.h>
Damjan Marion7cd468a2016-12-19 23:05:39 +010030#include <vnet/vxlan/vxlan.h>
31#include <vnet/gre/gre.h>
32#include <vnet/vxlan-gpe/vxlan_gpe.h>
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
Neale Ranns5a8844b2019-04-16 07:15:35 +00002399static void vl_api_gre_tunnel_add_del_reply_t_handler
2400 (vl_api_gre_tunnel_add_del_reply_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002401{
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 }
2414}
2415
Neale Ranns5a8844b2019-04-16 07:15:35 +00002416static void vl_api_gre_tunnel_add_del_reply_t_handler_json
2417 (vl_api_gre_tunnel_add_del_reply_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002418{
2419 vat_main_t *vam = &vat_main;
2420 vat_json_node_t node;
2421
2422 vat_json_init_object (&node);
2423 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2424 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2425
2426 vat_json_print (vam->ofp, &node);
2427 vat_json_free (&node);
2428
2429 vam->retval = ntohl (mp->retval);
2430 vam->result_ready = 1;
2431}
2432
2433static void vl_api_create_vhost_user_if_reply_t_handler
2434 (vl_api_create_vhost_user_if_reply_t * mp)
2435{
2436 vat_main_t *vam = &vat_main;
2437 i32 retval = ntohl (mp->retval);
2438 if (vam->async_mode)
2439 {
2440 vam->async_errors += (retval < 0);
2441 }
2442 else
2443 {
2444 vam->retval = retval;
2445 vam->sw_if_index = ntohl (mp->sw_if_index);
2446 vam->result_ready = 1;
2447 }
Dave Barachf72212e2018-01-11 10:25:07 -05002448 vam->regenerate_interface_table = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002449}
2450
2451static void vl_api_create_vhost_user_if_reply_t_handler_json
2452 (vl_api_create_vhost_user_if_reply_t * mp)
2453{
2454 vat_main_t *vam = &vat_main;
2455 vat_json_node_t node;
2456
2457 vat_json_init_object (&node);
2458 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2459 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2460
2461 vat_json_print (vam->ofp, &node);
2462 vat_json_free (&node);
2463
2464 vam->retval = ntohl (mp->retval);
2465 vam->result_ready = 1;
2466}
2467
2468static void vl_api_ip_address_details_t_handler
2469 (vl_api_ip_address_details_t * mp)
2470{
2471 vat_main_t *vam = &vat_main;
2472 static ip_address_details_t empty_ip_address_details = { {0} };
2473 ip_address_details_t *address = NULL;
2474 ip_details_t *current_ip_details = NULL;
2475 ip_details_t *details = NULL;
2476
2477 details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2478
2479 if (!details || vam->current_sw_if_index >= vec_len (details)
2480 || !details[vam->current_sw_if_index].present)
2481 {
2482 errmsg ("ip address details arrived but not stored");
2483 errmsg ("ip_dump should be called first");
2484 return;
2485 }
2486
2487 current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2488
2489#define addresses (current_ip_details->addr)
2490
2491 vec_validate_init_empty (addresses, vec_len (addresses),
2492 empty_ip_address_details);
2493
2494 address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2495
Neale Ranns097fa662018-05-01 05:17:55 -07002496 clib_memcpy (&address->ip, &mp->prefix.address.un, sizeof (address->ip));
Paul Vinciguerraab055082019-06-06 14:07:55 -04002497 address->prefix_length = mp->prefix.len;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002498#undef addresses
2499}
2500
2501static void vl_api_ip_address_details_t_handler_json
2502 (vl_api_ip_address_details_t * mp)
2503{
2504 vat_main_t *vam = &vat_main;
2505 vat_json_node_t *node = NULL;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002506
2507 if (VAT_JSON_ARRAY != vam->json_tree.type)
2508 {
2509 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2510 vat_json_init_array (&vam->json_tree);
2511 }
2512 node = vat_json_array_add (&vam->json_tree);
2513
2514 vat_json_init_object (node);
Neale Ranns097fa662018-05-01 05:17:55 -07002515 vat_json_object_add_prefix (node, &mp->prefix);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002516}
2517
2518static void
2519vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2520{
2521 vat_main_t *vam = &vat_main;
2522 static ip_details_t empty_ip_details = { 0 };
2523 ip_details_t *ip = NULL;
2524 u32 sw_if_index = ~0;
2525
2526 sw_if_index = ntohl (mp->sw_if_index);
2527
2528 vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2529 sw_if_index, empty_ip_details);
2530
2531 ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2532 sw_if_index);
2533
2534 ip->present = 1;
2535}
2536
2537static void
2538vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2539{
2540 vat_main_t *vam = &vat_main;
2541
2542 if (VAT_JSON_ARRAY != vam->json_tree.type)
2543 {
2544 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2545 vat_json_init_array (&vam->json_tree);
2546 }
2547 vat_json_array_add_uint (&vam->json_tree,
2548 clib_net_to_host_u32 (mp->sw_if_index));
2549}
2550
Damjan Marion7cd468a2016-12-19 23:05:39 +01002551static void vl_api_get_first_msg_id_reply_t_handler
2552 (vl_api_get_first_msg_id_reply_t * mp)
2553{
2554 vat_main_t *vam = &vat_main;
2555 i32 retval = ntohl (mp->retval);
2556
2557 if (vam->async_mode)
2558 {
2559 vam->async_errors += (retval < 0);
2560 }
2561 else
2562 {
2563 vam->retval = retval;
2564 vam->result_ready = 1;
2565 }
2566 if (retval >= 0)
2567 {
2568 errmsg ("first message id %d", ntohs (mp->first_msg_id));
2569 }
2570}
2571
2572static void vl_api_get_first_msg_id_reply_t_handler_json
2573 (vl_api_get_first_msg_id_reply_t * mp)
2574{
2575 vat_main_t *vam = &vat_main;
2576 vat_json_node_t node;
2577
2578 vat_json_init_object (&node);
2579 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2580 vat_json_object_add_uint (&node, "first_msg_id",
2581 (uint) ntohs (mp->first_msg_id));
2582
2583 vat_json_print (vam->ofp, &node);
2584 vat_json_free (&node);
2585
2586 vam->retval = ntohl (mp->retval);
2587 vam->result_ready = 1;
2588}
2589
2590static void vl_api_get_node_graph_reply_t_handler
2591 (vl_api_get_node_graph_reply_t * mp)
2592{
2593 vat_main_t *vam = &vat_main;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002594 i32 retval = ntohl (mp->retval);
2595 u8 *pvt_copy, *reply;
2596 void *oldheap;
2597 vlib_node_t *node;
2598 int i;
2599
2600 if (vam->async_mode)
2601 {
2602 vam->async_errors += (retval < 0);
2603 }
2604 else
2605 {
2606 vam->retval = retval;
2607 vam->result_ready = 1;
2608 }
2609
2610 /* "Should never happen..." */
2611 if (retval != 0)
2612 return;
2613
Damjan Marion7bee80c2017-04-26 15:32:12 +02002614 reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002615 pvt_copy = vec_dup (reply);
2616
2617 /* Toss the shared-memory original... */
Nathan Skrzypczak0aa40132019-11-25 16:29:38 +01002618 oldheap = vl_msg_push_heap ();
Damjan Marion7cd468a2016-12-19 23:05:39 +01002619
2620 vec_free (reply);
2621
Nathan Skrzypczak0aa40132019-11-25 16:29:38 +01002622 vl_msg_pop_heap (oldheap);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002623
2624 if (vam->graph_nodes)
2625 {
2626 hash_free (vam->graph_node_index_by_name);
2627
Dave Barach1ddbc012018-06-13 09:26:05 -04002628 for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002629 {
Dave Barach1ddbc012018-06-13 09:26:05 -04002630 node = vam->graph_nodes[0][i];
Damjan Marion7cd468a2016-12-19 23:05:39 +01002631 vec_free (node->name);
2632 vec_free (node->next_nodes);
2633 vec_free (node);
2634 }
Dave Barach1ddbc012018-06-13 09:26:05 -04002635 vec_free (vam->graph_nodes[0]);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002636 vec_free (vam->graph_nodes);
2637 }
2638
2639 vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2640 vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2641 vec_free (pvt_copy);
2642
Dave Barach1ddbc012018-06-13 09:26:05 -04002643 for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002644 {
Dave Barach1ddbc012018-06-13 09:26:05 -04002645 node = vam->graph_nodes[0][i];
Damjan Marion7cd468a2016-12-19 23:05:39 +01002646 hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2647 }
2648}
2649
2650static void vl_api_get_node_graph_reply_t_handler_json
2651 (vl_api_get_node_graph_reply_t * mp)
2652{
2653 vat_main_t *vam = &vat_main;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002654 void *oldheap;
2655 vat_json_node_t node;
2656 u8 *reply;
2657
2658 /* $$$$ make this real? */
2659 vat_json_init_object (&node);
2660 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2661 vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2662
Damjan Marion7bee80c2017-04-26 15:32:12 +02002663 reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002664
2665 /* Toss the shared-memory original... */
Nathan Skrzypczak0aa40132019-11-25 16:29:38 +01002666 oldheap = vl_msg_push_heap ();
Damjan Marion7cd468a2016-12-19 23:05:39 +01002667
2668 vec_free (reply);
2669
Nathan Skrzypczak0aa40132019-11-25 16:29:38 +01002670 vl_msg_pop_heap (oldheap);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002671
2672 vat_json_print (vam->ofp, &node);
2673 vat_json_free (&node);
2674
2675 vam->retval = ntohl (mp->retval);
2676 vam->result_ready = 1;
2677}
2678
Damjan Marion7cd468a2016-12-19 23:05:39 +01002679static u8 *
2680format_policer_type (u8 * s, va_list * va)
2681{
2682 u32 i = va_arg (*va, u32);
2683
2684 if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2685 s = format (s, "1r2c");
2686 else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2687 s = format (s, "1r3c");
2688 else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2689 s = format (s, "2r3c-2698");
2690 else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2691 s = format (s, "2r3c-4115");
2692 else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2693 s = format (s, "2r3c-mef5cf1");
2694 else
2695 s = format (s, "ILLEGAL");
2696 return s;
2697}
2698
2699static u8 *
2700format_policer_rate_type (u8 * s, va_list * va)
2701{
2702 u32 i = va_arg (*va, u32);
2703
2704 if (i == SSE2_QOS_RATE_KBPS)
2705 s = format (s, "kbps");
2706 else if (i == SSE2_QOS_RATE_PPS)
2707 s = format (s, "pps");
2708 else
2709 s = format (s, "ILLEGAL");
2710 return s;
2711}
2712
2713static u8 *
2714format_policer_round_type (u8 * s, va_list * va)
2715{
2716 u32 i = va_arg (*va, u32);
2717
2718 if (i == SSE2_QOS_ROUND_TO_CLOSEST)
2719 s = format (s, "closest");
2720 else if (i == SSE2_QOS_ROUND_TO_UP)
2721 s = format (s, "up");
2722 else if (i == SSE2_QOS_ROUND_TO_DOWN)
2723 s = format (s, "down");
2724 else
2725 s = format (s, "ILLEGAL");
2726 return s;
2727}
2728
2729static u8 *
2730format_policer_action_type (u8 * s, va_list * va)
2731{
2732 u32 i = va_arg (*va, u32);
2733
2734 if (i == SSE2_QOS_ACTION_DROP)
2735 s = format (s, "drop");
2736 else if (i == SSE2_QOS_ACTION_TRANSMIT)
2737 s = format (s, "transmit");
2738 else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2739 s = format (s, "mark-and-transmit");
2740 else
2741 s = format (s, "ILLEGAL");
2742 return s;
2743}
2744
2745static u8 *
2746format_dscp (u8 * s, va_list * va)
2747{
2748 u32 i = va_arg (*va, u32);
2749 char *t = 0;
2750
2751 switch (i)
2752 {
2753#define _(v,f,str) case VNET_DSCP_##f: t = str; break;
2754 foreach_vnet_dscp
2755#undef _
2756 default:
2757 return format (s, "ILLEGAL");
2758 }
2759 s = format (s, "%s", t);
2760 return s;
2761}
2762
2763static void
2764vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
2765{
2766 vat_main_t *vam = &vat_main;
2767 u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
2768
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002769 if (mp->conform_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
2770 conform_dscp_str = format (0, "%U", format_dscp, mp->conform_action.dscp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002771 else
2772 conform_dscp_str = format (0, "");
2773
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002774 if (mp->exceed_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
2775 exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_action.dscp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002776 else
2777 exceed_dscp_str = format (0, "");
2778
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002779 if (mp->violate_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
2780 violate_dscp_str = format (0, "%U", format_dscp, mp->violate_action.dscp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002781 else
2782 violate_dscp_str = format (0, "");
2783
2784 print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
2785 "rate type %U, round type %U, %s rate, %s color-aware, "
2786 "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
2787 "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
2788 "conform action %U%s, exceed action %U%s, violate action %U%s",
2789 mp->name,
2790 format_policer_type, mp->type,
2791 ntohl (mp->cir),
2792 ntohl (mp->eir),
2793 clib_net_to_host_u64 (mp->cb),
2794 clib_net_to_host_u64 (mp->eb),
2795 format_policer_rate_type, mp->rate_type,
2796 format_policer_round_type, mp->round_type,
2797 mp->single_rate ? "single" : "dual",
2798 mp->color_aware ? "is" : "not",
2799 ntohl (mp->cir_tokens_per_period),
2800 ntohl (mp->pir_tokens_per_period),
2801 ntohl (mp->scale),
2802 ntohl (mp->current_limit),
2803 ntohl (mp->current_bucket),
2804 ntohl (mp->extended_limit),
2805 ntohl (mp->extended_bucket),
2806 clib_net_to_host_u64 (mp->last_update_time),
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002807 format_policer_action_type, mp->conform_action.type,
Damjan Marion7cd468a2016-12-19 23:05:39 +01002808 conform_dscp_str,
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002809 format_policer_action_type, mp->exceed_action.type,
Damjan Marion7cd468a2016-12-19 23:05:39 +01002810 exceed_dscp_str,
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002811 format_policer_action_type, mp->violate_action.type,
Damjan Marion7cd468a2016-12-19 23:05:39 +01002812 violate_dscp_str);
2813
2814 vec_free (conform_dscp_str);
2815 vec_free (exceed_dscp_str);
2816 vec_free (violate_dscp_str);
2817}
2818
2819static void vl_api_policer_details_t_handler_json
2820 (vl_api_policer_details_t * mp)
2821{
2822 vat_main_t *vam = &vat_main;
2823 vat_json_node_t *node;
2824 u8 *rate_type_str, *round_type_str, *type_str;
2825 u8 *conform_action_str, *exceed_action_str, *violate_action_str;
2826
2827 rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
2828 round_type_str =
2829 format (0, "%U", format_policer_round_type, mp->round_type);
2830 type_str = format (0, "%U", format_policer_type, mp->type);
2831 conform_action_str = format (0, "%U", format_policer_action_type,
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002832 mp->conform_action.type);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002833 exceed_action_str = format (0, "%U", format_policer_action_type,
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002834 mp->exceed_action.type);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002835 violate_action_str = format (0, "%U", format_policer_action_type,
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002836 mp->violate_action.type);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002837
2838 if (VAT_JSON_ARRAY != vam->json_tree.type)
2839 {
2840 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2841 vat_json_init_array (&vam->json_tree);
2842 }
2843 node = vat_json_array_add (&vam->json_tree);
2844
2845 vat_json_init_object (node);
2846 vat_json_object_add_string_copy (node, "name", mp->name);
2847 vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
2848 vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
Marek Gradzki59ed4902017-03-21 11:51:54 +01002849 vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
2850 vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
Damjan Marion7cd468a2016-12-19 23:05:39 +01002851 vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
2852 vat_json_object_add_string_copy (node, "round_type", round_type_str);
2853 vat_json_object_add_string_copy (node, "type", type_str);
2854 vat_json_object_add_uint (node, "single_rate", mp->single_rate);
2855 vat_json_object_add_uint (node, "color_aware", mp->color_aware);
2856 vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
2857 vat_json_object_add_uint (node, "cir_tokens_per_period",
2858 ntohl (mp->cir_tokens_per_period));
2859 vat_json_object_add_uint (node, "eir_tokens_per_period",
2860 ntohl (mp->pir_tokens_per_period));
2861 vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
2862 vat_json_object_add_uint (node, "current_bucket",
2863 ntohl (mp->current_bucket));
2864 vat_json_object_add_uint (node, "extended_limit",
2865 ntohl (mp->extended_limit));
2866 vat_json_object_add_uint (node, "extended_bucket",
2867 ntohl (mp->extended_bucket));
2868 vat_json_object_add_uint (node, "last_update_time",
2869 ntohl (mp->last_update_time));
2870 vat_json_object_add_string_copy (node, "conform_action",
2871 conform_action_str);
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002872 if (mp->conform_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002873 {
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002874 u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_action.dscp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002875 vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
2876 vec_free (dscp_str);
2877 }
2878 vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002879 if (mp->exceed_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002880 {
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002881 u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_action.dscp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002882 vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
2883 vec_free (dscp_str);
2884 }
2885 vat_json_object_add_string_copy (node, "violate_action",
2886 violate_action_str);
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002887 if (mp->violate_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002888 {
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002889 u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_action.dscp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002890 vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
2891 vec_free (dscp_str);
2892 }
2893
2894 vec_free (rate_type_str);
2895 vec_free (round_type_str);
2896 vec_free (type_str);
2897 vec_free (conform_action_str);
2898 vec_free (exceed_action_str);
2899 vec_free (violate_action_str);
2900}
2901
2902static void
2903vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
2904 mp)
2905{
2906 vat_main_t *vam = &vat_main;
2907 int i, count = ntohl (mp->count);
2908
2909 if (count > 0)
2910 print (vam->ofp, "classify table ids (%d) : ", count);
2911 for (i = 0; i < count; i++)
2912 {
2913 print (vam->ofp, "%d", ntohl (mp->ids[i]));
2914 print (vam->ofp, (i < count - 1) ? "," : "");
2915 }
2916 vam->retval = ntohl (mp->retval);
2917 vam->result_ready = 1;
2918}
2919
2920static void
2921 vl_api_classify_table_ids_reply_t_handler_json
2922 (vl_api_classify_table_ids_reply_t * mp)
2923{
2924 vat_main_t *vam = &vat_main;
2925 int i, count = ntohl (mp->count);
2926
2927 if (count > 0)
2928 {
2929 vat_json_node_t node;
2930
2931 vat_json_init_object (&node);
2932 for (i = 0; i < count; i++)
2933 {
2934 vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
2935 }
2936 vat_json_print (vam->ofp, &node);
2937 vat_json_free (&node);
2938 }
2939 vam->retval = ntohl (mp->retval);
2940 vam->result_ready = 1;
2941}
2942
2943static void
2944 vl_api_classify_table_by_interface_reply_t_handler
2945 (vl_api_classify_table_by_interface_reply_t * mp)
2946{
2947 vat_main_t *vam = &vat_main;
2948 u32 table_id;
2949
2950 table_id = ntohl (mp->l2_table_id);
2951 if (table_id != ~0)
2952 print (vam->ofp, "l2 table id : %d", table_id);
2953 else
2954 print (vam->ofp, "l2 table id : No input ACL tables configured");
2955 table_id = ntohl (mp->ip4_table_id);
2956 if (table_id != ~0)
2957 print (vam->ofp, "ip4 table id : %d", table_id);
2958 else
2959 print (vam->ofp, "ip4 table id : No input ACL tables configured");
2960 table_id = ntohl (mp->ip6_table_id);
2961 if (table_id != ~0)
2962 print (vam->ofp, "ip6 table id : %d", table_id);
2963 else
2964 print (vam->ofp, "ip6 table id : No input ACL tables configured");
2965 vam->retval = ntohl (mp->retval);
2966 vam->result_ready = 1;
2967}
2968
2969static void
2970 vl_api_classify_table_by_interface_reply_t_handler_json
2971 (vl_api_classify_table_by_interface_reply_t * mp)
2972{
2973 vat_main_t *vam = &vat_main;
2974 vat_json_node_t node;
2975
2976 vat_json_init_object (&node);
2977
2978 vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
2979 vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
2980 vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
2981
2982 vat_json_print (vam->ofp, &node);
2983 vat_json_free (&node);
2984
2985 vam->retval = ntohl (mp->retval);
2986 vam->result_ready = 1;
2987}
2988
2989static void vl_api_policer_add_del_reply_t_handler
2990 (vl_api_policer_add_del_reply_t * mp)
2991{
2992 vat_main_t *vam = &vat_main;
2993 i32 retval = ntohl (mp->retval);
2994 if (vam->async_mode)
2995 {
2996 vam->async_errors += (retval < 0);
2997 }
2998 else
2999 {
3000 vam->retval = retval;
3001 vam->result_ready = 1;
3002 if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3003 /*
3004 * Note: this is just barely thread-safe, depends on
3005 * the main thread spinning waiting for an answer...
3006 */
3007 errmsg ("policer index %d", ntohl (mp->policer_index));
3008 }
3009}
3010
3011static void vl_api_policer_add_del_reply_t_handler_json
3012 (vl_api_policer_add_del_reply_t * mp)
3013{
3014 vat_main_t *vam = &vat_main;
3015 vat_json_node_t node;
3016
3017 vat_json_init_object (&node);
3018 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3019 vat_json_object_add_uint (&node, "policer_index",
3020 ntohl (mp->policer_index));
3021
3022 vat_json_print (vam->ofp, &node);
3023 vat_json_free (&node);
3024
3025 vam->retval = ntohl (mp->retval);
3026 vam->result_ready = 1;
3027}
3028
3029/* Format hex dump. */
3030u8 *
3031format_hex_bytes (u8 * s, va_list * va)
3032{
3033 u8 *bytes = va_arg (*va, u8 *);
3034 int n_bytes = va_arg (*va, int);
3035 uword i;
3036
3037 /* Print short or long form depending on byte count. */
3038 uword short_form = n_bytes <= 32;
Christophe Fontained3c008d2017-10-02 18:10:54 +02003039 u32 indent = format_get_indent (s);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003040
3041 if (n_bytes == 0)
3042 return s;
3043
3044 for (i = 0; i < n_bytes; i++)
3045 {
3046 if (!short_form && (i % 32) == 0)
3047 s = format (s, "%08x: ", i);
3048 s = format (s, "%02x", bytes[i]);
3049 if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3050 s = format (s, "\n%U", format_white_space, indent);
3051 }
3052
3053 return s;
3054}
3055
3056static void
3057vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3058 * mp)
3059{
3060 vat_main_t *vam = &vat_main;
3061 i32 retval = ntohl (mp->retval);
3062 if (retval == 0)
3063 {
3064 print (vam->ofp, "classify table info :");
3065 print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
3066 ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3067 ntohl (mp->miss_next_index));
3068 print (vam->ofp, "nbuckets: %d skip: %d match: %d",
3069 ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3070 ntohl (mp->match_n_vectors));
3071 print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
3072 ntohl (mp->mask_length));
3073 }
3074 vam->retval = retval;
3075 vam->result_ready = 1;
3076}
3077
3078static void
3079 vl_api_classify_table_info_reply_t_handler_json
3080 (vl_api_classify_table_info_reply_t * mp)
3081{
3082 vat_main_t *vam = &vat_main;
3083 vat_json_node_t node;
3084
3085 i32 retval = ntohl (mp->retval);
3086 if (retval == 0)
3087 {
3088 vat_json_init_object (&node);
3089
3090 vat_json_object_add_int (&node, "sessions",
3091 ntohl (mp->active_sessions));
3092 vat_json_object_add_int (&node, "nexttbl",
3093 ntohl (mp->next_table_index));
3094 vat_json_object_add_int (&node, "nextnode",
3095 ntohl (mp->miss_next_index));
3096 vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3097 vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3098 vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3099 u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3100 ntohl (mp->mask_length), 0);
3101 vat_json_object_add_string_copy (&node, "mask", s);
3102
3103 vat_json_print (vam->ofp, &node);
3104 vat_json_free (&node);
3105 }
3106 vam->retval = ntohl (mp->retval);
3107 vam->result_ready = 1;
3108}
3109
3110static void
3111vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3112 mp)
3113{
3114 vat_main_t *vam = &vat_main;
3115
3116 print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3117 ntohl (mp->hit_next_index), ntohl (mp->advance),
3118 ntohl (mp->opaque_index));
3119 print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
3120 ntohl (mp->match_length));
3121}
3122
3123static void
3124 vl_api_classify_session_details_t_handler_json
3125 (vl_api_classify_session_details_t * mp)
3126{
3127 vat_main_t *vam = &vat_main;
3128 vat_json_node_t *node = NULL;
3129
3130 if (VAT_JSON_ARRAY != vam->json_tree.type)
3131 {
3132 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3133 vat_json_init_array (&vam->json_tree);
3134 }
3135 node = vat_json_array_add (&vam->json_tree);
3136
3137 vat_json_init_object (node);
3138 vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3139 vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3140 vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3141 u8 *s =
3142 format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3143 0);
3144 vat_json_object_add_string_copy (node, "match", s);
3145}
3146
3147static void vl_api_pg_create_interface_reply_t_handler
3148 (vl_api_pg_create_interface_reply_t * mp)
3149{
3150 vat_main_t *vam = &vat_main;
3151
3152 vam->retval = ntohl (mp->retval);
3153 vam->result_ready = 1;
3154}
3155
3156static void vl_api_pg_create_interface_reply_t_handler_json
3157 (vl_api_pg_create_interface_reply_t * mp)
3158{
3159 vat_main_t *vam = &vat_main;
3160 vat_json_node_t node;
3161
3162 i32 retval = ntohl (mp->retval);
3163 if (retval == 0)
3164 {
3165 vat_json_init_object (&node);
3166
3167 vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3168
3169 vat_json_print (vam->ofp, &node);
3170 vat_json_free (&node);
3171 }
3172 vam->retval = ntohl (mp->retval);
3173 vam->result_ready = 1;
3174}
3175
3176static void vl_api_policer_classify_details_t_handler
3177 (vl_api_policer_classify_details_t * mp)
3178{
3179 vat_main_t *vam = &vat_main;
3180
3181 print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3182 ntohl (mp->table_index));
3183}
3184
3185static void vl_api_policer_classify_details_t_handler_json
3186 (vl_api_policer_classify_details_t * mp)
3187{
3188 vat_main_t *vam = &vat_main;
3189 vat_json_node_t *node;
3190
3191 if (VAT_JSON_ARRAY != vam->json_tree.type)
3192 {
3193 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3194 vat_json_init_array (&vam->json_tree);
3195 }
3196 node = vat_json_array_add (&vam->json_tree);
3197
3198 vat_json_init_object (node);
3199 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3200 vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3201}
3202
Damjan Marion7cd468a2016-12-19 23:05:39 +01003203static void vl_api_flow_classify_details_t_handler
3204 (vl_api_flow_classify_details_t * mp)
3205{
3206 vat_main_t *vam = &vat_main;
3207
3208 print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3209 ntohl (mp->table_index));
3210}
3211
3212static void vl_api_flow_classify_details_t_handler_json
3213 (vl_api_flow_classify_details_t * mp)
3214{
3215 vat_main_t *vam = &vat_main;
3216 vat_json_node_t *node;
3217
3218 if (VAT_JSON_ARRAY != vam->json_tree.type)
3219 {
3220 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3221 vat_json_init_array (&vam->json_tree);
3222 }
3223 node = vat_json_array_add (&vam->json_tree);
3224
3225 vat_json_init_object (node);
3226 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3227 vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3228}
3229
Damjan Marion7cd468a2016-12-19 23:05:39 +01003230/*
3231 * Generate boilerplate reply handlers, which
3232 * dig the return value out of the xxx_reply_t API message,
3233 * stick it into vam->retval, and set vam->result_ready
3234 *
3235 * Could also do this by pointing N message decode slots at
3236 * a single function, but that could break in subtle ways.
3237 */
3238
3239#define foreach_standard_reply_retval_handler \
3240_(sw_interface_set_flags_reply) \
3241_(sw_interface_add_del_address_reply) \
Stevenad8015b2017-10-29 22:10:46 -07003242_(sw_interface_set_rx_mode_reply) \
Mohsin Kazmi54f7c512018-08-23 18:28:11 +02003243_(sw_interface_set_rx_placement_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003244_(sw_interface_set_table_reply) \
3245_(sw_interface_set_mpls_enable_reply) \
3246_(sw_interface_set_vpath_reply) \
3247_(sw_interface_set_vxlan_bypass_reply) \
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +08003248_(sw_interface_set_vxlan_gpe_bypass_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003249_(sw_interface_set_l2_bridge_reply) \
Steven Luonga1876b82019-08-20 16:58:00 -07003250_(sw_interface_set_bond_weight_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003251_(bridge_domain_add_del_reply) \
3252_(sw_interface_set_l2_xconnect_reply) \
3253_(l2fib_add_del_reply) \
Eyal Barif24991c2017-04-05 05:33:21 +03003254_(l2fib_flush_int_reply) \
3255_(l2fib_flush_bd_reply) \
Neale Ranns097fa662018-05-01 05:17:55 -07003256_(ip_route_add_del_reply) \
Neale Ranns28ab9cc2017-08-14 07:18:42 -07003257_(ip_table_add_del_reply) \
Neale Ranns9db6ada2019-11-08 12:42:31 +00003258_(ip_table_replace_begin_reply) \
3259_(ip_table_flush_reply) \
3260_(ip_table_replace_end_reply) \
Neale Ranns32e1c012016-11-22 17:07:28 +00003261_(ip_mroute_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003262_(mpls_route_add_del_reply) \
Neale Ranns28ab9cc2017-08-14 07:18:42 -07003263_(mpls_table_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003264_(mpls_ip_bind_unbind_reply) \
Neale Rannsd792d9c2017-10-21 10:53:20 -07003265_(bier_route_add_del_reply) \
3266_(bier_table_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003267_(sw_interface_set_unnumbered_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003268_(set_ip_flow_hash_reply) \
3269_(sw_interface_ip6_enable_disable_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003270_(l2_patch_add_del_reply) \
John Loe166fd92018-09-13 14:08:59 -04003271_(sr_mpls_policy_add_reply) \
3272_(sr_mpls_policy_mod_reply) \
3273_(sr_mpls_policy_del_reply) \
Pablo Camarillofb380952016-12-07 18:34:18 +01003274_(sr_policy_add_reply) \
3275_(sr_policy_mod_reply) \
3276_(sr_policy_del_reply) \
3277_(sr_localsid_add_del_reply) \
3278_(sr_steering_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003279_(classify_add_del_session_reply) \
3280_(classify_set_interface_ip_table_reply) \
3281_(classify_set_interface_l2_tables_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003282_(l2_fib_clear_table_reply) \
3283_(l2_interface_efp_filter_reply) \
3284_(l2_interface_vlan_tag_rewrite_reply) \
3285_(modify_vhost_user_if_reply) \
3286_(delete_vhost_user_if_reply) \
John Lo8d00fff2017-08-03 00:35:36 -04003287_(want_l2_macs_events_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003288_(input_acl_set_interface_reply) \
3289_(ipsec_spd_add_del_reply) \
3290_(ipsec_interface_add_del_spd_reply) \
Neale Ranns17dcec02019-01-09 21:22:20 -08003291_(ipsec_spd_entry_add_del_reply) \
3292_(ipsec_sad_entry_add_del_reply) \
Matthew Smithb0972cb2017-05-02 16:20:41 -05003293_(ipsec_tunnel_if_add_del_reply) \
Matthew Smithca514fd2017-10-12 12:06:59 -05003294_(ipsec_tunnel_if_set_sa_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003295_(delete_loopback_reply) \
3296_(bd_ip_mac_add_del_reply) \
John Loe26c81f2019-01-07 15:16:33 -05003297_(bd_ip_mac_flush_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003298_(want_interface_events_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003299_(cop_interface_enable_disable_reply) \
3300_(cop_whitelist_enable_disable_reply) \
3301_(sw_interface_clear_stats_reply) \
Dave Barach65457162017-10-10 17:53:14 -04003302_(ioam_enable_reply) \
3303_(ioam_disable_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003304_(af_packet_delete_reply) \
3305_(policer_classify_set_interface_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003306_(set_ipfix_exporter_reply) \
3307_(set_ipfix_classify_stream_reply) \
3308_(ipfix_classify_table_add_del_reply) \
3309_(flow_classify_set_interface_reply) \
3310_(sw_interface_span_enable_disable_reply) \
3311_(pg_capture_reply) \
3312_(pg_enable_disable_reply) \
Mohsin Kazmif382b062020-08-11 15:00:44 +02003313_(pg_interface_enable_disable_coalesce_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003314_(ip_source_and_port_range_check_add_del_reply) \
3315_(ip_source_and_port_range_check_interface_add_del_reply)\
3316_(delete_subif_reply) \
3317_(l2_interface_pbb_tag_rewrite_reply) \
Pavel Kotuceke88865d2018-11-28 07:42:11 +01003318_(set_punt_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003319_(feature_enable_disable_reply) \
Mohsin Kazmi29467b52019-10-08 19:42:38 +02003320_(feature_gso_enable_disable_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003321_(sw_interface_tag_add_del_reply) \
Matthew Smithe0792fd2019-07-12 11:48:24 -05003322_(sw_interface_add_del_mac_address_reply) \
Ole Troand7231612018-06-07 10:17:57 +02003323_(hw_interface_set_mtu_reply) \
Pavel Kotucek6899a302017-06-08 08:46:10 +02003324_(p2p_ethernet_add_reply) \
Steve Shin99a0e602017-07-01 04:16:20 +00003325_(p2p_ethernet_del_reply) \
Florin Corascea194d2017-10-02 00:18:51 -07003326_(tcp_configure_src_addresses_reply) \
Florin Coras595992c2017-11-06 17:17:08 -08003327_(session_rule_add_del_reply) \
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +01003328_(ip_container_proxy_add_del_reply) \
Igor Mikhailov (imichail)582caa32018-04-26 21:33:02 -07003329_(output_acl_set_interface_reply) \
Chenmin Sund0236f72020-07-27 17:54:40 +08003330_(qos_record_enable_disable_reply) \
3331_(flow_add_reply)
Damjan Marion7cd468a2016-12-19 23:05:39 +01003332
3333#define _(n) \
3334 static void vl_api_##n##_t_handler \
3335 (vl_api_##n##_t * mp) \
3336 { \
3337 vat_main_t * vam = &vat_main; \
3338 i32 retval = ntohl(mp->retval); \
3339 if (vam->async_mode) { \
3340 vam->async_errors += (retval < 0); \
3341 } else { \
3342 vam->retval = retval; \
3343 vam->result_ready = 1; \
3344 } \
3345 }
3346foreach_standard_reply_retval_handler;
3347#undef _
3348
3349#define _(n) \
3350 static void vl_api_##n##_t_handler_json \
3351 (vl_api_##n##_t * mp) \
3352 { \
3353 vat_main_t * vam = &vat_main; \
3354 vat_json_node_t node; \
3355 vat_json_init_object(&node); \
3356 vat_json_object_add_int(&node, "retval", ntohl(mp->retval)); \
3357 vat_json_print(vam->ofp, &node); \
3358 vam->retval = ntohl(mp->retval); \
3359 vam->result_ready = 1; \
3360 }
3361foreach_standard_reply_retval_handler;
3362#undef _
3363
3364/*
3365 * Table of message reply handlers, must include boilerplate handlers
3366 * we just generated
3367 */
3368
3369#define foreach_vpe_api_reply_msg \
3370_(CREATE_LOOPBACK_REPLY, create_loopback_reply) \
Jon Loeligerc83c3b72017-02-23 13:57:35 -06003371_(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003372_(SW_INTERFACE_DETAILS, sw_interface_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003373_(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply) \
3374_(CONTROL_PING_REPLY, control_ping_reply) \
3375_(CLI_REPLY, cli_reply) \
3376_(CLI_INBAND_REPLY, cli_inband_reply) \
3377_(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY, \
3378 sw_interface_add_del_address_reply) \
Stevenad8015b2017-10-29 22:10:46 -07003379_(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply) \
Mohsin Kazmi54f7c512018-08-23 18:28:11 +02003380_(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply) \
Mohsin Kazmif0b42f42018-09-10 18:11:00 +02003381_(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003382_(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply) \
3383_(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
3384_(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply) \
3385_(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +08003386_(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003387_(SW_INTERFACE_SET_L2_XCONNECT_REPLY, \
3388 sw_interface_set_l2_xconnect_reply) \
3389_(SW_INTERFACE_SET_L2_BRIDGE_REPLY, \
3390 sw_interface_set_l2_bridge_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003391_(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply) \
3392_(BRIDGE_DOMAIN_DETAILS, bridge_domain_details) \
Eyal Barifead6702017-04-04 04:46:32 +03003393_(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003394_(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply) \
Eyal Barif24991c2017-04-05 05:33:21 +03003395_(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply) \
3396_(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003397_(L2_FLAGS_REPLY, l2_flags_reply) \
3398_(BRIDGE_FLAGS_REPLY, bridge_flags_reply) \
Damjan Marion8389fb92017-10-13 18:29:53 +02003399_(TAP_CREATE_V2_REPLY, tap_create_v2_reply) \
3400_(TAP_DELETE_V2_REPLY, tap_delete_v2_reply) \
3401_(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details) \
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01003402_(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply) \
Mohsin Kazmi518251b2020-09-01 17:17:44 +00003403_(VIRTIO_PCI_CREATE_V2_REPLY, virtio_pci_create_v2_reply) \
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01003404_(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply) \
3405_(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details) \
Steven9cd2d7a2017-12-20 12:43:01 -08003406_(BOND_CREATE_REPLY, bond_create_reply) \
Steven Luongea717862020-07-30 07:31:40 -07003407_(BOND_CREATE2_REPLY, bond_create2_reply) \
Steven9cd2d7a2017-12-20 12:43:01 -08003408_(BOND_DELETE_REPLY, bond_delete_reply) \
Steven Luong4c4223e2020-07-15 08:44:54 -07003409_(BOND_ADD_MEMBER_REPLY, bond_add_member_reply) \
3410_(BOND_DETACH_MEMBER_REPLY, bond_detach_member_reply) \
Steven Luonga1876b82019-08-20 16:58:00 -07003411_(SW_INTERFACE_SET_BOND_WEIGHT_REPLY, sw_interface_set_bond_weight_reply) \
Steven Luong4c4223e2020-07-15 08:44:54 -07003412_(SW_BOND_INTERFACE_DETAILS, sw_bond_interface_details) \
3413_(SW_MEMBER_INTERFACE_DETAILS, sw_member_interface_details) \
Neale Ranns097fa662018-05-01 05:17:55 -07003414_(IP_ROUTE_ADD_DEL_REPLY, ip_route_add_del_reply) \
Neale Ranns28ab9cc2017-08-14 07:18:42 -07003415_(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply) \
Neale Ranns9db6ada2019-11-08 12:42:31 +00003416_(IP_TABLE_REPLACE_BEGIN_REPLY, ip_table_replace_begin_reply) \
3417_(IP_TABLE_FLUSH_REPLY, ip_table_flush_reply) \
3418_(IP_TABLE_REPLACE_END_REPLY, ip_table_replace_end_reply) \
Neale Ranns32e1c012016-11-22 17:07:28 +00003419_(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply) \
Neale Ranns28ab9cc2017-08-14 07:18:42 -07003420_(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003421_(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply) \
3422_(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply) \
Neale Rannsd792d9c2017-10-21 10:53:20 -07003423_(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply) \
3424_(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003425_(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply) \
3426_(SW_INTERFACE_SET_UNNUMBERED_REPLY, \
3427 sw_interface_set_unnumbered_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003428_(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply) \
3429_(CREATE_SUBIF_REPLY, create_subif_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003430_(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply) \
3431_(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY, \
3432 sw_interface_ip6_enable_disable_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003433_(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply) \
John Loe166fd92018-09-13 14:08:59 -04003434_(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply) \
3435_(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply) \
3436_(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply) \
Pablo Camarillofb380952016-12-07 18:34:18 +01003437_(SR_POLICY_ADD_REPLY, sr_policy_add_reply) \
3438_(SR_POLICY_MOD_REPLY, sr_policy_mod_reply) \
3439_(SR_POLICY_DEL_REPLY, sr_policy_del_reply) \
3440_(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply) \
3441_(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003442_(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply) \
3443_(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply) \
3444_(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY, \
3445classify_set_interface_ip_table_reply) \
3446_(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY, \
3447 classify_set_interface_l2_tables_reply) \
3448_(GET_NODE_INDEX_REPLY, get_node_index_reply) \
3449_(ADD_NODE_NEXT_REPLY, add_node_next_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003450_(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply) \
eyal bariaf86a482018-04-17 11:20:27 +03003451_(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003452_(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details) \
Neale Ranns5a8844b2019-04-16 07:15:35 +00003453_(GRE_TUNNEL_ADD_DEL_REPLY, gre_tunnel_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003454_(GRE_TUNNEL_DETAILS, gre_tunnel_details) \
3455_(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply) \
3456_(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply) \
3457_(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3458_(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details) \
3459_(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply) \
3460_(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply) \
3461_(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply) \
3462_(SHOW_VERSION_REPLY, show_version_reply) \
Mohsin Kazmi5d64c782018-09-11 20:27:09 +02003463_(SHOW_THREADS_REPLY, show_threads_reply) \
Ole Troan01384fe2017-05-12 11:55:35 +02003464_(L2_FIB_TABLE_DETAILS, l2_fib_table_details) \
John Loc7b43042018-04-13 16:46:22 -04003465_(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003466_(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details) \
3467_(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply) \
John Lo8d00fff2017-08-03 00:35:36 -04003468_(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply) \
3469_(L2_MACS_EVENT, l2_macs_event) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003470_(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply) \
3471_(IP_ADDRESS_DETAILS, ip_address_details) \
3472_(IP_DETAILS, ip_details) \
3473_(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply) \
3474_(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
Neale Ranns17dcec02019-01-09 21:22:20 -08003475_(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply) \
3476_(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply) \
Matthew Smith28029532017-09-26 13:33:44 -05003477_(IPSEC_SA_DETAILS, ipsec_sa_details) \
Matthew Smithb0972cb2017-05-02 16:20:41 -05003478_(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply) \
Matthew Smithca514fd2017-10-12 12:06:59 -05003479_(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003480_(DELETE_LOOPBACK_REPLY, delete_loopback_reply) \
3481_(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply) \
John Loe26c81f2019-01-07 15:16:33 -05003482_(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply) \
Mohsin Kazmi5d82d2f2018-08-13 19:17:54 +02003483_(BD_IP_MAC_DETAILS, bd_ip_mac_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003484_(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003485_(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply) \
3486_(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
3487_(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
3488_(GET_NODE_GRAPH_REPLY, get_node_graph_reply) \
3489_(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply) \
3490_(IOAM_ENABLE_REPLY, ioam_enable_reply) \
3491_(IOAM_DISABLE_REPLY, ioam_disable_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003492_(AF_PACKET_CREATE_REPLY, af_packet_create_reply) \
3493_(AF_PACKET_DELETE_REPLY, af_packet_delete_reply) \
Mohsin Kazmi04e0bb22018-05-28 18:55:37 +02003494_(AF_PACKET_DETAILS, af_packet_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003495_(POLICER_ADD_DEL_REPLY, policer_add_del_reply) \
3496_(POLICER_DETAILS, policer_details) \
3497_(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3498_(POLICER_CLASSIFY_DETAILS, policer_classify_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003499_(MPLS_TUNNEL_DETAILS, mpls_tunnel_details) \
Neale Ranns097fa662018-05-01 05:17:55 -07003500_(MPLS_TABLE_DETAILS, mpls_table_details) \
3501_(MPLS_ROUTE_DETAILS, mpls_route_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003502_(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply) \
3503_(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3504_(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply) \
3505_(CLASSIFY_SESSION_DETAILS, classify_session_details) \
3506_(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply) \
3507_(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details) \
3508_(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply) \
3509_(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details) \
3510_(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
3511_(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details) \
3512_(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
3513_(FLOW_CLASSIFY_DETAILS, flow_classify_details) \
3514_(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
3515_(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details) \
3516_(GET_NEXT_INDEX_REPLY, get_next_index_reply) \
3517_(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply) \
3518_(PG_CAPTURE_REPLY, pg_capture_reply) \
3519_(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply) \
Mohsin Kazmif382b062020-08-11 15:00:44 +02003520_(PG_INTERFACE_ENABLE_DISABLE_COALESCE_REPLY, pg_interface_enable_disable_coalesce_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003521_(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY, \
3522 ip_source_and_port_range_check_add_del_reply) \
3523_(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY, \
3524 ip_source_and_port_range_check_interface_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003525_(DELETE_SUBIF_REPLY, delete_subif_reply) \
3526_(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
Pavel Kotuceke88865d2018-11-28 07:42:11 +01003527_(SET_PUNT_REPLY, set_punt_reply) \
Neale Ranns097fa662018-05-01 05:17:55 -07003528_(IP_TABLE_DETAILS, ip_table_details) \
3529_(IP_ROUTE_DETAILS, ip_route_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003530_(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply) \
Mohsin Kazmi29467b52019-10-08 19:42:38 +02003531_(FEATURE_GSO_ENABLE_DISABLE_REPLY, feature_gso_enable_disable_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003532_(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply) \
Matthew Smithe0792fd2019-07-12 11:48:24 -05003533_(SW_INTERFACE_ADD_DEL_MAC_ADDRESS_REPLY, sw_interface_add_del_mac_address_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003534_(L2_XCONNECT_DETAILS, l2_xconnect_details) \
Ole Troand7231612018-06-07 10:17:57 +02003535_(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply) \
Pavel Kotucek6899a302017-06-08 08:46:10 +02003536_(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply) \
3537_(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply) \
Steve Shin99a0e602017-07-01 04:16:20 +00003538_(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply) \
Florin Corascea194d2017-10-02 00:18:51 -07003539_(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
Dave Barach65457162017-10-10 17:53:14 -04003540_(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply) \
Florin Coras6c36f532017-11-03 18:32:34 -07003541_(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply) \
Florin Coras595992c2017-11-06 17:17:08 -08003542_(SESSION_RULES_DETAILS, session_rules_details) \
3543_(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply) \
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +01003544_(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply) \
Chenmin Sund0236f72020-07-27 17:54:40 +08003545_(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply) \
3546_(FLOW_ADD_REPLY, flow_add_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003547
Dave Baracha1a093d2017-03-02 13:13:23 -05003548#define foreach_standalone_reply_msg \
Ole Troanf49ba0e2018-11-13 14:04:50 +01003549_(SW_INTERFACE_EVENT, sw_interface_event)
Dave Baracha1a093d2017-03-02 13:13:23 -05003550
Damjan Marion7cd468a2016-12-19 23:05:39 +01003551typedef struct
3552{
3553 u8 *name;
3554 u32 value;
3555} name_sort_t;
3556
Damjan Marion7cd468a2016-12-19 23:05:39 +01003557#define STR_VTR_OP_CASE(op) \
3558 case L2_VTR_ ## op: \
3559 return "" # op;
3560
3561static const char *
3562str_vtr_op (u32 vtr_op)
3563{
3564 switch (vtr_op)
3565 {
3566 STR_VTR_OP_CASE (DISABLED);
3567 STR_VTR_OP_CASE (PUSH_1);
3568 STR_VTR_OP_CASE (PUSH_2);
3569 STR_VTR_OP_CASE (POP_1);
3570 STR_VTR_OP_CASE (POP_2);
3571 STR_VTR_OP_CASE (TRANSLATE_1_1);
3572 STR_VTR_OP_CASE (TRANSLATE_1_2);
3573 STR_VTR_OP_CASE (TRANSLATE_2_1);
3574 STR_VTR_OP_CASE (TRANSLATE_2_2);
3575 }
3576
3577 return "UNKNOWN";
3578}
3579
3580static int
3581dump_sub_interface_table (vat_main_t * vam)
3582{
3583 const sw_interface_subif_t *sub = NULL;
3584
3585 if (vam->json_output)
3586 {
3587 clib_warning
3588 ("JSON output supported only for VPE API calls and dump_stats_table");
3589 return -99;
3590 }
3591
3592 print (vam->ofp,
3593 "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
3594 "Interface", "sw_if_index",
3595 "sub id", "dot1ad", "tags", "outer id",
3596 "inner id", "exact", "default", "outer any", "inner any");
3597
3598 vec_foreach (sub, vam->sw_if_subif_table)
3599 {
3600 print (vam->ofp,
3601 "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
3602 sub->interface_name,
3603 sub->sw_if_index,
3604 sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
3605 sub->sub_number_of_tags, sub->sub_outer_vlan_id,
3606 sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
3607 sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
3608 if (sub->vtr_op != L2_VTR_DISABLED)
3609 {
3610 print (vam->ofp,
3611 " vlan-tag-rewrite - op: %-14s [ dot1q: %d "
3612 "tag1: %d tag2: %d ]",
3613 str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
3614 sub->vtr_tag1, sub->vtr_tag2);
3615 }
3616 }
3617
3618 return 0;
3619}
3620
3621static int
3622name_sort_cmp (void *a1, void *a2)
3623{
3624 name_sort_t *n1 = a1;
3625 name_sort_t *n2 = a2;
3626
3627 return strcmp ((char *) n1->name, (char *) n2->name);
3628}
3629
3630static int
3631dump_interface_table (vat_main_t * vam)
3632{
3633 hash_pair_t *p;
3634 name_sort_t *nses = 0, *ns;
3635
3636 if (vam->json_output)
3637 {
3638 clib_warning
3639 ("JSON output supported only for VPE API calls and dump_stats_table");
3640 return -99;
3641 }
3642
3643 /* *INDENT-OFF* */
3644 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3645 ({
3646 vec_add2 (nses, ns, 1);
3647 ns->name = (u8 *)(p->key);
3648 ns->value = (u32) p->value[0];
3649 }));
3650 /* *INDENT-ON* */
3651
3652 vec_sort_with_function (nses, name_sort_cmp);
3653
3654 print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
3655 vec_foreach (ns, nses)
3656 {
3657 print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
3658 }
3659 vec_free (nses);
3660 return 0;
3661}
3662
3663static int
3664dump_ip_table (vat_main_t * vam, int is_ipv6)
3665{
3666 const ip_details_t *det = NULL;
3667 const ip_address_details_t *address = NULL;
3668 u32 i = ~0;
3669
3670 print (vam->ofp, "%-12s", "sw_if_index");
3671
3672 vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
3673 {
3674 i++;
3675 if (!det->present)
3676 {
3677 continue;
3678 }
3679 print (vam->ofp, "%-12d", i);
3680 print (vam->ofp, " %-30s%-13s", "Address", "Prefix length");
3681 if (!det->addr)
3682 {
3683 continue;
3684 }
3685 vec_foreach (address, det->addr)
3686 {
3687 print (vam->ofp,
3688 " %-30U%-13d",
3689 is_ipv6 ? format_ip6_address : format_ip4_address,
3690 address->ip, address->prefix_length);
3691 }
3692 }
3693
3694 return 0;
3695}
3696
3697static int
3698dump_ipv4_table (vat_main_t * vam)
3699{
3700 if (vam->json_output)
3701 {
3702 clib_warning
3703 ("JSON output supported only for VPE API calls and dump_stats_table");
3704 return -99;
3705 }
3706
3707 return dump_ip_table (vam, 0);
3708}
3709
3710static int
3711dump_ipv6_table (vat_main_t * vam)
3712{
3713 if (vam->json_output)
3714 {
3715 clib_warning
3716 ("JSON output supported only for VPE API calls and dump_stats_table");
3717 return -99;
3718 }
3719
3720 return dump_ip_table (vam, 1);
3721}
3722
Damjan Marion7cd468a2016-12-19 23:05:39 +01003723/*
Dave Barach59b25652017-09-10 15:04:27 -04003724 * Pass CLI buffers directly in the CLI_INBAND API message,
3725 * instead of an additional shared memory area.
Damjan Marion7cd468a2016-12-19 23:05:39 +01003726 */
3727static int
3728exec_inband (vat_main_t * vam)
3729{
3730 vl_api_cli_inband_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003731 unformat_input_t *i = vam->input;
Jon Loeliger56c7b012017-02-01 12:31:41 -06003732 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003733
3734 if (vec_len (i->buffer) == 0)
3735 return -1;
3736
3737 if (vam->exec_mode == 0 && unformat (i, "mode"))
3738 {
3739 vam->exec_mode = 1;
3740 return 0;
3741 }
3742 if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
3743 {
3744 vam->exec_mode = 0;
3745 return 0;
3746 }
3747
3748 /*
3749 * In order for the CLI command to work, it
3750 * must be a vector ending in \n, not a C-string ending
3751 * in \n\0.
3752 */
Jakub Grajciar2dbee932020-02-07 11:30:26 +01003753 M2 (CLI_INBAND, mp, vec_len (vam->input->buffer));
3754 vl_api_vec_to_api_string (vam->input->buffer, &mp->cmd);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003755
Jon Loeliger7bc770c2017-01-31 14:03:33 -06003756 S (mp);
Dave Barach59b25652017-09-10 15:04:27 -04003757 W (ret);
3758 /* json responses may or may not include a useful reply... */
3759 if (vec_len (vam->cmd_reply))
Dave Barachcf5e8482017-10-17 11:48:29 -04003760 print (vam->ofp, "%v", (char *) (vam->cmd_reply));
Jon Loeliger56c7b012017-02-01 12:31:41 -06003761 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003762}
3763
Dave Barach59b25652017-09-10 15:04:27 -04003764int
3765exec (vat_main_t * vam)
3766{
3767 return exec_inband (vam);
3768}
3769
Damjan Marion7cd468a2016-12-19 23:05:39 +01003770static int
3771api_create_loopback (vat_main_t * vam)
3772{
3773 unformat_input_t *i = vam->input;
3774 vl_api_create_loopback_t *mp;
Jon Loeligerc83c3b72017-02-23 13:57:35 -06003775 vl_api_create_loopback_instance_t *mp_lbi;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003776 u8 mac_address[6];
3777 u8 mac_set = 0;
Jon Loeligerc83c3b72017-02-23 13:57:35 -06003778 u8 is_specified = 0;
3779 u32 user_instance = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06003780 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003781
Dave Barachb7b92992018-10-17 10:38:51 -04003782 clib_memset (mac_address, 0, sizeof (mac_address));
Damjan Marion7cd468a2016-12-19 23:05:39 +01003783
3784 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3785 {
3786 if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
3787 mac_set = 1;
Jon Loeligerc83c3b72017-02-23 13:57:35 -06003788 if (unformat (i, "instance %d", &user_instance))
3789 is_specified = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003790 else
3791 break;
3792 }
3793
Jon Loeligerc83c3b72017-02-23 13:57:35 -06003794 if (is_specified)
3795 {
3796 M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
3797 mp_lbi->is_specified = is_specified;
3798 if (is_specified)
3799 mp_lbi->user_instance = htonl (user_instance);
3800 if (mac_set)
3801 clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
3802 S (mp_lbi);
3803 }
3804 else
3805 {
3806 /* Construct the API message */
3807 M (CREATE_LOOPBACK, mp);
3808 if (mac_set)
3809 clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
3810 S (mp);
3811 }
Damjan Marion7cd468a2016-12-19 23:05:39 +01003812
Jon Loeliger56c7b012017-02-01 12:31:41 -06003813 W (ret);
3814 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003815}
3816
3817static int
3818api_delete_loopback (vat_main_t * vam)
3819{
3820 unformat_input_t *i = vam->input;
3821 vl_api_delete_loopback_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003822 u32 sw_if_index = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06003823 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003824
3825 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3826 {
3827 if (unformat (i, "sw_if_index %d", &sw_if_index))
3828 ;
3829 else
3830 break;
3831 }
3832
3833 if (sw_if_index == ~0)
3834 {
3835 errmsg ("missing sw_if_index");
3836 return -99;
3837 }
3838
3839 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06003840 M (DELETE_LOOPBACK, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003841 mp->sw_if_index = ntohl (sw_if_index);
3842
Jon Loeliger7bc770c2017-01-31 14:03:33 -06003843 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06003844 W (ret);
3845 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003846}
3847
3848static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01003849api_want_interface_events (vat_main_t * vam)
3850{
3851 unformat_input_t *i = vam->input;
3852 vl_api_want_interface_events_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003853 int enable = -1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06003854 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003855
3856 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3857 {
3858 if (unformat (i, "enable"))
3859 enable = 1;
3860 else if (unformat (i, "disable"))
3861 enable = 0;
3862 else
3863 break;
3864 }
3865
3866 if (enable == -1)
3867 {
3868 errmsg ("missing enable|disable");
3869 return -99;
3870 }
3871
Jon Loeliger8a2aea32017-01-31 13:19:40 -06003872 M (WANT_INTERFACE_EVENTS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003873 mp->enable_disable = enable;
3874
3875 vam->interface_event_display = enable;
3876
Jon Loeliger7bc770c2017-01-31 14:03:33 -06003877 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06003878 W (ret);
3879 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003880}
3881
3882
3883/* Note: non-static, called once to set up the initial intfc table */
3884int
3885api_sw_interface_dump (vat_main_t * vam)
3886{
3887 vl_api_sw_interface_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -06003888 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003889 hash_pair_t *p;
3890 name_sort_t *nses = 0, *ns;
3891 sw_interface_subif_t *sub = NULL;
Jon Loeliger56c7b012017-02-01 12:31:41 -06003892 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003893
3894 /* Toss the old name table */
3895 /* *INDENT-OFF* */
3896 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3897 ({
3898 vec_add2 (nses, ns, 1);
3899 ns->name = (u8 *)(p->key);
3900 ns->value = (u32) p->value[0];
3901 }));
3902 /* *INDENT-ON* */
3903
3904 hash_free (vam->sw_if_index_by_interface_name);
3905
3906 vec_foreach (ns, nses) vec_free (ns->name);
3907
3908 vec_free (nses);
3909
3910 vec_foreach (sub, vam->sw_if_subif_table)
3911 {
3912 vec_free (sub->interface_name);
3913 }
3914 vec_free (vam->sw_if_subif_table);
3915
3916 /* recreate the interface name hash table */
3917 vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
3918
Dave Barachf72212e2018-01-11 10:25:07 -05003919 /*
3920 * Ask for all interface names. Otherwise, the epic catalog of
3921 * name filters becomes ridiculously long, and vat ends up needing
3922 * to be taught about new interface types.
3923 */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06003924 M (SW_INTERFACE_DUMP, mp);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06003925 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003926
3927 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -04003928 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06003929 S (mp_ping);
3930
Jon Loeliger56c7b012017-02-01 12:31:41 -06003931 W (ret);
3932 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003933}
3934
3935static int
3936api_sw_interface_set_flags (vat_main_t * vam)
3937{
3938 unformat_input_t *i = vam->input;
3939 vl_api_sw_interface_set_flags_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003940 u32 sw_if_index;
3941 u8 sw_if_index_set = 0;
Neale Rannsa07bd702017-08-07 07:53:49 -07003942 u8 admin_up = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06003943 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003944
3945 /* Parse args required to build the message */
3946 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3947 {
3948 if (unformat (i, "admin-up"))
3949 admin_up = 1;
3950 else if (unformat (i, "admin-down"))
3951 admin_up = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003952 else
3953 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
3954 sw_if_index_set = 1;
3955 else if (unformat (i, "sw_if_index %d", &sw_if_index))
3956 sw_if_index_set = 1;
3957 else
3958 break;
3959 }
3960
3961 if (sw_if_index_set == 0)
3962 {
3963 errmsg ("missing interface name or sw_if_index");
3964 return -99;
3965 }
3966
3967 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06003968 M (SW_INTERFACE_SET_FLAGS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003969 mp->sw_if_index = ntohl (sw_if_index);
Jakub Grajciar053204a2019-03-18 13:17:53 +01003970 mp->flags = ntohl ((admin_up) ? IF_STATUS_API_FLAG_ADMIN_UP : 0);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003971
3972 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06003973 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003974
3975 /* Wait for a reply, return the good/bad news... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06003976 W (ret);
3977 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003978}
3979
3980static int
Stevenad8015b2017-10-29 22:10:46 -07003981api_sw_interface_set_rx_mode (vat_main_t * vam)
3982{
3983 unformat_input_t *i = vam->input;
3984 vl_api_sw_interface_set_rx_mode_t *mp;
3985 u32 sw_if_index;
3986 u8 sw_if_index_set = 0;
3987 int ret;
3988 u8 queue_id_valid = 0;
3989 u32 queue_id;
Damjan Marioneabd4242020-10-07 20:59:07 +02003990 vnet_hw_if_rx_mode mode = VNET_HW_IF_RX_MODE_UNKNOWN;
Stevenad8015b2017-10-29 22:10:46 -07003991
3992 /* Parse args required to build the message */
3993 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3994 {
3995 if (unformat (i, "queue %d", &queue_id))
3996 queue_id_valid = 1;
3997 else if (unformat (i, "polling"))
Damjan Marioneabd4242020-10-07 20:59:07 +02003998 mode = VNET_HW_IF_RX_MODE_POLLING;
Stevenad8015b2017-10-29 22:10:46 -07003999 else if (unformat (i, "interrupt"))
Damjan Marioneabd4242020-10-07 20:59:07 +02004000 mode = VNET_HW_IF_RX_MODE_INTERRUPT;
Stevenad8015b2017-10-29 22:10:46 -07004001 else if (unformat (i, "adaptive"))
Damjan Marioneabd4242020-10-07 20:59:07 +02004002 mode = VNET_HW_IF_RX_MODE_ADAPTIVE;
Stevenad8015b2017-10-29 22:10:46 -07004003 else
4004 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4005 sw_if_index_set = 1;
4006 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4007 sw_if_index_set = 1;
4008 else
4009 break;
4010 }
4011
4012 if (sw_if_index_set == 0)
4013 {
4014 errmsg ("missing interface name or sw_if_index");
4015 return -99;
4016 }
Damjan Marioneabd4242020-10-07 20:59:07 +02004017 if (mode == VNET_HW_IF_RX_MODE_UNKNOWN)
Stevenad8015b2017-10-29 22:10:46 -07004018 {
4019 errmsg ("missing rx-mode");
4020 return -99;
4021 }
4022
4023 /* Construct the API message */
4024 M (SW_INTERFACE_SET_RX_MODE, mp);
4025 mp->sw_if_index = ntohl (sw_if_index);
Jakub Grajciar053204a2019-03-18 13:17:53 +01004026 mp->mode = (vl_api_rx_mode_t) mode;
Stevenad8015b2017-10-29 22:10:46 -07004027 mp->queue_id_valid = queue_id_valid;
4028 mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
4029
4030 /* send it... */
4031 S (mp);
4032
4033 /* Wait for a reply, return the good/bad news... */
4034 W (ret);
4035 return ret;
4036}
4037
4038static int
Mohsin Kazmi54f7c512018-08-23 18:28:11 +02004039api_sw_interface_set_rx_placement (vat_main_t * vam)
4040{
4041 unformat_input_t *i = vam->input;
4042 vl_api_sw_interface_set_rx_placement_t *mp;
4043 u32 sw_if_index;
4044 u8 sw_if_index_set = 0;
4045 int ret;
4046 u8 is_main = 0;
4047 u32 queue_id, thread_index;
4048
4049 /* Parse args required to build the message */
4050 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4051 {
4052 if (unformat (i, "queue %d", &queue_id))
4053 ;
4054 else if (unformat (i, "main"))
4055 is_main = 1;
4056 else if (unformat (i, "worker %d", &thread_index))
4057 ;
4058 else
4059 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4060 sw_if_index_set = 1;
4061 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4062 sw_if_index_set = 1;
4063 else
4064 break;
4065 }
4066
4067 if (sw_if_index_set == 0)
4068 {
4069 errmsg ("missing interface name or sw_if_index");
4070 return -99;
4071 }
4072
4073 if (is_main)
4074 thread_index = 0;
4075 /* Construct the API message */
4076 M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
4077 mp->sw_if_index = ntohl (sw_if_index);
4078 mp->worker_id = ntohl (thread_index);
4079 mp->queue_id = ntohl (queue_id);
4080 mp->is_main = is_main;
4081
4082 /* send it... */
4083 S (mp);
4084 /* Wait for a reply, return the good/bad news... */
4085 W (ret);
4086 return ret;
4087}
4088
Mohsin Kazmif0b42f42018-09-10 18:11:00 +02004089static void vl_api_sw_interface_rx_placement_details_t_handler
4090 (vl_api_sw_interface_rx_placement_details_t * mp)
4091{
4092 vat_main_t *vam = &vat_main;
4093 u32 worker_id = ntohl (mp->worker_id);
4094
4095 print (vam->ofp,
4096 "\n%-11d %-11s %-6d %-5d %-9s",
4097 ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
4098 worker_id, ntohl (mp->queue_id),
4099 (mp->mode ==
4100 1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
4101}
4102
4103static void vl_api_sw_interface_rx_placement_details_t_handler_json
4104 (vl_api_sw_interface_rx_placement_details_t * mp)
4105{
4106 vat_main_t *vam = &vat_main;
4107 vat_json_node_t *node = NULL;
4108
4109 if (VAT_JSON_ARRAY != vam->json_tree.type)
4110 {
4111 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4112 vat_json_init_array (&vam->json_tree);
4113 }
4114 node = vat_json_array_add (&vam->json_tree);
4115
4116 vat_json_init_object (node);
4117 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4118 vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
4119 vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
4120 vat_json_object_add_uint (node, "mode", mp->mode);
4121}
4122
4123static int
4124api_sw_interface_rx_placement_dump (vat_main_t * vam)
4125{
4126 unformat_input_t *i = vam->input;
4127 vl_api_sw_interface_rx_placement_dump_t *mp;
4128 vl_api_control_ping_t *mp_ping;
4129 int ret;
4130 u32 sw_if_index;
4131 u8 sw_if_index_set = 0;
4132
4133 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4134 {
4135 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4136 sw_if_index_set++;
4137 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4138 sw_if_index_set++;
4139 else
4140 break;
4141 }
4142
4143 print (vam->ofp,
4144 "\n%-11s %-11s %-6s %-5s %-4s",
4145 "sw_if_index", "main/worker", "thread", "queue", "mode");
4146
4147 /* Dump Interface rx placement */
4148 M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
4149
4150 if (sw_if_index_set)
4151 mp->sw_if_index = htonl (sw_if_index);
4152 else
4153 mp->sw_if_index = ~0;
4154
4155 S (mp);
4156
4157 /* Use a control ping for synchronization */
4158 MPING (CONTROL_PING, mp_ping);
4159 S (mp_ping);
4160
4161 W (ret);
4162 return ret;
4163}
4164
Mohsin Kazmi54f7c512018-08-23 18:28:11 +02004165static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01004166api_sw_interface_clear_stats (vat_main_t * vam)
4167{
4168 unformat_input_t *i = vam->input;
4169 vl_api_sw_interface_clear_stats_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004170 u32 sw_if_index;
4171 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004172 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004173
4174 /* Parse args required to build the message */
4175 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4176 {
4177 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4178 sw_if_index_set = 1;
4179 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4180 sw_if_index_set = 1;
4181 else
4182 break;
4183 }
4184
4185 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004186 M (SW_INTERFACE_CLEAR_STATS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004187
4188 if (sw_if_index_set == 1)
4189 mp->sw_if_index = ntohl (sw_if_index);
4190 else
4191 mp->sw_if_index = ~0;
4192
4193 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004194 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004195
4196 /* Wait for a reply, return the good/bad news... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06004197 W (ret);
4198 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004199}
4200
Damjan Marion7cd468a2016-12-19 23:05:39 +01004201static int
4202api_sw_interface_add_del_address (vat_main_t * vam)
4203{
4204 unformat_input_t *i = vam->input;
4205 vl_api_sw_interface_add_del_address_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004206 u32 sw_if_index;
4207 u8 sw_if_index_set = 0;
4208 u8 is_add = 1, del_all = 0;
4209 u32 address_length = 0;
4210 u8 v4_address_set = 0;
4211 u8 v6_address_set = 0;
4212 ip4_address_t v4address;
4213 ip6_address_t v6address;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004214 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004215
4216 /* Parse args required to build the message */
4217 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4218 {
4219 if (unformat (i, "del-all"))
4220 del_all = 1;
4221 else if (unformat (i, "del"))
4222 is_add = 0;
4223 else
4224 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4225 sw_if_index_set = 1;
4226 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4227 sw_if_index_set = 1;
4228 else if (unformat (i, "%U/%d",
4229 unformat_ip4_address, &v4address, &address_length))
4230 v4_address_set = 1;
4231 else if (unformat (i, "%U/%d",
4232 unformat_ip6_address, &v6address, &address_length))
4233 v6_address_set = 1;
4234 else
4235 break;
4236 }
4237
4238 if (sw_if_index_set == 0)
4239 {
4240 errmsg ("missing interface name or sw_if_index");
4241 return -99;
4242 }
4243 if (v4_address_set && v6_address_set)
4244 {
4245 errmsg ("both v4 and v6 addresses set");
4246 return -99;
4247 }
4248 if (!v4_address_set && !v6_address_set && !del_all)
4249 {
4250 errmsg ("no addresses set");
4251 return -99;
4252 }
4253
4254 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004255 M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004256
4257 mp->sw_if_index = ntohl (sw_if_index);
4258 mp->is_add = is_add;
4259 mp->del_all = del_all;
4260 if (v6_address_set)
4261 {
Jakub Grajciar053204a2019-03-18 13:17:53 +01004262 mp->prefix.address.af = ADDRESS_IP6;
4263 clib_memcpy (mp->prefix.address.un.ip6, &v6address, sizeof (v6address));
Damjan Marion7cd468a2016-12-19 23:05:39 +01004264 }
4265 else
4266 {
Jakub Grajciar053204a2019-03-18 13:17:53 +01004267 mp->prefix.address.af = ADDRESS_IP4;
4268 clib_memcpy (mp->prefix.address.un.ip4, &v4address, sizeof (v4address));
Damjan Marion7cd468a2016-12-19 23:05:39 +01004269 }
Jakub Grajciar053204a2019-03-18 13:17:53 +01004270 mp->prefix.len = address_length;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004271
4272 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004273 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004274
4275 /* Wait for a reply, return good/bad news */
Jon Loeliger56c7b012017-02-01 12:31:41 -06004276 W (ret);
4277 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004278}
4279
4280static int
4281api_sw_interface_set_mpls_enable (vat_main_t * vam)
4282{
4283 unformat_input_t *i = vam->input;
4284 vl_api_sw_interface_set_mpls_enable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004285 u32 sw_if_index;
4286 u8 sw_if_index_set = 0;
4287 u8 enable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004288 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004289
4290 /* Parse args required to build the message */
4291 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4292 {
4293 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4294 sw_if_index_set = 1;
4295 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4296 sw_if_index_set = 1;
4297 else if (unformat (i, "disable"))
4298 enable = 0;
4299 else if (unformat (i, "dis"))
4300 enable = 0;
4301 else
4302 break;
4303 }
4304
4305 if (sw_if_index_set == 0)
4306 {
4307 errmsg ("missing interface name or sw_if_index");
4308 return -99;
4309 }
4310
4311 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004312 M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004313
4314 mp->sw_if_index = ntohl (sw_if_index);
4315 mp->enable = enable;
4316
4317 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004318 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004319
4320 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06004321 W (ret);
4322 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004323}
4324
4325static int
4326api_sw_interface_set_table (vat_main_t * vam)
4327{
4328 unformat_input_t *i = vam->input;
4329 vl_api_sw_interface_set_table_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004330 u32 sw_if_index, vrf_id = 0;
4331 u8 sw_if_index_set = 0;
4332 u8 is_ipv6 = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004333 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004334
4335 /* Parse args required to build the message */
4336 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4337 {
4338 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4339 sw_if_index_set = 1;
4340 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4341 sw_if_index_set = 1;
4342 else if (unformat (i, "vrf %d", &vrf_id))
4343 ;
4344 else if (unformat (i, "ipv6"))
4345 is_ipv6 = 1;
4346 else
4347 break;
4348 }
4349
4350 if (sw_if_index_set == 0)
4351 {
4352 errmsg ("missing interface name or sw_if_index");
4353 return -99;
4354 }
4355
4356 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004357 M (SW_INTERFACE_SET_TABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004358
4359 mp->sw_if_index = ntohl (sw_if_index);
4360 mp->is_ipv6 = is_ipv6;
4361 mp->vrf_id = ntohl (vrf_id);
4362
4363 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004364 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004365
4366 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06004367 W (ret);
4368 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004369}
4370
4371static void vl_api_sw_interface_get_table_reply_t_handler
4372 (vl_api_sw_interface_get_table_reply_t * mp)
4373{
4374 vat_main_t *vam = &vat_main;
4375
4376 print (vam->ofp, "%d", ntohl (mp->vrf_id));
4377
4378 vam->retval = ntohl (mp->retval);
4379 vam->result_ready = 1;
4380
4381}
4382
4383static void vl_api_sw_interface_get_table_reply_t_handler_json
4384 (vl_api_sw_interface_get_table_reply_t * mp)
4385{
4386 vat_main_t *vam = &vat_main;
4387 vat_json_node_t node;
4388
4389 vat_json_init_object (&node);
4390 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4391 vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
4392
4393 vat_json_print (vam->ofp, &node);
4394 vat_json_free (&node);
4395
4396 vam->retval = ntohl (mp->retval);
4397 vam->result_ready = 1;
4398}
4399
4400static int
4401api_sw_interface_get_table (vat_main_t * vam)
4402{
4403 unformat_input_t *i = vam->input;
4404 vl_api_sw_interface_get_table_t *mp;
4405 u32 sw_if_index;
4406 u8 sw_if_index_set = 0;
4407 u8 is_ipv6 = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004408 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004409
4410 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4411 {
4412 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4413 sw_if_index_set = 1;
4414 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4415 sw_if_index_set = 1;
4416 else if (unformat (i, "ipv6"))
4417 is_ipv6 = 1;
4418 else
4419 break;
4420 }
4421
4422 if (sw_if_index_set == 0)
4423 {
4424 errmsg ("missing interface name or sw_if_index");
4425 return -99;
4426 }
4427
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004428 M (SW_INTERFACE_GET_TABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004429 mp->sw_if_index = htonl (sw_if_index);
4430 mp->is_ipv6 = is_ipv6;
4431
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004432 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06004433 W (ret);
4434 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004435}
4436
4437static int
4438api_sw_interface_set_vpath (vat_main_t * vam)
4439{
4440 unformat_input_t *i = vam->input;
4441 vl_api_sw_interface_set_vpath_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004442 u32 sw_if_index = 0;
4443 u8 sw_if_index_set = 0;
4444 u8 is_enable = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004445 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004446
4447 /* Parse args required to build the message */
4448 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4449 {
4450 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4451 sw_if_index_set = 1;
4452 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4453 sw_if_index_set = 1;
4454 else if (unformat (i, "enable"))
4455 is_enable = 1;
4456 else if (unformat (i, "disable"))
4457 is_enable = 0;
4458 else
4459 break;
4460 }
4461
4462 if (sw_if_index_set == 0)
4463 {
4464 errmsg ("missing interface name or sw_if_index");
4465 return -99;
4466 }
4467
4468 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004469 M (SW_INTERFACE_SET_VPATH, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004470
4471 mp->sw_if_index = ntohl (sw_if_index);
4472 mp->enable = is_enable;
4473
4474 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004475 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004476
4477 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06004478 W (ret);
4479 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004480}
4481
4482static int
4483api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
4484{
4485 unformat_input_t *i = vam->input;
4486 vl_api_sw_interface_set_vxlan_bypass_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004487 u32 sw_if_index = 0;
4488 u8 sw_if_index_set = 0;
John Lo2b81eb82017-01-30 13:12:10 -05004489 u8 is_enable = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004490 u8 is_ipv6 = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004491 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004492
4493 /* Parse args required to build the message */
4494 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4495 {
4496 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4497 sw_if_index_set = 1;
4498 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4499 sw_if_index_set = 1;
4500 else if (unformat (i, "enable"))
4501 is_enable = 1;
4502 else if (unformat (i, "disable"))
4503 is_enable = 0;
4504 else if (unformat (i, "ip4"))
4505 is_ipv6 = 0;
4506 else if (unformat (i, "ip6"))
4507 is_ipv6 = 1;
4508 else
4509 break;
4510 }
4511
4512 if (sw_if_index_set == 0)
4513 {
4514 errmsg ("missing interface name or sw_if_index");
4515 return -99;
4516 }
4517
4518 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004519 M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004520
4521 mp->sw_if_index = ntohl (sw_if_index);
4522 mp->enable = is_enable;
4523 mp->is_ipv6 = is_ipv6;
4524
4525 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004526 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004527
4528 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06004529 W (ret);
4530 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004531}
4532
Marco Varleseb598f1d2017-09-19 14:25:28 +02004533static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01004534api_sw_interface_set_l2_xconnect (vat_main_t * vam)
4535{
4536 unformat_input_t *i = vam->input;
4537 vl_api_sw_interface_set_l2_xconnect_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004538 u32 rx_sw_if_index;
4539 u8 rx_sw_if_index_set = 0;
4540 u32 tx_sw_if_index;
4541 u8 tx_sw_if_index_set = 0;
4542 u8 enable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004543 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004544
4545 /* Parse args required to build the message */
4546 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4547 {
4548 if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
4549 rx_sw_if_index_set = 1;
4550 else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
4551 tx_sw_if_index_set = 1;
4552 else if (unformat (i, "rx"))
4553 {
4554 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4555 {
4556 if (unformat (i, "%U", api_unformat_sw_if_index, vam,
4557 &rx_sw_if_index))
4558 rx_sw_if_index_set = 1;
4559 }
4560 else
4561 break;
4562 }
4563 else if (unformat (i, "tx"))
4564 {
4565 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4566 {
4567 if (unformat (i, "%U", api_unformat_sw_if_index, vam,
4568 &tx_sw_if_index))
4569 tx_sw_if_index_set = 1;
4570 }
4571 else
4572 break;
4573 }
4574 else if (unformat (i, "enable"))
4575 enable = 1;
4576 else if (unformat (i, "disable"))
4577 enable = 0;
4578 else
4579 break;
4580 }
4581
4582 if (rx_sw_if_index_set == 0)
4583 {
4584 errmsg ("missing rx interface name or rx_sw_if_index");
4585 return -99;
4586 }
4587
4588 if (enable && (tx_sw_if_index_set == 0))
4589 {
4590 errmsg ("missing tx interface name or tx_sw_if_index");
4591 return -99;
4592 }
4593
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004594 M (SW_INTERFACE_SET_L2_XCONNECT, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004595
4596 mp->rx_sw_if_index = ntohl (rx_sw_if_index);
4597 mp->tx_sw_if_index = ntohl (tx_sw_if_index);
4598 mp->enable = enable;
4599
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004600 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06004601 W (ret);
4602 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004603}
4604
4605static int
4606api_sw_interface_set_l2_bridge (vat_main_t * vam)
4607{
4608 unformat_input_t *i = vam->input;
4609 vl_api_sw_interface_set_l2_bridge_t *mp;
Neale Rannsb4743802018-09-05 09:13:57 -07004610 vl_api_l2_port_type_t port_type;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004611 u32 rx_sw_if_index;
4612 u8 rx_sw_if_index_set = 0;
4613 u32 bd_id;
4614 u8 bd_id_set = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004615 u32 shg = 0;
4616 u8 enable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004617 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004618
Neale Rannsb4743802018-09-05 09:13:57 -07004619 port_type = L2_API_PORT_TYPE_NORMAL;
4620
Damjan Marion7cd468a2016-12-19 23:05:39 +01004621 /* Parse args required to build the message */
4622 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4623 {
4624 if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
4625 rx_sw_if_index_set = 1;
4626 else if (unformat (i, "bd_id %d", &bd_id))
4627 bd_id_set = 1;
4628 else
4629 if (unformat
4630 (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
4631 rx_sw_if_index_set = 1;
4632 else if (unformat (i, "shg %d", &shg))
4633 ;
4634 else if (unformat (i, "bvi"))
Neale Rannsb4743802018-09-05 09:13:57 -07004635 port_type = L2_API_PORT_TYPE_BVI;
4636 else if (unformat (i, "uu-fwd"))
4637 port_type = L2_API_PORT_TYPE_UU_FWD;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004638 else if (unformat (i, "enable"))
4639 enable = 1;
4640 else if (unformat (i, "disable"))
4641 enable = 0;
4642 else
4643 break;
4644 }
4645
4646 if (rx_sw_if_index_set == 0)
4647 {
4648 errmsg ("missing rx interface name or sw_if_index");
4649 return -99;
4650 }
4651
4652 if (enable && (bd_id_set == 0))
4653 {
4654 errmsg ("missing bridge domain");
4655 return -99;
4656 }
4657
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004658 M (SW_INTERFACE_SET_L2_BRIDGE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004659
4660 mp->rx_sw_if_index = ntohl (rx_sw_if_index);
4661 mp->bd_id = ntohl (bd_id);
4662 mp->shg = (u8) shg;
Neale Rannsb4743802018-09-05 09:13:57 -07004663 mp->port_type = ntohl (port_type);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004664 mp->enable = enable;
4665
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004666 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06004667 W (ret);
4668 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004669}
4670
4671static int
4672api_bridge_domain_dump (vat_main_t * vam)
4673{
4674 unformat_input_t *i = vam->input;
4675 vl_api_bridge_domain_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -06004676 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004677 u32 bd_id = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004678 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004679
4680 /* Parse args required to build the message */
4681 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4682 {
4683 if (unformat (i, "bd_id %d", &bd_id))
4684 ;
4685 else
4686 break;
4687 }
4688
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004689 M (BRIDGE_DOMAIN_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004690 mp->bd_id = ntohl (bd_id);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004691 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004692
4693 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -04004694 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06004695 S (mp_ping);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004696
Jon Loeliger56c7b012017-02-01 12:31:41 -06004697 W (ret);
4698 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004699}
4700
4701static int
4702api_bridge_domain_add_del (vat_main_t * vam)
4703{
4704 unformat_input_t *i = vam->input;
4705 vl_api_bridge_domain_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004706 u32 bd_id = ~0;
4707 u8 is_add = 1;
4708 u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
Jerome Tollet50570ec2017-09-14 12:53:56 +01004709 u8 *bd_tag = NULL;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004710 u32 mac_age = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004711 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004712
4713 /* Parse args required to build the message */
4714 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4715 {
4716 if (unformat (i, "bd_id %d", &bd_id))
4717 ;
4718 else if (unformat (i, "flood %d", &flood))
4719 ;
4720 else if (unformat (i, "uu-flood %d", &uu_flood))
4721 ;
4722 else if (unformat (i, "forward %d", &forward))
4723 ;
4724 else if (unformat (i, "learn %d", &learn))
4725 ;
4726 else if (unformat (i, "arp-term %d", &arp_term))
4727 ;
4728 else if (unformat (i, "mac-age %d", &mac_age))
4729 ;
Jerome Tollet50570ec2017-09-14 12:53:56 +01004730 else if (unformat (i, "bd-tag %s", &bd_tag))
4731 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004732 else if (unformat (i, "del"))
4733 {
4734 is_add = 0;
4735 flood = uu_flood = forward = learn = 0;
4736 }
4737 else
4738 break;
4739 }
4740
4741 if (bd_id == ~0)
4742 {
4743 errmsg ("missing bridge domain");
Jerome Tollet50570ec2017-09-14 12:53:56 +01004744 ret = -99;
4745 goto done;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004746 }
4747
4748 if (mac_age > 255)
4749 {
4750 errmsg ("mac age must be less than 256 ");
Jerome Tollet50570ec2017-09-14 12:53:56 +01004751 ret = -99;
4752 goto done;
4753 }
4754
John Lo70bfcaf2017-11-14 13:19:26 -05004755 if ((bd_tag) && (vec_len (bd_tag) > 63))
Jerome Tollet50570ec2017-09-14 12:53:56 +01004756 {
4757 errmsg ("bd-tag cannot be longer than 63");
4758 ret = -99;
4759 goto done;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004760 }
4761
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004762 M (BRIDGE_DOMAIN_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004763
4764 mp->bd_id = ntohl (bd_id);
4765 mp->flood = flood;
4766 mp->uu_flood = uu_flood;
4767 mp->forward = forward;
4768 mp->learn = learn;
4769 mp->arp_term = arp_term;
4770 mp->is_add = is_add;
4771 mp->mac_age = (u8) mac_age;
Jerome Tollet50570ec2017-09-14 12:53:56 +01004772 if (bd_tag)
John Lo70bfcaf2017-11-14 13:19:26 -05004773 {
4774 clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
4775 mp->bd_tag[vec_len (bd_tag)] = 0;
4776 }
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004777 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06004778 W (ret);
Jerome Tollet50570ec2017-09-14 12:53:56 +01004779
4780done:
4781 vec_free (bd_tag);
Jon Loeliger56c7b012017-02-01 12:31:41 -06004782 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004783}
4784
4785static int
Eyal Barif24991c2017-04-05 05:33:21 +03004786api_l2fib_flush_bd (vat_main_t * vam)
4787{
4788 unformat_input_t *i = vam->input;
4789 vl_api_l2fib_flush_bd_t *mp;
4790 u32 bd_id = ~0;
4791 int ret;
4792
4793 /* Parse args required to build the message */
4794 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4795 {
4796 if (unformat (i, "bd_id %d", &bd_id));
4797 else
4798 break;
4799 }
4800
4801 if (bd_id == ~0)
4802 {
4803 errmsg ("missing bridge domain");
4804 return -99;
4805 }
4806
4807 M (L2FIB_FLUSH_BD, mp);
4808
4809 mp->bd_id = htonl (bd_id);
4810
4811 S (mp);
4812 W (ret);
4813 return ret;
4814}
4815
4816static int
4817api_l2fib_flush_int (vat_main_t * vam)
4818{
4819 unformat_input_t *i = vam->input;
4820 vl_api_l2fib_flush_int_t *mp;
4821 u32 sw_if_index = ~0;
4822 int ret;
4823
4824 /* Parse args required to build the message */
4825 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4826 {
4827 if (unformat (i, "sw_if_index %d", &sw_if_index));
4828 else
4829 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
4830 else
4831 break;
4832 }
4833
4834 if (sw_if_index == ~0)
4835 {
4836 errmsg ("missing interface name or sw_if_index");
4837 return -99;
4838 }
4839
4840 M (L2FIB_FLUSH_INT, mp);
4841
4842 mp->sw_if_index = ntohl (sw_if_index);
4843
4844 S (mp);
4845 W (ret);
4846 return ret;
4847}
4848
4849static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01004850api_l2fib_add_del (vat_main_t * vam)
4851{
4852 unformat_input_t *i = vam->input;
4853 vl_api_l2fib_add_del_t *mp;
4854 f64 timeout;
Mohsin Kazmi57938f62017-10-27 21:28:07 +02004855 u8 mac[6] = { 0 };
Damjan Marion7cd468a2016-12-19 23:05:39 +01004856 u8 mac_set = 0;
4857 u32 bd_id;
4858 u8 bd_id_set = 0;
John Lo7dbd7262018-05-31 10:25:18 -04004859 u32 sw_if_index = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004860 u8 sw_if_index_set = 0;
4861 u8 is_add = 1;
4862 u8 static_mac = 0;
4863 u8 filter_mac = 0;
4864 u8 bvi_mac = 0;
4865 int count = 1;
4866 f64 before = 0;
4867 int j;
4868
4869 /* Parse args required to build the message */
4870 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4871 {
Mohsin Kazmi57938f62017-10-27 21:28:07 +02004872 if (unformat (i, "mac %U", unformat_ethernet_address, mac))
Damjan Marion7cd468a2016-12-19 23:05:39 +01004873 mac_set = 1;
4874 else if (unformat (i, "bd_id %d", &bd_id))
4875 bd_id_set = 1;
4876 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4877 sw_if_index_set = 1;
4878 else if (unformat (i, "sw_if"))
4879 {
4880 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4881 {
4882 if (unformat
4883 (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4884 sw_if_index_set = 1;
4885 }
4886 else
4887 break;
4888 }
4889 else if (unformat (i, "static"))
4890 static_mac = 1;
4891 else if (unformat (i, "filter"))
4892 {
4893 filter_mac = 1;
4894 static_mac = 1;
4895 }
4896 else if (unformat (i, "bvi"))
4897 {
4898 bvi_mac = 1;
4899 static_mac = 1;
4900 }
4901 else if (unformat (i, "del"))
4902 is_add = 0;
4903 else if (unformat (i, "count %d", &count))
4904 ;
4905 else
4906 break;
4907 }
4908
4909 if (mac_set == 0)
4910 {
4911 errmsg ("missing mac address");
4912 return -99;
4913 }
4914
4915 if (bd_id_set == 0)
4916 {
4917 errmsg ("missing bridge domain");
4918 return -99;
4919 }
4920
4921 if (is_add && sw_if_index_set == 0 && filter_mac == 0)
4922 {
4923 errmsg ("missing interface name or sw_if_index");
4924 return -99;
4925 }
4926
4927 if (count > 1)
4928 {
4929 /* Turn on async mode */
4930 vam->async_mode = 1;
4931 vam->async_errors = 0;
4932 before = vat_time_now (vam);
4933 }
4934
4935 for (j = 0; j < count; j++)
4936 {
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004937 M (L2FIB_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004938
Mohsin Kazmi57938f62017-10-27 21:28:07 +02004939 clib_memcpy (mp->mac, mac, 6);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004940 mp->bd_id = ntohl (bd_id);
4941 mp->is_add = is_add;
John Lo7dbd7262018-05-31 10:25:18 -04004942 mp->sw_if_index = ntohl (sw_if_index);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004943
4944 if (is_add)
4945 {
Damjan Marion7cd468a2016-12-19 23:05:39 +01004946 mp->static_mac = static_mac;
4947 mp->filter_mac = filter_mac;
4948 mp->bvi_mac = bvi_mac;
4949 }
Mohsin Kazmi57938f62017-10-27 21:28:07 +02004950 increment_mac_address (mac);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004951 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004952 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004953 }
4954
4955 if (count > 1)
4956 {
Jon Loeliger2d23eca2017-02-01 13:09:58 -06004957 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004958 f64 after;
4959
4960 /* Shut off async mode */
4961 vam->async_mode = 0;
4962
Dave Barach59b25652017-09-10 15:04:27 -04004963 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06004964 S (mp_ping);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004965
4966 timeout = vat_time_now (vam) + 1.0;
4967 while (vat_time_now (vam) < timeout)
4968 if (vam->result_ready == 1)
4969 goto out;
4970 vam->retval = -99;
4971
4972 out:
4973 if (vam->retval == -99)
4974 errmsg ("timeout");
4975
4976 if (vam->async_errors > 0)
4977 {
4978 errmsg ("%d asynchronous errors", vam->async_errors);
4979 vam->retval = -98;
4980 }
4981 vam->async_errors = 0;
4982 after = vat_time_now (vam);
4983
4984 print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
4985 count, after - before, count / (after - before));
4986 }
4987 else
4988 {
Jon Loeliger56c7b012017-02-01 12:31:41 -06004989 int ret;
4990
Damjan Marion7cd468a2016-12-19 23:05:39 +01004991 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06004992 W (ret);
4993 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004994 }
4995 /* Return the good/bad news */
4996 return (vam->retval);
4997}
4998
4999static int
Eyal Barifead6702017-04-04 04:46:32 +03005000api_bridge_domain_set_mac_age (vat_main_t * vam)
5001{
5002 unformat_input_t *i = vam->input;
5003 vl_api_bridge_domain_set_mac_age_t *mp;
5004 u32 bd_id = ~0;
5005 u32 mac_age = 0;
5006 int ret;
5007
5008 /* Parse args required to build the message */
5009 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5010 {
5011 if (unformat (i, "bd_id %d", &bd_id));
5012 else if (unformat (i, "mac-age %d", &mac_age));
5013 else
5014 break;
5015 }
5016
5017 if (bd_id == ~0)
5018 {
5019 errmsg ("missing bridge domain");
5020 return -99;
5021 }
5022
5023 if (mac_age > 255)
5024 {
5025 errmsg ("mac age must be less than 256 ");
5026 return -99;
5027 }
5028
5029 M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
5030
5031 mp->bd_id = htonl (bd_id);
5032 mp->mac_age = (u8) mac_age;
5033
5034 S (mp);
5035 W (ret);
5036 return ret;
5037}
5038
5039static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01005040api_l2_flags (vat_main_t * vam)
5041{
5042 unformat_input_t *i = vam->input;
5043 vl_api_l2_flags_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005044 u32 sw_if_index;
John Lo8d00fff2017-08-03 00:35:36 -04005045 u32 flags = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005046 u8 sw_if_index_set = 0;
John Lo8d00fff2017-08-03 00:35:36 -04005047 u8 is_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005048 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005049
5050 /* Parse args required to build the message */
5051 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5052 {
5053 if (unformat (i, "sw_if_index %d", &sw_if_index))
5054 sw_if_index_set = 1;
5055 else if (unformat (i, "sw_if"))
5056 {
5057 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5058 {
5059 if (unformat
5060 (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5061 sw_if_index_set = 1;
5062 }
5063 else
5064 break;
5065 }
5066 else if (unformat (i, "learn"))
John Lo8d00fff2017-08-03 00:35:36 -04005067 flags |= L2_LEARN;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005068 else if (unformat (i, "forward"))
John Lo8d00fff2017-08-03 00:35:36 -04005069 flags |= L2_FWD;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005070 else if (unformat (i, "flood"))
John Lo8d00fff2017-08-03 00:35:36 -04005071 flags |= L2_FLOOD;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005072 else if (unformat (i, "uu-flood"))
John Lo8d00fff2017-08-03 00:35:36 -04005073 flags |= L2_UU_FLOOD;
5074 else if (unformat (i, "arp-term"))
5075 flags |= L2_ARP_TERM;
5076 else if (unformat (i, "off"))
5077 is_set = 0;
5078 else if (unformat (i, "disable"))
5079 is_set = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005080 else
5081 break;
5082 }
5083
5084 if (sw_if_index_set == 0)
5085 {
5086 errmsg ("missing interface name or sw_if_index");
5087 return -99;
5088 }
5089
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005090 M (L2_FLAGS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005091
5092 mp->sw_if_index = ntohl (sw_if_index);
John Lo8d00fff2017-08-03 00:35:36 -04005093 mp->feature_bitmap = ntohl (flags);
5094 mp->is_set = is_set;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005095
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005096 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06005097 W (ret);
5098 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005099}
5100
5101static int
5102api_bridge_flags (vat_main_t * vam)
5103{
5104 unformat_input_t *i = vam->input;
5105 vl_api_bridge_flags_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005106 u32 bd_id;
5107 u8 bd_id_set = 0;
5108 u8 is_set = 1;
Neale Rannsb4743802018-09-05 09:13:57 -07005109 bd_flags_t flags = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005110 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005111
5112 /* Parse args required to build the message */
5113 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5114 {
5115 if (unformat (i, "bd_id %d", &bd_id))
5116 bd_id_set = 1;
5117 else if (unformat (i, "learn"))
Neale Rannsb4743802018-09-05 09:13:57 -07005118 flags |= BRIDGE_API_FLAG_LEARN;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005119 else if (unformat (i, "forward"))
Neale Rannsb4743802018-09-05 09:13:57 -07005120 flags |= BRIDGE_API_FLAG_FWD;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005121 else if (unformat (i, "flood"))
Neale Rannsb4743802018-09-05 09:13:57 -07005122 flags |= BRIDGE_API_FLAG_FLOOD;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005123 else if (unformat (i, "uu-flood"))
Neale Rannsb4743802018-09-05 09:13:57 -07005124 flags |= BRIDGE_API_FLAG_UU_FLOOD;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005125 else if (unformat (i, "arp-term"))
Neale Rannsb4743802018-09-05 09:13:57 -07005126 flags |= BRIDGE_API_FLAG_ARP_TERM;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005127 else if (unformat (i, "off"))
5128 is_set = 0;
5129 else if (unformat (i, "disable"))
5130 is_set = 0;
5131 else
5132 break;
5133 }
5134
5135 if (bd_id_set == 0)
5136 {
5137 errmsg ("missing bridge domain");
5138 return -99;
5139 }
5140
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005141 M (BRIDGE_FLAGS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005142
5143 mp->bd_id = ntohl (bd_id);
Neale Rannsb4743802018-09-05 09:13:57 -07005144 mp->flags = ntohl (flags);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005145 mp->is_set = is_set;
5146
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005147 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06005148 W (ret);
5149 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005150}
5151
5152static int
5153api_bd_ip_mac_add_del (vat_main_t * vam)
5154{
Neale Ranns4d5b9172018-10-24 02:57:49 -07005155 vl_api_address_t ip = VL_API_ZERO_ADDRESS;
Ole Troan8006c6a2018-12-17 12:02:26 +01005156 vl_api_mac_address_t mac = { 0 };
Damjan Marion7cd468a2016-12-19 23:05:39 +01005157 unformat_input_t *i = vam->input;
5158 vl_api_bd_ip_mac_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005159 u32 bd_id;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005160 u8 is_add = 1;
5161 u8 bd_id_set = 0;
5162 u8 ip_set = 0;
5163 u8 mac_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005164 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005165
5166
5167 /* Parse args required to build the message */
5168 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5169 {
5170 if (unformat (i, "bd_id %d", &bd_id))
5171 {
5172 bd_id_set++;
5173 }
Neale Ranns4d5b9172018-10-24 02:57:49 -07005174 else if (unformat (i, "%U", unformat_vl_api_address, &ip))
Damjan Marion7cd468a2016-12-19 23:05:39 +01005175 {
5176 ip_set++;
5177 }
Neale Ranns4d5b9172018-10-24 02:57:49 -07005178 else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
Damjan Marion7cd468a2016-12-19 23:05:39 +01005179 {
5180 mac_set++;
5181 }
5182 else if (unformat (i, "del"))
5183 is_add = 0;
5184 else
5185 break;
5186 }
5187
5188 if (bd_id_set == 0)
5189 {
5190 errmsg ("missing bridge domain");
5191 return -99;
5192 }
5193 else if (ip_set == 0)
5194 {
5195 errmsg ("missing IP address");
5196 return -99;
5197 }
5198 else if (mac_set == 0)
5199 {
5200 errmsg ("missing MAC address");
5201 return -99;
5202 }
5203
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005204 M (BD_IP_MAC_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005205
Neale Rannsbc764c82019-06-19 07:07:13 -07005206 mp->entry.bd_id = ntohl (bd_id);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005207 mp->is_add = is_add;
Neale Ranns4d5b9172018-10-24 02:57:49 -07005208
Neale Rannsbc764c82019-06-19 07:07:13 -07005209 clib_memcpy (&mp->entry.ip, &ip, sizeof (ip));
5210 clib_memcpy (&mp->entry.mac, &mac, sizeof (mac));
Neale Ranns4d5b9172018-10-24 02:57:49 -07005211
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005212 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06005213 W (ret);
5214 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005215}
5216
John Loe26c81f2019-01-07 15:16:33 -05005217static int
5218api_bd_ip_mac_flush (vat_main_t * vam)
5219{
5220 unformat_input_t *i = vam->input;
5221 vl_api_bd_ip_mac_flush_t *mp;
5222 u32 bd_id;
5223 u8 bd_id_set = 0;
5224 int ret;
5225
5226 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5227 {
5228 if (unformat (i, "bd_id %d", &bd_id))
5229 {
5230 bd_id_set++;
5231 }
5232 else
5233 break;
5234 }
5235
5236 if (bd_id_set == 0)
5237 {
5238 errmsg ("missing bridge domain");
5239 return -99;
5240 }
5241
5242 M (BD_IP_MAC_FLUSH, mp);
5243
5244 mp->bd_id = ntohl (bd_id);
5245
5246 S (mp);
5247 W (ret);
5248 return ret;
5249}
5250
Mohsin Kazmi5d82d2f2018-08-13 19:17:54 +02005251static void vl_api_bd_ip_mac_details_t_handler
5252 (vl_api_bd_ip_mac_details_t * mp)
5253{
5254 vat_main_t *vam = &vat_main;
Mohsin Kazmi5d82d2f2018-08-13 19:17:54 +02005255
5256 print (vam->ofp,
Neale Rannsbc764c82019-06-19 07:07:13 -07005257 "\n%-5d %U %U",
5258 ntohl (mp->entry.bd_id),
5259 format_vl_api_mac_address, mp->entry.mac,
5260 format_vl_api_address, &mp->entry.ip);
Mohsin Kazmi5d82d2f2018-08-13 19:17:54 +02005261}
5262
5263static void vl_api_bd_ip_mac_details_t_handler_json
5264 (vl_api_bd_ip_mac_details_t * mp)
5265{
5266 vat_main_t *vam = &vat_main;
5267 vat_json_node_t *node = NULL;
5268
5269 if (VAT_JSON_ARRAY != vam->json_tree.type)
5270 {
5271 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5272 vat_json_init_array (&vam->json_tree);
5273 }
5274 node = vat_json_array_add (&vam->json_tree);
5275
5276 vat_json_init_object (node);
Neale Rannsbc764c82019-06-19 07:07:13 -07005277 vat_json_object_add_uint (node, "bd_id", ntohl (mp->entry.bd_id));
Mohsin Kazmi5d82d2f2018-08-13 19:17:54 +02005278 vat_json_object_add_string_copy (node, "mac_address",
Neale Rannsbc764c82019-06-19 07:07:13 -07005279 format (0, "%U", format_vl_api_mac_address,
5280 &mp->entry.mac));
Mohsin Kazmi5d82d2f2018-08-13 19:17:54 +02005281 u8 *ip = 0;
5282
Neale Rannsbc764c82019-06-19 07:07:13 -07005283 ip = format (0, "%U", format_vl_api_address, &mp->entry.ip);
Mohsin Kazmi5d82d2f2018-08-13 19:17:54 +02005284 vat_json_object_add_string_copy (node, "ip_address", ip);
5285 vec_free (ip);
5286}
5287
5288static int
5289api_bd_ip_mac_dump (vat_main_t * vam)
5290{
5291 unformat_input_t *i = vam->input;
5292 vl_api_bd_ip_mac_dump_t *mp;
5293 vl_api_control_ping_t *mp_ping;
5294 int ret;
5295 u32 bd_id;
5296 u8 bd_id_set = 0;
5297
5298 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5299 {
5300 if (unformat (i, "bd_id %d", &bd_id))
5301 {
5302 bd_id_set++;
5303 }
5304 else
5305 break;
5306 }
5307
5308 print (vam->ofp,
5309 "\n%-5s %-7s %-20s %-30s",
5310 "bd_id", "is_ipv6", "mac_address", "ip_address");
5311
5312 /* Dump Bridge Domain Ip to Mac entries */
5313 M (BD_IP_MAC_DUMP, mp);
5314
5315 if (bd_id_set)
5316 mp->bd_id = htonl (bd_id);
5317 else
5318 mp->bd_id = ~0;
5319
5320 S (mp);
5321
5322 /* Use a control ping for synchronization */
5323 MPING (CONTROL_PING, mp_ping);
5324 S (mp_ping);
5325
5326 W (ret);
5327 return ret;
5328}
5329
Damjan Marion7cd468a2016-12-19 23:05:39 +01005330static int
Damjan Marion8389fb92017-10-13 18:29:53 +02005331api_tap_create_v2 (vat_main_t * vam)
5332{
5333 unformat_input_t *i = vam->input;
5334 vl_api_tap_create_v2_t *mp;
5335 u8 mac_address[6];
5336 u8 random_mac = 1;
Damjan Marion2df39092017-12-04 20:03:37 +01005337 u32 id = ~0;
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005338 u32 num_rx_queues = 0;
Damjan Marion2df39092017-12-04 20:03:37 +01005339 u8 *host_if_name = 0;
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005340 u8 host_if_name_set = 0;
Damjan Marion2df39092017-12-04 20:03:37 +01005341 u8 *host_ns = 0;
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005342 u8 host_ns_set = 0;
Damjan Marion2df39092017-12-04 20:03:37 +01005343 u8 host_mac_addr[6];
5344 u8 host_mac_addr_set = 0;
Damjan Marion91c6ef72017-12-01 13:34:24 +01005345 u8 *host_bridge = 0;
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005346 u8 host_bridge_set = 0;
5347 u8 host_ip4_prefix_set = 0;
5348 u8 host_ip6_prefix_set = 0;
Damjan Marion91c6ef72017-12-01 13:34:24 +01005349 ip4_address_t host_ip4_addr;
Damjan Marion7866c452018-01-18 13:35:11 +01005350 ip4_address_t host_ip4_gw;
5351 u8 host_ip4_gw_set = 0;
Damjan Marion91c6ef72017-12-01 13:34:24 +01005352 u32 host_ip4_prefix_len = 0;
5353 ip6_address_t host_ip6_addr;
Damjan Marion7866c452018-01-18 13:35:11 +01005354 ip6_address_t host_ip6_gw;
5355 u8 host_ip6_gw_set = 0;
Damjan Marion91c6ef72017-12-01 13:34:24 +01005356 u32 host_ip6_prefix_len = 0;
Mohsin Kazmi97d54ed2019-06-10 11:20:15 +02005357 u32 host_mtu_size = 0;
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005358 u8 host_mtu_set = 0;
Mohsin Kazmi97d54ed2019-06-10 11:20:15 +02005359 u32 tap_flags = 0;
Damjan Marion8389fb92017-10-13 18:29:53 +02005360 int ret;
Steven9e635692018-03-01 09:36:01 -08005361 u32 rx_ring_sz = 0, tx_ring_sz = 0;
Damjan Marion8389fb92017-10-13 18:29:53 +02005362
Dave Barachb7b92992018-10-17 10:38:51 -04005363 clib_memset (mac_address, 0, sizeof (mac_address));
Damjan Marion8389fb92017-10-13 18:29:53 +02005364
5365 /* Parse args required to build the message */
5366 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5367 {
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005368 if (unformat (i, "id %u", &id))
Damjan Marion91c6ef72017-12-01 13:34:24 +01005369 ;
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005370 else
5371 if (unformat
5372 (i, "hw-addr %U", unformat_ethernet_address, mac_address))
5373 random_mac = 0;
Damjan Marion2df39092017-12-04 20:03:37 +01005374 else if (unformat (i, "host-if-name %s", &host_if_name))
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005375 host_if_name_set = 1;
5376 else if (unformat (i, "num-rx-queues %u", &num_rx_queues))
Damjan Marion91c6ef72017-12-01 13:34:24 +01005377 ;
Damjan Marion2df39092017-12-04 20:03:37 +01005378 else if (unformat (i, "host-ns %s", &host_ns))
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005379 host_ns_set = 1;
Damjan Marion2df39092017-12-04 20:03:37 +01005380 else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
5381 host_mac_addr))
5382 host_mac_addr_set = 1;
Damjan Marion91c6ef72017-12-01 13:34:24 +01005383 else if (unformat (i, "host-bridge %s", &host_bridge))
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005384 host_bridge_set = 1;
5385 else if (unformat (i, "host-ip4-addr %U/%u", unformat_ip4_address,
Damjan Marion91c6ef72017-12-01 13:34:24 +01005386 &host_ip4_addr, &host_ip4_prefix_len))
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005387 host_ip4_prefix_set = 1;
5388 else if (unformat (i, "host-ip6-addr %U/%u", unformat_ip6_address,
Damjan Marion91c6ef72017-12-01 13:34:24 +01005389 &host_ip6_addr, &host_ip6_prefix_len))
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005390 host_ip6_prefix_set = 1;
Damjan Marion7866c452018-01-18 13:35:11 +01005391 else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
5392 &host_ip4_gw))
5393 host_ip4_gw_set = 1;
5394 else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
5395 &host_ip6_gw))
5396 host_ip6_gw_set = 1;
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005397 else if (unformat (i, "rx-ring-size %u", &rx_ring_sz))
Damjan Marion8389fb92017-10-13 18:29:53 +02005398 ;
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005399 else if (unformat (i, "tx-ring-size %u", &tx_ring_sz))
Damjan Marion8389fb92017-10-13 18:29:53 +02005400 ;
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005401 else if (unformat (i, "host-mtu-size %u", &host_mtu_size))
Mohsin Kazmi97d54ed2019-06-10 11:20:15 +02005402 host_mtu_set = 1;
5403 else if (unformat (i, "no-gso"))
Mohsin Kazmid88fc0f2020-04-30 19:05:56 +02005404 tap_flags &= ~TAP_API_FLAG_GSO;
Mohsin Kazmi97d54ed2019-06-10 11:20:15 +02005405 else if (unformat (i, "gso"))
Mohsin Kazmid88fc0f2020-04-30 19:05:56 +02005406 tap_flags |= TAP_API_FLAG_GSO;
Mohsin Kazmiba0061f2019-12-18 17:08:54 +01005407 else if (unformat (i, "csum-offload"))
Mohsin Kazmid88fc0f2020-04-30 19:05:56 +02005408 tap_flags |= TAP_API_FLAG_CSUM_OFFLOAD;
Mohsin Kazmib49bc1a2020-02-14 17:51:04 +00005409 else if (unformat (i, "persist"))
Mohsin Kazmid88fc0f2020-04-30 19:05:56 +02005410 tap_flags |= TAP_API_FLAG_PERSIST;
Mohsin Kazmib49bc1a2020-02-14 17:51:04 +00005411 else if (unformat (i, "attach"))
Mohsin Kazmid88fc0f2020-04-30 19:05:56 +02005412 tap_flags |= TAP_API_FLAG_ATTACH;
5413 else if (unformat (i, "tun"))
5414 tap_flags |= TAP_API_FLAG_TUN;
5415 else if (unformat (i, "gro-coalesce"))
5416 tap_flags |= TAP_API_FLAG_GRO_COALESCE;
Mohsin Kazmi50bd1652020-08-26 11:07:48 +02005417 else if (unformat (i, "packed"))
5418 tap_flags |= TAP_API_FLAG_PACKED;
5419 else if (unformat (i, "in-order"))
5420 tap_flags |= TAP_API_FLAG_IN_ORDER;
Damjan Marion8389fb92017-10-13 18:29:53 +02005421 else
5422 break;
5423 }
5424
Damjan Marion2df39092017-12-04 20:03:37 +01005425 if (vec_len (host_if_name) > 63)
Damjan Marion8389fb92017-10-13 18:29:53 +02005426 {
5427 errmsg ("tap name too long. ");
5428 return -99;
5429 }
Damjan Marion2df39092017-12-04 20:03:37 +01005430 if (vec_len (host_ns) > 63)
Damjan Marion8389fb92017-10-13 18:29:53 +02005431 {
5432 errmsg ("host name space too long. ");
5433 return -99;
5434 }
Damjan Marion91c6ef72017-12-01 13:34:24 +01005435 if (vec_len (host_bridge) > 63)
5436 {
5437 errmsg ("host bridge name too long. ");
5438 return -99;
5439 }
5440 if (host_ip4_prefix_len > 32)
5441 {
5442 errmsg ("host ip4 prefix length not valid. ");
5443 return -99;
5444 }
5445 if (host_ip6_prefix_len > 128)
5446 {
5447 errmsg ("host ip6 prefix length not valid. ");
5448 return -99;
5449 }
Damjan Marion8389fb92017-10-13 18:29:53 +02005450 if (!is_pow2 (rx_ring_sz))
5451 {
5452 errmsg ("rx ring size must be power of 2. ");
5453 return -99;
5454 }
5455 if (rx_ring_sz > 32768)
5456 {
5457 errmsg ("rx ring size must be 32768 or lower. ");
5458 return -99;
5459 }
5460 if (!is_pow2 (tx_ring_sz))
5461 {
5462 errmsg ("tx ring size must be power of 2. ");
5463 return -99;
5464 }
5465 if (tx_ring_sz > 32768)
5466 {
5467 errmsg ("tx ring size must be 32768 or lower. ");
5468 return -99;
5469 }
Mohsin Kazmi97d54ed2019-06-10 11:20:15 +02005470 if (host_mtu_set && (host_mtu_size < 64 || host_mtu_size > 65355))
5471 {
5472 errmsg ("host MTU size must be in between 64 and 65355. ");
5473 return -99;
5474 }
Damjan Marion8389fb92017-10-13 18:29:53 +02005475
Damjan Marion8389fb92017-10-13 18:29:53 +02005476 /* Construct the API message */
5477 M (TAP_CREATE_V2, mp);
5478
Steven9e635692018-03-01 09:36:01 -08005479 mp->id = ntohl (id);
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005480 mp->use_random_mac = random_mac;
5481 mp->num_rx_queues = (u8) num_rx_queues;
Steven9e635692018-03-01 09:36:01 -08005482 mp->tx_ring_sz = ntohs (tx_ring_sz);
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005483 mp->rx_ring_sz = ntohs (rx_ring_sz);
Mohsin Kazmi97d54ed2019-06-10 11:20:15 +02005484 mp->host_mtu_set = host_mtu_set;
5485 mp->host_mtu_size = ntohl (host_mtu_size);
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005486 mp->host_mac_addr_set = host_mac_addr_set;
5487 mp->host_ip4_prefix_set = host_ip4_prefix_set;
5488 mp->host_ip6_prefix_set = host_ip6_prefix_set;
5489 mp->host_ip4_gw_set = host_ip4_gw_set;
5490 mp->host_ip6_gw_set = host_ip6_gw_set;
Mohsin Kazmi97d54ed2019-06-10 11:20:15 +02005491 mp->tap_flags = ntohl (tap_flags);
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005492 mp->host_namespace_set = host_ns_set;
5493 mp->host_if_name_set = host_if_name_set;
5494 mp->host_bridge_set = host_bridge_set;
Damjan Marion2df39092017-12-04 20:03:37 +01005495
Steven9e635692018-03-01 09:36:01 -08005496 if (random_mac == 0)
Damjan Marion2df39092017-12-04 20:03:37 +01005497 clib_memcpy (mp->mac_address, mac_address, 6);
5498 if (host_mac_addr_set)
5499 clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005500 if (host_if_name_set)
Damjan Marion2df39092017-12-04 20:03:37 +01005501 clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005502 if (host_ns_set)
Damjan Marion2df39092017-12-04 20:03:37 +01005503 clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005504 if (host_bridge_set)
Damjan Marion91c6ef72017-12-01 13:34:24 +01005505 clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005506 if (host_ip4_prefix_set)
5507 {
5508 clib_memcpy (mp->host_ip4_prefix.address, &host_ip4_addr, 4);
5509 mp->host_ip4_prefix.len = (u8) host_ip4_prefix_len;
5510 }
5511 if (host_ip6_prefix_set)
5512 {
5513 clib_memcpy (mp->host_ip6_prefix.address, &host_ip6_addr, 16);
5514 mp->host_ip6_prefix.len = (u8) host_ip6_prefix_len;
5515 }
Damjan Marion7866c452018-01-18 13:35:11 +01005516 if (host_ip4_gw_set)
5517 clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
5518 if (host_ip6_gw_set)
5519 clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
Damjan Marion8389fb92017-10-13 18:29:53 +02005520
Damjan Marion2df39092017-12-04 20:03:37 +01005521 vec_free (host_ns);
5522 vec_free (host_if_name);
5523 vec_free (host_bridge);
Damjan Marion8389fb92017-10-13 18:29:53 +02005524
5525 /* send it... */
5526 S (mp);
5527
5528 /* Wait for a reply... */
5529 W (ret);
5530 return ret;
5531}
5532
5533static int
5534api_tap_delete_v2 (vat_main_t * vam)
5535{
5536 unformat_input_t *i = vam->input;
5537 vl_api_tap_delete_v2_t *mp;
5538 u32 sw_if_index = ~0;
5539 u8 sw_if_index_set = 0;
5540 int ret;
5541
5542 /* Parse args required to build the message */
5543 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5544 {
5545 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5546 sw_if_index_set = 1;
5547 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5548 sw_if_index_set = 1;
5549 else
5550 break;
5551 }
5552
5553 if (sw_if_index_set == 0)
5554 {
5555 errmsg ("missing vpp interface name. ");
5556 return -99;
5557 }
5558
5559 /* Construct the API message */
5560 M (TAP_DELETE_V2, mp);
5561
5562 mp->sw_if_index = ntohl (sw_if_index);
5563
5564 /* send it... */
5565 S (mp);
5566
5567 /* Wait for a reply... */
5568 W (ret);
5569 return ret;
5570}
5571
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005572uword
jialv01082ebeb2019-09-10 00:23:55 +08005573unformat_vlib_pci_addr (unformat_input_t * input, va_list * args)
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005574{
jialv01082ebeb2019-09-10 00:23:55 +08005575 vlib_pci_addr_t *addr = va_arg (*args, vlib_pci_addr_t *);
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005576 u32 x[4];
5577
5578 if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
5579 return 0;
5580
5581 addr->domain = x[0];
5582 addr->bus = x[1];
5583 addr->slot = x[2];
5584 addr->function = x[3];
5585
5586 return 1;
5587}
5588
5589static int
Mohsin Kazmi518251b2020-09-01 17:17:44 +00005590api_virtio_pci_create_v2 (vat_main_t * vam)
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005591{
5592 unformat_input_t *i = vam->input;
Mohsin Kazmi518251b2020-09-01 17:17:44 +00005593 vl_api_virtio_pci_create_v2_t *mp;
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005594 u8 mac_address[6];
5595 u8 random_mac = 1;
5596 u32 pci_addr = 0;
5597 u64 features = (u64) ~ (0ULL);
Mohsin Kazmi518251b2020-09-01 17:17:44 +00005598 u32 virtio_flags = 0;
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005599 int ret;
5600
5601 clib_memset (mac_address, 0, sizeof (mac_address));
5602
5603 /* Parse args required to build the message */
5604 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5605 {
5606 if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
5607 {
5608 random_mac = 0;
5609 }
jialv01082ebeb2019-09-10 00:23:55 +08005610 else if (unformat (i, "pci-addr %U", unformat_vlib_pci_addr, &pci_addr))
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005611 ;
5612 else if (unformat (i, "features 0x%llx", &features))
5613 ;
Mohsin Kazmibbd6b742019-05-02 13:54:59 +02005614 else if (unformat (i, "gso-enabled"))
Mohsin Kazmi518251b2020-09-01 17:17:44 +00005615 virtio_flags |= VIRTIO_API_FLAG_GSO;
Mohsin Kazmi6d4af892020-01-03 15:11:53 +00005616 else if (unformat (i, "csum-offload-enabled"))
Mohsin Kazmi518251b2020-09-01 17:17:44 +00005617 virtio_flags |= VIRTIO_API_FLAG_CSUM_OFFLOAD;
5618 else if (unformat (i, "gro-coalesce"))
5619 virtio_flags |= VIRTIO_API_FLAG_GRO_COALESCE;
5620 else if (unformat (i, "packed"))
5621 virtio_flags |= VIRTIO_API_FLAG_PACKED;
5622 else if (unformat (i, "in-order"))
5623 virtio_flags |= VIRTIO_API_FLAG_IN_ORDER;
Mohsin Kazmie347acb2020-09-28 10:26:33 +00005624 else if (unformat (i, "buffering"))
5625 virtio_flags |= VIRTIO_API_FLAG_BUFFERING;
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005626 else
5627 break;
5628 }
5629
5630 if (pci_addr == 0)
5631 {
5632 errmsg ("pci address must be non zero. ");
5633 return -99;
5634 }
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005635
5636 /* Construct the API message */
Mohsin Kazmi518251b2020-09-01 17:17:44 +00005637 M (VIRTIO_PCI_CREATE_V2, mp);
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005638
5639 mp->use_random_mac = random_mac;
5640
Jakub Grajciar2c504f82019-09-26 10:34:41 +02005641 mp->pci_addr.domain = htons (((vlib_pci_addr_t) pci_addr).domain);
5642 mp->pci_addr.bus = ((vlib_pci_addr_t) pci_addr).bus;
5643 mp->pci_addr.slot = ((vlib_pci_addr_t) pci_addr).slot;
5644 mp->pci_addr.function = ((vlib_pci_addr_t) pci_addr).function;
5645
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005646 mp->features = clib_host_to_net_u64 (features);
Mohsin Kazmi518251b2020-09-01 17:17:44 +00005647 mp->virtio_flags = clib_host_to_net_u32 (virtio_flags);
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005648
5649 if (random_mac == 0)
5650 clib_memcpy (mp->mac_address, mac_address, 6);
5651
5652 /* send it... */
5653 S (mp);
5654
5655 /* Wait for a reply... */
5656 W (ret);
5657 return ret;
5658}
5659
5660static int
5661api_virtio_pci_delete (vat_main_t * vam)
5662{
5663 unformat_input_t *i = vam->input;
5664 vl_api_virtio_pci_delete_t *mp;
5665 u32 sw_if_index = ~0;
5666 u8 sw_if_index_set = 0;
5667 int ret;
5668
5669 /* Parse args required to build the message */
5670 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5671 {
5672 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5673 sw_if_index_set = 1;
5674 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5675 sw_if_index_set = 1;
5676 else
5677 break;
5678 }
5679
5680 if (sw_if_index_set == 0)
5681 {
5682 errmsg ("missing vpp interface name. ");
5683 return -99;
5684 }
5685
5686 /* Construct the API message */
5687 M (VIRTIO_PCI_DELETE, mp);
5688
5689 mp->sw_if_index = htonl (sw_if_index);
5690
5691 /* send it... */
5692 S (mp);
5693
5694 /* Wait for a reply... */
5695 W (ret);
5696 return ret;
5697}
5698
Damjan Marion8389fb92017-10-13 18:29:53 +02005699static int
Steven9cd2d7a2017-12-20 12:43:01 -08005700api_bond_create (vat_main_t * vam)
5701{
5702 unformat_input_t *i = vam->input;
5703 vl_api_bond_create_t *mp;
5704 u8 mac_address[6];
5705 u8 custom_mac = 0;
5706 int ret;
5707 u8 mode;
5708 u8 lb;
5709 u8 mode_is_set = 0;
Alexander Chernavinad9d5282018-12-13 09:08:09 -05005710 u32 id = ~0;
Zhiyong Yang751e3f32019-06-26 05:49:14 -04005711 u8 numa_only = 0;
Steven9cd2d7a2017-12-20 12:43:01 -08005712
Dave Barachb7b92992018-10-17 10:38:51 -04005713 clib_memset (mac_address, 0, sizeof (mac_address));
Steven9cd2d7a2017-12-20 12:43:01 -08005714 lb = BOND_LB_L2;
5715
5716 /* Parse args required to build the message */
5717 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5718 {
5719 if (unformat (i, "mode %U", unformat_bond_mode, &mode))
5720 mode_is_set = 1;
5721 else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
5722 && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
5723 ;
5724 else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
5725 mac_address))
5726 custom_mac = 1;
Zhiyong Yang751e3f32019-06-26 05:49:14 -04005727 else if (unformat (i, "numa-only"))
5728 numa_only = 1;
Alexander Chernavinad9d5282018-12-13 09:08:09 -05005729 else if (unformat (i, "id %u", &id))
5730 ;
Steven9cd2d7a2017-12-20 12:43:01 -08005731 else
5732 break;
5733 }
5734
5735 if (mode_is_set == 0)
5736 {
5737 errmsg ("Missing bond mode. ");
5738 return -99;
5739 }
5740
5741 /* Construct the API message */
5742 M (BOND_CREATE, mp);
5743
5744 mp->use_custom_mac = custom_mac;
5745
Jakub Grajciar3d1ef872019-08-26 12:55:15 +02005746 mp->mode = htonl (mode);
5747 mp->lb = htonl (lb);
Alexander Chernavinad9d5282018-12-13 09:08:09 -05005748 mp->id = htonl (id);
Zhiyong Yang751e3f32019-06-26 05:49:14 -04005749 mp->numa_only = numa_only;
Steven9cd2d7a2017-12-20 12:43:01 -08005750
5751 if (custom_mac)
5752 clib_memcpy (mp->mac_address, mac_address, 6);
5753
5754 /* send it... */
5755 S (mp);
5756
5757 /* Wait for a reply... */
5758 W (ret);
5759 return ret;
5760}
5761
5762static int
Steven Luongea717862020-07-30 07:31:40 -07005763api_bond_create2 (vat_main_t * vam)
5764{
5765 unformat_input_t *i = vam->input;
5766 vl_api_bond_create2_t *mp;
5767 u8 mac_address[6];
5768 u8 custom_mac = 0;
5769 int ret;
5770 u8 mode;
5771 u8 lb;
5772 u8 mode_is_set = 0;
5773 u32 id = ~0;
5774 u8 numa_only = 0;
5775 u8 gso = 0;
5776
5777 clib_memset (mac_address, 0, sizeof (mac_address));
5778 lb = BOND_LB_L2;
5779
5780 /* Parse args required to build the message */
5781 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5782 {
5783 if (unformat (i, "mode %U", unformat_bond_mode, &mode))
5784 mode_is_set = 1;
5785 else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
5786 && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
5787 ;
5788 else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
5789 mac_address))
5790 custom_mac = 1;
5791 else if (unformat (i, "numa-only"))
5792 numa_only = 1;
5793 else if (unformat (i, "gso"))
5794 gso = 1;
5795 else if (unformat (i, "id %u", &id))
5796 ;
5797 else
5798 break;
5799 }
5800
5801 if (mode_is_set == 0)
5802 {
5803 errmsg ("Missing bond mode. ");
5804 return -99;
5805 }
5806
5807 /* Construct the API message */
5808 M (BOND_CREATE2, mp);
5809
5810 mp->use_custom_mac = custom_mac;
5811
5812 mp->mode = htonl (mode);
5813 mp->lb = htonl (lb);
5814 mp->id = htonl (id);
5815 mp->numa_only = numa_only;
5816 mp->enable_gso = gso;
5817
5818 if (custom_mac)
5819 clib_memcpy (mp->mac_address, mac_address, 6);
5820
5821 /* send it... */
5822 S (mp);
5823
5824 /* Wait for a reply... */
5825 W (ret);
5826 return ret;
5827}
5828
5829static int
Steven9cd2d7a2017-12-20 12:43:01 -08005830api_bond_delete (vat_main_t * vam)
5831{
5832 unformat_input_t *i = vam->input;
5833 vl_api_bond_delete_t *mp;
5834 u32 sw_if_index = ~0;
5835 u8 sw_if_index_set = 0;
5836 int ret;
5837
5838 /* Parse args required to build the message */
5839 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5840 {
5841 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5842 sw_if_index_set = 1;
5843 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5844 sw_if_index_set = 1;
5845 else
5846 break;
5847 }
5848
5849 if (sw_if_index_set == 0)
5850 {
5851 errmsg ("missing vpp interface name. ");
5852 return -99;
5853 }
5854
5855 /* Construct the API message */
5856 M (BOND_DELETE, mp);
5857
5858 mp->sw_if_index = ntohl (sw_if_index);
5859
5860 /* send it... */
5861 S (mp);
5862
5863 /* Wait for a reply... */
5864 W (ret);
5865 return ret;
5866}
5867
5868static int
Steven Luong4c4223e2020-07-15 08:44:54 -07005869api_bond_add_member (vat_main_t * vam)
Steven9cd2d7a2017-12-20 12:43:01 -08005870{
5871 unformat_input_t *i = vam->input;
Steven Luong4c4223e2020-07-15 08:44:54 -07005872 vl_api_bond_add_member_t *mp;
Steven9cd2d7a2017-12-20 12:43:01 -08005873 u32 bond_sw_if_index;
5874 int ret;
5875 u8 is_passive;
5876 u8 is_long_timeout;
5877 u32 bond_sw_if_index_is_set = 0;
5878 u32 sw_if_index;
5879 u8 sw_if_index_is_set = 0;
5880
5881 /* Parse args required to build the message */
5882 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5883 {
5884 if (unformat (i, "sw_if_index %d", &sw_if_index))
5885 sw_if_index_is_set = 1;
5886 else if (unformat (i, "bond %u", &bond_sw_if_index))
5887 bond_sw_if_index_is_set = 1;
5888 else if (unformat (i, "passive %d", &is_passive))
5889 ;
5890 else if (unformat (i, "long-timeout %d", &is_long_timeout))
5891 ;
5892 else
5893 break;
5894 }
5895
5896 if (bond_sw_if_index_is_set == 0)
5897 {
5898 errmsg ("Missing bond sw_if_index. ");
5899 return -99;
5900 }
5901 if (sw_if_index_is_set == 0)
5902 {
Steven Luong4c4223e2020-07-15 08:44:54 -07005903 errmsg ("Missing member sw_if_index. ");
Steven9cd2d7a2017-12-20 12:43:01 -08005904 return -99;
5905 }
5906
5907 /* Construct the API message */
Steven Luong4c4223e2020-07-15 08:44:54 -07005908 M (BOND_ADD_MEMBER, mp);
Steven9cd2d7a2017-12-20 12:43:01 -08005909
5910 mp->bond_sw_if_index = ntohl (bond_sw_if_index);
5911 mp->sw_if_index = ntohl (sw_if_index);
5912 mp->is_long_timeout = is_long_timeout;
5913 mp->is_passive = is_passive;
5914
5915 /* send it... */
5916 S (mp);
5917
5918 /* Wait for a reply... */
5919 W (ret);
5920 return ret;
5921}
5922
5923static int
Steven Luong4c4223e2020-07-15 08:44:54 -07005924api_bond_detach_member (vat_main_t * vam)
Steven9cd2d7a2017-12-20 12:43:01 -08005925{
5926 unformat_input_t *i = vam->input;
Steven Luong4c4223e2020-07-15 08:44:54 -07005927 vl_api_bond_detach_member_t *mp;
Steven9cd2d7a2017-12-20 12:43:01 -08005928 u32 sw_if_index = ~0;
5929 u8 sw_if_index_set = 0;
5930 int ret;
5931
5932 /* Parse args required to build the message */
5933 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5934 {
5935 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5936 sw_if_index_set = 1;
5937 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5938 sw_if_index_set = 1;
5939 else
5940 break;
5941 }
5942
5943 if (sw_if_index_set == 0)
5944 {
5945 errmsg ("missing vpp interface name. ");
5946 return -99;
5947 }
5948
5949 /* Construct the API message */
Steven Luong4c4223e2020-07-15 08:44:54 -07005950 M (BOND_DETACH_MEMBER, mp);
Steven9cd2d7a2017-12-20 12:43:01 -08005951
5952 mp->sw_if_index = ntohl (sw_if_index);
5953
5954 /* send it... */
5955 S (mp);
5956
5957 /* Wait for a reply... */
5958 W (ret);
5959 return ret;
5960}
5961
5962static int
Neale Ranns28ab9cc2017-08-14 07:18:42 -07005963api_ip_table_add_del (vat_main_t * vam)
5964{
5965 unformat_input_t *i = vam->input;
5966 vl_api_ip_table_add_del_t *mp;
5967 u32 table_id = ~0;
5968 u8 is_ipv6 = 0;
5969 u8 is_add = 1;
5970 int ret = 0;
5971
5972 /* Parse args required to build the message */
5973 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5974 {
5975 if (unformat (i, "ipv6"))
5976 is_ipv6 = 1;
5977 else if (unformat (i, "del"))
5978 is_add = 0;
5979 else if (unformat (i, "add"))
5980 is_add = 1;
5981 else if (unformat (i, "table %d", &table_id))
5982 ;
5983 else
5984 {
5985 clib_warning ("parse error '%U'", format_unformat_error, i);
5986 return -99;
5987 }
5988 }
5989
5990 if (~0 == table_id)
5991 {
5992 errmsg ("missing table-ID");
5993 return -99;
5994 }
5995
5996 /* Construct the API message */
5997 M (IP_TABLE_ADD_DEL, mp);
5998
Neale Ranns097fa662018-05-01 05:17:55 -07005999 mp->table.table_id = ntohl (table_id);
6000 mp->table.is_ip6 = is_ipv6;
Neale Ranns28ab9cc2017-08-14 07:18:42 -07006001 mp->is_add = is_add;
6002
6003 /* send it... */
6004 S (mp);
6005
6006 /* Wait for a reply... */
6007 W (ret);
6008
6009 return ret;
6010}
6011
Neale Ranns097fa662018-05-01 05:17:55 -07006012uword
6013unformat_fib_path (unformat_input_t * input, va_list * args)
6014{
6015 vat_main_t *vam = va_arg (*args, vat_main_t *);
6016 vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
6017 u32 weight, preference;
6018 mpls_label_t out_label;
6019
6020 clib_memset (path, 0, sizeof (*path));
6021 path->weight = 1;
6022 path->sw_if_index = ~0;
6023 path->rpf_id = ~0;
6024 path->n_labels = 0;
6025
6026 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
6027 {
6028 if (unformat (input, "%U %U",
6029 unformat_vl_api_ip4_address,
6030 &path->nh.address.ip4,
6031 api_unformat_sw_if_index, vam, &path->sw_if_index))
6032 {
6033 path->proto = FIB_API_PATH_NH_PROTO_IP4;
6034 }
6035 else if (unformat (input, "%U %U",
6036 unformat_vl_api_ip6_address,
6037 &path->nh.address.ip6,
6038 api_unformat_sw_if_index, vam, &path->sw_if_index))
6039 {
6040 path->proto = FIB_API_PATH_NH_PROTO_IP6;
6041 }
6042 else if (unformat (input, "weight %u", &weight))
6043 {
6044 path->weight = weight;
6045 }
6046 else if (unformat (input, "preference %u", &preference))
6047 {
6048 path->preference = preference;
6049 }
6050 else if (unformat (input, "%U next-hop-table %d",
6051 unformat_vl_api_ip4_address,
6052 &path->nh.address.ip4, &path->table_id))
6053 {
6054 path->proto = FIB_API_PATH_NH_PROTO_IP4;
6055 }
6056 else if (unformat (input, "%U next-hop-table %d",
6057 unformat_vl_api_ip6_address,
6058 &path->nh.address.ip6, &path->table_id))
6059 {
6060 path->proto = FIB_API_PATH_NH_PROTO_IP6;
6061 }
6062 else if (unformat (input, "%U",
6063 unformat_vl_api_ip4_address, &path->nh.address.ip4))
6064 {
6065 /*
6066 * the recursive next-hops are by default in the default table
6067 */
6068 path->table_id = 0;
6069 path->sw_if_index = ~0;
6070 path->proto = FIB_API_PATH_NH_PROTO_IP4;
6071 }
6072 else if (unformat (input, "%U",
6073 unformat_vl_api_ip6_address, &path->nh.address.ip6))
6074 {
6075 /*
6076 * the recursive next-hops are by default in the default table
6077 */
6078 path->table_id = 0;
6079 path->sw_if_index = ~0;
6080 path->proto = FIB_API_PATH_NH_PROTO_IP6;
6081 }
6082 else if (unformat (input, "resolve-via-host"))
6083 {
6084 path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
6085 }
6086 else if (unformat (input, "resolve-via-attached"))
6087 {
6088 path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
6089 }
6090 else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
6091 {
6092 path->type = FIB_API_PATH_TYPE_LOCAL;
6093 path->sw_if_index = ~0;
6094 path->proto = FIB_API_PATH_NH_PROTO_IP4;
6095 }
6096 else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
6097 {
6098 path->type = FIB_API_PATH_TYPE_LOCAL;
6099 path->sw_if_index = ~0;
6100 path->proto = FIB_API_PATH_NH_PROTO_IP6;
6101 }
6102 else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
6103 ;
6104 else if (unformat (input, "via-label %d", &path->nh.via_label))
6105 {
6106 path->proto = FIB_API_PATH_NH_PROTO_MPLS;
6107 path->sw_if_index = ~0;
6108 }
6109 else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
6110 {
6111 path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
6112 path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
6113 }
6114 else if (unformat (input, "local"))
6115 {
6116 path->type = FIB_API_PATH_TYPE_LOCAL;
6117 }
6118 else if (unformat (input, "out-labels"))
6119 {
6120 while (unformat (input, "%d", &out_label))
6121 {
6122 path->label_stack[path->n_labels].label = out_label;
6123 path->label_stack[path->n_labels].is_uniform = 0;
6124 path->label_stack[path->n_labels].ttl = 64;
6125 path->n_labels++;
6126 }
6127 }
6128 else if (unformat (input, "via"))
6129 {
6130 /* new path, back up and return */
6131 unformat_put_input (input);
6132 unformat_put_input (input);
6133 unformat_put_input (input);
6134 unformat_put_input (input);
6135 break;
6136 }
6137 else
6138 {
6139 return (0);
6140 }
6141 }
6142
6143 path->proto = ntohl (path->proto);
6144 path->type = ntohl (path->type);
6145 path->flags = ntohl (path->flags);
6146 path->table_id = ntohl (path->table_id);
6147 path->sw_if_index = ntohl (path->sw_if_index);
6148
6149 return (1);
6150}
6151
Neale Ranns28ab9cc2017-08-14 07:18:42 -07006152static int
Neale Ranns097fa662018-05-01 05:17:55 -07006153api_ip_route_add_del (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +01006154{
6155 unformat_input_t *i = vam->input;
Neale Ranns097fa662018-05-01 05:17:55 -07006156 vl_api_ip_route_add_del_t *mp;
6157 u32 vrf_id = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006158 u8 is_add = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006159 u8 is_multipath = 0;
Neale Ranns097fa662018-05-01 05:17:55 -07006160 u8 prefix_set = 0;
6161 u8 path_count = 0;
6162 vl_api_prefix_t pfx = { };
6163 vl_api_fib_path_t paths[8];
Damjan Marion7cd468a2016-12-19 23:05:39 +01006164 int count = 1;
6165 int j;
6166 f64 before = 0;
6167 u32 random_add_del = 0;
6168 u32 *random_vector = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006169 u32 random_seed = 0xdeaddabe;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006170
6171 /* Parse args required to build the message */
6172 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6173 {
Neale Ranns097fa662018-05-01 05:17:55 -07006174 if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
6175 prefix_set = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006176 else if (unformat (i, "del"))
6177 is_add = 0;
6178 else if (unformat (i, "add"))
6179 is_add = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006180 else if (unformat (i, "vrf %d", &vrf_id))
6181 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006182 else if (unformat (i, "count %d", &count))
6183 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006184 else if (unformat (i, "random"))
6185 random_add_del = 1;
Neale Ranns097fa662018-05-01 05:17:55 -07006186 else if (unformat (i, "multipath"))
6187 is_multipath = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006188 else if (unformat (i, "seed %d", &random_seed))
6189 ;
6190 else
Neale Ranns097fa662018-05-01 05:17:55 -07006191 if (unformat
6192 (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
6193 {
6194 path_count++;
6195 if (8 == path_count)
6196 {
6197 errmsg ("max 8 paths");
6198 return -99;
6199 }
6200 }
6201 else
Damjan Marion7cd468a2016-12-19 23:05:39 +01006202 {
6203 clib_warning ("parse error '%U'", format_unformat_error, i);
6204 return -99;
6205 }
6206 }
6207
Neale Ranns097fa662018-05-01 05:17:55 -07006208 if (!path_count)
Damjan Marion7cd468a2016-12-19 23:05:39 +01006209 {
Neale Ranns097fa662018-05-01 05:17:55 -07006210 errmsg ("specify a path; via ...");
Damjan Marion7cd468a2016-12-19 23:05:39 +01006211 return -99;
6212 }
Neale Ranns097fa662018-05-01 05:17:55 -07006213 if (prefix_set == 0)
Damjan Marion7cd468a2016-12-19 23:05:39 +01006214 {
Neale Ranns097fa662018-05-01 05:17:55 -07006215 errmsg ("missing prefix");
Damjan Marion7cd468a2016-12-19 23:05:39 +01006216 return -99;
6217 }
6218
6219 /* Generate a pile of unique, random routes */
6220 if (random_add_del)
6221 {
Neale Ranns097fa662018-05-01 05:17:55 -07006222 ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006223 u32 this_random_address;
Neale Ranns097fa662018-05-01 05:17:55 -07006224 uword *random_hash;
6225
Damjan Marion7cd468a2016-12-19 23:05:39 +01006226 random_hash = hash_create (count, sizeof (uword));
6227
Neale Ranns097fa662018-05-01 05:17:55 -07006228 hash_set (random_hash, i->as_u32, 1);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006229 for (j = 0; j <= count; j++)
6230 {
6231 do
6232 {
6233 this_random_address = random_u32 (&random_seed);
6234 this_random_address =
6235 clib_host_to_net_u32 (this_random_address);
6236 }
6237 while (hash_get (random_hash, this_random_address));
6238 vec_add1 (random_vector, this_random_address);
6239 hash_set (random_hash, this_random_address, 1);
6240 }
6241 hash_free (random_hash);
Neale Ranns097fa662018-05-01 05:17:55 -07006242 set_ip4_address (&pfx.address, random_vector[0]);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006243 }
6244
6245 if (count > 1)
6246 {
6247 /* Turn on async mode */
6248 vam->async_mode = 1;
6249 vam->async_errors = 0;
6250 before = vat_time_now (vam);
6251 }
6252
6253 for (j = 0; j < count; j++)
6254 {
6255 /* Construct the API message */
Neale Ranns097fa662018-05-01 05:17:55 -07006256 M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006257
6258 mp->is_add = is_add;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006259 mp->is_multipath = is_multipath;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006260
Neale Ranns097fa662018-05-01 05:17:55 -07006261 clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
6262 mp->route.table_id = ntohl (vrf_id);
6263 mp->route.n_paths = path_count;
6264
6265 clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
6266
6267 if (random_add_del)
6268 set_ip4_address (&pfx.address, random_vector[j + 1]);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006269 else
Neale Ranns097fa662018-05-01 05:17:55 -07006270 increment_address (&pfx.address);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006271 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006272 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006273 /* If we receive SIGTERM, stop now... */
6274 if (vam->do_exit)
6275 break;
6276 }
6277
6278 /* When testing multiple add/del ops, use a control-ping to sync */
6279 if (count > 1)
6280 {
Jon Loeliger2d23eca2017-02-01 13:09:58 -06006281 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006282 f64 after;
Jon Loeliger1f9191f2017-01-31 15:27:19 -06006283 f64 timeout;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006284
6285 /* Shut off async mode */
6286 vam->async_mode = 0;
6287
Dave Barach59b25652017-09-10 15:04:27 -04006288 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06006289 S (mp_ping);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006290
6291 timeout = vat_time_now (vam) + 1.0;
6292 while (vat_time_now (vam) < timeout)
6293 if (vam->result_ready == 1)
6294 goto out;
6295 vam->retval = -99;
6296
6297 out:
6298 if (vam->retval == -99)
6299 errmsg ("timeout");
6300
6301 if (vam->async_errors > 0)
6302 {
6303 errmsg ("%d asynchronous errors", vam->async_errors);
6304 vam->retval = -98;
6305 }
6306 vam->async_errors = 0;
6307 after = vat_time_now (vam);
6308
6309 /* slim chance, but we might have eaten SIGTERM on the first iteration */
6310 if (j > 0)
6311 count = j;
6312
6313 print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6314 count, after - before, count / (after - before));
6315 }
6316 else
6317 {
Jon Loeliger56c7b012017-02-01 12:31:41 -06006318 int ret;
6319
Damjan Marion7cd468a2016-12-19 23:05:39 +01006320 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06006321 W (ret);
6322 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006323 }
6324
6325 /* Return the good/bad news */
6326 return (vam->retval);
6327}
6328
6329static int
Neale Ranns32e1c012016-11-22 17:07:28 +00006330api_ip_mroute_add_del (vat_main_t * vam)
6331{
6332 unformat_input_t *i = vam->input;
Neale Ranns097fa662018-05-01 05:17:55 -07006333 u8 path_set = 0, prefix_set = 0, is_add = 1;
Neale Ranns32e1c012016-11-22 17:07:28 +00006334 vl_api_ip_mroute_add_del_t *mp;
Neale Ranns32e1c012016-11-22 17:07:28 +00006335 mfib_entry_flags_t eflags = 0;
Neale Ranns097fa662018-05-01 05:17:55 -07006336 vl_api_mfib_path_t path;
6337 vl_api_mprefix_t pfx = { };
6338 u32 vrf_id = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006339 int ret;
Neale Ranns32e1c012016-11-22 17:07:28 +00006340
6341 /* Parse args required to build the message */
6342 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6343 {
Neale Ranns097fa662018-05-01 05:17:55 -07006344 if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
Neale Ranns32e1c012016-11-22 17:07:28 +00006345 {
Neale Ranns097fa662018-05-01 05:17:55 -07006346 prefix_set = 1;
6347 pfx.grp_address_length = htons (pfx.grp_address_length);
Neale Ranns32e1c012016-11-22 17:07:28 +00006348 }
6349 else if (unformat (i, "del"))
6350 is_add = 0;
6351 else if (unformat (i, "add"))
6352 is_add = 1;
6353 else if (unformat (i, "vrf %d", &vrf_id))
6354 ;
Neale Ranns097fa662018-05-01 05:17:55 -07006355 else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
6356 path.itf_flags = htonl (path.itf_flags);
Neale Ranns32e1c012016-11-22 17:07:28 +00006357 else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
6358 ;
Neale Ranns097fa662018-05-01 05:17:55 -07006359 else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
6360 path_set = 1;
Neale Ranns32e1c012016-11-22 17:07:28 +00006361 else
6362 {
6363 clib_warning ("parse error '%U'", format_unformat_error, i);
6364 return -99;
6365 }
6366 }
6367
Neale Ranns097fa662018-05-01 05:17:55 -07006368 if (prefix_set == 0)
Neale Ranns32e1c012016-11-22 17:07:28 +00006369 {
6370 errmsg ("missing addresses\n");
6371 return -99;
6372 }
Neale Ranns097fa662018-05-01 05:17:55 -07006373 if (path_set == 0)
6374 {
6375 errmsg ("missing path\n");
6376 return -99;
6377 }
Neale Ranns32e1c012016-11-22 17:07:28 +00006378
6379 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006380 M (IP_MROUTE_ADD_DEL, mp);
Neale Ranns32e1c012016-11-22 17:07:28 +00006381
Neale Ranns32e1c012016-11-22 17:07:28 +00006382 mp->is_add = is_add;
Neale Ranns097fa662018-05-01 05:17:55 -07006383 mp->is_multipath = 1;
Neale Ranns32e1c012016-11-22 17:07:28 +00006384
Neale Ranns097fa662018-05-01 05:17:55 -07006385 clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
6386 mp->route.table_id = htonl (vrf_id);
6387 mp->route.n_paths = 1;
6388 mp->route.entry_flags = htonl (eflags);
Neale Ranns32e1c012016-11-22 17:07:28 +00006389
Neale Ranns097fa662018-05-01 05:17:55 -07006390 clib_memcpy (&mp->route.paths, &path, sizeof (path));
Neale Ranns32e1c012016-11-22 17:07:28 +00006391
6392 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006393 S (mp);
Neale Ranns32e1c012016-11-22 17:07:28 +00006394 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06006395 W (ret);
6396 return ret;
Neale Ranns32e1c012016-11-22 17:07:28 +00006397}
6398
6399static int
Neale Ranns28ab9cc2017-08-14 07:18:42 -07006400api_mpls_table_add_del (vat_main_t * vam)
6401{
6402 unformat_input_t *i = vam->input;
6403 vl_api_mpls_table_add_del_t *mp;
6404 u32 table_id = ~0;
6405 u8 is_add = 1;
6406 int ret = 0;
6407
6408 /* Parse args required to build the message */
6409 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6410 {
Florin Corasd0a59722017-10-15 17:41:21 +00006411 if (unformat (i, "table %d", &table_id))
6412 ;
6413 else if (unformat (i, "del"))
Neale Ranns28ab9cc2017-08-14 07:18:42 -07006414 is_add = 0;
6415 else if (unformat (i, "add"))
6416 is_add = 1;
6417 else
6418 {
6419 clib_warning ("parse error '%U'", format_unformat_error, i);
6420 return -99;
6421 }
6422 }
6423
6424 if (~0 == table_id)
6425 {
6426 errmsg ("missing table-ID");
6427 return -99;
6428 }
6429
6430 /* Construct the API message */
6431 M (MPLS_TABLE_ADD_DEL, mp);
6432
Neale Ranns097fa662018-05-01 05:17:55 -07006433 mp->mt_table.mt_table_id = ntohl (table_id);
Neale Ranns28ab9cc2017-08-14 07:18:42 -07006434 mp->mt_is_add = is_add;
6435
6436 /* send it... */
6437 S (mp);
6438
6439 /* Wait for a reply... */
6440 W (ret);
6441
6442 return ret;
6443}
6444
6445static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01006446api_mpls_route_add_del (vat_main_t * vam)
6447{
Neale Ranns097fa662018-05-01 05:17:55 -07006448 u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
6449 mpls_label_t local_label = MPLS_LABEL_INVALID;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006450 unformat_input_t *i = vam->input;
6451 vl_api_mpls_route_add_del_t *mp;
Neale Ranns097fa662018-05-01 05:17:55 -07006452 vl_api_fib_path_t paths[8];
6453 int count = 1, j;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006454 f64 before = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006455
6456 /* Parse args required to build the message */
6457 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6458 {
Neale Ranns097fa662018-05-01 05:17:55 -07006459 if (unformat (i, "%d", &local_label))
Damjan Marion7cd468a2016-12-19 23:05:39 +01006460 ;
6461 else if (unformat (i, "eos"))
6462 is_eos = 1;
6463 else if (unformat (i, "non-eos"))
6464 is_eos = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006465 else if (unformat (i, "del"))
6466 is_add = 0;
6467 else if (unformat (i, "add"))
6468 is_add = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006469 else if (unformat (i, "multipath"))
6470 is_multipath = 1;
6471 else if (unformat (i, "count %d", &count))
6472 ;
John Loe166fd92018-09-13 14:08:59 -04006473 else
6474 if (unformat
Neale Ranns097fa662018-05-01 05:17:55 -07006475 (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
John Loe166fd92018-09-13 14:08:59 -04006476 {
Neale Ranns097fa662018-05-01 05:17:55 -07006477 path_count++;
6478 if (8 == path_count)
6479 {
6480 errmsg ("max 8 paths");
6481 return -99;
6482 }
John Loe166fd92018-09-13 14:08:59 -04006483 }
Damjan Marion7cd468a2016-12-19 23:05:39 +01006484 else
6485 {
6486 clib_warning ("parse error '%U'", format_unformat_error, i);
6487 return -99;
6488 }
6489 }
6490
Neale Ranns097fa662018-05-01 05:17:55 -07006491 if (!path_count)
Damjan Marion7cd468a2016-12-19 23:05:39 +01006492 {
Neale Ranns097fa662018-05-01 05:17:55 -07006493 errmsg ("specify a path; via ...");
Damjan Marion7cd468a2016-12-19 23:05:39 +01006494 return -99;
6495 }
6496
6497 if (MPLS_LABEL_INVALID == local_label)
6498 {
6499 errmsg ("missing label");
6500 return -99;
6501 }
6502
6503 if (count > 1)
6504 {
6505 /* Turn on async mode */
6506 vam->async_mode = 1;
6507 vam->async_errors = 0;
6508 before = vat_time_now (vam);
6509 }
6510
6511 for (j = 0; j < count; j++)
6512 {
6513 /* Construct the API message */
Neale Ranns097fa662018-05-01 05:17:55 -07006514 M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006515
6516 mp->mr_is_add = is_add;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006517 mp->mr_is_multipath = is_multipath;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006518
Neale Ranns097fa662018-05-01 05:17:55 -07006519 mp->mr_route.mr_label = local_label;
6520 mp->mr_route.mr_eos = is_eos;
6521 mp->mr_route.mr_table_id = 0;
6522 mp->mr_route.mr_n_paths = path_count;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006523
Neale Ranns097fa662018-05-01 05:17:55 -07006524 clib_memcpy (&mp->mr_route.mr_paths, paths,
6525 sizeof (paths[0]) * path_count);
Neale Rannsda78f952017-05-24 09:15:43 -07006526
Damjan Marion7cd468a2016-12-19 23:05:39 +01006527 local_label++;
6528
6529 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006530 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006531 /* If we receive SIGTERM, stop now... */
6532 if (vam->do_exit)
6533 break;
6534 }
6535
6536 /* When testing multiple add/del ops, use a control-ping to sync */
6537 if (count > 1)
6538 {
Jon Loeliger2d23eca2017-02-01 13:09:58 -06006539 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006540 f64 after;
Jon Loeliger1f9191f2017-01-31 15:27:19 -06006541 f64 timeout;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006542
6543 /* Shut off async mode */
6544 vam->async_mode = 0;
6545
Dave Barach59b25652017-09-10 15:04:27 -04006546 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06006547 S (mp_ping);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006548
6549 timeout = vat_time_now (vam) + 1.0;
6550 while (vat_time_now (vam) < timeout)
6551 if (vam->result_ready == 1)
6552 goto out;
6553 vam->retval = -99;
6554
6555 out:
6556 if (vam->retval == -99)
6557 errmsg ("timeout");
6558
6559 if (vam->async_errors > 0)
6560 {
6561 errmsg ("%d asynchronous errors", vam->async_errors);
6562 vam->retval = -98;
6563 }
6564 vam->async_errors = 0;
6565 after = vat_time_now (vam);
6566
6567 /* slim chance, but we might have eaten SIGTERM on the first iteration */
6568 if (j > 0)
6569 count = j;
6570
6571 print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6572 count, after - before, count / (after - before));
6573 }
6574 else
6575 {
Jon Loeliger56c7b012017-02-01 12:31:41 -06006576 int ret;
6577
Damjan Marion7cd468a2016-12-19 23:05:39 +01006578 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06006579 W (ret);
6580 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006581 }
6582
6583 /* Return the good/bad news */
6584 return (vam->retval);
Neale Ranns097fa662018-05-01 05:17:55 -07006585 return (0);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006586}
6587
6588static int
6589api_mpls_ip_bind_unbind (vat_main_t * vam)
6590{
6591 unformat_input_t *i = vam->input;
6592 vl_api_mpls_ip_bind_unbind_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006593 u32 ip_table_id = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006594 u8 is_bind = 1;
Neale Ranns097fa662018-05-01 05:17:55 -07006595 vl_api_prefix_t pfx;
6596 u8 prefix_set = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006597 mpls_label_t local_label = MPLS_LABEL_INVALID;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006598 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006599
6600 /* Parse args required to build the message */
6601 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6602 {
Neale Ranns097fa662018-05-01 05:17:55 -07006603 if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
6604 prefix_set = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006605 else if (unformat (i, "%d", &local_label))
6606 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006607 else if (unformat (i, "table-id %d", &ip_table_id))
6608 ;
6609 else if (unformat (i, "unbind"))
6610 is_bind = 0;
6611 else if (unformat (i, "bind"))
6612 is_bind = 1;
6613 else
6614 {
6615 clib_warning ("parse error '%U'", format_unformat_error, i);
6616 return -99;
6617 }
6618 }
6619
Neale Ranns097fa662018-05-01 05:17:55 -07006620 if (!prefix_set)
Damjan Marion7cd468a2016-12-19 23:05:39 +01006621 {
Neale Ranns097fa662018-05-01 05:17:55 -07006622 errmsg ("IP prefix not set");
Damjan Marion7cd468a2016-12-19 23:05:39 +01006623 return -99;
6624 }
6625
6626 if (MPLS_LABEL_INVALID == local_label)
6627 {
6628 errmsg ("missing label");
6629 return -99;
6630 }
6631
6632 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006633 M (MPLS_IP_BIND_UNBIND, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006634
Damjan Marion7cd468a2016-12-19 23:05:39 +01006635 mp->mb_is_bind = is_bind;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006636 mp->mb_ip_table_id = ntohl (ip_table_id);
6637 mp->mb_mpls_table_id = 0;
6638 mp->mb_label = ntohl (local_label);
Neale Ranns097fa662018-05-01 05:17:55 -07006639 clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
Damjan Marion7cd468a2016-12-19 23:05:39 +01006640
6641 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006642 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006643
6644 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06006645 W (ret);
6646 return ret;
Neale Ranns097fa662018-05-01 05:17:55 -07006647 return (0);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006648}
6649
6650static int
John Loe166fd92018-09-13 14:08:59 -04006651api_sr_mpls_policy_add (vat_main_t * vam)
6652{
6653 unformat_input_t *i = vam->input;
6654 vl_api_sr_mpls_policy_add_t *mp;
6655 u32 bsid = 0;
6656 u32 weight = 1;
6657 u8 type = 0;
6658 u8 n_segments = 0;
6659 u32 sid;
6660 u32 *segments = NULL;
6661 int ret;
6662
6663 /* Parse args required to build the message */
6664 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6665 {
6666 if (unformat (i, "bsid %d", &bsid))
6667 ;
6668 else if (unformat (i, "weight %d", &weight))
6669 ;
6670 else if (unformat (i, "spray"))
6671 type = 1;
6672 else if (unformat (i, "next %d", &sid))
6673 {
6674 n_segments += 1;
6675 vec_add1 (segments, htonl (sid));
6676 }
6677 else
6678 {
6679 clib_warning ("parse error '%U'", format_unformat_error, i);
6680 return -99;
6681 }
6682 }
6683
6684 if (bsid == 0)
6685 {
6686 errmsg ("bsid not set");
6687 return -99;
6688 }
6689
6690 if (n_segments == 0)
6691 {
6692 errmsg ("no sid in segment stack");
6693 return -99;
6694 }
6695
6696 /* Construct the API message */
6697 M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
6698
6699 mp->bsid = htonl (bsid);
6700 mp->weight = htonl (weight);
Jakub Grajciar00ec4012020-01-31 10:17:29 +01006701 mp->is_spray = type;
John Loe166fd92018-09-13 14:08:59 -04006702 mp->n_segments = n_segments;
6703 memcpy (mp->segments, segments, sizeof (u32) * n_segments);
6704 vec_free (segments);
6705
6706 /* send it... */
6707 S (mp);
6708
6709 /* Wait for a reply... */
6710 W (ret);
6711 return ret;
6712}
6713
6714static int
6715api_sr_mpls_policy_del (vat_main_t * vam)
6716{
6717 unformat_input_t *i = vam->input;
6718 vl_api_sr_mpls_policy_del_t *mp;
6719 u32 bsid = 0;
6720 int ret;
6721
6722 /* Parse args required to build the message */
6723 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6724 {
6725 if (unformat (i, "bsid %d", &bsid))
6726 ;
6727 else
6728 {
6729 clib_warning ("parse error '%U'", format_unformat_error, i);
6730 return -99;
6731 }
6732 }
6733
6734 if (bsid == 0)
6735 {
6736 errmsg ("bsid not set");
6737 return -99;
6738 }
6739
6740 /* Construct the API message */
6741 M (SR_MPLS_POLICY_DEL, mp);
6742
6743 mp->bsid = htonl (bsid);
6744
6745 /* send it... */
6746 S (mp);
6747
6748 /* Wait for a reply... */
6749 W (ret);
6750 return ret;
6751}
6752
6753static int
Neale Rannsd792d9c2017-10-21 10:53:20 -07006754api_bier_table_add_del (vat_main_t * vam)
6755{
6756 unformat_input_t *i = vam->input;
6757 vl_api_bier_table_add_del_t *mp;
6758 u8 is_add = 1;
6759 u32 set = 0, sub_domain = 0, hdr_len = 3;
6760 mpls_label_t local_label = MPLS_LABEL_INVALID;
6761 int ret;
6762
6763 /* Parse args required to build the message */
6764 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6765 {
6766 if (unformat (i, "sub-domain %d", &sub_domain))
6767 ;
6768 else if (unformat (i, "set %d", &set))
6769 ;
6770 else if (unformat (i, "label %d", &local_label))
6771 ;
6772 else if (unformat (i, "hdr-len %d", &hdr_len))
6773 ;
6774 else if (unformat (i, "add"))
6775 is_add = 1;
6776 else if (unformat (i, "del"))
6777 is_add = 0;
6778 else
6779 {
6780 clib_warning ("parse error '%U'", format_unformat_error, i);
6781 return -99;
6782 }
6783 }
6784
6785 if (MPLS_LABEL_INVALID == local_label)
6786 {
6787 errmsg ("missing label\n");
6788 return -99;
6789 }
6790
6791 /* Construct the API message */
6792 M (BIER_TABLE_ADD_DEL, mp);
6793
6794 mp->bt_is_add = is_add;
6795 mp->bt_label = ntohl (local_label);
6796 mp->bt_tbl_id.bt_set = set;
6797 mp->bt_tbl_id.bt_sub_domain = sub_domain;
6798 mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
6799
6800 /* send it... */
6801 S (mp);
6802
6803 /* Wait for a reply... */
6804 W (ret);
6805
6806 return (ret);
6807}
6808
6809static int
6810api_bier_route_add_del (vat_main_t * vam)
6811{
6812 unformat_input_t *i = vam->input;
6813 vl_api_bier_route_add_del_t *mp;
6814 u8 is_add = 1;
6815 u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
6816 ip4_address_t v4_next_hop_address;
6817 ip6_address_t v6_next_hop_address;
6818 u8 next_hop_set = 0;
6819 u8 next_hop_proto_is_ip4 = 1;
6820 mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6821 int ret;
6822
6823 /* Parse args required to build the message */
6824 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6825 {
6826 if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
6827 {
6828 next_hop_proto_is_ip4 = 1;
6829 next_hop_set = 1;
6830 }
6831 else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
6832 {
6833 next_hop_proto_is_ip4 = 0;
6834 next_hop_set = 1;
6835 }
6836 if (unformat (i, "sub-domain %d", &sub_domain))
6837 ;
6838 else if (unformat (i, "set %d", &set))
6839 ;
6840 else if (unformat (i, "hdr-len %d", &hdr_len))
6841 ;
6842 else if (unformat (i, "bp %d", &bp))
6843 ;
6844 else if (unformat (i, "add"))
6845 is_add = 1;
6846 else if (unformat (i, "del"))
6847 is_add = 0;
6848 else if (unformat (i, "out-label %d", &next_hop_out_label))
6849 ;
6850 else
6851 {
6852 clib_warning ("parse error '%U'", format_unformat_error, i);
6853 return -99;
6854 }
6855 }
6856
6857 if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
6858 {
6859 errmsg ("next hop / label set\n");
6860 return -99;
6861 }
6862 if (0 == bp)
6863 {
6864 errmsg ("bit=position not set\n");
6865 return -99;
6866 }
6867
6868 /* Construct the API message */
Neale Ranns31ed7442018-02-23 05:29:09 -08006869 M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
Neale Rannsd792d9c2017-10-21 10:53:20 -07006870
6871 mp->br_is_add = is_add;
Neale Ranns097fa662018-05-01 05:17:55 -07006872 mp->br_route.br_tbl_id.bt_set = set;
6873 mp->br_route.br_tbl_id.bt_sub_domain = sub_domain;
6874 mp->br_route.br_tbl_id.bt_hdr_len_id = hdr_len;
6875 mp->br_route.br_bp = ntohs (bp);
6876 mp->br_route.br_n_paths = 1;
6877 mp->br_route.br_paths[0].n_labels = 1;
6878 mp->br_route.br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
6879 mp->br_route.br_paths[0].proto = (next_hop_proto_is_ip4 ?
6880 FIB_API_PATH_NH_PROTO_IP4 :
6881 FIB_API_PATH_NH_PROTO_IP6);
Neale Rannsd792d9c2017-10-21 10:53:20 -07006882
6883 if (next_hop_proto_is_ip4)
6884 {
Neale Ranns097fa662018-05-01 05:17:55 -07006885 clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip4,
Neale Rannsd792d9c2017-10-21 10:53:20 -07006886 &v4_next_hop_address, sizeof (v4_next_hop_address));
6887 }
6888 else
6889 {
Neale Ranns097fa662018-05-01 05:17:55 -07006890 clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip6,
Neale Rannsd792d9c2017-10-21 10:53:20 -07006891 &v6_next_hop_address, sizeof (v6_next_hop_address));
6892 }
6893
6894 /* send it... */
6895 S (mp);
6896
6897 /* Wait for a reply... */
6898 W (ret);
6899
6900 return (ret);
6901}
6902
6903static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01006904api_mpls_tunnel_add_del (vat_main_t * vam)
6905{
6906 unformat_input_t *i = vam->input;
6907 vl_api_mpls_tunnel_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006908
Neale Ranns097fa662018-05-01 05:17:55 -07006909 vl_api_fib_path_t paths[8];
Damjan Marion7cd468a2016-12-19 23:05:39 +01006910 u32 sw_if_index = ~0;
Neale Ranns097fa662018-05-01 05:17:55 -07006911 u8 path_count = 0;
6912 u8 l2_only = 0;
6913 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006914 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006915
6916 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6917 {
6918 if (unformat (i, "add"))
6919 is_add = 1;
John Lo06fda9c2018-10-03 16:32:44 -04006920 else
6921 if (unformat
6922 (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
6923 is_add = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006924 else if (unformat (i, "del sw_if_index %d", &sw_if_index))
6925 is_add = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006926 else if (unformat (i, "l2-only"))
6927 l2_only = 1;
Neale Ranns097fa662018-05-01 05:17:55 -07006928 else
6929 if (unformat
6930 (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
John Lo06fda9c2018-10-03 16:32:44 -04006931 {
Neale Ranns097fa662018-05-01 05:17:55 -07006932 path_count++;
6933 if (8 == path_count)
6934 {
6935 errmsg ("max 8 paths");
6936 return -99;
6937 }
John Lo06fda9c2018-10-03 16:32:44 -04006938 }
Damjan Marion7cd468a2016-12-19 23:05:39 +01006939 else
6940 {
6941 clib_warning ("parse error '%U'", format_unformat_error, i);
6942 return -99;
6943 }
6944 }
6945
Neale Ranns097fa662018-05-01 05:17:55 -07006946 M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006947
Damjan Marion7cd468a2016-12-19 23:05:39 +01006948 mp->mt_is_add = is_add;
Neale Ranns097fa662018-05-01 05:17:55 -07006949 mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
6950 mp->mt_tunnel.mt_l2_only = l2_only;
6951 mp->mt_tunnel.mt_is_multicast = 0;
6952 mp->mt_tunnel.mt_n_paths = path_count;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006953
Neale Ranns097fa662018-05-01 05:17:55 -07006954 clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
6955 sizeof (paths[0]) * path_count);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006956
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006957 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06006958 W (ret);
6959 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006960}
6961
6962static int
6963api_sw_interface_set_unnumbered (vat_main_t * vam)
6964{
6965 unformat_input_t *i = vam->input;
6966 vl_api_sw_interface_set_unnumbered_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006967 u32 sw_if_index;
6968 u32 unnum_sw_index = ~0;
6969 u8 is_add = 1;
6970 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006971 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006972
6973 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6974 {
6975 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6976 sw_if_index_set = 1;
6977 else if (unformat (i, "sw_if_index %d", &sw_if_index))
6978 sw_if_index_set = 1;
6979 else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
6980 ;
6981 else if (unformat (i, "del"))
6982 is_add = 0;
6983 else
6984 {
6985 clib_warning ("parse error '%U'", format_unformat_error, i);
6986 return -99;
6987 }
6988 }
6989
6990 if (sw_if_index_set == 0)
6991 {
6992 errmsg ("missing interface name or sw_if_index");
6993 return -99;
6994 }
6995
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006996 M (SW_INTERFACE_SET_UNNUMBERED, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006997
6998 mp->sw_if_index = ntohl (sw_if_index);
6999 mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
7000 mp->is_add = is_add;
7001
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007002 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007003 W (ret);
7004 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007005}
7006
Damjan Marion7cd468a2016-12-19 23:05:39 +01007007
7008static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01007009api_create_vlan_subif (vat_main_t * vam)
7010{
7011 unformat_input_t *i = vam->input;
7012 vl_api_create_vlan_subif_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007013 u32 sw_if_index;
7014 u8 sw_if_index_set = 0;
7015 u32 vlan_id;
7016 u8 vlan_id_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007017 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007018
7019 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7020 {
7021 if (unformat (i, "sw_if_index %d", &sw_if_index))
7022 sw_if_index_set = 1;
7023 else
7024 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7025 sw_if_index_set = 1;
7026 else if (unformat (i, "vlan %d", &vlan_id))
7027 vlan_id_set = 1;
7028 else
7029 {
7030 clib_warning ("parse error '%U'", format_unformat_error, i);
7031 return -99;
7032 }
7033 }
7034
7035 if (sw_if_index_set == 0)
7036 {
7037 errmsg ("missing interface name or sw_if_index");
7038 return -99;
7039 }
7040
7041 if (vlan_id_set == 0)
7042 {
7043 errmsg ("missing vlan_id");
7044 return -99;
7045 }
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007046 M (CREATE_VLAN_SUBIF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007047
7048 mp->sw_if_index = ntohl (sw_if_index);
7049 mp->vlan_id = ntohl (vlan_id);
7050
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007051 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007052 W (ret);
7053 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007054}
7055
7056#define foreach_create_subif_bit \
7057_(no_tags) \
7058_(one_tag) \
7059_(two_tags) \
7060_(dot1ad) \
7061_(exact_match) \
7062_(default_sub) \
7063_(outer_vlan_id_any) \
7064_(inner_vlan_id_any)
7065
Jakub Grajciar053204a2019-03-18 13:17:53 +01007066#define foreach_create_subif_flag \
7067_(0, "no_tags") \
7068_(1, "one_tag") \
7069_(2, "two_tags") \
7070_(3, "dot1ad") \
7071_(4, "exact_match") \
7072_(5, "default_sub") \
7073_(6, "outer_vlan_id_any") \
7074_(7, "inner_vlan_id_any")
7075
Damjan Marion7cd468a2016-12-19 23:05:39 +01007076static int
7077api_create_subif (vat_main_t * vam)
7078{
7079 unformat_input_t *i = vam->input;
7080 vl_api_create_subif_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007081 u32 sw_if_index;
7082 u8 sw_if_index_set = 0;
7083 u32 sub_id;
7084 u8 sub_id_set = 0;
Jakub Grajciar053204a2019-03-18 13:17:53 +01007085 u32 __attribute__ ((unused)) no_tags = 0;
7086 u32 __attribute__ ((unused)) one_tag = 0;
7087 u32 __attribute__ ((unused)) two_tags = 0;
7088 u32 __attribute__ ((unused)) dot1ad = 0;
7089 u32 __attribute__ ((unused)) exact_match = 0;
7090 u32 __attribute__ ((unused)) default_sub = 0;
7091 u32 __attribute__ ((unused)) outer_vlan_id_any = 0;
7092 u32 __attribute__ ((unused)) inner_vlan_id_any = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007093 u32 tmp;
7094 u16 outer_vlan_id = 0;
7095 u16 inner_vlan_id = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007096 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007097
7098 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7099 {
7100 if (unformat (i, "sw_if_index %d", &sw_if_index))
7101 sw_if_index_set = 1;
7102 else
7103 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7104 sw_if_index_set = 1;
7105 else if (unformat (i, "sub_id %d", &sub_id))
7106 sub_id_set = 1;
7107 else if (unformat (i, "outer_vlan_id %d", &tmp))
7108 outer_vlan_id = tmp;
7109 else if (unformat (i, "inner_vlan_id %d", &tmp))
7110 inner_vlan_id = tmp;
7111
7112#define _(a) else if (unformat (i, #a)) a = 1 ;
7113 foreach_create_subif_bit
7114#undef _
7115 else
7116 {
7117 clib_warning ("parse error '%U'", format_unformat_error, i);
7118 return -99;
7119 }
7120 }
7121
7122 if (sw_if_index_set == 0)
7123 {
7124 errmsg ("missing interface name or sw_if_index");
7125 return -99;
7126 }
7127
7128 if (sub_id_set == 0)
7129 {
7130 errmsg ("missing sub_id");
7131 return -99;
7132 }
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007133 M (CREATE_SUBIF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007134
7135 mp->sw_if_index = ntohl (sw_if_index);
7136 mp->sub_id = ntohl (sub_id);
7137
Jakub Grajciar053204a2019-03-18 13:17:53 +01007138#define _(a,b) mp->sub_if_flags |= (1 << a);
7139 foreach_create_subif_flag;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007140#undef _
7141
7142 mp->outer_vlan_id = ntohs (outer_vlan_id);
7143 mp->inner_vlan_id = ntohs (inner_vlan_id);
7144
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007145 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007146 W (ret);
7147 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007148}
7149
7150static int
Neale Ranns9db6ada2019-11-08 12:42:31 +00007151api_ip_table_replace_begin (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +01007152{
7153 unformat_input_t *i = vam->input;
Neale Ranns9db6ada2019-11-08 12:42:31 +00007154 vl_api_ip_table_replace_begin_t *mp;
7155 u32 table_id = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007156 u8 is_ipv6 = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007157
Jon Loeliger56c7b012017-02-01 12:31:41 -06007158 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007159 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7160 {
Neale Ranns9db6ada2019-11-08 12:42:31 +00007161 if (unformat (i, "table %d", &table_id))
7162 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007163 else if (unformat (i, "ipv6"))
7164 is_ipv6 = 1;
7165 else
7166 {
7167 clib_warning ("parse error '%U'", format_unformat_error, i);
7168 return -99;
7169 }
7170 }
7171
Neale Ranns9db6ada2019-11-08 12:42:31 +00007172 M (IP_TABLE_REPLACE_BEGIN, mp);
7173
7174 mp->table.table_id = ntohl (table_id);
7175 mp->table.is_ip6 = is_ipv6;
7176
7177 S (mp);
7178 W (ret);
7179 return ret;
7180}
7181
7182static int
7183api_ip_table_flush (vat_main_t * vam)
7184{
7185 unformat_input_t *i = vam->input;
7186 vl_api_ip_table_flush_t *mp;
7187 u32 table_id = 0;
7188 u8 is_ipv6 = 0;
7189
7190 int ret;
7191 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
Damjan Marion7cd468a2016-12-19 23:05:39 +01007192 {
Neale Ranns9db6ada2019-11-08 12:42:31 +00007193 if (unformat (i, "table %d", &table_id))
7194 ;
7195 else if (unformat (i, "ipv6"))
7196 is_ipv6 = 1;
7197 else
7198 {
7199 clib_warning ("parse error '%U'", format_unformat_error, i);
7200 return -99;
7201 }
Damjan Marion7cd468a2016-12-19 23:05:39 +01007202 }
7203
Neale Ranns9db6ada2019-11-08 12:42:31 +00007204 M (IP_TABLE_FLUSH, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007205
Neale Ranns9db6ada2019-11-08 12:42:31 +00007206 mp->table.table_id = ntohl (table_id);
7207 mp->table.is_ip6 = is_ipv6;
7208
7209 S (mp);
7210 W (ret);
7211 return ret;
7212}
7213
7214static int
7215api_ip_table_replace_end (vat_main_t * vam)
7216{
7217 unformat_input_t *i = vam->input;
7218 vl_api_ip_table_replace_end_t *mp;
7219 u32 table_id = 0;
7220 u8 is_ipv6 = 0;
7221
7222 int ret;
7223 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7224 {
7225 if (unformat (i, "table %d", &table_id))
7226 ;
7227 else if (unformat (i, "ipv6"))
7228 is_ipv6 = 1;
7229 else
7230 {
7231 clib_warning ("parse error '%U'", format_unformat_error, i);
7232 return -99;
7233 }
7234 }
7235
7236 M (IP_TABLE_REPLACE_END, mp);
7237
7238 mp->table.table_id = ntohl (table_id);
7239 mp->table.is_ip6 = is_ipv6;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007240
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007241 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007242 W (ret);
7243 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007244}
7245
7246static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01007247api_set_ip_flow_hash (vat_main_t * vam)
7248{
7249 unformat_input_t *i = vam->input;
7250 vl_api_set_ip_flow_hash_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007251 u32 vrf_id = 0;
7252 u8 is_ipv6 = 0;
7253 u8 vrf_id_set = 0;
7254 u8 src = 0;
7255 u8 dst = 0;
7256 u8 sport = 0;
7257 u8 dport = 0;
7258 u8 proto = 0;
7259 u8 reverse = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007260 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007261
7262 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7263 {
7264 if (unformat (i, "vrf %d", &vrf_id))
7265 vrf_id_set = 1;
7266 else if (unformat (i, "ipv6"))
7267 is_ipv6 = 1;
7268 else if (unformat (i, "src"))
7269 src = 1;
7270 else if (unformat (i, "dst"))
7271 dst = 1;
7272 else if (unformat (i, "sport"))
7273 sport = 1;
7274 else if (unformat (i, "dport"))
7275 dport = 1;
7276 else if (unformat (i, "proto"))
7277 proto = 1;
7278 else if (unformat (i, "reverse"))
7279 reverse = 1;
7280
7281 else
7282 {
7283 clib_warning ("parse error '%U'", format_unformat_error, i);
7284 return -99;
7285 }
7286 }
7287
7288 if (vrf_id_set == 0)
7289 {
7290 errmsg ("missing vrf id");
7291 return -99;
7292 }
7293
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007294 M (SET_IP_FLOW_HASH, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007295 mp->src = src;
7296 mp->dst = dst;
7297 mp->sport = sport;
7298 mp->dport = dport;
7299 mp->proto = proto;
7300 mp->reverse = reverse;
7301 mp->vrf_id = ntohl (vrf_id);
7302 mp->is_ipv6 = is_ipv6;
7303
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007304 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007305 W (ret);
7306 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007307}
7308
7309static int
7310api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7311{
7312 unformat_input_t *i = vam->input;
7313 vl_api_sw_interface_ip6_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007314 u32 sw_if_index;
7315 u8 sw_if_index_set = 0;
7316 u8 enable = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007317 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007318
7319 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7320 {
7321 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7322 sw_if_index_set = 1;
7323 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7324 sw_if_index_set = 1;
7325 else if (unformat (i, "enable"))
7326 enable = 1;
7327 else if (unformat (i, "disable"))
7328 enable = 0;
7329 else
7330 {
7331 clib_warning ("parse error '%U'", format_unformat_error, i);
7332 return -99;
7333 }
7334 }
7335
7336 if (sw_if_index_set == 0)
7337 {
7338 errmsg ("missing interface name or sw_if_index");
7339 return -99;
7340 }
7341
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007342 M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007343
7344 mp->sw_if_index = ntohl (sw_if_index);
7345 mp->enable = enable;
7346
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007347 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007348 W (ret);
7349 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007350}
7351
Damjan Marion7cd468a2016-12-19 23:05:39 +01007352
7353static int
7354api_l2_patch_add_del (vat_main_t * vam)
7355{
7356 unformat_input_t *i = vam->input;
7357 vl_api_l2_patch_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007358 u32 rx_sw_if_index;
7359 u8 rx_sw_if_index_set = 0;
7360 u32 tx_sw_if_index;
7361 u8 tx_sw_if_index_set = 0;
7362 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007363 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007364
7365 /* Parse args required to build the message */
7366 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7367 {
7368 if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7369 rx_sw_if_index_set = 1;
7370 else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7371 tx_sw_if_index_set = 1;
7372 else if (unformat (i, "rx"))
7373 {
7374 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7375 {
7376 if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7377 &rx_sw_if_index))
7378 rx_sw_if_index_set = 1;
7379 }
7380 else
7381 break;
7382 }
7383 else if (unformat (i, "tx"))
7384 {
7385 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7386 {
7387 if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7388 &tx_sw_if_index))
7389 tx_sw_if_index_set = 1;
7390 }
7391 else
7392 break;
7393 }
7394 else if (unformat (i, "del"))
7395 is_add = 0;
7396 else
7397 break;
7398 }
7399
7400 if (rx_sw_if_index_set == 0)
7401 {
7402 errmsg ("missing rx interface name or rx_sw_if_index");
7403 return -99;
7404 }
7405
7406 if (tx_sw_if_index_set == 0)
7407 {
7408 errmsg ("missing tx interface name or tx_sw_if_index");
7409 return -99;
7410 }
7411
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007412 M (L2_PATCH_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007413
7414 mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7415 mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7416 mp->is_add = is_add;
7417
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007418 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007419 W (ret);
7420 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007421}
7422
Pablo Camarillofb380952016-12-07 18:34:18 +01007423u8 is_del;
7424u8 localsid_addr[16];
7425u8 end_psp;
7426u8 behavior;
7427u32 sw_if_index;
7428u32 vlan_index;
7429u32 fib_table;
7430u8 nh_addr[16];
7431
7432static int
7433api_sr_localsid_add_del (vat_main_t * vam)
7434{
7435 unformat_input_t *i = vam->input;
7436 vl_api_sr_localsid_add_del_t *mp;
7437
7438 u8 is_del;
7439 ip6_address_t localsid;
7440 u8 end_psp = 0;
7441 u8 behavior = ~0;
7442 u32 sw_if_index;
7443 u32 fib_table = ~(u32) 0;
Jakub Grajciar0938eba2020-03-04 13:08:27 +01007444 ip46_address_t nh_addr;
7445 clib_memset (&nh_addr, 0, sizeof (ip46_address_t));
Pablo Camarillofb380952016-12-07 18:34:18 +01007446
7447 bool nexthop_set = 0;
7448
7449 int ret;
7450
7451 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7452 {
7453 if (unformat (i, "del"))
7454 is_del = 1;
7455 else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
Jakub Grajciar0938eba2020-03-04 13:08:27 +01007456 else if (unformat (i, "next-hop %U", unformat_ip46_address, &nh_addr))
Pablo Camarillofb380952016-12-07 18:34:18 +01007457 nexthop_set = 1;
7458 else if (unformat (i, "behavior %u", &behavior));
7459 else if (unformat (i, "sw_if_index %u", &sw_if_index));
7460 else if (unformat (i, "fib-table %u", &fib_table));
7461 else if (unformat (i, "end.psp %u", &behavior));
7462 else
7463 break;
7464 }
7465
7466 M (SR_LOCALSID_ADD_DEL, mp);
7467
Jakub Grajciar0938eba2020-03-04 13:08:27 +01007468 clib_memcpy (mp->localsid, &localsid, sizeof (mp->localsid));
Tetsuya Murakami1b81e6e2019-11-06 11:05:51 -08007469
Pablo Camarillofb380952016-12-07 18:34:18 +01007470 if (nexthop_set)
Pablo Camarillo3337bd22018-06-19 15:49:02 +02007471 {
Jakub Grajciar0938eba2020-03-04 13:08:27 +01007472 clib_memcpy (&mp->nh_addr.un, &nh_addr, sizeof (mp->nh_addr.un));
Pablo Camarillo3337bd22018-06-19 15:49:02 +02007473 }
Pablo Camarillofb380952016-12-07 18:34:18 +01007474 mp->behavior = behavior;
7475 mp->sw_if_index = ntohl (sw_if_index);
7476 mp->fib_table = ntohl (fib_table);
7477 mp->end_psp = end_psp;
7478 mp->is_del = is_del;
7479
7480 S (mp);
7481 W (ret);
7482 return ret;
7483}
7484
Damjan Marion7cd468a2016-12-19 23:05:39 +01007485static int
7486api_ioam_enable (vat_main_t * vam)
7487{
7488 unformat_input_t *input = vam->input;
7489 vl_api_ioam_enable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007490 u32 id = 0;
7491 int has_trace_option = 0;
7492 int has_pot_option = 0;
7493 int has_seqno_option = 0;
7494 int has_analyse_option = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007495 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007496
7497 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7498 {
7499 if (unformat (input, "trace"))
7500 has_trace_option = 1;
7501 else if (unformat (input, "pot"))
7502 has_pot_option = 1;
7503 else if (unformat (input, "seqno"))
7504 has_seqno_option = 1;
7505 else if (unformat (input, "analyse"))
7506 has_analyse_option = 1;
7507 else
7508 break;
7509 }
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007510 M (IOAM_ENABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007511 mp->id = htons (id);
7512 mp->seqno = has_seqno_option;
7513 mp->analyse = has_analyse_option;
7514 mp->pot_enable = has_pot_option;
7515 mp->trace_enable = has_trace_option;
7516
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007517 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007518 W (ret);
7519 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007520}
7521
7522
7523static int
7524api_ioam_disable (vat_main_t * vam)
7525{
7526 vl_api_ioam_disable_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007527 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007528
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007529 M (IOAM_DISABLE, mp);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007530 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007531 W (ret);
7532 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007533}
7534
Damjan Marion7cd468a2016-12-19 23:05:39 +01007535#define foreach_tcp_proto_field \
7536_(src_port) \
7537_(dst_port)
7538
7539#define foreach_udp_proto_field \
7540_(src_port) \
7541_(dst_port)
7542
7543#define foreach_ip4_proto_field \
7544_(src_address) \
7545_(dst_address) \
7546_(tos) \
7547_(length) \
7548_(fragment_id) \
7549_(ttl) \
7550_(protocol) \
7551_(checksum)
7552
Dave Barach4a3f69c2017-02-22 12:44:56 -05007553typedef struct
7554{
7555 u16 src_port, dst_port;
7556} tcpudp_header_t;
7557
7558#if VPP_API_TEST_BUILTIN == 0
Damjan Marion7cd468a2016-12-19 23:05:39 +01007559uword
7560unformat_tcp_mask (unformat_input_t * input, va_list * args)
7561{
7562 u8 **maskp = va_arg (*args, u8 **);
7563 u8 *mask = 0;
7564 u8 found_something = 0;
7565 tcp_header_t *tcp;
7566
7567#define _(a) u8 a=0;
7568 foreach_tcp_proto_field;
7569#undef _
7570
7571 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7572 {
7573 if (0);
7574#define _(a) else if (unformat (input, #a)) a=1;
7575 foreach_tcp_proto_field
7576#undef _
7577 else
7578 break;
7579 }
7580
7581#define _(a) found_something += a;
7582 foreach_tcp_proto_field;
7583#undef _
7584
7585 if (found_something == 0)
7586 return 0;
7587
7588 vec_validate (mask, sizeof (*tcp) - 1);
7589
7590 tcp = (tcp_header_t *) mask;
7591
Dave Barachb7b92992018-10-17 10:38:51 -04007592#define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
Damjan Marion7cd468a2016-12-19 23:05:39 +01007593 foreach_tcp_proto_field;
7594#undef _
7595
7596 *maskp = mask;
7597 return 1;
7598}
7599
7600uword
7601unformat_udp_mask (unformat_input_t * input, va_list * args)
7602{
7603 u8 **maskp = va_arg (*args, u8 **);
7604 u8 *mask = 0;
7605 u8 found_something = 0;
7606 udp_header_t *udp;
7607
7608#define _(a) u8 a=0;
7609 foreach_udp_proto_field;
7610#undef _
7611
7612 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7613 {
7614 if (0);
7615#define _(a) else if (unformat (input, #a)) a=1;
7616 foreach_udp_proto_field
7617#undef _
7618 else
7619 break;
7620 }
7621
7622#define _(a) found_something += a;
7623 foreach_udp_proto_field;
7624#undef _
7625
7626 if (found_something == 0)
7627 return 0;
7628
7629 vec_validate (mask, sizeof (*udp) - 1);
7630
7631 udp = (udp_header_t *) mask;
7632
Dave Barachb7b92992018-10-17 10:38:51 -04007633#define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
Damjan Marion7cd468a2016-12-19 23:05:39 +01007634 foreach_udp_proto_field;
7635#undef _
7636
7637 *maskp = mask;
7638 return 1;
7639}
7640
Damjan Marion7cd468a2016-12-19 23:05:39 +01007641uword
7642unformat_l4_mask (unformat_input_t * input, va_list * args)
7643{
7644 u8 **maskp = va_arg (*args, u8 **);
7645 u16 src_port = 0, dst_port = 0;
7646 tcpudp_header_t *tcpudp;
7647
7648 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7649 {
7650 if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
7651 return 1;
7652 else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
7653 return 1;
7654 else if (unformat (input, "src_port"))
7655 src_port = 0xFFFF;
7656 else if (unformat (input, "dst_port"))
7657 dst_port = 0xFFFF;
7658 else
7659 return 0;
7660 }
7661
7662 if (!src_port && !dst_port)
7663 return 0;
7664
7665 u8 *mask = 0;
7666 vec_validate (mask, sizeof (tcpudp_header_t) - 1);
7667
7668 tcpudp = (tcpudp_header_t *) mask;
7669 tcpudp->src_port = src_port;
7670 tcpudp->dst_port = dst_port;
7671
7672 *maskp = mask;
7673
7674 return 1;
7675}
7676
7677uword
7678unformat_ip4_mask (unformat_input_t * input, va_list * args)
7679{
7680 u8 **maskp = va_arg (*args, u8 **);
7681 u8 *mask = 0;
7682 u8 found_something = 0;
7683 ip4_header_t *ip;
7684
7685#define _(a) u8 a=0;
7686 foreach_ip4_proto_field;
7687#undef _
7688 u8 version = 0;
7689 u8 hdr_length = 0;
7690
7691
7692 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7693 {
7694 if (unformat (input, "version"))
7695 version = 1;
7696 else if (unformat (input, "hdr_length"))
7697 hdr_length = 1;
7698 else if (unformat (input, "src"))
7699 src_address = 1;
7700 else if (unformat (input, "dst"))
7701 dst_address = 1;
7702 else if (unformat (input, "proto"))
7703 protocol = 1;
7704
7705#define _(a) else if (unformat (input, #a)) a=1;
7706 foreach_ip4_proto_field
7707#undef _
7708 else
7709 break;
7710 }
7711
7712#define _(a) found_something += a;
7713 foreach_ip4_proto_field;
7714#undef _
7715
7716 if (found_something == 0)
7717 return 0;
7718
7719 vec_validate (mask, sizeof (*ip) - 1);
7720
7721 ip = (ip4_header_t *) mask;
7722
Dave Barachb7b92992018-10-17 10:38:51 -04007723#define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
Damjan Marion7cd468a2016-12-19 23:05:39 +01007724 foreach_ip4_proto_field;
7725#undef _
7726
7727 ip->ip_version_and_header_length = 0;
7728
7729 if (version)
7730 ip->ip_version_and_header_length |= 0xF0;
7731
7732 if (hdr_length)
7733 ip->ip_version_and_header_length |= 0x0F;
7734
7735 *maskp = mask;
7736 return 1;
7737}
7738
7739#define foreach_ip6_proto_field \
7740_(src_address) \
7741_(dst_address) \
7742_(payload_length) \
7743_(hop_limit) \
7744_(protocol)
7745
7746uword
7747unformat_ip6_mask (unformat_input_t * input, va_list * args)
7748{
7749 u8 **maskp = va_arg (*args, u8 **);
7750 u8 *mask = 0;
7751 u8 found_something = 0;
7752 ip6_header_t *ip;
7753 u32 ip_version_traffic_class_and_flow_label;
7754
7755#define _(a) u8 a=0;
7756 foreach_ip6_proto_field;
7757#undef _
7758 u8 version = 0;
7759 u8 traffic_class = 0;
7760 u8 flow_label = 0;
7761
7762 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7763 {
7764 if (unformat (input, "version"))
7765 version = 1;
7766 else if (unformat (input, "traffic-class"))
7767 traffic_class = 1;
7768 else if (unformat (input, "flow-label"))
7769 flow_label = 1;
7770 else if (unformat (input, "src"))
7771 src_address = 1;
7772 else if (unformat (input, "dst"))
7773 dst_address = 1;
7774 else if (unformat (input, "proto"))
7775 protocol = 1;
7776
7777#define _(a) else if (unformat (input, #a)) a=1;
7778 foreach_ip6_proto_field
7779#undef _
7780 else
7781 break;
7782 }
7783
7784#define _(a) found_something += a;
7785 foreach_ip6_proto_field;
7786#undef _
7787
7788 if (found_something == 0)
7789 return 0;
7790
7791 vec_validate (mask, sizeof (*ip) - 1);
7792
7793 ip = (ip6_header_t *) mask;
7794
Dave Barachb7b92992018-10-17 10:38:51 -04007795#define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
Damjan Marion7cd468a2016-12-19 23:05:39 +01007796 foreach_ip6_proto_field;
7797#undef _
7798
7799 ip_version_traffic_class_and_flow_label = 0;
7800
7801 if (version)
7802 ip_version_traffic_class_and_flow_label |= 0xF0000000;
7803
7804 if (traffic_class)
7805 ip_version_traffic_class_and_flow_label |= 0x0FF00000;
7806
7807 if (flow_label)
7808 ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
7809
7810 ip->ip_version_traffic_class_and_flow_label =
7811 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
7812
7813 *maskp = mask;
7814 return 1;
7815}
7816
7817uword
7818unformat_l3_mask (unformat_input_t * input, va_list * args)
7819{
7820 u8 **maskp = va_arg (*args, u8 **);
7821
7822 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7823 {
7824 if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
7825 return 1;
7826 else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
7827 return 1;
7828 else
7829 break;
7830 }
7831 return 0;
7832}
7833
7834uword
7835unformat_l2_mask (unformat_input_t * input, va_list * args)
7836{
7837 u8 **maskp = va_arg (*args, u8 **);
7838 u8 *mask = 0;
7839 u8 src = 0;
7840 u8 dst = 0;
7841 u8 proto = 0;
7842 u8 tag1 = 0;
7843 u8 tag2 = 0;
7844 u8 ignore_tag1 = 0;
7845 u8 ignore_tag2 = 0;
7846 u8 cos1 = 0;
7847 u8 cos2 = 0;
7848 u8 dot1q = 0;
7849 u8 dot1ad = 0;
7850 int len = 14;
7851
7852 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7853 {
7854 if (unformat (input, "src"))
7855 src = 1;
7856 else if (unformat (input, "dst"))
7857 dst = 1;
7858 else if (unformat (input, "proto"))
7859 proto = 1;
7860 else if (unformat (input, "tag1"))
7861 tag1 = 1;
7862 else if (unformat (input, "tag2"))
7863 tag2 = 1;
7864 else if (unformat (input, "ignore-tag1"))
7865 ignore_tag1 = 1;
7866 else if (unformat (input, "ignore-tag2"))
7867 ignore_tag2 = 1;
7868 else if (unformat (input, "cos1"))
7869 cos1 = 1;
7870 else if (unformat (input, "cos2"))
7871 cos2 = 1;
7872 else if (unformat (input, "dot1q"))
7873 dot1q = 1;
7874 else if (unformat (input, "dot1ad"))
7875 dot1ad = 1;
7876 else
7877 break;
7878 }
7879 if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
7880 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
7881 return 0;
7882
7883 if (tag1 || ignore_tag1 || cos1 || dot1q)
7884 len = 18;
7885 if (tag2 || ignore_tag2 || cos2 || dot1ad)
7886 len = 22;
7887
7888 vec_validate (mask, len - 1);
7889
7890 if (dst)
Dave Barachb7b92992018-10-17 10:38:51 -04007891 clib_memset (mask, 0xff, 6);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007892
7893 if (src)
Dave Barachb7b92992018-10-17 10:38:51 -04007894 clib_memset (mask + 6, 0xff, 6);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007895
7896 if (tag2 || dot1ad)
7897 {
7898 /* inner vlan tag */
7899 if (tag2)
7900 {
7901 mask[19] = 0xff;
7902 mask[18] = 0x0f;
7903 }
7904 if (cos2)
7905 mask[18] |= 0xe0;
7906 if (proto)
7907 mask[21] = mask[20] = 0xff;
7908 if (tag1)
7909 {
7910 mask[15] = 0xff;
7911 mask[14] = 0x0f;
7912 }
7913 if (cos1)
7914 mask[14] |= 0xe0;
7915 *maskp = mask;
7916 return 1;
7917 }
7918 if (tag1 | dot1q)
7919 {
7920 if (tag1)
7921 {
7922 mask[15] = 0xff;
7923 mask[14] = 0x0f;
7924 }
7925 if (cos1)
7926 mask[14] |= 0xe0;
7927 if (proto)
7928 mask[16] = mask[17] = 0xff;
7929
7930 *maskp = mask;
7931 return 1;
7932 }
7933 if (cos2)
7934 mask[18] |= 0xe0;
7935 if (cos1)
7936 mask[14] |= 0xe0;
7937 if (proto)
7938 mask[12] = mask[13] = 0xff;
7939
7940 *maskp = mask;
7941 return 1;
7942}
7943
7944uword
7945unformat_classify_mask (unformat_input_t * input, va_list * args)
7946{
7947 u8 **maskp = va_arg (*args, u8 **);
7948 u32 *skipp = va_arg (*args, u32 *);
7949 u32 *matchp = va_arg (*args, u32 *);
7950 u32 match;
7951 u8 *mask = 0;
7952 u8 *l2 = 0;
7953 u8 *l3 = 0;
7954 u8 *l4 = 0;
7955 int i;
7956
7957 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7958 {
7959 if (unformat (input, "hex %U", unformat_hex_string, &mask))
7960 ;
7961 else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
7962 ;
7963 else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
7964 ;
7965 else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
7966 ;
7967 else
7968 break;
7969 }
7970
7971 if (l4 && !l3)
7972 {
7973 vec_free (mask);
7974 vec_free (l2);
7975 vec_free (l4);
7976 return 0;
7977 }
7978
7979 if (mask || l2 || l3 || l4)
7980 {
7981 if (l2 || l3 || l4)
7982 {
7983 /* "With a free Ethernet header in every package" */
7984 if (l2 == 0)
7985 vec_validate (l2, 13);
7986 mask = l2;
7987 if (vec_len (l3))
7988 {
7989 vec_append (mask, l3);
7990 vec_free (l3);
7991 }
7992 if (vec_len (l4))
7993 {
7994 vec_append (mask, l4);
7995 vec_free (l4);
7996 }
7997 }
7998
7999 /* Scan forward looking for the first significant mask octet */
8000 for (i = 0; i < vec_len (mask); i++)
8001 if (mask[i])
8002 break;
8003
8004 /* compute (skip, match) params */
8005 *skipp = i / sizeof (u32x4);
8006 vec_delete (mask, *skipp * sizeof (u32x4), 0);
8007
8008 /* Pad mask to an even multiple of the vector size */
8009 while (vec_len (mask) % sizeof (u32x4))
8010 vec_add1 (mask, 0);
8011
8012 match = vec_len (mask) / sizeof (u32x4);
8013
8014 for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
8015 {
8016 u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
8017 if (*tmp || *(tmp + 1))
8018 break;
8019 match--;
8020 }
8021 if (match == 0)
8022 clib_warning ("BUG: match 0");
8023
8024 _vec_len (mask) = match * sizeof (u32x4);
8025
8026 *matchp = match;
8027 *maskp = mask;
8028
8029 return 1;
8030 }
8031
8032 return 0;
8033}
Dave Barach4a3f69c2017-02-22 12:44:56 -05008034#endif /* VPP_API_TEST_BUILTIN */
Damjan Marion7cd468a2016-12-19 23:05:39 +01008035
8036#define foreach_l2_next \
8037_(drop, DROP) \
8038_(ethernet, ETHERNET_INPUT) \
8039_(ip4, IP4_INPUT) \
8040_(ip6, IP6_INPUT)
8041
8042uword
8043unformat_l2_next_index (unformat_input_t * input, va_list * args)
8044{
8045 u32 *miss_next_indexp = va_arg (*args, u32 *);
8046 u32 next_index = 0;
8047 u32 tmp;
8048
8049#define _(n,N) \
8050 if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
8051 foreach_l2_next;
8052#undef _
8053
8054 if (unformat (input, "%d", &tmp))
8055 {
8056 next_index = tmp;
8057 goto out;
8058 }
8059
8060 return 0;
8061
8062out:
8063 *miss_next_indexp = next_index;
8064 return 1;
8065}
8066
8067#define foreach_ip_next \
8068_(drop, DROP) \
8069_(local, LOCAL) \
8070_(rewrite, REWRITE)
8071
8072uword
Dave Barach4a3f69c2017-02-22 12:44:56 -05008073api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
Damjan Marion7cd468a2016-12-19 23:05:39 +01008074{
8075 u32 *miss_next_indexp = va_arg (*args, u32 *);
8076 u32 next_index = 0;
8077 u32 tmp;
8078
8079#define _(n,N) \
8080 if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
8081 foreach_ip_next;
8082#undef _
8083
8084 if (unformat (input, "%d", &tmp))
8085 {
8086 next_index = tmp;
8087 goto out;
8088 }
8089
8090 return 0;
8091
8092out:
8093 *miss_next_indexp = next_index;
8094 return 1;
8095}
8096
8097#define foreach_acl_next \
8098_(deny, DENY)
8099
8100uword
Dave Barach4a3f69c2017-02-22 12:44:56 -05008101api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
Damjan Marion7cd468a2016-12-19 23:05:39 +01008102{
8103 u32 *miss_next_indexp = va_arg (*args, u32 *);
8104 u32 next_index = 0;
8105 u32 tmp;
8106
8107#define _(n,N) \
8108 if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
8109 foreach_acl_next;
8110#undef _
8111
8112 if (unformat (input, "permit"))
8113 {
8114 next_index = ~0;
8115 goto out;
8116 }
8117 else if (unformat (input, "%d", &tmp))
8118 {
8119 next_index = tmp;
8120 goto out;
8121 }
8122
8123 return 0;
8124
8125out:
8126 *miss_next_indexp = next_index;
8127 return 1;
8128}
8129
8130uword
8131unformat_policer_precolor (unformat_input_t * input, va_list * args)
8132{
8133 u32 *r = va_arg (*args, u32 *);
8134
8135 if (unformat (input, "conform-color"))
8136 *r = POLICE_CONFORM;
8137 else if (unformat (input, "exceed-color"))
8138 *r = POLICE_EXCEED;
8139 else
8140 return 0;
8141
8142 return 1;
8143}
8144
8145static int
8146api_classify_add_del_table (vat_main_t * vam)
8147{
8148 unformat_input_t *i = vam->input;
8149 vl_api_classify_add_del_table_t *mp;
8150
8151 u32 nbuckets = 2;
8152 u32 skip = ~0;
8153 u32 match = ~0;
8154 int is_add = 1;
8155 int del_chain = 0;
8156 u32 table_index = ~0;
8157 u32 next_table_index = ~0;
8158 u32 miss_next_index = ~0;
8159 u32 memory_size = 32 << 20;
8160 u8 *mask = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008161 u32 current_data_flag = 0;
8162 int current_data_offset = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008163 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008164
8165 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8166 {
8167 if (unformat (i, "del"))
8168 is_add = 0;
8169 else if (unformat (i, "del-chain"))
8170 {
8171 is_add = 0;
8172 del_chain = 1;
8173 }
8174 else if (unformat (i, "buckets %d", &nbuckets))
8175 ;
8176 else if (unformat (i, "memory_size %d", &memory_size))
8177 ;
8178 else if (unformat (i, "skip %d", &skip))
8179 ;
8180 else if (unformat (i, "match %d", &match))
8181 ;
8182 else if (unformat (i, "table %d", &table_index))
8183 ;
8184 else if (unformat (i, "mask %U", unformat_classify_mask,
8185 &mask, &skip, &match))
8186 ;
8187 else if (unformat (i, "next-table %d", &next_table_index))
8188 ;
Dave Barach4a3f69c2017-02-22 12:44:56 -05008189 else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
Damjan Marion7cd468a2016-12-19 23:05:39 +01008190 &miss_next_index))
8191 ;
8192 else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
8193 &miss_next_index))
8194 ;
Dave Barach4a3f69c2017-02-22 12:44:56 -05008195 else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
Damjan Marion7cd468a2016-12-19 23:05:39 +01008196 &miss_next_index))
8197 ;
8198 else if (unformat (i, "current-data-flag %d", &current_data_flag))
8199 ;
8200 else if (unformat (i, "current-data-offset %d", &current_data_offset))
8201 ;
8202 else
8203 break;
8204 }
8205
8206 if (is_add && mask == 0)
8207 {
8208 errmsg ("Mask required");
8209 return -99;
8210 }
8211
8212 if (is_add && skip == ~0)
8213 {
8214 errmsg ("skip count required");
8215 return -99;
8216 }
8217
8218 if (is_add && match == ~0)
8219 {
8220 errmsg ("match count required");
8221 return -99;
8222 }
8223
8224 if (!is_add && table_index == ~0)
8225 {
8226 errmsg ("table index required for delete");
8227 return -99;
8228 }
8229
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008230 M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
Damjan Marion7cd468a2016-12-19 23:05:39 +01008231
8232 mp->is_add = is_add;
8233 mp->del_chain = del_chain;
8234 mp->table_index = ntohl (table_index);
8235 mp->nbuckets = ntohl (nbuckets);
8236 mp->memory_size = ntohl (memory_size);
8237 mp->skip_n_vectors = ntohl (skip);
8238 mp->match_n_vectors = ntohl (match);
8239 mp->next_table_index = ntohl (next_table_index);
8240 mp->miss_next_index = ntohl (miss_next_index);
8241 mp->current_data_flag = ntohl (current_data_flag);
8242 mp->current_data_offset = ntohl (current_data_offset);
Juraj Sloboda75282452018-06-12 14:20:49 +02008243 mp->mask_len = ntohl (vec_len (mask));
Damjan Marion7cd468a2016-12-19 23:05:39 +01008244 clib_memcpy (mp->mask, mask, vec_len (mask));
8245
8246 vec_free (mask);
8247
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008248 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008249 W (ret);
8250 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008251}
8252
Dave Barach4a3f69c2017-02-22 12:44:56 -05008253#if VPP_API_TEST_BUILTIN == 0
Damjan Marion7cd468a2016-12-19 23:05:39 +01008254uword
8255unformat_l4_match (unformat_input_t * input, va_list * args)
8256{
8257 u8 **matchp = va_arg (*args, u8 **);
8258
8259 u8 *proto_header = 0;
8260 int src_port = 0;
8261 int dst_port = 0;
8262
8263 tcpudp_header_t h;
8264
8265 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8266 {
8267 if (unformat (input, "src_port %d", &src_port))
8268 ;
8269 else if (unformat (input, "dst_port %d", &dst_port))
8270 ;
8271 else
8272 return 0;
8273 }
8274
8275 h.src_port = clib_host_to_net_u16 (src_port);
8276 h.dst_port = clib_host_to_net_u16 (dst_port);
8277 vec_validate (proto_header, sizeof (h) - 1);
8278 memcpy (proto_header, &h, sizeof (h));
8279
8280 *matchp = proto_header;
8281
8282 return 1;
8283}
8284
8285uword
8286unformat_ip4_match (unformat_input_t * input, va_list * args)
8287{
8288 u8 **matchp = va_arg (*args, u8 **);
8289 u8 *match = 0;
8290 ip4_header_t *ip;
8291 int version = 0;
8292 u32 version_val;
8293 int hdr_length = 0;
8294 u32 hdr_length_val;
8295 int src = 0, dst = 0;
8296 ip4_address_t src_val, dst_val;
8297 int proto = 0;
8298 u32 proto_val;
8299 int tos = 0;
8300 u32 tos_val;
8301 int length = 0;
8302 u32 length_val;
8303 int fragment_id = 0;
8304 u32 fragment_id_val;
8305 int ttl = 0;
8306 int ttl_val;
8307 int checksum = 0;
8308 u32 checksum_val;
8309
8310 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8311 {
8312 if (unformat (input, "version %d", &version_val))
8313 version = 1;
8314 else if (unformat (input, "hdr_length %d", &hdr_length_val))
8315 hdr_length = 1;
8316 else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
8317 src = 1;
8318 else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
8319 dst = 1;
8320 else if (unformat (input, "proto %d", &proto_val))
8321 proto = 1;
8322 else if (unformat (input, "tos %d", &tos_val))
8323 tos = 1;
8324 else if (unformat (input, "length %d", &length_val))
8325 length = 1;
8326 else if (unformat (input, "fragment_id %d", &fragment_id_val))
8327 fragment_id = 1;
8328 else if (unformat (input, "ttl %d", &ttl_val))
8329 ttl = 1;
8330 else if (unformat (input, "checksum %d", &checksum_val))
8331 checksum = 1;
8332 else
8333 break;
8334 }
8335
8336 if (version + hdr_length + src + dst + proto + tos + length + fragment_id
8337 + ttl + checksum == 0)
8338 return 0;
8339
8340 /*
8341 * Aligned because we use the real comparison functions
8342 */
8343 vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8344
8345 ip = (ip4_header_t *) match;
8346
8347 /* These are realistically matched in practice */
8348 if (src)
8349 ip->src_address.as_u32 = src_val.as_u32;
8350
8351 if (dst)
8352 ip->dst_address.as_u32 = dst_val.as_u32;
8353
8354 if (proto)
8355 ip->protocol = proto_val;
8356
8357
8358 /* These are not, but they're included for completeness */
8359 if (version)
8360 ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
8361
8362 if (hdr_length)
8363 ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
8364
8365 if (tos)
8366 ip->tos = tos_val;
8367
8368 if (length)
8369 ip->length = clib_host_to_net_u16 (length_val);
8370
8371 if (ttl)
8372 ip->ttl = ttl_val;
8373
8374 if (checksum)
8375 ip->checksum = clib_host_to_net_u16 (checksum_val);
8376
8377 *matchp = match;
8378 return 1;
8379}
8380
8381uword
8382unformat_ip6_match (unformat_input_t * input, va_list * args)
8383{
8384 u8 **matchp = va_arg (*args, u8 **);
8385 u8 *match = 0;
8386 ip6_header_t *ip;
8387 int version = 0;
8388 u32 version_val;
8389 u8 traffic_class = 0;
8390 u32 traffic_class_val = 0;
8391 u8 flow_label = 0;
8392 u8 flow_label_val;
8393 int src = 0, dst = 0;
8394 ip6_address_t src_val, dst_val;
8395 int proto = 0;
8396 u32 proto_val;
8397 int payload_length = 0;
8398 u32 payload_length_val;
8399 int hop_limit = 0;
8400 int hop_limit_val;
8401 u32 ip_version_traffic_class_and_flow_label;
8402
8403 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8404 {
8405 if (unformat (input, "version %d", &version_val))
8406 version = 1;
8407 else if (unformat (input, "traffic_class %d", &traffic_class_val))
8408 traffic_class = 1;
8409 else if (unformat (input, "flow_label %d", &flow_label_val))
8410 flow_label = 1;
8411 else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
8412 src = 1;
8413 else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
8414 dst = 1;
8415 else if (unformat (input, "proto %d", &proto_val))
8416 proto = 1;
8417 else if (unformat (input, "payload_length %d", &payload_length_val))
8418 payload_length = 1;
8419 else if (unformat (input, "hop_limit %d", &hop_limit_val))
8420 hop_limit = 1;
8421 else
8422 break;
8423 }
8424
8425 if (version + traffic_class + flow_label + src + dst + proto +
8426 payload_length + hop_limit == 0)
8427 return 0;
8428
8429 /*
8430 * Aligned because we use the real comparison functions
8431 */
8432 vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8433
8434 ip = (ip6_header_t *) match;
8435
8436 if (src)
8437 clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
8438
8439 if (dst)
8440 clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
8441
8442 if (proto)
8443 ip->protocol = proto_val;
8444
8445 ip_version_traffic_class_and_flow_label = 0;
8446
8447 if (version)
8448 ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
8449
8450 if (traffic_class)
8451 ip_version_traffic_class_and_flow_label |=
8452 (traffic_class_val & 0xFF) << 20;
8453
8454 if (flow_label)
8455 ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
8456
8457 ip->ip_version_traffic_class_and_flow_label =
8458 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8459
8460 if (payload_length)
8461 ip->payload_length = clib_host_to_net_u16 (payload_length_val);
8462
8463 if (hop_limit)
8464 ip->hop_limit = hop_limit_val;
8465
8466 *matchp = match;
8467 return 1;
8468}
8469
8470uword
8471unformat_l3_match (unformat_input_t * input, va_list * args)
8472{
8473 u8 **matchp = va_arg (*args, u8 **);
8474
8475 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8476 {
8477 if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
8478 return 1;
8479 else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
8480 return 1;
8481 else
8482 break;
8483 }
8484 return 0;
8485}
8486
8487uword
8488unformat_vlan_tag (unformat_input_t * input, va_list * args)
8489{
8490 u8 *tagp = va_arg (*args, u8 *);
8491 u32 tag;
8492
8493 if (unformat (input, "%d", &tag))
8494 {
8495 tagp[0] = (tag >> 8) & 0x0F;
8496 tagp[1] = tag & 0xFF;
8497 return 1;
8498 }
8499
8500 return 0;
8501}
8502
8503uword
8504unformat_l2_match (unformat_input_t * input, va_list * args)
8505{
8506 u8 **matchp = va_arg (*args, u8 **);
8507 u8 *match = 0;
8508 u8 src = 0;
8509 u8 src_val[6];
8510 u8 dst = 0;
8511 u8 dst_val[6];
8512 u8 proto = 0;
8513 u16 proto_val;
8514 u8 tag1 = 0;
8515 u8 tag1_val[2];
8516 u8 tag2 = 0;
8517 u8 tag2_val[2];
8518 int len = 14;
8519 u8 ignore_tag1 = 0;
8520 u8 ignore_tag2 = 0;
8521 u8 cos1 = 0;
8522 u8 cos2 = 0;
8523 u32 cos1_val = 0;
8524 u32 cos2_val = 0;
8525
8526 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8527 {
8528 if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
8529 src = 1;
8530 else
8531 if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
8532 dst = 1;
8533 else if (unformat (input, "proto %U",
8534 unformat_ethernet_type_host_byte_order, &proto_val))
8535 proto = 1;
8536 else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
8537 tag1 = 1;
8538 else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
8539 tag2 = 1;
8540 else if (unformat (input, "ignore-tag1"))
8541 ignore_tag1 = 1;
8542 else if (unformat (input, "ignore-tag2"))
8543 ignore_tag2 = 1;
8544 else if (unformat (input, "cos1 %d", &cos1_val))
8545 cos1 = 1;
8546 else if (unformat (input, "cos2 %d", &cos2_val))
8547 cos2 = 1;
8548 else
8549 break;
8550 }
8551 if ((src + dst + proto + tag1 + tag2 +
8552 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8553 return 0;
8554
8555 if (tag1 || ignore_tag1 || cos1)
8556 len = 18;
8557 if (tag2 || ignore_tag2 || cos2)
8558 len = 22;
8559
8560 vec_validate_aligned (match, len - 1, sizeof (u32x4));
8561
8562 if (dst)
8563 clib_memcpy (match, dst_val, 6);
8564
8565 if (src)
8566 clib_memcpy (match + 6, src_val, 6);
8567
8568 if (tag2)
8569 {
8570 /* inner vlan tag */
8571 match[19] = tag2_val[1];
8572 match[18] = tag2_val[0];
8573 if (cos2)
8574 match[18] |= (cos2_val & 0x7) << 5;
8575 if (proto)
8576 {
8577 match[21] = proto_val & 0xff;
8578 match[20] = proto_val >> 8;
8579 }
8580 if (tag1)
8581 {
8582 match[15] = tag1_val[1];
8583 match[14] = tag1_val[0];
8584 }
8585 if (cos1)
8586 match[14] |= (cos1_val & 0x7) << 5;
8587 *matchp = match;
8588 return 1;
8589 }
8590 if (tag1)
8591 {
8592 match[15] = tag1_val[1];
8593 match[14] = tag1_val[0];
8594 if (proto)
8595 {
8596 match[17] = proto_val & 0xff;
8597 match[16] = proto_val >> 8;
8598 }
8599 if (cos1)
8600 match[14] |= (cos1_val & 0x7) << 5;
8601
8602 *matchp = match;
8603 return 1;
8604 }
8605 if (cos2)
8606 match[18] |= (cos2_val & 0x7) << 5;
8607 if (cos1)
8608 match[14] |= (cos1_val & 0x7) << 5;
8609 if (proto)
8610 {
8611 match[13] = proto_val & 0xff;
8612 match[12] = proto_val >> 8;
8613 }
8614
8615 *matchp = match;
8616 return 1;
8617}
Igor Mikhailov (imichail)582caa32018-04-26 21:33:02 -07008618
8619uword
8620unformat_qos_source (unformat_input_t * input, va_list * args)
8621{
8622 int *qs = va_arg (*args, int *);
8623
8624 if (unformat (input, "ip"))
8625 *qs = QOS_SOURCE_IP;
8626 else if (unformat (input, "mpls"))
8627 *qs = QOS_SOURCE_MPLS;
8628 else if (unformat (input, "ext"))
8629 *qs = QOS_SOURCE_EXT;
8630 else if (unformat (input, "vlan"))
8631 *qs = QOS_SOURCE_VLAN;
8632 else
8633 return 0;
8634
8635 return 1;
8636}
Dave Barach4a3f69c2017-02-22 12:44:56 -05008637#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +01008638
8639uword
Dave Barach4a3f69c2017-02-22 12:44:56 -05008640api_unformat_classify_match (unformat_input_t * input, va_list * args)
Damjan Marion7cd468a2016-12-19 23:05:39 +01008641{
8642 u8 **matchp = va_arg (*args, u8 **);
8643 u32 skip_n_vectors = va_arg (*args, u32);
8644 u32 match_n_vectors = va_arg (*args, u32);
8645
8646 u8 *match = 0;
8647 u8 *l2 = 0;
8648 u8 *l3 = 0;
8649 u8 *l4 = 0;
8650
8651 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8652 {
8653 if (unformat (input, "hex %U", unformat_hex_string, &match))
8654 ;
8655 else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
8656 ;
8657 else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
8658 ;
8659 else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
8660 ;
8661 else
8662 break;
8663 }
8664
8665 if (l4 && !l3)
8666 {
8667 vec_free (match);
8668 vec_free (l2);
8669 vec_free (l4);
8670 return 0;
8671 }
8672
8673 if (match || l2 || l3 || l4)
8674 {
8675 if (l2 || l3 || l4)
8676 {
8677 /* "Win a free Ethernet header in every packet" */
8678 if (l2 == 0)
8679 vec_validate_aligned (l2, 13, sizeof (u32x4));
8680 match = l2;
8681 if (vec_len (l3))
8682 {
8683 vec_append_aligned (match, l3, sizeof (u32x4));
8684 vec_free (l3);
8685 }
8686 if (vec_len (l4))
8687 {
8688 vec_append_aligned (match, l4, sizeof (u32x4));
8689 vec_free (l4);
8690 }
8691 }
8692
8693 /* Make sure the vector is big enough even if key is all 0's */
8694 vec_validate_aligned
8695 (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
8696 sizeof (u32x4));
8697
8698 /* Set size, include skipped vectors */
8699 _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
8700
8701 *matchp = match;
8702
8703 return 1;
8704 }
8705
8706 return 0;
8707}
8708
8709static int
8710api_classify_add_del_session (vat_main_t * vam)
8711{
8712 unformat_input_t *i = vam->input;
8713 vl_api_classify_add_del_session_t *mp;
8714 int is_add = 1;
8715 u32 table_index = ~0;
8716 u32 hit_next_index = ~0;
8717 u32 opaque_index = ~0;
8718 u8 *match = 0;
8719 i32 advance = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008720 u32 skip_n_vectors = 0;
8721 u32 match_n_vectors = 0;
8722 u32 action = 0;
8723 u32 metadata = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008724 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008725
8726 /*
8727 * Warning: you have to supply skip_n and match_n
8728 * because the API client cant simply look at the classify
8729 * table object.
8730 */
8731
8732 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8733 {
8734 if (unformat (i, "del"))
8735 is_add = 0;
Dave Barach4a3f69c2017-02-22 12:44:56 -05008736 else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
Damjan Marion7cd468a2016-12-19 23:05:39 +01008737 &hit_next_index))
8738 ;
8739 else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
8740 &hit_next_index))
8741 ;
Dave Barach4a3f69c2017-02-22 12:44:56 -05008742 else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
Damjan Marion7cd468a2016-12-19 23:05:39 +01008743 &hit_next_index))
8744 ;
8745 else if (unformat (i, "policer-hit-next %d", &hit_next_index))
8746 ;
8747 else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
8748 ;
8749 else if (unformat (i, "opaque-index %d", &opaque_index))
8750 ;
8751 else if (unformat (i, "skip_n %d", &skip_n_vectors))
8752 ;
8753 else if (unformat (i, "match_n %d", &match_n_vectors))
8754 ;
Dave Barach4a3f69c2017-02-22 12:44:56 -05008755 else if (unformat (i, "match %U", api_unformat_classify_match,
Damjan Marion7cd468a2016-12-19 23:05:39 +01008756 &match, skip_n_vectors, match_n_vectors))
8757 ;
8758 else if (unformat (i, "advance %d", &advance))
8759 ;
8760 else if (unformat (i, "table-index %d", &table_index))
8761 ;
8762 else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
8763 action = 1;
8764 else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
8765 action = 2;
8766 else if (unformat (i, "action %d", &action))
8767 ;
8768 else if (unformat (i, "metadata %d", &metadata))
8769 ;
8770 else
8771 break;
8772 }
8773
8774 if (table_index == ~0)
8775 {
8776 errmsg ("Table index required");
8777 return -99;
8778 }
8779
8780 if (is_add && match == 0)
8781 {
8782 errmsg ("Match value required");
8783 return -99;
8784 }
8785
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008786 M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
Damjan Marion7cd468a2016-12-19 23:05:39 +01008787
8788 mp->is_add = is_add;
8789 mp->table_index = ntohl (table_index);
8790 mp->hit_next_index = ntohl (hit_next_index);
8791 mp->opaque_index = ntohl (opaque_index);
8792 mp->advance = ntohl (advance);
8793 mp->action = action;
8794 mp->metadata = ntohl (metadata);
Juraj Sloboda75282452018-06-12 14:20:49 +02008795 mp->match_len = ntohl (vec_len (match));
Damjan Marion7cd468a2016-12-19 23:05:39 +01008796 clib_memcpy (mp->match, match, vec_len (match));
8797 vec_free (match);
8798
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008799 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008800 W (ret);
8801 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008802}
8803
8804static int
8805api_classify_set_interface_ip_table (vat_main_t * vam)
8806{
8807 unformat_input_t *i = vam->input;
8808 vl_api_classify_set_interface_ip_table_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008809 u32 sw_if_index;
8810 int sw_if_index_set;
8811 u32 table_index = ~0;
8812 u8 is_ipv6 = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008813 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008814
8815 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8816 {
8817 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8818 sw_if_index_set = 1;
8819 else if (unformat (i, "sw_if_index %d", &sw_if_index))
8820 sw_if_index_set = 1;
8821 else if (unformat (i, "table %d", &table_index))
8822 ;
8823 else
8824 {
8825 clib_warning ("parse error '%U'", format_unformat_error, i);
8826 return -99;
8827 }
8828 }
8829
8830 if (sw_if_index_set == 0)
8831 {
8832 errmsg ("missing interface name or sw_if_index");
8833 return -99;
8834 }
8835
8836
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008837 M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008838
8839 mp->sw_if_index = ntohl (sw_if_index);
8840 mp->table_index = ntohl (table_index);
8841 mp->is_ipv6 = is_ipv6;
8842
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008843 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008844 W (ret);
8845 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008846}
8847
8848static int
8849api_classify_set_interface_l2_tables (vat_main_t * vam)
8850{
8851 unformat_input_t *i = vam->input;
8852 vl_api_classify_set_interface_l2_tables_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008853 u32 sw_if_index;
8854 int sw_if_index_set;
8855 u32 ip4_table_index = ~0;
8856 u32 ip6_table_index = ~0;
8857 u32 other_table_index = ~0;
8858 u32 is_input = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008859 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008860
8861 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8862 {
8863 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8864 sw_if_index_set = 1;
8865 else if (unformat (i, "sw_if_index %d", &sw_if_index))
8866 sw_if_index_set = 1;
8867 else if (unformat (i, "ip4-table %d", &ip4_table_index))
8868 ;
8869 else if (unformat (i, "ip6-table %d", &ip6_table_index))
8870 ;
8871 else if (unformat (i, "other-table %d", &other_table_index))
8872 ;
8873 else if (unformat (i, "is-input %d", &is_input))
8874 ;
8875 else
8876 {
8877 clib_warning ("parse error '%U'", format_unformat_error, i);
8878 return -99;
8879 }
8880 }
8881
8882 if (sw_if_index_set == 0)
8883 {
8884 errmsg ("missing interface name or sw_if_index");
8885 return -99;
8886 }
8887
8888
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008889 M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008890
8891 mp->sw_if_index = ntohl (sw_if_index);
8892 mp->ip4_table_index = ntohl (ip4_table_index);
8893 mp->ip6_table_index = ntohl (ip6_table_index);
8894 mp->other_table_index = ntohl (other_table_index);
8895 mp->is_input = (u8) is_input;
8896
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008897 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008898 W (ret);
8899 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008900}
8901
8902static int
8903api_set_ipfix_exporter (vat_main_t * vam)
8904{
8905 unformat_input_t *i = vam->input;
8906 vl_api_set_ipfix_exporter_t *mp;
8907 ip4_address_t collector_address;
8908 u8 collector_address_set = 0;
8909 u32 collector_port = ~0;
8910 ip4_address_t src_address;
8911 u8 src_address_set = 0;
8912 u32 vrf_id = ~0;
8913 u32 path_mtu = ~0;
8914 u32 template_interval = ~0;
8915 u8 udp_checksum = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008916 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008917
8918 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8919 {
8920 if (unformat (i, "collector_address %U", unformat_ip4_address,
8921 &collector_address))
8922 collector_address_set = 1;
8923 else if (unformat (i, "collector_port %d", &collector_port))
8924 ;
8925 else if (unformat (i, "src_address %U", unformat_ip4_address,
8926 &src_address))
8927 src_address_set = 1;
8928 else if (unformat (i, "vrf_id %d", &vrf_id))
8929 ;
8930 else if (unformat (i, "path_mtu %d", &path_mtu))
8931 ;
8932 else if (unformat (i, "template_interval %d", &template_interval))
8933 ;
8934 else if (unformat (i, "udp_checksum"))
8935 udp_checksum = 1;
8936 else
8937 break;
8938 }
8939
8940 if (collector_address_set == 0)
8941 {
8942 errmsg ("collector_address required");
8943 return -99;
8944 }
8945
8946 if (src_address_set == 0)
8947 {
8948 errmsg ("src_address required");
8949 return -99;
8950 }
8951
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008952 M (SET_IPFIX_EXPORTER, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008953
Jakub Grajciar2f71a882019-10-10 14:21:22 +02008954 memcpy (mp->collector_address.un.ip4, collector_address.data,
Damjan Marion7cd468a2016-12-19 23:05:39 +01008955 sizeof (collector_address.data));
8956 mp->collector_port = htons ((u16) collector_port);
Jakub Grajciar2f71a882019-10-10 14:21:22 +02008957 memcpy (mp->src_address.un.ip4, src_address.data,
8958 sizeof (src_address.data));
Damjan Marion7cd468a2016-12-19 23:05:39 +01008959 mp->vrf_id = htonl (vrf_id);
8960 mp->path_mtu = htonl (path_mtu);
8961 mp->template_interval = htonl (template_interval);
8962 mp->udp_checksum = udp_checksum;
8963
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008964 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008965 W (ret);
8966 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008967}
8968
8969static int
8970api_set_ipfix_classify_stream (vat_main_t * vam)
8971{
8972 unformat_input_t *i = vam->input;
8973 vl_api_set_ipfix_classify_stream_t *mp;
8974 u32 domain_id = 0;
8975 u32 src_port = UDP_DST_PORT_ipfix;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008976 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008977
8978 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8979 {
8980 if (unformat (i, "domain %d", &domain_id))
8981 ;
8982 else if (unformat (i, "src_port %d", &src_port))
8983 ;
8984 else
8985 {
8986 errmsg ("unknown input `%U'", format_unformat_error, i);
8987 return -99;
8988 }
8989 }
8990
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008991 M (SET_IPFIX_CLASSIFY_STREAM, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008992
8993 mp->domain_id = htonl (domain_id);
8994 mp->src_port = htons ((u16) src_port);
8995
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008996 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008997 W (ret);
8998 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008999}
9000
9001static int
9002api_ipfix_classify_table_add_del (vat_main_t * vam)
9003{
9004 unformat_input_t *i = vam->input;
9005 vl_api_ipfix_classify_table_add_del_t *mp;
9006 int is_add = -1;
9007 u32 classify_table_index = ~0;
9008 u8 ip_version = 0;
9009 u8 transport_protocol = 255;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009010 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009011
9012 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9013 {
9014 if (unformat (i, "add"))
9015 is_add = 1;
9016 else if (unformat (i, "del"))
9017 is_add = 0;
9018 else if (unformat (i, "table %d", &classify_table_index))
9019 ;
9020 else if (unformat (i, "ip4"))
9021 ip_version = 4;
9022 else if (unformat (i, "ip6"))
9023 ip_version = 6;
9024 else if (unformat (i, "tcp"))
9025 transport_protocol = 6;
9026 else if (unformat (i, "udp"))
9027 transport_protocol = 17;
9028 else
9029 {
9030 errmsg ("unknown input `%U'", format_unformat_error, i);
9031 return -99;
9032 }
9033 }
9034
9035 if (is_add == -1)
9036 {
9037 errmsg ("expecting: add|del");
9038 return -99;
9039 }
9040 if (classify_table_index == ~0)
9041 {
9042 errmsg ("classifier table not specified");
9043 return -99;
9044 }
9045 if (ip_version == 0)
9046 {
9047 errmsg ("IP version not specified");
9048 return -99;
9049 }
9050
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009051 M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009052
9053 mp->is_add = is_add;
9054 mp->table_id = htonl (classify_table_index);
9055 mp->ip_version = ip_version;
9056 mp->transport_protocol = transport_protocol;
9057
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009058 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06009059 W (ret);
9060 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009061}
9062
9063static int
9064api_get_node_index (vat_main_t * vam)
9065{
9066 unformat_input_t *i = vam->input;
9067 vl_api_get_node_index_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009068 u8 *name = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009069 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009070
9071 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9072 {
9073 if (unformat (i, "node %s", &name))
9074 ;
9075 else
9076 break;
9077 }
9078 if (name == 0)
9079 {
9080 errmsg ("node name required");
9081 return -99;
9082 }
9083 if (vec_len (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
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009089 M (GET_NODE_INDEX, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009090 clib_memcpy (mp->node_name, name, vec_len (name));
9091 vec_free (name);
9092
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009093 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06009094 W (ret);
9095 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009096}
9097
9098static int
9099api_get_next_index (vat_main_t * vam)
9100{
9101 unformat_input_t *i = vam->input;
9102 vl_api_get_next_index_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009103 u8 *node_name = 0, *next_node_name = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009104 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009105
9106 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9107 {
9108 if (unformat (i, "node-name %s", &node_name))
9109 ;
9110 else if (unformat (i, "next-node-name %s", &next_node_name))
9111 break;
9112 }
9113
9114 if (node_name == 0)
9115 {
9116 errmsg ("node name required");
9117 return -99;
9118 }
9119 if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
9120 {
9121 errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9122 return -99;
9123 }
9124
9125 if (next_node_name == 0)
9126 {
9127 errmsg ("next node name required");
9128 return -99;
9129 }
9130 if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
9131 {
9132 errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
9133 return -99;
9134 }
9135
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009136 M (GET_NEXT_INDEX, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009137 clib_memcpy (mp->node_name, node_name, vec_len (node_name));
9138 clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
9139 vec_free (node_name);
9140 vec_free (next_node_name);
9141
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009142 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06009143 W (ret);
9144 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009145}
9146
9147static int
9148api_add_node_next (vat_main_t * vam)
9149{
9150 unformat_input_t *i = vam->input;
9151 vl_api_add_node_next_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009152 u8 *name = 0;
9153 u8 *next = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009154 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009155
9156 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9157 {
9158 if (unformat (i, "node %s", &name))
9159 ;
9160 else if (unformat (i, "next %s", &next))
9161 ;
9162 else
9163 break;
9164 }
9165 if (name == 0)
9166 {
9167 errmsg ("node name required");
9168 return -99;
9169 }
9170 if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9171 {
9172 errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9173 return -99;
9174 }
9175 if (next == 0)
9176 {
9177 errmsg ("next node required");
9178 return -99;
9179 }
9180 if (vec_len (next) >= ARRAY_LEN (mp->next_name))
9181 {
9182 errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
9183 return -99;
9184 }
9185
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009186 M (ADD_NODE_NEXT, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009187 clib_memcpy (mp->node_name, name, vec_len (name));
9188 clib_memcpy (mp->next_name, next, vec_len (next));
9189 vec_free (name);
9190 vec_free (next);
9191
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009192 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06009193 W (ret);
9194 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009195}
9196
Damjan Marion8389fb92017-10-13 18:29:53 +02009197static void vl_api_sw_interface_tap_v2_details_t_handler
9198 (vl_api_sw_interface_tap_v2_details_t * mp)
9199{
9200 vat_main_t *vam = &vat_main;
9201
Jakub Grajciar5de4fb72019-09-03 10:40:01 +02009202 u8 *ip4 =
9203 format (0, "%U/%d", format_ip4_address, mp->host_ip4_prefix.address,
9204 mp->host_ip4_prefix.len);
9205 u8 *ip6 =
9206 format (0, "%U/%d", format_ip6_address, mp->host_ip6_prefix.address,
9207 mp->host_ip6_prefix.len);
Milan Lenco73e7f422017-12-14 10:04:25 +01009208
9209 print (vam->ofp,
Andrew Yourtchenko754f24b2019-01-07 20:56:46 +01009210 "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
Milan Lenco73e7f422017-12-14 10:04:25 +01009211 mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
9212 ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
9213 format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
Andrew Yourtchenko754f24b2019-01-07 20:56:46 +01009214 mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
Milan Lenco73e7f422017-12-14 10:04:25 +01009215
9216 vec_free (ip4);
9217 vec_free (ip6);
Damjan Marion8389fb92017-10-13 18:29:53 +02009218}
9219
9220static void vl_api_sw_interface_tap_v2_details_t_handler_json
9221 (vl_api_sw_interface_tap_v2_details_t * mp)
9222{
9223 vat_main_t *vam = &vat_main;
9224 vat_json_node_t *node = NULL;
9225
9226 if (VAT_JSON_ARRAY != vam->json_tree.type)
9227 {
9228 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9229 vat_json_init_array (&vam->json_tree);
9230 }
9231 node = vat_json_array_add (&vam->json_tree);
9232
9233 vat_json_init_object (node);
Milan Lenco73e7f422017-12-14 10:04:25 +01009234 vat_json_object_add_uint (node, "id", ntohl (mp->id));
Damjan Marion8389fb92017-10-13 18:29:53 +02009235 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
Andrew Yourtchenko754f24b2019-01-07 20:56:46 +01009236 vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
Damjan Marion8389fb92017-10-13 18:29:53 +02009237 vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
Milan Lenco73e7f422017-12-14 10:04:25 +01009238 vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
9239 vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
9240 vat_json_object_add_string_copy (node, "host_mac_addr",
9241 format (0, "%U", format_ethernet_address,
9242 &mp->host_mac_addr));
9243 vat_json_object_add_string_copy (node, "host_namespace",
9244 mp->host_namespace);
9245 vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
9246 vat_json_object_add_string_copy (node, "host_ip4_addr",
9247 format (0, "%U/%d", format_ip4_address,
Jakub Grajciar5de4fb72019-09-03 10:40:01 +02009248 mp->host_ip4_prefix.address,
9249 mp->host_ip4_prefix.len));
9250 vat_json_object_add_string_copy (node, "host_ip6_prefix",
Milan Lenco73e7f422017-12-14 10:04:25 +01009251 format (0, "%U/%d", format_ip6_address,
Jakub Grajciar5de4fb72019-09-03 10:40:01 +02009252 mp->host_ip6_prefix.address,
9253 mp->host_ip6_prefix.len));
Milan Lenco73e7f422017-12-14 10:04:25 +01009254
Damjan Marion8389fb92017-10-13 18:29:53 +02009255}
9256
9257static int
9258api_sw_interface_tap_v2_dump (vat_main_t * vam)
9259{
9260 vl_api_sw_interface_tap_v2_dump_t *mp;
9261 vl_api_control_ping_t *mp_ping;
9262 int ret;
9263
Milan Lenco73e7f422017-12-14 10:04:25 +01009264 print (vam->ofp,
9265 "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
9266 "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
9267 "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
9268 "host_ip6_addr");
9269
Damjan Marion8389fb92017-10-13 18:29:53 +02009270 /* Get list of tap interfaces */
9271 M (SW_INTERFACE_TAP_V2_DUMP, mp);
9272 S (mp);
9273
9274 /* Use a control ping for synchronization */
9275 MPING (CONTROL_PING, mp_ping);
9276 S (mp_ping);
9277
9278 W (ret);
9279 return ret;
9280}
9281
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01009282static void vl_api_sw_interface_virtio_pci_details_t_handler
9283 (vl_api_sw_interface_virtio_pci_details_t * mp)
9284{
9285 vat_main_t *vam = &vat_main;
9286
9287 typedef union
9288 {
9289 struct
9290 {
9291 u16 domain;
9292 u8 bus;
9293 u8 slot:5;
9294 u8 function:3;
9295 };
9296 u32 as_u32;
9297 } pci_addr_t;
9298 pci_addr_t addr;
Jakub Grajciar2c504f82019-09-26 10:34:41 +02009299
9300 addr.domain = ntohs (mp->pci_addr.domain);
9301 addr.bus = mp->pci_addr.bus;
9302 addr.slot = mp->pci_addr.slot;
9303 addr.function = mp->pci_addr.function;
9304
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01009305 u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
9306 addr.slot, addr.function);
9307
9308 print (vam->ofp,
9309 "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
9310 pci_addr, ntohl (mp->sw_if_index),
9311 ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
9312 format_ethernet_address, mp->mac_addr,
9313 clib_net_to_host_u64 (mp->features));
9314 vec_free (pci_addr);
9315}
9316
9317static void vl_api_sw_interface_virtio_pci_details_t_handler_json
9318 (vl_api_sw_interface_virtio_pci_details_t * mp)
9319{
9320 vat_main_t *vam = &vat_main;
9321 vat_json_node_t *node = NULL;
Jakub Grajciar2c504f82019-09-26 10:34:41 +02009322 vlib_pci_addr_t pci_addr;
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01009323
9324 if (VAT_JSON_ARRAY != vam->json_tree.type)
9325 {
9326 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9327 vat_json_init_array (&vam->json_tree);
9328 }
9329 node = vat_json_array_add (&vam->json_tree);
9330
Jakub Grajciar2c504f82019-09-26 10:34:41 +02009331 pci_addr.domain = ntohs (mp->pci_addr.domain);
9332 pci_addr.bus = mp->pci_addr.bus;
9333 pci_addr.slot = mp->pci_addr.slot;
9334 pci_addr.function = mp->pci_addr.function;
9335
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01009336 vat_json_init_object (node);
Jakub Grajciar2c504f82019-09-26 10:34:41 +02009337 vat_json_object_add_uint (node, "pci-addr", pci_addr.as_u32);
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01009338 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9339 vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
9340 vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
9341 vat_json_object_add_uint (node, "features",
9342 clib_net_to_host_u64 (mp->features));
9343 vat_json_object_add_string_copy (node, "mac_addr",
9344 format (0, "%U", format_ethernet_address,
9345 &mp->mac_addr));
9346}
9347
9348static int
9349api_sw_interface_virtio_pci_dump (vat_main_t * vam)
9350{
9351 vl_api_sw_interface_virtio_pci_dump_t *mp;
9352 vl_api_control_ping_t *mp_ping;
9353 int ret;
9354
9355 print (vam->ofp,
9356 "\n%-12s %-12s %-12s %-12s %-17s %-08s",
9357 "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
9358 "mac_addr", "features");
9359
9360 /* Get list of tap interfaces */
9361 M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
9362 S (mp);
9363
9364 /* Use a control ping for synchronization */
9365 MPING (CONTROL_PING, mp_ping);
9366 S (mp_ping);
9367
9368 W (ret);
9369 return ret;
9370}
9371
eyal bariaf86a482018-04-17 11:20:27 +03009372static int
9373api_vxlan_offload_rx (vat_main_t * vam)
9374{
9375 unformat_input_t *line_input = vam->input;
9376 vl_api_vxlan_offload_rx_t *mp;
9377 u32 hw_if_index = ~0, rx_if_index = ~0;
9378 u8 is_add = 1;
9379 int ret;
9380
9381 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9382 {
9383 if (unformat (line_input, "del"))
9384 is_add = 0;
9385 else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
9386 &hw_if_index))
9387 ;
9388 else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
9389 ;
9390 else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
9391 &rx_if_index))
9392 ;
9393 else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
9394 ;
9395 else
9396 {
9397 errmsg ("parse error '%U'", format_unformat_error, line_input);
9398 return -99;
9399 }
9400 }
9401
9402 if (hw_if_index == ~0)
9403 {
9404 errmsg ("no hw interface");
9405 return -99;
9406 }
9407
9408 if (rx_if_index == ~0)
9409 {
9410 errmsg ("no rx tunnel");
9411 return -99;
9412 }
9413
9414 M (VXLAN_OFFLOAD_RX, mp);
9415
9416 mp->hw_if_index = ntohl (hw_if_index);
9417 mp->sw_if_index = ntohl (rx_if_index);
9418 mp->enable = is_add;
9419
9420 S (mp);
9421 W (ret);
9422 return ret;
9423}
9424
Damjan Marion7cd468a2016-12-19 23:05:39 +01009425static uword unformat_vxlan_decap_next
9426 (unformat_input_t * input, va_list * args)
9427{
9428 u32 *result = va_arg (*args, u32 *);
9429 u32 tmp;
9430
9431 if (unformat (input, "l2"))
9432 *result = VXLAN_INPUT_NEXT_L2_INPUT;
9433 else if (unformat (input, "%d", &tmp))
9434 *result = tmp;
9435 else
9436 return 0;
9437 return 1;
9438}
9439
9440static int
9441api_vxlan_add_del_tunnel (vat_main_t * vam)
9442{
9443 unformat_input_t *line_input = vam->input;
9444 vl_api_vxlan_add_del_tunnel_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009445 ip46_address_t src, dst;
9446 u8 is_add = 1;
9447 u8 ipv4_set = 0, ipv6_set = 0;
9448 u8 src_set = 0;
9449 u8 dst_set = 0;
9450 u8 grp_set = 0;
Jon Loeliger3d460bd2018-02-01 16:36:12 -06009451 u32 instance = ~0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009452 u32 mcast_sw_if_index = ~0;
9453 u32 encap_vrf_id = 0;
9454 u32 decap_next_index = ~0;
9455 u32 vni = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009456 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009457
9458 /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
Dave Barachb7b92992018-10-17 10:38:51 -04009459 clib_memset (&src, 0, sizeof src);
9460 clib_memset (&dst, 0, sizeof dst);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009461
9462 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9463 {
9464 if (unformat (line_input, "del"))
9465 is_add = 0;
Jon Loeliger3d460bd2018-02-01 16:36:12 -06009466 else if (unformat (line_input, "instance %d", &instance))
9467 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009468 else
9469 if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
9470 {
9471 ipv4_set = 1;
9472 src_set = 1;
9473 }
9474 else
9475 if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
9476 {
9477 ipv4_set = 1;
9478 dst_set = 1;
9479 }
9480 else
9481 if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
9482 {
9483 ipv6_set = 1;
9484 src_set = 1;
9485 }
9486 else
9487 if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
9488 {
9489 ipv6_set = 1;
9490 dst_set = 1;
9491 }
9492 else if (unformat (line_input, "group %U %U",
9493 unformat_ip4_address, &dst.ip4,
9494 api_unformat_sw_if_index, vam, &mcast_sw_if_index))
9495 {
9496 grp_set = dst_set = 1;
9497 ipv4_set = 1;
9498 }
9499 else if (unformat (line_input, "group %U",
9500 unformat_ip4_address, &dst.ip4))
9501 {
9502 grp_set = dst_set = 1;
9503 ipv4_set = 1;
9504 }
9505 else if (unformat (line_input, "group %U %U",
9506 unformat_ip6_address, &dst.ip6,
9507 api_unformat_sw_if_index, vam, &mcast_sw_if_index))
9508 {
9509 grp_set = dst_set = 1;
9510 ipv6_set = 1;
9511 }
9512 else if (unformat (line_input, "group %U",
9513 unformat_ip6_address, &dst.ip6))
9514 {
9515 grp_set = dst_set = 1;
9516 ipv6_set = 1;
9517 }
9518 else
9519 if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
9520 ;
9521 else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
9522 ;
9523 else if (unformat (line_input, "decap-next %U",
9524 unformat_vxlan_decap_next, &decap_next_index))
9525 ;
9526 else if (unformat (line_input, "vni %d", &vni))
9527 ;
9528 else
9529 {
9530 errmsg ("parse error '%U'", format_unformat_error, line_input);
9531 return -99;
9532 }
9533 }
9534
9535 if (src_set == 0)
9536 {
9537 errmsg ("tunnel src address not specified");
9538 return -99;
9539 }
9540 if (dst_set == 0)
9541 {
9542 errmsg ("tunnel dst address not specified");
9543 return -99;
9544 }
9545
9546 if (grp_set && !ip46_address_is_multicast (&dst))
9547 {
9548 errmsg ("tunnel group address not multicast");
9549 return -99;
9550 }
9551 if (grp_set && mcast_sw_if_index == ~0)
9552 {
9553 errmsg ("tunnel nonexistent multicast device");
9554 return -99;
9555 }
9556 if (grp_set == 0 && ip46_address_is_multicast (&dst))
9557 {
9558 errmsg ("tunnel dst address must be unicast");
9559 return -99;
9560 }
9561
9562
9563 if (ipv4_set && ipv6_set)
9564 {
9565 errmsg ("both IPv4 and IPv6 addresses specified");
9566 return -99;
9567 }
9568
9569 if ((vni == 0) || (vni >> 24))
9570 {
9571 errmsg ("vni not specified or out of range");
9572 return -99;
9573 }
9574
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009575 M (VXLAN_ADD_DEL_TUNNEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009576
9577 if (ipv6_set)
9578 {
Jakub Grajciar7c0eb562020-03-02 13:55:31 +01009579 clib_memcpy (mp->src_address.un.ip6, &src.ip6, sizeof (src.ip6));
9580 clib_memcpy (mp->dst_address.un.ip6, &dst.ip6, sizeof (dst.ip6));
Damjan Marion7cd468a2016-12-19 23:05:39 +01009581 }
9582 else
9583 {
Jakub Grajciar7c0eb562020-03-02 13:55:31 +01009584 clib_memcpy (mp->src_address.un.ip4, &src.ip4, sizeof (src.ip4));
9585 clib_memcpy (mp->dst_address.un.ip4, &dst.ip4, sizeof (dst.ip4));
Damjan Marion7cd468a2016-12-19 23:05:39 +01009586 }
Jakub Grajciar7c0eb562020-03-02 13:55:31 +01009587 mp->src_address.af = ipv6_set;
9588 mp->dst_address.af = ipv6_set;
Jon Loeliger3d460bd2018-02-01 16:36:12 -06009589
9590 mp->instance = htonl (instance);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009591 mp->encap_vrf_id = ntohl (encap_vrf_id);
9592 mp->decap_next_index = ntohl (decap_next_index);
9593 mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
9594 mp->vni = ntohl (vni);
9595 mp->is_add = is_add;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009596
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009597 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06009598 W (ret);
9599 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009600}
9601
9602static void vl_api_vxlan_tunnel_details_t_handler
9603 (vl_api_vxlan_tunnel_details_t * mp)
9604{
9605 vat_main_t *vam = &vat_main;
Jakub Grajciar7c0eb562020-03-02 13:55:31 +01009606 ip46_address_t src =
9607 to_ip46 (mp->dst_address.af, (u8 *) & mp->dst_address.un);
9608 ip46_address_t dst =
9609 to_ip46 (mp->dst_address.af, (u8 *) & mp->src_address.un);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009610
Jon Loeliger3d460bd2018-02-01 16:36:12 -06009611 print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
Damjan Marion7cd468a2016-12-19 23:05:39 +01009612 ntohl (mp->sw_if_index),
Jon Loeliger3d460bd2018-02-01 16:36:12 -06009613 ntohl (mp->instance),
Damjan Marion7cd468a2016-12-19 23:05:39 +01009614 format_ip46_address, &src, IP46_TYPE_ANY,
9615 format_ip46_address, &dst, IP46_TYPE_ANY,
9616 ntohl (mp->encap_vrf_id),
9617 ntohl (mp->decap_next_index), ntohl (mp->vni),
9618 ntohl (mp->mcast_sw_if_index));
9619}
9620
9621static void vl_api_vxlan_tunnel_details_t_handler_json
9622 (vl_api_vxlan_tunnel_details_t * mp)
9623{
9624 vat_main_t *vam = &vat_main;
9625 vat_json_node_t *node = NULL;
9626
9627 if (VAT_JSON_ARRAY != vam->json_tree.type)
9628 {
9629 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9630 vat_json_init_array (&vam->json_tree);
9631 }
9632 node = vat_json_array_add (&vam->json_tree);
9633
9634 vat_json_init_object (node);
9635 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
Jon Loeliger3d460bd2018-02-01 16:36:12 -06009636
9637 vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
9638
Jakub Grajciar7c0eb562020-03-02 13:55:31 +01009639 if (mp->src_address.af)
Damjan Marion7cd468a2016-12-19 23:05:39 +01009640 {
9641 struct in6_addr ip6;
9642
Jakub Grajciar7c0eb562020-03-02 13:55:31 +01009643 clib_memcpy (&ip6, mp->src_address.un.ip6, sizeof (ip6));
Damjan Marion7cd468a2016-12-19 23:05:39 +01009644 vat_json_object_add_ip6 (node, "src_address", ip6);
Jakub Grajciar7c0eb562020-03-02 13:55:31 +01009645 clib_memcpy (&ip6, mp->dst_address.un.ip6, sizeof (ip6));
Damjan Marion7cd468a2016-12-19 23:05:39 +01009646 vat_json_object_add_ip6 (node, "dst_address", ip6);
9647 }
9648 else
9649 {
9650 struct in_addr ip4;
9651
Jakub Grajciar7c0eb562020-03-02 13:55:31 +01009652 clib_memcpy (&ip4, mp->src_address.un.ip4, sizeof (ip4));
Damjan Marion7cd468a2016-12-19 23:05:39 +01009653 vat_json_object_add_ip4 (node, "src_address", ip4);
Jakub Grajciar7c0eb562020-03-02 13:55:31 +01009654 clib_memcpy (&ip4, mp->dst_address.un.ip4, sizeof (ip4));
Damjan Marion7cd468a2016-12-19 23:05:39 +01009655 vat_json_object_add_ip4 (node, "dst_address", ip4);
9656 }
9657 vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
9658 vat_json_object_add_uint (node, "decap_next_index",
9659 ntohl (mp->decap_next_index));
9660 vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
Damjan Marion7cd468a2016-12-19 23:05:39 +01009661 vat_json_object_add_uint (node, "mcast_sw_if_index",
9662 ntohl (mp->mcast_sw_if_index));
9663}
9664
9665static int
9666api_vxlan_tunnel_dump (vat_main_t * vam)
9667{
9668 unformat_input_t *i = vam->input;
9669 vl_api_vxlan_tunnel_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -06009670 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009671 u32 sw_if_index;
9672 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009673 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009674
9675 /* Parse args required to build the message */
9676 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9677 {
9678 if (unformat (i, "sw_if_index %d", &sw_if_index))
9679 sw_if_index_set = 1;
9680 else
9681 break;
9682 }
9683
9684 if (sw_if_index_set == 0)
9685 {
9686 sw_if_index = ~0;
9687 }
9688
9689 if (!vam->json_output)
9690 {
Jon Loeliger3d460bd2018-02-01 16:36:12 -06009691 print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
9692 "sw_if_index", "instance", "src_address", "dst_address",
Damjan Marion7cd468a2016-12-19 23:05:39 +01009693 "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
9694 }
9695
9696 /* Get list of vxlan-tunnel interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009697 M (VXLAN_TUNNEL_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009698
9699 mp->sw_if_index = htonl (sw_if_index);
9700
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009701 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009702
9703 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -04009704 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06009705 S (mp_ping);
9706
Jon Loeliger56c7b012017-02-01 12:31:41 -06009707 W (ret);
9708 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009709}
9710
9711static int
Neale Ranns5a8844b2019-04-16 07:15:35 +00009712api_gre_tunnel_add_del (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +01009713{
9714 unformat_input_t *line_input = vam->input;
Neale Ranns5a8844b2019-04-16 07:15:35 +00009715 vl_api_address_t src = { }, dst =
9716 {
9717 };
9718 vl_api_gre_tunnel_add_del_t *mp;
9719 vl_api_gre_tunnel_type_t t_type;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009720 u8 is_add = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009721 u8 src_set = 0;
9722 u8 dst_set = 0;
Neale Ranns5f8f6172019-04-18 10:23:56 +00009723 u32 outer_table_id = 0;
John Loa43ccae2018-02-13 17:15:23 -05009724 u32 session_id = 0;
9725 u32 instance = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009726 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009727
Neale Ranns5a8844b2019-04-16 07:15:35 +00009728 t_type = GRE_API_TUNNEL_TYPE_L3;
Ciara Loftus7eac9162016-09-30 15:47:03 +01009729
Damjan Marion7cd468a2016-12-19 23:05:39 +01009730 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9731 {
9732 if (unformat (line_input, "del"))
9733 is_add = 0;
John Loa43ccae2018-02-13 17:15:23 -05009734 else if (unformat (line_input, "instance %d", &instance))
9735 ;
Neale Ranns5a8844b2019-04-16 07:15:35 +00009736 else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
Ciara Loftus7eac9162016-09-30 15:47:03 +01009737 {
9738 src_set = 1;
Ciara Loftus7eac9162016-09-30 15:47:03 +01009739 }
Neale Ranns5a8844b2019-04-16 07:15:35 +00009740 else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
Ciara Loftus7eac9162016-09-30 15:47:03 +01009741 {
9742 dst_set = 1;
Ciara Loftus7eac9162016-09-30 15:47:03 +01009743 }
Neale Ranns5f8f6172019-04-18 10:23:56 +00009744 else if (unformat (line_input, "outer-table-id %d", &outer_table_id))
Damjan Marion7cd468a2016-12-19 23:05:39 +01009745 ;
9746 else if (unformat (line_input, "teb"))
Neale Ranns5a8844b2019-04-16 07:15:35 +00009747 t_type = GRE_API_TUNNEL_TYPE_TEB;
John Loa43ccae2018-02-13 17:15:23 -05009748 else if (unformat (line_input, "erspan %d", &session_id))
Neale Ranns5a8844b2019-04-16 07:15:35 +00009749 t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009750 else
9751 {
9752 errmsg ("parse error '%U'", format_unformat_error, line_input);
9753 return -99;
9754 }
9755 }
9756
9757 if (src_set == 0)
9758 {
9759 errmsg ("tunnel src address not specified");
9760 return -99;
9761 }
9762 if (dst_set == 0)
9763 {
9764 errmsg ("tunnel dst address not specified");
9765 return -99;
9766 }
9767
Neale Ranns5a8844b2019-04-16 07:15:35 +00009768 M (GRE_TUNNEL_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009769
Neale Ranns5a8844b2019-04-16 07:15:35 +00009770 clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
9771 clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
Damjan Marion7cd468a2016-12-19 23:05:39 +01009772
Neale Ranns5a8844b2019-04-16 07:15:35 +00009773 mp->tunnel.instance = htonl (instance);
Neale Ranns5f8f6172019-04-18 10:23:56 +00009774 mp->tunnel.outer_table_id = htonl (outer_table_id);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009775 mp->is_add = is_add;
Neale Ranns5a8844b2019-04-16 07:15:35 +00009776 mp->tunnel.session_id = htons ((u16) session_id);
9777 mp->tunnel.type = htonl (t_type);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009778
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009779 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06009780 W (ret);
9781 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009782}
9783
9784static void vl_api_gre_tunnel_details_t_handler
9785 (vl_api_gre_tunnel_details_t * mp)
9786{
9787 vat_main_t *vam = &vat_main;
9788
John Loa43ccae2018-02-13 17:15:23 -05009789 print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
Neale Ranns5a8844b2019-04-16 07:15:35 +00009790 ntohl (mp->tunnel.sw_if_index),
9791 ntohl (mp->tunnel.instance),
9792 format_vl_api_address, &mp->tunnel.src,
9793 format_vl_api_address, &mp->tunnel.dst,
Neale Ranns5f8f6172019-04-18 10:23:56 +00009794 mp->tunnel.type, ntohl (mp->tunnel.outer_table_id),
Neale Ranns5a8844b2019-04-16 07:15:35 +00009795 ntohl (mp->tunnel.session_id));
9796}
9797
Damjan Marion7cd468a2016-12-19 23:05:39 +01009798static void vl_api_gre_tunnel_details_t_handler_json
9799 (vl_api_gre_tunnel_details_t * mp)
9800{
9801 vat_main_t *vam = &vat_main;
9802 vat_json_node_t *node = NULL;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009803
9804 if (VAT_JSON_ARRAY != vam->json_tree.type)
9805 {
9806 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9807 vat_json_init_array (&vam->json_tree);
9808 }
9809 node = vat_json_array_add (&vam->json_tree);
9810
9811 vat_json_init_object (node);
Neale Ranns5a8844b2019-04-16 07:15:35 +00009812 vat_json_object_add_uint (node, "sw_if_index",
9813 ntohl (mp->tunnel.sw_if_index));
9814 vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
9815
9816 vat_json_object_add_address (node, "src", &mp->tunnel.src);
9817 vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
9818 vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
Neale Ranns5f8f6172019-04-18 10:23:56 +00009819 vat_json_object_add_uint (node, "outer_table_id",
9820 ntohl (mp->tunnel.outer_table_id));
Neale Ranns5a8844b2019-04-16 07:15:35 +00009821 vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009822}
9823
9824static int
9825api_gre_tunnel_dump (vat_main_t * vam)
9826{
9827 unformat_input_t *i = vam->input;
9828 vl_api_gre_tunnel_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -06009829 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009830 u32 sw_if_index;
9831 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009832 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009833
9834 /* Parse args required to build the message */
9835 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9836 {
9837 if (unformat (i, "sw_if_index %d", &sw_if_index))
9838 sw_if_index_set = 1;
9839 else
9840 break;
9841 }
9842
9843 if (sw_if_index_set == 0)
9844 {
9845 sw_if_index = ~0;
9846 }
9847
9848 if (!vam->json_output)
9849 {
John Loa43ccae2018-02-13 17:15:23 -05009850 print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
9851 "sw_if_index", "instance", "src_address", "dst_address",
9852 "tunnel_type", "outer_fib_id", "session_id");
Damjan Marion7cd468a2016-12-19 23:05:39 +01009853 }
9854
9855 /* Get list of gre-tunnel interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009856 M (GRE_TUNNEL_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009857
9858 mp->sw_if_index = htonl (sw_if_index);
9859
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009860 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009861
9862 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -04009863 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06009864 S (mp_ping);
9865
Jon Loeliger56c7b012017-02-01 12:31:41 -06009866 W (ret);
9867 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009868}
9869
9870static int
9871api_l2_fib_clear_table (vat_main_t * vam)
9872{
9873// unformat_input_t * i = vam->input;
9874 vl_api_l2_fib_clear_table_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009875 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009876
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009877 M (L2_FIB_CLEAR_TABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009878
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009879 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06009880 W (ret);
9881 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009882}
9883
9884static int
9885api_l2_interface_efp_filter (vat_main_t * vam)
9886{
9887 unformat_input_t *i = vam->input;
9888 vl_api_l2_interface_efp_filter_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009889 u32 sw_if_index;
9890 u8 enable = 1;
9891 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009892 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009893
9894 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9895 {
9896 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9897 sw_if_index_set = 1;
9898 else if (unformat (i, "sw_if_index %d", &sw_if_index))
9899 sw_if_index_set = 1;
9900 else if (unformat (i, "enable"))
9901 enable = 1;
9902 else if (unformat (i, "disable"))
9903 enable = 0;
9904 else
9905 {
9906 clib_warning ("parse error '%U'", format_unformat_error, i);
9907 return -99;
9908 }
9909 }
9910
9911 if (sw_if_index_set == 0)
9912 {
9913 errmsg ("missing sw_if_index");
9914 return -99;
9915 }
9916
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009917 M (L2_INTERFACE_EFP_FILTER, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009918
9919 mp->sw_if_index = ntohl (sw_if_index);
9920 mp->enable_disable = enable;
9921
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009922 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06009923 W (ret);
9924 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009925}
9926
9927#define foreach_vtr_op \
9928_("disable", L2_VTR_DISABLED) \
9929_("push-1", L2_VTR_PUSH_1) \
9930_("push-2", L2_VTR_PUSH_2) \
9931_("pop-1", L2_VTR_POP_1) \
9932_("pop-2", L2_VTR_POP_2) \
9933_("translate-1-1", L2_VTR_TRANSLATE_1_1) \
9934_("translate-1-2", L2_VTR_TRANSLATE_1_2) \
9935_("translate-2-1", L2_VTR_TRANSLATE_2_1) \
9936_("translate-2-2", L2_VTR_TRANSLATE_2_2)
9937
9938static int
9939api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
9940{
9941 unformat_input_t *i = vam->input;
9942 vl_api_l2_interface_vlan_tag_rewrite_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009943 u32 sw_if_index;
9944 u8 sw_if_index_set = 0;
9945 u8 vtr_op_set = 0;
9946 u32 vtr_op = 0;
9947 u32 push_dot1q = 1;
9948 u32 tag1 = ~0;
9949 u32 tag2 = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009950 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009951
9952 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9953 {
9954 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9955 sw_if_index_set = 1;
9956 else if (unformat (i, "sw_if_index %d", &sw_if_index))
9957 sw_if_index_set = 1;
9958 else if (unformat (i, "vtr_op %d", &vtr_op))
9959 vtr_op_set = 1;
9960#define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
9961 foreach_vtr_op
9962#undef _
9963 else if (unformat (i, "push_dot1q %d", &push_dot1q))
9964 ;
9965 else if (unformat (i, "tag1 %d", &tag1))
9966 ;
9967 else if (unformat (i, "tag2 %d", &tag2))
9968 ;
9969 else
9970 {
9971 clib_warning ("parse error '%U'", format_unformat_error, i);
9972 return -99;
9973 }
9974 }
9975
9976 if ((sw_if_index_set == 0) || (vtr_op_set == 0))
9977 {
9978 errmsg ("missing vtr operation or sw_if_index");
9979 return -99;
9980 }
9981
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009982 M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
9983 mp->sw_if_index = ntohl (sw_if_index);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009984 mp->vtr_op = ntohl (vtr_op);
9985 mp->push_dot1q = ntohl (push_dot1q);
9986 mp->tag1 = ntohl (tag1);
9987 mp->tag2 = ntohl (tag2);
9988
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009989 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06009990 W (ret);
9991 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009992}
9993
9994static int
9995api_create_vhost_user_if (vat_main_t * vam)
9996{
9997 unformat_input_t *i = vam->input;
9998 vl_api_create_vhost_user_if_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009999 u8 *file_name;
10000 u8 is_server = 0;
10001 u8 file_name_set = 0;
10002 u32 custom_dev_instance = ~0;
10003 u8 hwaddr[6];
10004 u8 use_custom_mac = 0;
Mohsin Kazmiee2e58f2018-08-21 16:07:03 +020010005 u8 disable_mrg_rxbuf = 0;
10006 u8 disable_indirect_desc = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010007 u8 *tag = 0;
Steven Luong4208a4c2019-05-06 08:51:56 -070010008 u8 enable_gso = 0;
Steven Luongbc0d9ff2020-03-23 09:34:59 -070010009 u8 enable_packed = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010010 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010011
10012 /* Shut up coverity */
Dave Barachb7b92992018-10-17 10:38:51 -040010013 clib_memset (hwaddr, 0, sizeof (hwaddr));
Damjan Marion7cd468a2016-12-19 23:05:39 +010010014
10015 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10016 {
10017 if (unformat (i, "socket %s", &file_name))
10018 {
10019 file_name_set = 1;
10020 }
10021 else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10022 ;
10023 else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
10024 use_custom_mac = 1;
10025 else if (unformat (i, "server"))
10026 is_server = 1;
Mohsin Kazmiee2e58f2018-08-21 16:07:03 +020010027 else if (unformat (i, "disable_mrg_rxbuf"))
10028 disable_mrg_rxbuf = 1;
10029 else if (unformat (i, "disable_indirect_desc"))
10030 disable_indirect_desc = 1;
Steven Luong4208a4c2019-05-06 08:51:56 -070010031 else if (unformat (i, "gso"))
10032 enable_gso = 1;
Steven Luongbc0d9ff2020-03-23 09:34:59 -070010033 else if (unformat (i, "packed"))
10034 enable_packed = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010035 else if (unformat (i, "tag %s", &tag))
10036 ;
10037 else
10038 break;
10039 }
10040
10041 if (file_name_set == 0)
10042 {
10043 errmsg ("missing socket file name");
10044 return -99;
10045 }
10046
10047 if (vec_len (file_name) > 255)
10048 {
10049 errmsg ("socket file name too long");
10050 return -99;
10051 }
10052 vec_add1 (file_name, 0);
10053
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010054 M (CREATE_VHOST_USER_IF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010055
10056 mp->is_server = is_server;
Mohsin Kazmiee2e58f2018-08-21 16:07:03 +020010057 mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
10058 mp->disable_indirect_desc = disable_indirect_desc;
Steven Luong4208a4c2019-05-06 08:51:56 -070010059 mp->enable_gso = enable_gso;
Steven Luongbc0d9ff2020-03-23 09:34:59 -070010060 mp->enable_packed = enable_packed;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010061 clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10062 vec_free (file_name);
10063 if (custom_dev_instance != ~0)
10064 {
10065 mp->renumber = 1;
10066 mp->custom_dev_instance = ntohl (custom_dev_instance);
10067 }
Mohsin Kazmiee2e58f2018-08-21 16:07:03 +020010068
Damjan Marion7cd468a2016-12-19 23:05:39 +010010069 mp->use_custom_mac = use_custom_mac;
10070 clib_memcpy (mp->mac_address, hwaddr, 6);
10071 if (tag)
10072 strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
10073 vec_free (tag);
10074
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010075 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010076 W (ret);
10077 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010078}
10079
10080static int
10081api_modify_vhost_user_if (vat_main_t * vam)
10082{
10083 unformat_input_t *i = vam->input;
10084 vl_api_modify_vhost_user_if_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010085 u8 *file_name;
10086 u8 is_server = 0;
10087 u8 file_name_set = 0;
10088 u32 custom_dev_instance = ~0;
10089 u8 sw_if_index_set = 0;
10090 u32 sw_if_index = (u32) ~ 0;
Steven Luong4208a4c2019-05-06 08:51:56 -070010091 u8 enable_gso = 0;
Steven Luongbc0d9ff2020-03-23 09:34:59 -070010092 u8 enable_packed = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010093 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010094
10095 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10096 {
10097 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10098 sw_if_index_set = 1;
10099 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10100 sw_if_index_set = 1;
10101 else if (unformat (i, "socket %s", &file_name))
10102 {
10103 file_name_set = 1;
10104 }
10105 else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10106 ;
10107 else if (unformat (i, "server"))
10108 is_server = 1;
Steven Luong4208a4c2019-05-06 08:51:56 -070010109 else if (unformat (i, "gso"))
10110 enable_gso = 1;
Steven Luongbc0d9ff2020-03-23 09:34:59 -070010111 else if (unformat (i, "packed"))
10112 enable_packed = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010113 else
10114 break;
10115 }
10116
10117 if (sw_if_index_set == 0)
10118 {
10119 errmsg ("missing sw_if_index or interface name");
10120 return -99;
10121 }
10122
10123 if (file_name_set == 0)
10124 {
10125 errmsg ("missing socket file name");
10126 return -99;
10127 }
10128
10129 if (vec_len (file_name) > 255)
10130 {
10131 errmsg ("socket file name too long");
10132 return -99;
10133 }
10134 vec_add1 (file_name, 0);
10135
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010136 M (MODIFY_VHOST_USER_IF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010137
10138 mp->sw_if_index = ntohl (sw_if_index);
10139 mp->is_server = is_server;
Steven Luong4208a4c2019-05-06 08:51:56 -070010140 mp->enable_gso = enable_gso;
Steven Luongbc0d9ff2020-03-23 09:34:59 -070010141 mp->enable_packed = enable_packed;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010142 clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10143 vec_free (file_name);
10144 if (custom_dev_instance != ~0)
10145 {
10146 mp->renumber = 1;
10147 mp->custom_dev_instance = ntohl (custom_dev_instance);
10148 }
10149
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010150 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010151 W (ret);
10152 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010153}
10154
10155static int
10156api_delete_vhost_user_if (vat_main_t * vam)
10157{
10158 unformat_input_t *i = vam->input;
10159 vl_api_delete_vhost_user_if_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010160 u32 sw_if_index = ~0;
10161 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010162 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010163
10164 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10165 {
10166 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10167 sw_if_index_set = 1;
10168 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10169 sw_if_index_set = 1;
10170 else
10171 break;
10172 }
10173
10174 if (sw_if_index_set == 0)
10175 {
10176 errmsg ("missing sw_if_index or interface name");
10177 return -99;
10178 }
10179
10180
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010181 M (DELETE_VHOST_USER_IF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010182
10183 mp->sw_if_index = ntohl (sw_if_index);
10184
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010185 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010186 W (ret);
10187 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010188}
10189
10190static void vl_api_sw_interface_vhost_user_details_t_handler
10191 (vl_api_sw_interface_vhost_user_details_t * mp)
10192{
10193 vat_main_t *vam = &vat_main;
Jakub Grajciar5d4c99f2019-09-26 10:21:59 +020010194 u64 features;
10195
10196 features =
10197 clib_net_to_host_u32 (mp->features_first_32) | ((u64)
10198 clib_net_to_host_u32
10199 (mp->features_last_32) <<
10200 32);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010201
Stevenf3b53642017-05-01 14:03:02 -070010202 print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
Damjan Marion7cd468a2016-12-19 23:05:39 +010010203 (char *) mp->interface_name,
10204 ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
Jakub Grajciar5d4c99f2019-09-26 10:21:59 +020010205 features, mp->is_server,
Stevenf3b53642017-05-01 14:03:02 -070010206 ntohl (mp->num_regions), (char *) mp->sock_filename);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010207 print (vam->ofp, " Status: '%s'", strerror (ntohl (mp->sock_errno)));
10208}
10209
10210static void vl_api_sw_interface_vhost_user_details_t_handler_json
10211 (vl_api_sw_interface_vhost_user_details_t * mp)
10212{
10213 vat_main_t *vam = &vat_main;
10214 vat_json_node_t *node = NULL;
10215
10216 if (VAT_JSON_ARRAY != vam->json_tree.type)
10217 {
10218 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10219 vat_json_init_array (&vam->json_tree);
10220 }
10221 node = vat_json_array_add (&vam->json_tree);
10222
10223 vat_json_init_object (node);
10224 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10225 vat_json_object_add_string_copy (node, "interface_name",
10226 mp->interface_name);
10227 vat_json_object_add_uint (node, "virtio_net_hdr_sz",
10228 ntohl (mp->virtio_net_hdr_sz));
Jakub Grajciar5d4c99f2019-09-26 10:21:59 +020010229 vat_json_object_add_uint (node, "features_first_32",
10230 clib_net_to_host_u32 (mp->features_first_32));
10231 vat_json_object_add_uint (node, "features_last_32",
10232 clib_net_to_host_u32 (mp->features_last_32));
Damjan Marion7cd468a2016-12-19 23:05:39 +010010233 vat_json_object_add_uint (node, "is_server", mp->is_server);
10234 vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
10235 vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
10236 vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
10237}
10238
10239static int
10240api_sw_interface_vhost_user_dump (vat_main_t * vam)
10241{
Steven Luonga0e8d962020-05-18 17:12:56 -070010242 unformat_input_t *i = vam->input;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010243 vl_api_sw_interface_vhost_user_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010244 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010245 int ret;
Steven Luonga0e8d962020-05-18 17:12:56 -070010246 u32 sw_if_index = ~0;
10247
10248 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10249 {
10250 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10251 ;
10252 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10253 ;
10254 else
10255 break;
10256 }
10257
Damjan Marion7cd468a2016-12-19 23:05:39 +010010258 print (vam->ofp,
Stevenf3b53642017-05-01 14:03:02 -070010259 "Interface name idx hdr_sz features server regions filename");
Damjan Marion7cd468a2016-12-19 23:05:39 +010010260
10261 /* Get list of vhost-user interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010262 M (SW_INTERFACE_VHOST_USER_DUMP, mp);
Steven Luonga0e8d962020-05-18 17:12:56 -070010263 mp->sw_if_index = ntohl (sw_if_index);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010264 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010265
10266 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040010267 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010268 S (mp_ping);
10269
Jon Loeliger56c7b012017-02-01 12:31:41 -060010270 W (ret);
10271 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010272}
10273
10274static int
10275api_show_version (vat_main_t * vam)
10276{
10277 vl_api_show_version_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010278 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010279
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010280 M (SHOW_VERSION, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010281
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010282 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010283 W (ret);
10284 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010285}
10286
10287
10288static int
10289api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
10290{
10291 unformat_input_t *line_input = vam->input;
10292 vl_api_vxlan_gpe_add_del_tunnel_t *mp;
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010293 ip46_address_t local, remote;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010294 u8 is_add = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010295 u8 local_set = 0;
10296 u8 remote_set = 0;
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010297 u8 grp_set = 0;
10298 u32 mcast_sw_if_index = ~0;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010299 u32 encap_vrf_id = 0;
10300 u32 decap_vrf_id = 0;
10301 u8 protocol = ~0;
10302 u32 vni;
10303 u8 vni_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010304 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010305
10306 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10307 {
10308 if (unformat (line_input, "del"))
10309 is_add = 0;
10310 else if (unformat (line_input, "local %U",
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010311 unformat_ip46_address, &local))
Damjan Marion7cd468a2016-12-19 23:05:39 +010010312 {
10313 local_set = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010314 }
10315 else if (unformat (line_input, "remote %U",
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010316 unformat_ip46_address, &remote))
Damjan Marion7cd468a2016-12-19 23:05:39 +010010317 {
10318 remote_set = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010319 }
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010320 else if (unformat (line_input, "group %U %U",
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010321 unformat_ip46_address, &remote,
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010322 api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10323 {
10324 grp_set = remote_set = 1;
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010325 }
10326 else if (unformat (line_input, "group %U",
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010327 unformat_ip46_address, &remote))
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010328 {
10329 grp_set = remote_set = 1;
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010330 }
10331 else
10332 if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10333 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010334 else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10335 ;
10336 else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
10337 ;
10338 else if (unformat (line_input, "vni %d", &vni))
10339 vni_set = 1;
10340 else if (unformat (line_input, "next-ip4"))
10341 protocol = 1;
10342 else if (unformat (line_input, "next-ip6"))
10343 protocol = 2;
10344 else if (unformat (line_input, "next-ethernet"))
10345 protocol = 3;
10346 else if (unformat (line_input, "next-nsh"))
10347 protocol = 4;
10348 else
10349 {
10350 errmsg ("parse error '%U'", format_unformat_error, line_input);
10351 return -99;
10352 }
10353 }
10354
10355 if (local_set == 0)
10356 {
10357 errmsg ("tunnel local address not specified");
10358 return -99;
10359 }
10360 if (remote_set == 0)
10361 {
10362 errmsg ("tunnel remote address not specified");
10363 return -99;
10364 }
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010365 if (grp_set && mcast_sw_if_index == ~0)
10366 {
10367 errmsg ("tunnel nonexistent multicast device");
10368 return -99;
10369 }
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010370 if (ip46_address_is_ip4 (&local) != ip46_address_is_ip4 (&remote))
Damjan Marion7cd468a2016-12-19 23:05:39 +010010371 {
10372 errmsg ("both IPv4 and IPv6 addresses specified");
10373 return -99;
10374 }
10375
10376 if (vni_set == 0)
10377 {
10378 errmsg ("vni not specified");
10379 return -99;
10380 }
10381
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010382 M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010383
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010384 ip_address_encode (&local,
10385 ip46_address_is_ip4 (&local) ? IP46_TYPE_IP4 :
10386 IP46_TYPE_IP6, &mp->local);
10387 ip_address_encode (&remote,
10388 ip46_address_is_ip4 (&remote) ? IP46_TYPE_IP4 :
10389 IP46_TYPE_IP6, &mp->remote);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010390
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010391 mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010392 mp->encap_vrf_id = ntohl (encap_vrf_id);
10393 mp->decap_vrf_id = ntohl (decap_vrf_id);
10394 mp->protocol = protocol;
10395 mp->vni = ntohl (vni);
10396 mp->is_add = is_add;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010397
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010398 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010399 W (ret);
10400 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010401}
10402
10403static void vl_api_vxlan_gpe_tunnel_details_t_handler
10404 (vl_api_vxlan_gpe_tunnel_details_t * mp)
10405{
10406 vat_main_t *vam = &vat_main;
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010407 ip46_address_t local, remote;
10408
10409 ip_address_decode (&mp->local, &local);
10410 ip_address_decode (&mp->remote, &remote);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010411
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010412 print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
Damjan Marion7cd468a2016-12-19 23:05:39 +010010413 ntohl (mp->sw_if_index),
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010414 format_ip46_address, &local, IP46_TYPE_ANY,
10415 format_ip46_address, &remote, IP46_TYPE_ANY,
10416 ntohl (mp->vni), mp->protocol,
10417 ntohl (mp->mcast_sw_if_index),
Damjan Marion7cd468a2016-12-19 23:05:39 +010010418 ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
10419}
10420
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010421
Damjan Marion7cd468a2016-12-19 23:05:39 +010010422static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
10423 (vl_api_vxlan_gpe_tunnel_details_t * mp)
10424{
10425 vat_main_t *vam = &vat_main;
10426 vat_json_node_t *node = NULL;
10427 struct in_addr ip4;
10428 struct in6_addr ip6;
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010429 ip46_address_t local, remote;
10430
10431 ip_address_decode (&mp->local, &local);
10432 ip_address_decode (&mp->remote, &remote);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010433
10434 if (VAT_JSON_ARRAY != vam->json_tree.type)
10435 {
10436 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10437 vat_json_init_array (&vam->json_tree);
10438 }
10439 node = vat_json_array_add (&vam->json_tree);
10440
10441 vat_json_init_object (node);
10442 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010443 if (ip46_address_is_ip4 (&local))
Damjan Marion7cd468a2016-12-19 23:05:39 +010010444 {
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010445 clib_memcpy (&ip4, &local.ip4, sizeof (ip4));
10446 vat_json_object_add_ip4 (node, "local", ip4);
10447 clib_memcpy (&ip4, &remote.ip4, sizeof (ip4));
10448 vat_json_object_add_ip4 (node, "remote", ip4);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010449 }
10450 else
10451 {
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010452 clib_memcpy (&ip6, &local.ip6, sizeof (ip6));
10453 vat_json_object_add_ip6 (node, "local", ip6);
10454 clib_memcpy (&ip6, &remote.ip6, sizeof (ip6));
10455 vat_json_object_add_ip6 (node, "remote", ip6);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010456 }
10457 vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10458 vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010459 vat_json_object_add_uint (node, "mcast_sw_if_index",
10460 ntohl (mp->mcast_sw_if_index));
Damjan Marion7cd468a2016-12-19 23:05:39 +010010461 vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10462 vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
10463 vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10464}
10465
10466static int
10467api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
10468{
10469 unformat_input_t *i = vam->input;
10470 vl_api_vxlan_gpe_tunnel_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010471 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010472 u32 sw_if_index;
10473 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010474 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010475
10476 /* Parse args required to build the message */
10477 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10478 {
10479 if (unformat (i, "sw_if_index %d", &sw_if_index))
10480 sw_if_index_set = 1;
10481 else
10482 break;
10483 }
10484
10485 if (sw_if_index_set == 0)
10486 {
10487 sw_if_index = ~0;
10488 }
10489
10490 if (!vam->json_output)
10491 {
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010492 print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
Damjan Marion7cd468a2016-12-19 23:05:39 +010010493 "sw_if_index", "local", "remote", "vni",
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010494 "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
Damjan Marion7cd468a2016-12-19 23:05:39 +010010495 }
10496
10497 /* Get list of vxlan-tunnel interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010498 M (VXLAN_GPE_TUNNEL_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010499
10500 mp->sw_if_index = htonl (sw_if_index);
10501
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010502 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010503
10504 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040010505 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010506 S (mp_ping);
10507
Jon Loeliger56c7b012017-02-01 12:31:41 -060010508 W (ret);
10509 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010510}
10511
Ole Troan01384fe2017-05-12 11:55:35 +020010512static void vl_api_l2_fib_table_details_t_handler
10513 (vl_api_l2_fib_table_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010010514{
10515 vat_main_t *vam = &vat_main;
10516
10517 print (vam->ofp, "%3" PRIu32 " %U %3" PRIu32
10518 " %d %d %d",
Mohsin Kazmi57938f62017-10-27 21:28:07 +020010519 ntohl (mp->bd_id), format_ethernet_address, mp->mac,
Damjan Marion7cd468a2016-12-19 23:05:39 +010010520 ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
10521 mp->bvi_mac);
10522}
10523
Ole Troan01384fe2017-05-12 11:55:35 +020010524static void vl_api_l2_fib_table_details_t_handler_json
10525 (vl_api_l2_fib_table_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010010526{
10527 vat_main_t *vam = &vat_main;
10528 vat_json_node_t *node = NULL;
10529
10530 if (VAT_JSON_ARRAY != vam->json_tree.type)
10531 {
10532 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10533 vat_json_init_array (&vam->json_tree);
10534 }
10535 node = vat_json_array_add (&vam->json_tree);
10536
10537 vat_json_init_object (node);
10538 vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
Mohsin Kazmi57938f62017-10-27 21:28:07 +020010539 vat_json_object_add_bytes (node, "mac", mp->mac, 6);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010540 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10541 vat_json_object_add_uint (node, "static_mac", mp->static_mac);
10542 vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
10543 vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
10544}
10545
10546static int
10547api_l2_fib_table_dump (vat_main_t * vam)
10548{
10549 unformat_input_t *i = vam->input;
10550 vl_api_l2_fib_table_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010551 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010552 u32 bd_id;
10553 u8 bd_id_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010554 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010555
10556 /* Parse args required to build the message */
10557 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10558 {
10559 if (unformat (i, "bd_id %d", &bd_id))
10560 bd_id_set = 1;
10561 else
10562 break;
10563 }
10564
10565 if (bd_id_set == 0)
10566 {
10567 errmsg ("missing bridge domain");
10568 return -99;
10569 }
10570
10571 print (vam->ofp, "BD-ID Mac Address sw-ndx Static Filter BVI");
10572
10573 /* Get list of l2 fib entries */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010574 M (L2_FIB_TABLE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010575
10576 mp->bd_id = ntohl (bd_id);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010577 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010578
10579 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040010580 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010581 S (mp_ping);
10582
Jon Loeliger56c7b012017-02-01 12:31:41 -060010583 W (ret);
10584 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010585}
10586
10587
10588static int
10589api_interface_name_renumber (vat_main_t * vam)
10590{
10591 unformat_input_t *line_input = vam->input;
10592 vl_api_interface_name_renumber_t *mp;
10593 u32 sw_if_index = ~0;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010594 u32 new_show_dev_instance = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010595 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010596
10597 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10598 {
10599 if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
10600 &sw_if_index))
10601 ;
10602 else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
10603 ;
10604 else if (unformat (line_input, "new_show_dev_instance %d",
10605 &new_show_dev_instance))
10606 ;
10607 else
10608 break;
10609 }
10610
10611 if (sw_if_index == ~0)
10612 {
10613 errmsg ("missing interface name or sw_if_index");
10614 return -99;
10615 }
10616
10617 if (new_show_dev_instance == ~0)
10618 {
10619 errmsg ("missing new_show_dev_instance");
10620 return -99;
10621 }
10622
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010623 M (INTERFACE_NAME_RENUMBER, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010624
10625 mp->sw_if_index = ntohl (sw_if_index);
10626 mp->new_show_dev_instance = ntohl (new_show_dev_instance);
10627
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010628 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010629 W (ret);
10630 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010631}
10632
10633static int
John Lo8d00fff2017-08-03 00:35:36 -040010634api_want_l2_macs_events (vat_main_t * vam)
10635{
10636 unformat_input_t *line_input = vam->input;
10637 vl_api_want_l2_macs_events_t *mp;
10638 u8 enable_disable = 1;
10639 u32 scan_delay = 0;
10640 u32 max_macs_in_event = 0;
10641 u32 learn_limit = 0;
10642 int ret;
10643
10644 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10645 {
10646 if (unformat (line_input, "learn-limit %d", &learn_limit))
10647 ;
10648 else if (unformat (line_input, "scan-delay %d", &scan_delay))
10649 ;
10650 else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
10651 ;
10652 else if (unformat (line_input, "disable"))
10653 enable_disable = 0;
10654 else
10655 break;
10656 }
10657
10658 M (WANT_L2_MACS_EVENTS, mp);
10659 mp->enable_disable = enable_disable;
10660 mp->pid = htonl (getpid ());
10661 mp->learn_limit = htonl (learn_limit);
10662 mp->scan_delay = (u8) scan_delay;
10663 mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
10664 S (mp);
10665 W (ret);
10666 return ret;
10667}
10668
10669static int
Damjan Marion7cd468a2016-12-19 23:05:39 +010010670api_input_acl_set_interface (vat_main_t * vam)
10671{
10672 unformat_input_t *i = vam->input;
10673 vl_api_input_acl_set_interface_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010674 u32 sw_if_index;
10675 int sw_if_index_set;
10676 u32 ip4_table_index = ~0;
10677 u32 ip6_table_index = ~0;
10678 u32 l2_table_index = ~0;
10679 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010680 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010681
10682 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10683 {
10684 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10685 sw_if_index_set = 1;
10686 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10687 sw_if_index_set = 1;
10688 else if (unformat (i, "del"))
10689 is_add = 0;
10690 else if (unformat (i, "ip4-table %d", &ip4_table_index))
10691 ;
10692 else if (unformat (i, "ip6-table %d", &ip6_table_index))
10693 ;
10694 else if (unformat (i, "l2-table %d", &l2_table_index))
10695 ;
10696 else
10697 {
10698 clib_warning ("parse error '%U'", format_unformat_error, i);
10699 return -99;
10700 }
10701 }
10702
10703 if (sw_if_index_set == 0)
10704 {
10705 errmsg ("missing interface name or sw_if_index");
10706 return -99;
10707 }
10708
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010709 M (INPUT_ACL_SET_INTERFACE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010710
10711 mp->sw_if_index = ntohl (sw_if_index);
10712 mp->ip4_table_index = ntohl (ip4_table_index);
10713 mp->ip6_table_index = ntohl (ip6_table_index);
10714 mp->l2_table_index = ntohl (l2_table_index);
10715 mp->is_add = is_add;
10716
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010717 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010718 W (ret);
10719 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010720}
10721
10722static int
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +010010723api_output_acl_set_interface (vat_main_t * vam)
10724{
10725 unformat_input_t *i = vam->input;
10726 vl_api_output_acl_set_interface_t *mp;
10727 u32 sw_if_index;
10728 int sw_if_index_set;
10729 u32 ip4_table_index = ~0;
10730 u32 ip6_table_index = ~0;
10731 u32 l2_table_index = ~0;
10732 u8 is_add = 1;
10733 int ret;
10734
10735 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10736 {
10737 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10738 sw_if_index_set = 1;
10739 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10740 sw_if_index_set = 1;
10741 else if (unformat (i, "del"))
10742 is_add = 0;
10743 else if (unformat (i, "ip4-table %d", &ip4_table_index))
10744 ;
10745 else if (unformat (i, "ip6-table %d", &ip6_table_index))
10746 ;
10747 else if (unformat (i, "l2-table %d", &l2_table_index))
10748 ;
10749 else
10750 {
10751 clib_warning ("parse error '%U'", format_unformat_error, i);
10752 return -99;
10753 }
10754 }
10755
10756 if (sw_if_index_set == 0)
10757 {
10758 errmsg ("missing interface name or sw_if_index");
10759 return -99;
10760 }
10761
10762 M (OUTPUT_ACL_SET_INTERFACE, mp);
10763
10764 mp->sw_if_index = ntohl (sw_if_index);
10765 mp->ip4_table_index = ntohl (ip4_table_index);
10766 mp->ip6_table_index = ntohl (ip6_table_index);
10767 mp->l2_table_index = ntohl (l2_table_index);
10768 mp->is_add = is_add;
10769
10770 S (mp);
10771 W (ret);
10772 return ret;
10773}
10774
10775static int
Damjan Marion7cd468a2016-12-19 23:05:39 +010010776api_ip_address_dump (vat_main_t * vam)
10777{
10778 unformat_input_t *i = vam->input;
10779 vl_api_ip_address_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010780 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010781 u32 sw_if_index = ~0;
10782 u8 sw_if_index_set = 0;
10783 u8 ipv4_set = 0;
10784 u8 ipv6_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010785 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010786
10787 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10788 {
10789 if (unformat (i, "sw_if_index %d", &sw_if_index))
10790 sw_if_index_set = 1;
10791 else
10792 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10793 sw_if_index_set = 1;
10794 else if (unformat (i, "ipv4"))
10795 ipv4_set = 1;
10796 else if (unformat (i, "ipv6"))
10797 ipv6_set = 1;
10798 else
10799 break;
10800 }
10801
10802 if (ipv4_set && ipv6_set)
10803 {
10804 errmsg ("ipv4 and ipv6 flags cannot be both set");
10805 return -99;
10806 }
10807
10808 if ((!ipv4_set) && (!ipv6_set))
10809 {
10810 errmsg ("no ipv4 nor ipv6 flag set");
10811 return -99;
10812 }
10813
10814 if (sw_if_index_set == 0)
10815 {
10816 errmsg ("missing interface name or sw_if_index");
10817 return -99;
10818 }
10819
10820 vam->current_sw_if_index = sw_if_index;
10821 vam->is_ipv6 = ipv6_set;
10822
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010823 M (IP_ADDRESS_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010824 mp->sw_if_index = ntohl (sw_if_index);
10825 mp->is_ipv6 = ipv6_set;
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010826 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010827
10828 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040010829 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010830 S (mp_ping);
10831
Jon Loeliger56c7b012017-02-01 12:31:41 -060010832 W (ret);
10833 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010834}
10835
10836static int
10837api_ip_dump (vat_main_t * vam)
10838{
10839 vl_api_ip_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010840 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010841 unformat_input_t *in = vam->input;
10842 int ipv4_set = 0;
10843 int ipv6_set = 0;
10844 int is_ipv6;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010845 int i;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010846 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010847
10848 while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
10849 {
10850 if (unformat (in, "ipv4"))
10851 ipv4_set = 1;
10852 else if (unformat (in, "ipv6"))
10853 ipv6_set = 1;
10854 else
10855 break;
10856 }
10857
10858 if (ipv4_set && ipv6_set)
10859 {
10860 errmsg ("ipv4 and ipv6 flags cannot be both set");
10861 return -99;
10862 }
10863
10864 if ((!ipv4_set) && (!ipv6_set))
10865 {
10866 errmsg ("no ipv4 nor ipv6 flag set");
10867 return -99;
10868 }
10869
10870 is_ipv6 = ipv6_set;
10871 vam->is_ipv6 = is_ipv6;
10872
10873 /* free old data */
10874 for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
10875 {
10876 vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
10877 }
10878 vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
10879
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010880 M (IP_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010881 mp->is_ipv6 = ipv6_set;
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010882 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010883
10884 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040010885 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010886 S (mp_ping);
10887
Jon Loeliger56c7b012017-02-01 12:31:41 -060010888 W (ret);
10889 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010890}
10891
10892static int
10893api_ipsec_spd_add_del (vat_main_t * vam)
10894{
10895 unformat_input_t *i = vam->input;
10896 vl_api_ipsec_spd_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010897 u32 spd_id = ~0;
10898 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010899 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010900
10901 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10902 {
10903 if (unformat (i, "spd_id %d", &spd_id))
10904 ;
10905 else if (unformat (i, "del"))
10906 is_add = 0;
10907 else
10908 {
10909 clib_warning ("parse error '%U'", format_unformat_error, i);
10910 return -99;
10911 }
10912 }
10913 if (spd_id == ~0)
10914 {
10915 errmsg ("spd_id must be set");
10916 return -99;
10917 }
10918
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010919 M (IPSEC_SPD_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010920
10921 mp->spd_id = ntohl (spd_id);
10922 mp->is_add = is_add;
10923
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010924 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010925 W (ret);
10926 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010927}
10928
10929static int
10930api_ipsec_interface_add_del_spd (vat_main_t * vam)
10931{
10932 unformat_input_t *i = vam->input;
10933 vl_api_ipsec_interface_add_del_spd_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010934 u32 sw_if_index;
10935 u8 sw_if_index_set = 0;
10936 u32 spd_id = (u32) ~ 0;
10937 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010938 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010939
10940 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10941 {
10942 if (unformat (i, "del"))
10943 is_add = 0;
10944 else if (unformat (i, "spd_id %d", &spd_id))
10945 ;
10946 else
10947 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10948 sw_if_index_set = 1;
10949 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10950 sw_if_index_set = 1;
10951 else
10952 {
10953 clib_warning ("parse error '%U'", format_unformat_error, i);
10954 return -99;
10955 }
10956
10957 }
10958
10959 if (spd_id == (u32) ~ 0)
10960 {
10961 errmsg ("spd_id must be set");
10962 return -99;
10963 }
10964
10965 if (sw_if_index_set == 0)
10966 {
10967 errmsg ("missing interface name or sw_if_index");
10968 return -99;
10969 }
10970
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010971 M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010972
10973 mp->spd_id = ntohl (spd_id);
10974 mp->sw_if_index = ntohl (sw_if_index);
10975 mp->is_add = is_add;
10976
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010977 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010978 W (ret);
10979 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010980}
10981
10982static int
Neale Ranns17dcec02019-01-09 21:22:20 -080010983api_ipsec_spd_entry_add_del (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010010984{
10985 unformat_input_t *i = vam->input;
Neale Ranns17dcec02019-01-09 21:22:20 -080010986 vl_api_ipsec_spd_entry_add_del_t *mp;
Benoît Ganne49ee6842019-04-30 11:50:46 +020010987 u8 is_add = 1, is_outbound = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010988 u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
10989 i32 priority = 0;
10990 u32 rport_start = 0, rport_stop = (u32) ~ 0;
10991 u32 lport_start = 0, lport_stop = (u32) ~ 0;
Neale Ranns17dcec02019-01-09 21:22:20 -080010992 vl_api_address_t laddr_start = { }, laddr_stop =
10993 {
10994 }, raddr_start =
10995 {
10996 }, raddr_stop =
10997 {
10998 };
Jon Loeliger56c7b012017-02-01 12:31:41 -060010999 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011000
Damjan Marion7cd468a2016-12-19 23:05:39 +010011001 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11002 {
11003 if (unformat (i, "del"))
11004 is_add = 0;
11005 if (unformat (i, "outbound"))
11006 is_outbound = 1;
11007 if (unformat (i, "inbound"))
11008 is_outbound = 0;
11009 else if (unformat (i, "spd_id %d", &spd_id))
11010 ;
11011 else if (unformat (i, "sa_id %d", &sa_id))
11012 ;
11013 else if (unformat (i, "priority %d", &priority))
11014 ;
11015 else if (unformat (i, "protocol %d", &protocol))
11016 ;
11017 else if (unformat (i, "lport_start %d", &lport_start))
11018 ;
11019 else if (unformat (i, "lport_stop %d", &lport_stop))
11020 ;
11021 else if (unformat (i, "rport_start %d", &rport_start))
11022 ;
11023 else if (unformat (i, "rport_stop %d", &rport_stop))
11024 ;
Neale Ranns17dcec02019-01-09 21:22:20 -080011025 else if (unformat (i, "laddr_start %U",
11026 unformat_vl_api_address, &laddr_start))
Benoît Ganne49ee6842019-04-30 11:50:46 +020011027 ;
Neale Ranns17dcec02019-01-09 21:22:20 -080011028 else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
11029 &laddr_stop))
Benoît Ganne49ee6842019-04-30 11:50:46 +020011030 ;
Neale Ranns17dcec02019-01-09 21:22:20 -080011031 else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
11032 &raddr_start))
Benoît Ganne49ee6842019-04-30 11:50:46 +020011033 ;
Neale Ranns17dcec02019-01-09 21:22:20 -080011034 else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
11035 &raddr_stop))
Benoît Ganne49ee6842019-04-30 11:50:46 +020011036 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011037 else
11038 if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
11039 {
11040 if (policy == IPSEC_POLICY_ACTION_RESOLVE)
11041 {
11042 clib_warning ("unsupported action: 'resolve'");
11043 return -99;
11044 }
11045 }
11046 else
11047 {
11048 clib_warning ("parse error '%U'", format_unformat_error, i);
11049 return -99;
11050 }
11051
11052 }
11053
Neale Ranns17dcec02019-01-09 21:22:20 -080011054 M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011055
Damjan Marion7cd468a2016-12-19 23:05:39 +010011056 mp->is_add = is_add;
Neale Ranns17dcec02019-01-09 21:22:20 -080011057
11058 mp->entry.spd_id = ntohl (spd_id);
11059 mp->entry.priority = ntohl (priority);
11060 mp->entry.is_outbound = is_outbound;
11061
11062 clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
11063 sizeof (vl_api_address_t));
11064 clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
11065 sizeof (vl_api_address_t));
11066 clib_memcpy (&mp->entry.local_address_start, &laddr_start,
11067 sizeof (vl_api_address_t));
11068 clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
11069 sizeof (vl_api_address_t));
11070
11071 mp->entry.protocol = (u8) protocol;
11072 mp->entry.local_port_start = ntohs ((u16) lport_start);
11073 mp->entry.local_port_stop = ntohs ((u16) lport_stop);
11074 mp->entry.remote_port_start = ntohs ((u16) rport_start);
11075 mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
11076 mp->entry.policy = (u8) policy;
11077 mp->entry.sa_id = ntohl (sa_id);
Neale Ranns17dcec02019-01-09 21:22:20 -080011078
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011079 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011080 W (ret);
11081 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011082}
11083
11084static int
Neale Ranns17dcec02019-01-09 21:22:20 -080011085api_ipsec_sad_entry_add_del (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010011086{
11087 unformat_input_t *i = vam->input;
Neale Ranns17dcec02019-01-09 21:22:20 -080011088 vl_api_ipsec_sad_entry_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011089 u32 sad_id = 0, spi = 0;
11090 u8 *ck = 0, *ik = 0;
11091 u8 is_add = 1;
11092
Neale Ranns17dcec02019-01-09 21:22:20 -080011093 vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
11094 vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
11095 vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
11096 vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
11097 vl_api_address_t tun_src, tun_dst;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011098 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011099
11100 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11101 {
11102 if (unformat (i, "del"))
11103 is_add = 0;
11104 else if (unformat (i, "sad_id %d", &sad_id))
11105 ;
11106 else if (unformat (i, "spi %d", &spi))
11107 ;
11108 else if (unformat (i, "esp"))
Neale Ranns17dcec02019-01-09 21:22:20 -080011109 protocol = IPSEC_API_PROTO_ESP;
11110 else
11111 if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
Damjan Marion7cd468a2016-12-19 23:05:39 +010011112 {
Neale Ranns17dcec02019-01-09 21:22:20 -080011113 flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
11114 if (ADDRESS_IP6 == tun_src.af)
11115 flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011116 }
11117 else
Neale Ranns17dcec02019-01-09 21:22:20 -080011118 if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
Damjan Marion7cd468a2016-12-19 23:05:39 +010011119 {
Neale Ranns17dcec02019-01-09 21:22:20 -080011120 flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
11121 if (ADDRESS_IP6 == tun_src.af)
11122 flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011123 }
Neale Ranns17dcec02019-01-09 21:22:20 -080011124 else
11125 if (unformat (i, "crypto_alg %U",
11126 unformat_ipsec_api_crypto_alg, &crypto_alg))
11127 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011128 else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11129 ;
Neale Ranns17dcec02019-01-09 21:22:20 -080011130 else if (unformat (i, "integ_alg %U",
11131 unformat_ipsec_api_integ_alg, &integ_alg))
11132 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011133 else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11134 ;
11135 else
11136 {
11137 clib_warning ("parse error '%U'", format_unformat_error, i);
11138 return -99;
11139 }
11140
11141 }
11142
Neale Ranns17dcec02019-01-09 21:22:20 -080011143 M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011144
Damjan Marion7cd468a2016-12-19 23:05:39 +010011145 mp->is_add = is_add;
Neale Ranns17dcec02019-01-09 21:22:20 -080011146 mp->entry.sad_id = ntohl (sad_id);
11147 mp->entry.protocol = protocol;
11148 mp->entry.spi = ntohl (spi);
11149 mp->entry.flags = flags;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011150
Neale Ranns17dcec02019-01-09 21:22:20 -080011151 mp->entry.crypto_algorithm = crypto_alg;
11152 mp->entry.integrity_algorithm = integ_alg;
11153 mp->entry.crypto_key.length = vec_len (ck);
11154 mp->entry.integrity_key.length = vec_len (ik);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011155
Neale Ranns17dcec02019-01-09 21:22:20 -080011156 if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
11157 mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
11158
11159 if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
11160 mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011161
11162 if (ck)
Neale Ranns17dcec02019-01-09 21:22:20 -080011163 clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011164 if (ik)
Neale Ranns17dcec02019-01-09 21:22:20 -080011165 clib_memcpy (mp->entry.integrity_key.data, ik,
11166 mp->entry.integrity_key.length);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011167
Neale Ranns17dcec02019-01-09 21:22:20 -080011168 if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
Damjan Marion7cd468a2016-12-19 23:05:39 +010011169 {
Neale Ranns17dcec02019-01-09 21:22:20 -080011170 clib_memcpy (&mp->entry.tunnel_src, &tun_src,
11171 sizeof (mp->entry.tunnel_src));
11172 clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
11173 sizeof (mp->entry.tunnel_dst));
Damjan Marion7cd468a2016-12-19 23:05:39 +010011174 }
11175
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011176 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011177 W (ret);
11178 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011179}
11180
11181static int
Matthew Smithb0972cb2017-05-02 16:20:41 -050011182api_ipsec_tunnel_if_add_del (vat_main_t * vam)
11183{
11184 unformat_input_t *i = vam->input;
11185 vl_api_ipsec_tunnel_if_add_del_t *mp;
11186 u32 local_spi = 0, remote_spi = 0;
11187 u32 crypto_alg = 0, integ_alg = 0;
11188 u8 *lck = NULL, *rck = NULL;
11189 u8 *lik = NULL, *rik = NULL;
Kingwel Xie1ba5bc82019-03-20 07:21:58 -040011190 vl_api_address_t local_ip = { 0 };
11191 vl_api_address_t remote_ip = { 0 };
Neale Ranns2b5ba952019-04-02 10:15:40 +000011192 f64 before = 0;
Matthew Smithb0972cb2017-05-02 16:20:41 -050011193 u8 is_add = 1;
11194 u8 esn = 0;
11195 u8 anti_replay = 0;
Matthew Smith8e1039a2018-04-12 07:32:56 -050011196 u8 renumber = 0;
11197 u32 instance = ~0;
Neale Ranns2b5ba952019-04-02 10:15:40 +000011198 u32 count = 1, jj;
Benoît Ganne49ee6842019-04-30 11:50:46 +020011199 int ret = -1;
Matthew Smithb0972cb2017-05-02 16:20:41 -050011200
11201 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11202 {
11203 if (unformat (i, "del"))
11204 is_add = 0;
11205 else if (unformat (i, "esn"))
11206 esn = 1;
Neale Ranns2b5ba952019-04-02 10:15:40 +000011207 else if (unformat (i, "anti-replay"))
Matthew Smithb0972cb2017-05-02 16:20:41 -050011208 anti_replay = 1;
Neale Ranns2b5ba952019-04-02 10:15:40 +000011209 else if (unformat (i, "count %d", &count))
11210 ;
Matthew Smithb0972cb2017-05-02 16:20:41 -050011211 else if (unformat (i, "local_spi %d", &local_spi))
11212 ;
11213 else if (unformat (i, "remote_spi %d", &remote_spi))
11214 ;
Kingwel Xie1ba5bc82019-03-20 07:21:58 -040011215 else
11216 if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
Matthew Smithb0972cb2017-05-02 16:20:41 -050011217 ;
Kingwel Xie1ba5bc82019-03-20 07:21:58 -040011218 else
11219 if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
Matthew Smithb0972cb2017-05-02 16:20:41 -050011220 ;
11221 else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
11222 ;
11223 else
11224 if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
11225 ;
11226 else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
11227 ;
11228 else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
11229 ;
11230 else
11231 if (unformat
Neale Ranns17dcec02019-01-09 21:22:20 -080011232 (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
Matthew Smithb0972cb2017-05-02 16:20:41 -050011233 {
Dave Baracha8d47642018-07-13 11:22:23 -040011234 if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
Matthew Smithb0972cb2017-05-02 16:20:41 -050011235 {
11236 errmsg ("unsupported crypto-alg: '%U'\n",
11237 format_ipsec_crypto_alg, crypto_alg);
11238 return -99;
11239 }
11240 }
11241 else
11242 if (unformat
Neale Ranns17dcec02019-01-09 21:22:20 -080011243 (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
Matthew Smithb0972cb2017-05-02 16:20:41 -050011244 {
Dave Baracha8d47642018-07-13 11:22:23 -040011245 if (integ_alg >= IPSEC_INTEG_N_ALG)
Matthew Smithb0972cb2017-05-02 16:20:41 -050011246 {
11247 errmsg ("unsupported integ-alg: '%U'\n",
11248 format_ipsec_integ_alg, integ_alg);
11249 return -99;
11250 }
11251 }
Matthew Smith8e1039a2018-04-12 07:32:56 -050011252 else if (unformat (i, "instance %u", &instance))
11253 renumber = 1;
Matthew Smithb0972cb2017-05-02 16:20:41 -050011254 else
11255 {
11256 errmsg ("parse error '%U'\n", format_unformat_error, i);
11257 return -99;
11258 }
11259 }
11260
Neale Ranns2b5ba952019-04-02 10:15:40 +000011261 if (count > 1)
Matthew Smithb0972cb2017-05-02 16:20:41 -050011262 {
Neale Ranns2b5ba952019-04-02 10:15:40 +000011263 /* Turn on async mode */
11264 vam->async_mode = 1;
11265 vam->async_errors = 0;
11266 before = vat_time_now (vam);
Matthew Smithb0972cb2017-05-02 16:20:41 -050011267 }
11268
Neale Ranns2b5ba952019-04-02 10:15:40 +000011269 for (jj = 0; jj < count; jj++)
Matthew Smithb0972cb2017-05-02 16:20:41 -050011270 {
Neale Ranns2b5ba952019-04-02 10:15:40 +000011271 M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
11272
11273 mp->is_add = is_add;
11274 mp->esn = esn;
11275 mp->anti_replay = anti_replay;
11276
11277 if (jj > 0)
Neale Ranns097fa662018-05-01 05:17:55 -070011278 increment_address (&remote_ip);
Neale Ranns2b5ba952019-04-02 10:15:40 +000011279
11280 clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
11281 clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
11282
11283 mp->local_spi = htonl (local_spi + jj);
11284 mp->remote_spi = htonl (remote_spi + jj);
11285 mp->crypto_alg = (u8) crypto_alg;
11286
11287 mp->local_crypto_key_len = 0;
11288 if (lck)
11289 {
11290 mp->local_crypto_key_len = vec_len (lck);
11291 if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
11292 mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
11293 clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
11294 }
11295
11296 mp->remote_crypto_key_len = 0;
11297 if (rck)
11298 {
11299 mp->remote_crypto_key_len = vec_len (rck);
11300 if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
11301 mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
11302 clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
11303 }
11304
11305 mp->integ_alg = (u8) integ_alg;
11306
11307 mp->local_integ_key_len = 0;
11308 if (lik)
11309 {
11310 mp->local_integ_key_len = vec_len (lik);
11311 if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
11312 mp->local_integ_key_len = sizeof (mp->local_integ_key);
11313 clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
11314 }
11315
11316 mp->remote_integ_key_len = 0;
11317 if (rik)
11318 {
11319 mp->remote_integ_key_len = vec_len (rik);
11320 if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
11321 mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
11322 clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
11323 }
11324
11325 if (renumber)
11326 {
11327 mp->renumber = renumber;
11328 mp->show_instance = ntohl (instance);
11329 }
11330 S (mp);
Matthew Smithb0972cb2017-05-02 16:20:41 -050011331 }
11332
Neale Ranns2b5ba952019-04-02 10:15:40 +000011333 /* When testing multiple add/del ops, use a control-ping to sync */
11334 if (count > 1)
Matthew Smithb0972cb2017-05-02 16:20:41 -050011335 {
Neale Ranns2b5ba952019-04-02 10:15:40 +000011336 vl_api_control_ping_t *mp_ping;
11337 f64 after;
11338 f64 timeout;
11339
11340 /* Shut off async mode */
11341 vam->async_mode = 0;
11342
11343 MPING (CONTROL_PING, mp_ping);
11344 S (mp_ping);
11345
11346 timeout = vat_time_now (vam) + 1.0;
11347 while (vat_time_now (vam) < timeout)
11348 if (vam->result_ready == 1)
11349 goto out;
11350 vam->retval = -99;
11351
11352 out:
11353 if (vam->retval == -99)
11354 errmsg ("timeout");
11355
11356 if (vam->async_errors > 0)
11357 {
11358 errmsg ("%d asynchronous errors", vam->async_errors);
11359 vam->retval = -98;
11360 }
11361 vam->async_errors = 0;
11362 after = vat_time_now (vam);
11363
11364 /* slim chance, but we might have eaten SIGTERM on the first iteration */
11365 if (jj > 0)
11366 count = jj;
11367
11368 print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
11369 count, after - before, count / (after - before));
11370 }
11371 else
11372 {
11373 /* Wait for a reply... */
11374 W (ret);
11375 return ret;
Matthew Smithb0972cb2017-05-02 16:20:41 -050011376 }
11377
Matthew Smithb0972cb2017-05-02 16:20:41 -050011378 return ret;
11379}
11380
Matthew Smith28029532017-09-26 13:33:44 -050011381static void
11382vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
11383{
11384 vat_main_t *vam = &vat_main;
11385
11386 print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
Neale Ranns8d7c5022019-02-06 01:41:05 -080011387 "crypto_key %U integ_alg %u integ_key %U flags %x "
Matthew Smith28029532017-09-26 13:33:44 -050011388 "tunnel_src_addr %U tunnel_dst_addr %U "
11389 "salt %u seq_outbound %lu last_seq_inbound %lu "
Matthew Smith48d32b42020-04-02 07:45:49 -050011390 "replay_window %lu stat_index %u\n",
Neale Ranns8d7c5022019-02-06 01:41:05 -080011391 ntohl (mp->entry.sad_id),
11392 ntohl (mp->sw_if_index),
11393 ntohl (mp->entry.spi),
11394 ntohl (mp->entry.protocol),
11395 ntohl (mp->entry.crypto_algorithm),
11396 format_hex_bytes, mp->entry.crypto_key.data,
11397 mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
11398 format_hex_bytes, mp->entry.integrity_key.data,
11399 mp->entry.integrity_key.length, ntohl (mp->entry.flags),
11400 format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
11401 &mp->entry.tunnel_dst, ntohl (mp->salt),
Matthew Smith28029532017-09-26 13:33:44 -050011402 clib_net_to_host_u64 (mp->seq_outbound),
11403 clib_net_to_host_u64 (mp->last_seq_inbound),
Matthew Smith48d32b42020-04-02 07:45:49 -050011404 clib_net_to_host_u64 (mp->replay_window), ntohl (mp->stat_index));
Matthew Smith28029532017-09-26 13:33:44 -050011405}
11406
11407#define vl_api_ipsec_sa_details_t_endian vl_noop_handler
11408#define vl_api_ipsec_sa_details_t_print vl_noop_handler
11409
11410static void vl_api_ipsec_sa_details_t_handler_json
11411 (vl_api_ipsec_sa_details_t * mp)
11412{
11413 vat_main_t *vam = &vat_main;
11414 vat_json_node_t *node = NULL;
Neale Ranns8d7c5022019-02-06 01:41:05 -080011415 vl_api_ipsec_sad_flags_t flags;
Matthew Smith28029532017-09-26 13:33:44 -050011416
11417 if (VAT_JSON_ARRAY != vam->json_tree.type)
11418 {
11419 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11420 vat_json_init_array (&vam->json_tree);
11421 }
11422 node = vat_json_array_add (&vam->json_tree);
11423
11424 vat_json_init_object (node);
Neale Ranns8d7c5022019-02-06 01:41:05 -080011425 vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
Matthew Smith28029532017-09-26 13:33:44 -050011426 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
Neale Ranns8d7c5022019-02-06 01:41:05 -080011427 vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
11428 vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
11429 vat_json_object_add_uint (node, "crypto_alg",
11430 ntohl (mp->entry.crypto_algorithm));
11431 vat_json_object_add_uint (node, "integ_alg",
11432 ntohl (mp->entry.integrity_algorithm));
11433 flags = ntohl (mp->entry.flags);
11434 vat_json_object_add_uint (node, "use_esn",
Damjan Marion1e3aa5e2019-03-28 10:58:59 +010011435 ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
Neale Ranns8d7c5022019-02-06 01:41:05 -080011436 vat_json_object_add_uint (node, "use_anti_replay",
11437 ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
11438 vat_json_object_add_uint (node, "is_tunnel",
11439 ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
11440 vat_json_object_add_uint (node, "is_tunnel_ip6",
11441 ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
11442 vat_json_object_add_uint (node, "udp_encap",
11443 ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
11444 vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
11445 mp->entry.crypto_key.length);
11446 vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
11447 mp->entry.integrity_key.length);
Neale Ranns5a8844b2019-04-16 07:15:35 +000011448 vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
11449 vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
Matthew Smith28029532017-09-26 13:33:44 -050011450 vat_json_object_add_uint (node, "replay_window",
11451 clib_net_to_host_u64 (mp->replay_window));
Matthew Smith48d32b42020-04-02 07:45:49 -050011452 vat_json_object_add_uint (node, "stat_index", ntohl (mp->stat_index));
Matthew Smith28029532017-09-26 13:33:44 -050011453}
11454
11455static int
11456api_ipsec_sa_dump (vat_main_t * vam)
11457{
11458 unformat_input_t *i = vam->input;
11459 vl_api_ipsec_sa_dump_t *mp;
11460 vl_api_control_ping_t *mp_ping;
11461 u32 sa_id = ~0;
11462 int ret;
11463
11464 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11465 {
11466 if (unformat (i, "sa_id %d", &sa_id))
11467 ;
11468 else
11469 {
11470 clib_warning ("parse error '%U'", format_unformat_error, i);
11471 return -99;
11472 }
11473 }
11474
11475 M (IPSEC_SA_DUMP, mp);
11476
11477 mp->sa_id = ntohl (sa_id);
11478
11479 S (mp);
11480
11481 /* Use a control ping for synchronization */
11482 M (CONTROL_PING, mp_ping);
11483 S (mp_ping);
11484
11485 W (ret);
11486 return ret;
11487}
11488
Matthew Smithb0972cb2017-05-02 16:20:41 -050011489static int
Matthew Smithca514fd2017-10-12 12:06:59 -050011490api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
11491{
11492 unformat_input_t *i = vam->input;
11493 vl_api_ipsec_tunnel_if_set_sa_t *mp;
11494 u32 sw_if_index = ~0;
11495 u32 sa_id = ~0;
11496 u8 is_outbound = (u8) ~ 0;
11497 int ret;
11498
11499 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11500 {
11501 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11502 ;
11503 else if (unformat (i, "sa_id %d", &sa_id))
11504 ;
11505 else if (unformat (i, "outbound"))
11506 is_outbound = 1;
11507 else if (unformat (i, "inbound"))
11508 is_outbound = 0;
11509 else
11510 {
11511 clib_warning ("parse error '%U'", format_unformat_error, i);
11512 return -99;
11513 }
11514 }
11515
11516 if (sw_if_index == ~0)
11517 {
11518 errmsg ("interface must be specified");
11519 return -99;
11520 }
11521
11522 if (sa_id == ~0)
11523 {
11524 errmsg ("SA ID must be specified");
11525 return -99;
11526 }
11527
11528 M (IPSEC_TUNNEL_IF_SET_SA, mp);
11529
11530 mp->sw_if_index = htonl (sw_if_index);
11531 mp->sa_id = htonl (sa_id);
11532 mp->is_outbound = is_outbound;
11533
11534 S (mp);
11535 W (ret);
11536
11537 return ret;
11538}
11539
11540static int
Damjan Marion7cd468a2016-12-19 23:05:39 +010011541api_get_first_msg_id (vat_main_t * vam)
11542{
11543 vl_api_get_first_msg_id_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011544 unformat_input_t *i = vam->input;
11545 u8 *name;
11546 u8 name_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011547 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011548
11549 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11550 {
11551 if (unformat (i, "client %s", &name))
11552 name_set = 1;
11553 else
11554 break;
11555 }
11556
11557 if (name_set == 0)
11558 {
11559 errmsg ("missing client name");
11560 return -99;
11561 }
11562 vec_add1 (name, 0);
11563
11564 if (vec_len (name) > 63)
11565 {
11566 errmsg ("client name too long");
11567 return -99;
11568 }
11569
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011570 M (GET_FIRST_MSG_ID, mp);
Ole Troan7adaa222019-08-27 15:05:27 +020011571 clib_memcpy (mp->name, name, vec_len (name));
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011572 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011573 W (ret);
11574 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011575}
11576
11577static int
11578api_cop_interface_enable_disable (vat_main_t * vam)
11579{
11580 unformat_input_t *line_input = vam->input;
11581 vl_api_cop_interface_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011582 u32 sw_if_index = ~0;
11583 u8 enable_disable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011584 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011585
11586 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11587 {
11588 if (unformat (line_input, "disable"))
11589 enable_disable = 0;
11590 if (unformat (line_input, "enable"))
11591 enable_disable = 1;
11592 else if (unformat (line_input, "%U", api_unformat_sw_if_index,
11593 vam, &sw_if_index))
11594 ;
11595 else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11596 ;
11597 else
11598 break;
11599 }
11600
11601 if (sw_if_index == ~0)
11602 {
11603 errmsg ("missing interface name or sw_if_index");
11604 return -99;
11605 }
11606
11607 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011608 M (COP_INTERFACE_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011609 mp->sw_if_index = ntohl (sw_if_index);
11610 mp->enable_disable = enable_disable;
11611
11612 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011613 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011614 /* Wait for the reply */
Jon Loeliger56c7b012017-02-01 12:31:41 -060011615 W (ret);
11616 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011617}
11618
11619static int
11620api_cop_whitelist_enable_disable (vat_main_t * vam)
11621{
11622 unformat_input_t *line_input = vam->input;
11623 vl_api_cop_whitelist_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011624 u32 sw_if_index = ~0;
11625 u8 ip4 = 0, ip6 = 0, default_cop = 0;
11626 u32 fib_id = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011627 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011628
11629 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11630 {
11631 if (unformat (line_input, "ip4"))
11632 ip4 = 1;
11633 else if (unformat (line_input, "ip6"))
11634 ip6 = 1;
11635 else if (unformat (line_input, "default"))
11636 default_cop = 1;
11637 else if (unformat (line_input, "%U", api_unformat_sw_if_index,
11638 vam, &sw_if_index))
11639 ;
11640 else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11641 ;
11642 else if (unformat (line_input, "fib-id %d", &fib_id))
11643 ;
11644 else
11645 break;
11646 }
11647
11648 if (sw_if_index == ~0)
11649 {
11650 errmsg ("missing interface name or sw_if_index");
11651 return -99;
11652 }
11653
11654 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011655 M (COP_WHITELIST_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011656 mp->sw_if_index = ntohl (sw_if_index);
11657 mp->fib_id = ntohl (fib_id);
11658 mp->ip4 = ip4;
11659 mp->ip6 = ip6;
11660 mp->default_cop = default_cop;
11661
11662 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011663 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011664 /* Wait for the reply */
Jon Loeliger56c7b012017-02-01 12:31:41 -060011665 W (ret);
11666 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011667}
11668
11669static int
11670api_get_node_graph (vat_main_t * vam)
11671{
11672 vl_api_get_node_graph_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011673 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011674
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011675 M (GET_NODE_GRAPH, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011676
11677 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011678 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011679 /* Wait for the reply */
Jon Loeliger56c7b012017-02-01 12:31:41 -060011680 W (ret);
11681 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011682}
11683
Damjan Marion7cd468a2016-12-19 23:05:39 +010011684static int
11685api_af_packet_create (vat_main_t * vam)
11686{
11687 unformat_input_t *i = vam->input;
11688 vl_api_af_packet_create_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011689 u8 *host_if_name = 0;
11690 u8 hw_addr[6];
11691 u8 random_hw_addr = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011692 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011693
Dave Barachb7b92992018-10-17 10:38:51 -040011694 clib_memset (hw_addr, 0, sizeof (hw_addr));
Damjan Marion7cd468a2016-12-19 23:05:39 +010011695
11696 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11697 {
11698 if (unformat (i, "name %s", &host_if_name))
11699 vec_add1 (host_if_name, 0);
11700 else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
11701 random_hw_addr = 0;
11702 else
11703 break;
11704 }
11705
11706 if (!vec_len (host_if_name))
11707 {
11708 errmsg ("host-interface name must be specified");
11709 return -99;
11710 }
11711
11712 if (vec_len (host_if_name) > 64)
11713 {
11714 errmsg ("host-interface name too long");
11715 return -99;
11716 }
11717
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011718 M (AF_PACKET_CREATE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011719
11720 clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
11721 clib_memcpy (mp->hw_addr, hw_addr, 6);
11722 mp->use_random_hw_addr = random_hw_addr;
11723 vec_free (host_if_name);
11724
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011725 S (mp);
Dave Baracha1a093d2017-03-02 13:13:23 -050011726
11727 /* *INDENT-OFF* */
11728 W2 (ret,
11729 ({
11730 if (ret == 0)
11731 fprintf (vam->ofp ? vam->ofp : stderr,
11732 " new sw_if_index = %d\n", vam->sw_if_index);
11733 }));
11734 /* *INDENT-ON* */
Jon Loeliger56c7b012017-02-01 12:31:41 -060011735 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011736}
11737
11738static int
11739api_af_packet_delete (vat_main_t * vam)
11740{
11741 unformat_input_t *i = vam->input;
11742 vl_api_af_packet_delete_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011743 u8 *host_if_name = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011744 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011745
11746 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11747 {
11748 if (unformat (i, "name %s", &host_if_name))
11749 vec_add1 (host_if_name, 0);
11750 else
11751 break;
11752 }
11753
11754 if (!vec_len (host_if_name))
11755 {
11756 errmsg ("host-interface name must be specified");
11757 return -99;
11758 }
11759
11760 if (vec_len (host_if_name) > 64)
11761 {
11762 errmsg ("host-interface name too long");
11763 return -99;
11764 }
11765
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011766 M (AF_PACKET_DELETE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011767
11768 clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
11769 vec_free (host_if_name);
11770
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011771 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011772 W (ret);
11773 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011774}
11775
Mohsin Kazmi04e0bb22018-05-28 18:55:37 +020011776static void vl_api_af_packet_details_t_handler
11777 (vl_api_af_packet_details_t * mp)
11778{
11779 vat_main_t *vam = &vat_main;
11780
11781 print (vam->ofp, "%-16s %d",
11782 mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
11783}
11784
11785static void vl_api_af_packet_details_t_handler_json
11786 (vl_api_af_packet_details_t * mp)
11787{
11788 vat_main_t *vam = &vat_main;
11789 vat_json_node_t *node = NULL;
11790
11791 if (VAT_JSON_ARRAY != vam->json_tree.type)
11792 {
11793 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11794 vat_json_init_array (&vam->json_tree);
11795 }
11796 node = vat_json_array_add (&vam->json_tree);
11797
11798 vat_json_init_object (node);
11799 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11800 vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
11801}
11802
11803static int
11804api_af_packet_dump (vat_main_t * vam)
11805{
11806 vl_api_af_packet_dump_t *mp;
11807 vl_api_control_ping_t *mp_ping;
11808 int ret;
11809
11810 print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
11811 /* Get list of tap interfaces */
11812 M (AF_PACKET_DUMP, mp);
11813 S (mp);
11814
11815 /* Use a control ping for synchronization */
11816 MPING (CONTROL_PING, mp_ping);
11817 S (mp_ping);
11818
11819 W (ret);
11820 return ret;
11821}
11822
Damjan Marion7cd468a2016-12-19 23:05:39 +010011823static int
11824api_policer_add_del (vat_main_t * vam)
11825{
11826 unformat_input_t *i = vam->input;
11827 vl_api_policer_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011828 u8 is_add = 1;
11829 u8 *name = 0;
11830 u32 cir = 0;
11831 u32 eir = 0;
11832 u64 cb = 0;
11833 u64 eb = 0;
11834 u8 rate_type = 0;
11835 u8 round_type = 0;
11836 u8 type = 0;
11837 u8 color_aware = 0;
11838 sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011839 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011840
11841 conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
11842 conform_action.dscp = 0;
11843 exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
11844 exceed_action.dscp = 0;
11845 violate_action.action_type = SSE2_QOS_ACTION_DROP;
11846 violate_action.dscp = 0;
11847
11848 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11849 {
11850 if (unformat (i, "del"))
11851 is_add = 0;
11852 else if (unformat (i, "name %s", &name))
11853 vec_add1 (name, 0);
11854 else if (unformat (i, "cir %u", &cir))
11855 ;
11856 else if (unformat (i, "eir %u", &eir))
11857 ;
11858 else if (unformat (i, "cb %u", &cb))
11859 ;
11860 else if (unformat (i, "eb %u", &eb))
11861 ;
11862 else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
11863 &rate_type))
11864 ;
11865 else if (unformat (i, "round_type %U", unformat_policer_round_type,
11866 &round_type))
11867 ;
11868 else if (unformat (i, "type %U", unformat_policer_type, &type))
11869 ;
11870 else if (unformat (i, "conform_action %U", unformat_policer_action_type,
11871 &conform_action))
11872 ;
11873 else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
11874 &exceed_action))
11875 ;
11876 else if (unformat (i, "violate_action %U", unformat_policer_action_type,
11877 &violate_action))
11878 ;
11879 else if (unformat (i, "color-aware"))
11880 color_aware = 1;
11881 else
11882 break;
11883 }
11884
11885 if (!vec_len (name))
11886 {
11887 errmsg ("policer name must be specified");
11888 return -99;
11889 }
11890
11891 if (vec_len (name) > 64)
11892 {
11893 errmsg ("policer name too long");
11894 return -99;
11895 }
11896
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011897 M (POLICER_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011898
11899 clib_memcpy (mp->name, name, vec_len (name));
11900 vec_free (name);
11901 mp->is_add = is_add;
Neale Rannsd91c1db2017-07-31 02:30:50 -070011902 mp->cir = ntohl (cir);
11903 mp->eir = ntohl (eir);
11904 mp->cb = clib_net_to_host_u64 (cb);
11905 mp->eb = clib_net_to_host_u64 (eb);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011906 mp->rate_type = rate_type;
11907 mp->round_type = round_type;
11908 mp->type = type;
Jakub Grajciarcd01fb42020-03-02 13:16:53 +010011909 mp->conform_action.type = conform_action.action_type;
11910 mp->conform_action.dscp = conform_action.dscp;
11911 mp->exceed_action.type = exceed_action.action_type;
11912 mp->exceed_action.dscp = exceed_action.dscp;
11913 mp->violate_action.type = violate_action.action_type;
11914 mp->violate_action.dscp = violate_action.dscp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011915 mp->color_aware = color_aware;
11916
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011917 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011918 W (ret);
11919 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011920}
11921
11922static int
11923api_policer_dump (vat_main_t * vam)
11924{
11925 unformat_input_t *i = vam->input;
11926 vl_api_policer_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011927 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011928 u8 *match_name = 0;
11929 u8 match_name_valid = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011930 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011931
11932 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11933 {
11934 if (unformat (i, "name %s", &match_name))
11935 {
11936 vec_add1 (match_name, 0);
11937 match_name_valid = 1;
11938 }
11939 else
11940 break;
11941 }
11942
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011943 M (POLICER_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011944 mp->match_name_valid = match_name_valid;
11945 clib_memcpy (mp->match_name, match_name, vec_len (match_name));
11946 vec_free (match_name);
11947 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011948 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011949
11950 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040011951 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011952 S (mp_ping);
11953
Damjan Marion7cd468a2016-12-19 23:05:39 +010011954 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060011955 W (ret);
11956 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011957}
11958
11959static int
11960api_policer_classify_set_interface (vat_main_t * vam)
11961{
11962 unformat_input_t *i = vam->input;
11963 vl_api_policer_classify_set_interface_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011964 u32 sw_if_index;
11965 int sw_if_index_set;
11966 u32 ip4_table_index = ~0;
11967 u32 ip6_table_index = ~0;
11968 u32 l2_table_index = ~0;
11969 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011970 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011971
11972 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11973 {
11974 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11975 sw_if_index_set = 1;
11976 else if (unformat (i, "sw_if_index %d", &sw_if_index))
11977 sw_if_index_set = 1;
11978 else if (unformat (i, "del"))
11979 is_add = 0;
11980 else if (unformat (i, "ip4-table %d", &ip4_table_index))
11981 ;
11982 else if (unformat (i, "ip6-table %d", &ip6_table_index))
11983 ;
11984 else if (unformat (i, "l2-table %d", &l2_table_index))
11985 ;
11986 else
11987 {
11988 clib_warning ("parse error '%U'", format_unformat_error, i);
11989 return -99;
11990 }
11991 }
11992
11993 if (sw_if_index_set == 0)
11994 {
11995 errmsg ("missing interface name or sw_if_index");
11996 return -99;
11997 }
11998
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011999 M (POLICER_CLASSIFY_SET_INTERFACE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012000
12001 mp->sw_if_index = ntohl (sw_if_index);
12002 mp->ip4_table_index = ntohl (ip4_table_index);
12003 mp->ip6_table_index = ntohl (ip6_table_index);
12004 mp->l2_table_index = ntohl (l2_table_index);
12005 mp->is_add = is_add;
12006
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012007 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012008 W (ret);
12009 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012010}
12011
12012static int
12013api_policer_classify_dump (vat_main_t * vam)
12014{
12015 unformat_input_t *i = vam->input;
12016 vl_api_policer_classify_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012017 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012018 u8 type = POLICER_CLASSIFY_N_TABLES;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012019 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012020
12021 if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
12022 ;
12023 else
12024 {
12025 errmsg ("classify table type must be specified");
12026 return -99;
12027 }
12028
12029 if (!vam->json_output)
12030 {
12031 print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
12032 }
12033
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012034 M (POLICER_CLASSIFY_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012035 mp->type = type;
12036 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012037 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012038
12039 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040012040 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012041 S (mp_ping);
12042
Damjan Marion7cd468a2016-12-19 23:05:39 +010012043 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060012044 W (ret);
12045 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012046}
12047
Neale Ranns097fa662018-05-01 05:17:55 -070012048static u8 *
12049format_fib_api_path_nh_proto (u8 * s, va_list * args)
Neale Ranns0f26c5a2017-03-01 15:12:11 -080012050{
Neale Ranns097fa662018-05-01 05:17:55 -070012051 vl_api_fib_path_nh_proto_t proto =
12052 va_arg (*args, vl_api_fib_path_nh_proto_t);
12053
12054 switch (proto)
12055 {
12056 case FIB_API_PATH_NH_PROTO_IP4:
12057 s = format (s, "ip4");
12058 break;
12059 case FIB_API_PATH_NH_PROTO_IP6:
12060 s = format (s, "ip6");
12061 break;
12062 case FIB_API_PATH_NH_PROTO_MPLS:
12063 s = format (s, "mpls");
12064 break;
12065 case FIB_API_PATH_NH_PROTO_BIER:
12066 s = format (s, "bier");
12067 break;
12068 case FIB_API_PATH_NH_PROTO_ETHERNET:
12069 s = format (s, "ethernet");
12070 break;
12071 }
12072
12073 return (s);
12074}
12075
12076static u8 *
12077format_vl_api_ip_address_union (u8 * s, va_list * args)
12078{
Jakub Grajciar7dd63e52020-03-19 08:03:55 +010012079 vl_api_address_family_t af = va_arg (*args, int);
Neale Ranns097fa662018-05-01 05:17:55 -070012080 const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
12081
12082 switch (af)
12083 {
12084 case ADDRESS_IP4:
12085 s = format (s, "%U", format_ip4_address, u->ip4);
12086 break;
12087 case ADDRESS_IP6:
12088 s = format (s, "%U", format_ip6_address, u->ip6);
12089 break;
12090 }
12091 return (s);
12092}
12093
12094static u8 *
12095format_vl_api_fib_path_type (u8 * s, va_list * args)
12096{
12097 vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
12098
12099 switch (t)
12100 {
12101 case FIB_API_PATH_TYPE_NORMAL:
12102 s = format (s, "normal");
12103 break;
12104 case FIB_API_PATH_TYPE_LOCAL:
12105 s = format (s, "local");
12106 break;
12107 case FIB_API_PATH_TYPE_DROP:
12108 s = format (s, "drop");
12109 break;
12110 case FIB_API_PATH_TYPE_UDP_ENCAP:
12111 s = format (s, "udp-encap");
12112 break;
12113 case FIB_API_PATH_TYPE_BIER_IMP:
12114 s = format (s, "bier-imp");
12115 break;
12116 case FIB_API_PATH_TYPE_ICMP_UNREACH:
12117 s = format (s, "unreach");
12118 break;
12119 case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
12120 s = format (s, "prohibit");
12121 break;
12122 case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
12123 s = format (s, "src-lookup");
12124 break;
12125 case FIB_API_PATH_TYPE_DVR:
12126 s = format (s, "dvr");
12127 break;
12128 case FIB_API_PATH_TYPE_INTERFACE_RX:
12129 s = format (s, "interface-rx");
12130 break;
12131 case FIB_API_PATH_TYPE_CLASSIFY:
12132 s = format (s, "classify");
12133 break;
12134 }
12135
12136 return (s);
12137}
12138
12139static void
12140vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
12141{
12142 print (vam->ofp,
12143 " weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
12144 ntohl (fp->weight), ntohl (fp->sw_if_index),
12145 format_vl_api_fib_path_type, fp->type,
12146 format_fib_api_path_nh_proto, fp->proto,
12147 format_vl_api_ip_address_union, &fp->nh.address);
Neale Ranns0f26c5a2017-03-01 15:12:11 -080012148}
12149
12150static void
12151vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
Neale Ranns31ed7442018-02-23 05:29:09 -080012152 vl_api_fib_path_t * fp)
Neale Ranns0f26c5a2017-03-01 15:12:11 -080012153{
12154 struct in_addr ip4;
12155 struct in6_addr ip6;
12156
12157 vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
12158 vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
Neale Ranns097fa662018-05-01 05:17:55 -070012159 vat_json_object_add_uint (node, "type", fp->type);
12160 vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
12161 if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
Neale Ranns0f26c5a2017-03-01 15:12:11 -080012162 {
Neale Ranns097fa662018-05-01 05:17:55 -070012163 clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
Neale Ranns0f26c5a2017-03-01 15:12:11 -080012164 vat_json_object_add_ip4 (node, "next_hop", ip4);
12165 }
Dave Barachc35f3e82020-04-02 10:44:09 -040012166 else if (fp->proto == FIB_API_PATH_NH_PROTO_IP6)
Neale Ranns0f26c5a2017-03-01 15:12:11 -080012167 {
Neale Ranns097fa662018-05-01 05:17:55 -070012168 clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
Neale Ranns0f26c5a2017-03-01 15:12:11 -080012169 vat_json_object_add_ip6 (node, "next_hop", ip6);
12170 }
12171}
12172
12173static void
12174vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012175{
12176 vat_main_t *vam = &vat_main;
Neale Ranns097fa662018-05-01 05:17:55 -070012177 int count = ntohl (mp->mt_tunnel.mt_n_paths);
Neale Ranns31ed7442018-02-23 05:29:09 -080012178 vl_api_fib_path_t *fp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012179 i32 i;
12180
Neale Ranns097fa662018-05-01 05:17:55 -070012181 print (vam->ofp, "sw_if_index %d via:",
12182 ntohl (mp->mt_tunnel.mt_sw_if_index));
12183 fp = mp->mt_tunnel.mt_paths;
Neale Ranns0f26c5a2017-03-01 15:12:11 -080012184 for (i = 0; i < count; i++)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012185 {
Neale Ranns097fa662018-05-01 05:17:55 -070012186 vl_api_fib_path_print (vam, fp);
Neale Ranns0f26c5a2017-03-01 15:12:11 -080012187 fp++;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012188 }
Neale Ranns0f26c5a2017-03-01 15:12:11 -080012189
Damjan Marion7cd468a2016-12-19 23:05:39 +010012190 print (vam->ofp, "");
12191}
12192
Neale Ranns0f26c5a2017-03-01 15:12:11 -080012193#define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
12194#define vl_api_mpls_tunnel_details_t_print vl_noop_handler
12195
12196static void
12197vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012198{
12199 vat_main_t *vam = &vat_main;
12200 vat_json_node_t *node = NULL;
Neale Ranns097fa662018-05-01 05:17:55 -070012201 int count = ntohl (mp->mt_tunnel.mt_n_paths);
Neale Ranns31ed7442018-02-23 05:29:09 -080012202 vl_api_fib_path_t *fp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012203 i32 i;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012204
12205 if (VAT_JSON_ARRAY != vam->json_tree.type)
12206 {
12207 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12208 vat_json_init_array (&vam->json_tree);
12209 }
12210 node = vat_json_array_add (&vam->json_tree);
12211
12212 vat_json_init_object (node);
Neale Ranns097fa662018-05-01 05:17:55 -070012213 vat_json_object_add_uint (node, "sw_if_index",
12214 ntohl (mp->mt_tunnel.mt_sw_if_index));
Neale Ranns0f26c5a2017-03-01 15:12:11 -080012215
Neale Ranns097fa662018-05-01 05:17:55 -070012216 vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
Neale Ranns0f26c5a2017-03-01 15:12:11 -080012217
Neale Ranns097fa662018-05-01 05:17:55 -070012218 fp = mp->mt_tunnel.mt_paths;
Neale Ranns0f26c5a2017-03-01 15:12:11 -080012219 for (i = 0; i < count; i++)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012220 {
Neale Ranns0f26c5a2017-03-01 15:12:11 -080012221 vl_api_mpls_fib_path_json_print (node, fp);
12222 fp++;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012223 }
12224}
12225
12226static int
12227api_mpls_tunnel_dump (vat_main_t * vam)
12228{
12229 vl_api_mpls_tunnel_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012230 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012231 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012232
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012233 M (MPLS_TUNNEL_DUMP, mp);
Neale Ranns097fa662018-05-01 05:17:55 -070012234
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012235 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012236
12237 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040012238 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012239 S (mp_ping);
12240
Jon Loeliger56c7b012017-02-01 12:31:41 -060012241 W (ret);
12242 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012243}
12244
Neale Ranns097fa662018-05-01 05:17:55 -070012245#define vl_api_mpls_table_details_t_endian vl_noop_handler
12246#define vl_api_mpls_table_details_t_print vl_noop_handler
Damjan Marion7cd468a2016-12-19 23:05:39 +010012247
Neale Ranns0f26c5a2017-03-01 15:12:11 -080012248
Damjan Marion7cd468a2016-12-19 23:05:39 +010012249static void
Neale Ranns097fa662018-05-01 05:17:55 -070012250vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012251{
12252 vat_main_t *vam = &vat_main;
Neale Ranns097fa662018-05-01 05:17:55 -070012253
12254 print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
12255}
12256
12257static void vl_api_mpls_table_details_t_handler_json
12258 (vl_api_mpls_table_details_t * mp)
12259{
12260 vat_main_t *vam = &vat_main;
12261 vat_json_node_t *node = NULL;
12262
12263 if (VAT_JSON_ARRAY != vam->json_tree.type)
12264 {
12265 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12266 vat_json_init_array (&vam->json_tree);
12267 }
12268 node = vat_json_array_add (&vam->json_tree);
12269
12270 vat_json_init_object (node);
12271 vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
12272}
12273
12274static int
12275api_mpls_table_dump (vat_main_t * vam)
12276{
12277 vl_api_mpls_table_dump_t *mp;
12278 vl_api_control_ping_t *mp_ping;
12279 int ret;
12280
12281 M (MPLS_TABLE_DUMP, mp);
12282 S (mp);
12283
12284 /* Use a control ping for synchronization */
12285 MPING (CONTROL_PING, mp_ping);
12286 S (mp_ping);
12287
12288 W (ret);
12289 return ret;
12290}
12291
12292#define vl_api_mpls_route_details_t_endian vl_noop_handler
12293#define vl_api_mpls_route_details_t_print vl_noop_handler
12294
12295static void
12296vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
12297{
12298 vat_main_t *vam = &vat_main;
Dave Barach4bda2d92019-07-03 15:21:50 -040012299 int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
Neale Ranns31ed7442018-02-23 05:29:09 -080012300 vl_api_fib_path_t *fp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012301 int i;
12302
12303 print (vam->ofp,
12304 "table-id %d, label %u, ess_bit %u",
Neale Ranns097fa662018-05-01 05:17:55 -070012305 ntohl (mp->mr_route.mr_table_id),
12306 ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
12307 fp = mp->mr_route.mr_paths;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012308 for (i = 0; i < count; i++)
12309 {
Neale Ranns097fa662018-05-01 05:17:55 -070012310 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_mpls_route_details_t_handler_json
12316 (vl_api_mpls_route_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012317{
12318 vat_main_t *vam = &vat_main;
Dave Barach4bda2d92019-07-03 15:21:50 -040012319 int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012320 vat_json_node_t *node = NULL;
Neale Ranns31ed7442018-02-23 05:29:09 -080012321 vl_api_fib_path_t *fp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012322 int i;
12323
12324 if (VAT_JSON_ARRAY != vam->json_tree.type)
12325 {
12326 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12327 vat_json_init_array (&vam->json_tree);
12328 }
12329 node = vat_json_array_add (&vam->json_tree);
12330
12331 vat_json_init_object (node);
Neale Ranns097fa662018-05-01 05:17:55 -070012332 vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
12333 vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
12334 vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
Damjan Marion7cd468a2016-12-19 23:05:39 +010012335 vat_json_object_add_uint (node, "path_count", count);
Neale Ranns097fa662018-05-01 05:17:55 -070012336 fp = mp->mr_route.mr_paths;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012337 for (i = 0; i < count; i++)
12338 {
Neale Ranns0f26c5a2017-03-01 15:12:11 -080012339 vl_api_mpls_fib_path_json_print (node, fp);
12340 fp++;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012341 }
12342}
12343
12344static int
Neale Ranns097fa662018-05-01 05:17:55 -070012345api_mpls_route_dump (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012346{
Neale Ranns097fa662018-05-01 05:17:55 -070012347 unformat_input_t *input = vam->input;
12348 vl_api_mpls_route_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012349 vl_api_control_ping_t *mp_ping;
Neale Ranns097fa662018-05-01 05:17:55 -070012350 u32 table_id;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012351 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012352
Neale Ranns097fa662018-05-01 05:17:55 -070012353 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12354 {
12355 if (unformat (input, "table_id %d", &table_id))
12356 ;
12357 else
12358 break;
12359 }
12360 if (table_id == ~0)
12361 {
12362 errmsg ("missing table id");
12363 return -99;
12364 }
12365
12366 M (MPLS_ROUTE_DUMP, mp);
12367
12368 mp->table.mt_table_id = ntohl (table_id);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012369 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012370
12371 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040012372 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012373 S (mp_ping);
12374
Jon Loeliger56c7b012017-02-01 12:31:41 -060012375 W (ret);
12376 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012377}
12378
Neale Ranns097fa662018-05-01 05:17:55 -070012379#define vl_api_ip_table_details_t_endian vl_noop_handler
12380#define vl_api_ip_table_details_t_print vl_noop_handler
Damjan Marion7cd468a2016-12-19 23:05:39 +010012381
12382static void
Neale Ranns097fa662018-05-01 05:17:55 -070012383vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012384{
12385 vat_main_t *vam = &vat_main;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012386
12387 print (vam->ofp,
Neale Ranns097fa662018-05-01 05:17:55 -070012388 "%s; table-id %d, prefix %U/%d",
12389 mp->table.name, ntohl (mp->table.table_id));
Damjan Marion7cd468a2016-12-19 23:05:39 +010012390}
12391
Neale Ranns097fa662018-05-01 05:17:55 -070012392
12393static void vl_api_ip_table_details_t_handler_json
12394 (vl_api_ip_table_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012395{
12396 vat_main_t *vam = &vat_main;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012397 vat_json_node_t *node = NULL;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012398
12399 if (VAT_JSON_ARRAY != vam->json_tree.type)
12400 {
12401 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12402 vat_json_init_array (&vam->json_tree);
12403 }
12404 node = vat_json_array_add (&vam->json_tree);
12405
12406 vat_json_init_object (node);
Neale Ranns097fa662018-05-01 05:17:55 -070012407 vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
Damjan Marion7cd468a2016-12-19 23:05:39 +010012408}
12409
12410static int
Neale Ranns097fa662018-05-01 05:17:55 -070012411api_ip_table_dump (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012412{
Neale Ranns097fa662018-05-01 05:17:55 -070012413 vl_api_ip_table_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012414 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012415 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012416
Neale Ranns097fa662018-05-01 05:17:55 -070012417 M (IP_TABLE_DUMP, mp);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012418 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012419
12420 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040012421 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012422 S (mp_ping);
12423
Jon Loeliger56c7b012017-02-01 12:31:41 -060012424 W (ret);
12425 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012426}
12427
Neale Ranns5a8123b2017-01-26 01:18:23 -080012428static int
Neale Ranns097fa662018-05-01 05:17:55 -070012429api_ip_mtable_dump (vat_main_t * vam)
Neale Ranns5a8123b2017-01-26 01:18:23 -080012430{
Neale Ranns097fa662018-05-01 05:17:55 -070012431 vl_api_ip_mtable_dump_t *mp;
Neale Ranns5a8123b2017-01-26 01:18:23 -080012432 vl_api_control_ping_t *mp_ping;
12433 int ret;
12434
Neale Ranns097fa662018-05-01 05:17:55 -070012435 M (IP_MTABLE_DUMP, mp);
12436 S (mp);
12437
12438 /* Use a control ping for synchronization */
12439 MPING (CONTROL_PING, mp_ping);
12440 S (mp_ping);
12441
12442 W (ret);
12443 return ret;
12444}
12445
12446static int
12447api_ip_mroute_dump (vat_main_t * vam)
12448{
12449 unformat_input_t *input = vam->input;
12450 vl_api_control_ping_t *mp_ping;
12451 vl_api_ip_mroute_dump_t *mp;
12452 int ret, is_ip6;
12453 u32 table_id;
12454
12455 is_ip6 = 0;
12456 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12457 {
12458 if (unformat (input, "table_id %d", &table_id))
12459 ;
12460 else if (unformat (input, "ip6"))
12461 is_ip6 = 1;
12462 else if (unformat (input, "ip4"))
12463 is_ip6 = 0;
12464 else
12465 break;
12466 }
12467 if (table_id == ~0)
12468 {
12469 errmsg ("missing table id");
12470 return -99;
12471 }
12472
12473 M (IP_MROUTE_DUMP, mp);
12474 mp->table.table_id = table_id;
12475 mp->table.is_ip6 = is_ip6;
Neale Ranns5a8123b2017-01-26 01:18:23 -080012476 S (mp);
12477
12478 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040012479 MPING (CONTROL_PING, mp_ping);
Neale Ranns5a8123b2017-01-26 01:18:23 -080012480 S (mp_ping);
12481
12482 W (ret);
12483 return ret;
12484}
12485
Neale Ranns097fa662018-05-01 05:17:55 -070012486#define vl_api_ip_route_details_t_endian vl_noop_handler
12487#define vl_api_ip_route_details_t_print vl_noop_handler
Damjan Marion7cd468a2016-12-19 23:05:39 +010012488
12489static void
Neale Ranns097fa662018-05-01 05:17:55 -070012490vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012491{
12492 vat_main_t *vam = &vat_main;
Neale Ranns097fa662018-05-01 05:17:55 -070012493 u8 count = mp->route.n_paths;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012494 vl_api_fib_path_t *fp;
12495 int i;
12496
12497 print (vam->ofp,
Neale Ranns097fa662018-05-01 05:17:55 -070012498 "table-id %d, prefix %U/%d",
12499 ntohl (mp->route.table_id),
Paul Vinciguerraab055082019-06-06 14:07:55 -040012500 format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012501 for (i = 0; i < count; i++)
12502 {
Neale Ranns097fa662018-05-01 05:17:55 -070012503 fp = &mp->route.paths[i];
12504
12505 vl_api_fib_path_print (vam, fp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012506 fp++;
12507 }
12508}
12509
Neale Ranns097fa662018-05-01 05:17:55 -070012510static void vl_api_ip_route_details_t_handler_json
12511 (vl_api_ip_route_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012512{
12513 vat_main_t *vam = &vat_main;
Neale Ranns097fa662018-05-01 05:17:55 -070012514 u8 count = mp->route.n_paths;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012515 vat_json_node_t *node = NULL;
12516 struct in_addr ip4;
12517 struct in6_addr ip6;
12518 vl_api_fib_path_t *fp;
12519 int i;
12520
12521 if (VAT_JSON_ARRAY != vam->json_tree.type)
12522 {
12523 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12524 vat_json_init_array (&vam->json_tree);
12525 }
12526 node = vat_json_array_add (&vam->json_tree);
12527
12528 vat_json_init_object (node);
Neale Ranns097fa662018-05-01 05:17:55 -070012529 vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
12530 if (ADDRESS_IP6 == mp->route.prefix.address.af)
12531 {
12532 clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
12533 vat_json_object_add_ip6 (node, "prefix", ip6);
12534 }
12535 else
12536 {
12537 clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
12538 vat_json_object_add_ip4 (node, "prefix", ip4);
12539 }
Paul Vinciguerraab055082019-06-06 14:07:55 -040012540 vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012541 vat_json_object_add_uint (node, "path_count", count);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012542 for (i = 0; i < count; i++)
12543 {
Neale Ranns097fa662018-05-01 05:17:55 -070012544 fp = &mp->route.paths[i];
12545 vl_api_mpls_fib_path_json_print (node, fp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012546 }
12547}
12548
12549static int
Neale Ranns097fa662018-05-01 05:17:55 -070012550api_ip_route_dump (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012551{
Neale Ranns097fa662018-05-01 05:17:55 -070012552 unformat_input_t *input = vam->input;
12553 vl_api_ip_route_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012554 vl_api_control_ping_t *mp_ping;
Neale Ranns097fa662018-05-01 05:17:55 -070012555 u32 table_id;
12556 u8 is_ip6;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012557 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012558
Neale Ranns097fa662018-05-01 05:17:55 -070012559 is_ip6 = 0;
12560 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12561 {
12562 if (unformat (input, "table_id %d", &table_id))
12563 ;
12564 else if (unformat (input, "ip6"))
12565 is_ip6 = 1;
12566 else if (unformat (input, "ip4"))
12567 is_ip6 = 0;
12568 else
12569 break;
12570 }
12571 if (table_id == ~0)
12572 {
12573 errmsg ("missing table id");
12574 return -99;
12575 }
Damjan Marion7cd468a2016-12-19 23:05:39 +010012576
Neale Ranns097fa662018-05-01 05:17:55 -070012577 M (IP_ROUTE_DUMP, mp);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012578
Neale Ranns097fa662018-05-01 05:17:55 -070012579 mp->table.table_id = table_id;
12580 mp->table.is_ip6 = is_ip6;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012581
Neale Ranns5a8123b2017-01-26 01:18:23 -080012582 S (mp);
12583
12584 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040012585 MPING (CONTROL_PING, mp_ping);
Neale Ranns5a8123b2017-01-26 01:18:23 -080012586 S (mp_ping);
12587
12588 W (ret);
12589 return ret;
12590}
12591
Damjan Marion7cd468a2016-12-19 23:05:39 +010012592int
12593api_classify_table_ids (vat_main_t * vam)
12594{
12595 vl_api_classify_table_ids_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012596 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012597
12598 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012599 M (CLASSIFY_TABLE_IDS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012600 mp->context = 0;
12601
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012602 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012603 W (ret);
12604 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012605}
12606
12607int
12608api_classify_table_by_interface (vat_main_t * vam)
12609{
12610 unformat_input_t *input = vam->input;
12611 vl_api_classify_table_by_interface_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012612
12613 u32 sw_if_index = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012614 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012615 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12616 {
12617 if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12618 ;
12619 else if (unformat (input, "sw_if_index %d", &sw_if_index))
12620 ;
12621 else
12622 break;
12623 }
12624 if (sw_if_index == ~0)
12625 {
12626 errmsg ("missing interface name or sw_if_index");
12627 return -99;
12628 }
12629
12630 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012631 M (CLASSIFY_TABLE_BY_INTERFACE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012632 mp->context = 0;
12633 mp->sw_if_index = ntohl (sw_if_index);
12634
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012635 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012636 W (ret);
12637 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012638}
12639
12640int
12641api_classify_table_info (vat_main_t * vam)
12642{
12643 unformat_input_t *input = vam->input;
12644 vl_api_classify_table_info_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012645
12646 u32 table_id = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012647 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012648 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12649 {
12650 if (unformat (input, "table_id %d", &table_id))
12651 ;
12652 else
12653 break;
12654 }
12655 if (table_id == ~0)
12656 {
12657 errmsg ("missing table id");
12658 return -99;
12659 }
12660
12661 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012662 M (CLASSIFY_TABLE_INFO, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012663 mp->context = 0;
12664 mp->table_id = ntohl (table_id);
12665
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012666 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012667 W (ret);
12668 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012669}
12670
12671int
12672api_classify_session_dump (vat_main_t * vam)
12673{
12674 unformat_input_t *input = vam->input;
12675 vl_api_classify_session_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012676 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012677
12678 u32 table_id = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012679 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012680 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12681 {
12682 if (unformat (input, "table_id %d", &table_id))
12683 ;
12684 else
12685 break;
12686 }
12687 if (table_id == ~0)
12688 {
12689 errmsg ("missing table id");
12690 return -99;
12691 }
12692
12693 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012694 M (CLASSIFY_SESSION_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012695 mp->context = 0;
12696 mp->table_id = ntohl (table_id);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012697 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012698
12699 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040012700 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012701 S (mp_ping);
12702
Jon Loeliger56c7b012017-02-01 12:31:41 -060012703 W (ret);
12704 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012705}
12706
12707static void
12708vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
12709{
12710 vat_main_t *vam = &vat_main;
12711
12712 print (vam->ofp, "collector_address %U, collector_port %d, "
12713 "src_address %U, vrf_id %d, path_mtu %u, "
12714 "template_interval %u, udp_checksum %d",
12715 format_ip4_address, mp->collector_address,
12716 ntohs (mp->collector_port),
12717 format_ip4_address, mp->src_address,
12718 ntohl (mp->vrf_id), ntohl (mp->path_mtu),
12719 ntohl (mp->template_interval), mp->udp_checksum);
12720
12721 vam->retval = 0;
12722 vam->result_ready = 1;
12723}
12724
12725static void
12726 vl_api_ipfix_exporter_details_t_handler_json
12727 (vl_api_ipfix_exporter_details_t * mp)
12728{
12729 vat_main_t *vam = &vat_main;
12730 vat_json_node_t node;
12731 struct in_addr collector_address;
12732 struct in_addr src_address;
12733
12734 vat_json_init_object (&node);
12735 clib_memcpy (&collector_address, &mp->collector_address,
12736 sizeof (collector_address));
12737 vat_json_object_add_ip4 (&node, "collector_address", collector_address);
12738 vat_json_object_add_uint (&node, "collector_port",
12739 ntohs (mp->collector_port));
12740 clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
12741 vat_json_object_add_ip4 (&node, "src_address", src_address);
12742 vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
12743 vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
12744 vat_json_object_add_uint (&node, "template_interval",
12745 ntohl (mp->template_interval));
12746 vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
12747
12748 vat_json_print (vam->ofp, &node);
12749 vat_json_free (&node);
12750 vam->retval = 0;
12751 vam->result_ready = 1;
12752}
12753
12754int
12755api_ipfix_exporter_dump (vat_main_t * vam)
12756{
12757 vl_api_ipfix_exporter_dump_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012758 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012759
12760 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012761 M (IPFIX_EXPORTER_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012762 mp->context = 0;
12763
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012764 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012765 W (ret);
12766 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012767}
12768
12769static int
12770api_ipfix_classify_stream_dump (vat_main_t * vam)
12771{
12772 vl_api_ipfix_classify_stream_dump_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012773 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012774
12775 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012776 M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012777 mp->context = 0;
12778
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012779 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012780 W (ret);
12781 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012782 /* NOTREACHED */
12783 return 0;
12784}
12785
12786static void
12787 vl_api_ipfix_classify_stream_details_t_handler
12788 (vl_api_ipfix_classify_stream_details_t * mp)
12789{
12790 vat_main_t *vam = &vat_main;
12791 print (vam->ofp, "domain_id %d, src_port %d",
12792 ntohl (mp->domain_id), ntohs (mp->src_port));
12793 vam->retval = 0;
12794 vam->result_ready = 1;
12795}
12796
12797static void
12798 vl_api_ipfix_classify_stream_details_t_handler_json
12799 (vl_api_ipfix_classify_stream_details_t * mp)
12800{
12801 vat_main_t *vam = &vat_main;
12802 vat_json_node_t node;
12803
12804 vat_json_init_object (&node);
12805 vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
12806 vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
12807
12808 vat_json_print (vam->ofp, &node);
12809 vat_json_free (&node);
12810 vam->retval = 0;
12811 vam->result_ready = 1;
12812}
12813
12814static int
12815api_ipfix_classify_table_dump (vat_main_t * vam)
12816{
12817 vl_api_ipfix_classify_table_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012818 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012819 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012820
12821 if (!vam->json_output)
12822 {
12823 print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
12824 "transport_protocol");
12825 }
12826
12827 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012828 M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012829
12830 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012831 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012832
12833 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040012834 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012835 S (mp_ping);
12836
Jon Loeliger56c7b012017-02-01 12:31:41 -060012837 W (ret);
12838 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012839}
12840
12841static void
12842 vl_api_ipfix_classify_table_details_t_handler
12843 (vl_api_ipfix_classify_table_details_t * mp)
12844{
12845 vat_main_t *vam = &vat_main;
12846 print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
12847 mp->transport_protocol);
12848}
12849
12850static void
12851 vl_api_ipfix_classify_table_details_t_handler_json
12852 (vl_api_ipfix_classify_table_details_t * mp)
12853{
12854 vat_json_node_t *node = NULL;
12855 vat_main_t *vam = &vat_main;
12856
12857 if (VAT_JSON_ARRAY != vam->json_tree.type)
12858 {
12859 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12860 vat_json_init_array (&vam->json_tree);
12861 }
12862
12863 node = vat_json_array_add (&vam->json_tree);
12864 vat_json_init_object (node);
12865
12866 vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
12867 vat_json_object_add_uint (node, "ip_version", mp->ip_version);
12868 vat_json_object_add_uint (node, "transport_protocol",
12869 mp->transport_protocol);
12870}
12871
12872static int
12873api_sw_interface_span_enable_disable (vat_main_t * vam)
12874{
12875 unformat_input_t *i = vam->input;
12876 vl_api_sw_interface_span_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012877 u32 src_sw_if_index = ~0;
12878 u32 dst_sw_if_index = ~0;
12879 u8 state = 3;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012880 int ret;
Eyal Bari001fd402017-07-16 09:34:53 +030012881 u8 is_l2 = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012882
12883 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12884 {
12885 if (unformat
12886 (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
12887 ;
12888 else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
12889 ;
12890 else
12891 if (unformat
12892 (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
12893 ;
12894 else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
12895 ;
12896 else if (unformat (i, "disable"))
12897 state = 0;
12898 else if (unformat (i, "rx"))
12899 state = 1;
12900 else if (unformat (i, "tx"))
12901 state = 2;
12902 else if (unformat (i, "both"))
12903 state = 3;
Eyal Bari001fd402017-07-16 09:34:53 +030012904 else if (unformat (i, "l2"))
12905 is_l2 = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012906 else
12907 break;
12908 }
12909
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012910 M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012911
12912 mp->sw_if_index_from = htonl (src_sw_if_index);
12913 mp->sw_if_index_to = htonl (dst_sw_if_index);
12914 mp->state = state;
Eyal Bari001fd402017-07-16 09:34:53 +030012915 mp->is_l2 = is_l2;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012916
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012917 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012918 W (ret);
12919 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012920}
12921
12922static void
12923vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
12924 * mp)
12925{
12926 vat_main_t *vam = &vat_main;
12927 u8 *sw_if_from_name = 0;
12928 u8 *sw_if_to_name = 0;
12929 u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
12930 u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
12931 char *states[] = { "none", "rx", "tx", "both" };
12932 hash_pair_t *p;
12933
12934 /* *INDENT-OFF* */
12935 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
12936 ({
12937 if ((u32) p->value[0] == sw_if_index_from)
12938 {
12939 sw_if_from_name = (u8 *)(p->key);
12940 if (sw_if_to_name)
12941 break;
12942 }
12943 if ((u32) p->value[0] == sw_if_index_to)
12944 {
12945 sw_if_to_name = (u8 *)(p->key);
12946 if (sw_if_from_name)
12947 break;
12948 }
12949 }));
12950 /* *INDENT-ON* */
Jon Loeliger179ab362018-03-12 14:50:08 -050012951 print (vam->ofp, "%20s => %20s (%s) %s",
12952 sw_if_from_name, sw_if_to_name, states[mp->state],
12953 mp->is_l2 ? "l2" : "device");
Damjan Marion7cd468a2016-12-19 23:05:39 +010012954}
12955
12956static void
12957 vl_api_sw_interface_span_details_t_handler_json
12958 (vl_api_sw_interface_span_details_t * mp)
12959{
12960 vat_main_t *vam = &vat_main;
12961 vat_json_node_t *node = NULL;
12962 u8 *sw_if_from_name = 0;
12963 u8 *sw_if_to_name = 0;
12964 u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
12965 u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
12966 hash_pair_t *p;
12967
12968 /* *INDENT-OFF* */
12969 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
12970 ({
12971 if ((u32) p->value[0] == sw_if_index_from)
12972 {
12973 sw_if_from_name = (u8 *)(p->key);
12974 if (sw_if_to_name)
12975 break;
12976 }
12977 if ((u32) p->value[0] == sw_if_index_to)
12978 {
12979 sw_if_to_name = (u8 *)(p->key);
12980 if (sw_if_from_name)
12981 break;
12982 }
12983 }));
12984 /* *INDENT-ON* */
12985
12986 if (VAT_JSON_ARRAY != vam->json_tree.type)
12987 {
12988 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12989 vat_json_init_array (&vam->json_tree);
12990 }
12991 node = vat_json_array_add (&vam->json_tree);
12992
12993 vat_json_init_object (node);
12994 vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
12995 vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
12996 vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
Neale Ranns05b2bf22017-01-30 06:44:58 -080012997 if (0 != sw_if_to_name)
12998 {
12999 vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
13000 }
Damjan Marion7cd468a2016-12-19 23:05:39 +010013001 vat_json_object_add_uint (node, "state", mp->state);
Jon Loeliger179ab362018-03-12 14:50:08 -050013002 vat_json_object_add_uint (node, "is-l2", mp->is_l2);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013003}
13004
13005static int
13006api_sw_interface_span_dump (vat_main_t * vam)
13007{
Eyal Bari5b311202017-07-31 13:12:30 +030013008 unformat_input_t *input = vam->input;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013009 vl_api_sw_interface_span_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060013010 vl_api_control_ping_t *mp_ping;
Eyal Bari5b311202017-07-31 13:12:30 +030013011 u8 is_l2 = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013012 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013013
Eyal Bari5b311202017-07-31 13:12:30 +030013014 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13015 {
13016 if (unformat (input, "l2"))
13017 is_l2 = 1;
13018 else
13019 break;
13020 }
13021
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013022 M (SW_INTERFACE_SPAN_DUMP, mp);
Eyal Bari5b311202017-07-31 13:12:30 +030013023 mp->is_l2 = is_l2;
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013024 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013025
13026 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040013027 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060013028 S (mp_ping);
13029
Jon Loeliger56c7b012017-02-01 12:31:41 -060013030 W (ret);
13031 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013032}
13033
13034int
13035api_pg_create_interface (vat_main_t * vam)
13036{
13037 unformat_input_t *input = vam->input;
13038 vl_api_pg_create_interface_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013039
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +020013040 u32 if_id = ~0, gso_size = 0;
13041 u8 gso_enabled = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013042 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013043 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13044 {
13045 if (unformat (input, "if_id %d", &if_id))
13046 ;
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +020013047 else if (unformat (input, "gso-enabled"))
13048 {
13049 gso_enabled = 1;
13050 if (unformat (input, "gso-size %u", &gso_size))
13051 ;
13052 else
13053 {
13054 errmsg ("missing gso-size");
13055 return -99;
13056 }
13057 }
Damjan Marion7cd468a2016-12-19 23:05:39 +010013058 else
13059 break;
13060 }
13061 if (if_id == ~0)
13062 {
13063 errmsg ("missing pg interface index");
13064 return -99;
13065 }
13066
13067 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013068 M (PG_CREATE_INTERFACE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013069 mp->context = 0;
13070 mp->interface_id = ntohl (if_id);
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +020013071 mp->gso_enabled = gso_enabled;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013072
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013073 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013074 W (ret);
13075 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013076}
13077
13078int
13079api_pg_capture (vat_main_t * vam)
13080{
13081 unformat_input_t *input = vam->input;
13082 vl_api_pg_capture_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013083
13084 u32 if_id = ~0;
13085 u8 enable = 1;
13086 u32 count = 1;
13087 u8 pcap_file_set = 0;
13088 u8 *pcap_file = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013089 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013090 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13091 {
13092 if (unformat (input, "if_id %d", &if_id))
13093 ;
13094 else if (unformat (input, "pcap %s", &pcap_file))
13095 pcap_file_set = 1;
13096 else if (unformat (input, "count %d", &count))
13097 ;
13098 else if (unformat (input, "disable"))
13099 enable = 0;
13100 else
13101 break;
13102 }
13103 if (if_id == ~0)
13104 {
13105 errmsg ("missing pg interface index");
13106 return -99;
13107 }
13108 if (pcap_file_set > 0)
13109 {
13110 if (vec_len (pcap_file) > 255)
13111 {
13112 errmsg ("pcap file name is too long");
13113 return -99;
13114 }
13115 }
13116
Damjan Marion7cd468a2016-12-19 23:05:39 +010013117 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013118 M (PG_CAPTURE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013119 mp->context = 0;
13120 mp->interface_id = ntohl (if_id);
13121 mp->is_enabled = enable;
13122 mp->count = ntohl (count);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013123 if (pcap_file_set != 0)
13124 {
Jakub Grajciardb863292020-01-30 14:14:15 +010013125 vl_api_vec_to_api_string (pcap_file, &mp->pcap_file_name);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013126 }
13127 vec_free (pcap_file);
13128
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013129 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013130 W (ret);
13131 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013132}
13133
13134int
13135api_pg_enable_disable (vat_main_t * vam)
13136{
13137 unformat_input_t *input = vam->input;
13138 vl_api_pg_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013139
13140 u8 enable = 1;
13141 u8 stream_name_set = 0;
13142 u8 *stream_name = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013143 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013144 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13145 {
13146 if (unformat (input, "stream %s", &stream_name))
13147 stream_name_set = 1;
13148 else if (unformat (input, "disable"))
13149 enable = 0;
13150 else
13151 break;
13152 }
13153
13154 if (stream_name_set > 0)
13155 {
13156 if (vec_len (stream_name) > 255)
13157 {
13158 errmsg ("stream name too long");
13159 return -99;
13160 }
13161 }
13162
Damjan Marion7cd468a2016-12-19 23:05:39 +010013163 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013164 M (PG_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013165 mp->context = 0;
13166 mp->is_enabled = enable;
13167 if (stream_name_set != 0)
13168 {
Jakub Grajciardb863292020-01-30 14:14:15 +010013169 vl_api_vec_to_api_string (stream_name, &mp->stream_name);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013170 }
13171 vec_free (stream_name);
13172
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013173 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013174 W (ret);
13175 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013176}
13177
13178int
Mohsin Kazmif382b062020-08-11 15:00:44 +020013179api_pg_interface_enable_disable_coalesce (vat_main_t * vam)
13180{
13181 unformat_input_t *input = vam->input;
13182 vl_api_pg_interface_enable_disable_coalesce_t *mp;
13183
13184 u32 sw_if_index = ~0;
13185 u8 enable = 1;
13186 int ret;
13187 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13188 {
13189 if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13190 ;
13191 else if (unformat (input, "sw_if_index %d", &sw_if_index))
13192 ;
13193 else if (unformat (input, "disable"))
13194 enable = 0;
13195 else
13196 break;
13197 }
13198
13199 if (sw_if_index == ~0)
13200 {
13201 errmsg ("Interface required but not specified");
13202 return -99;
13203 }
13204
13205 /* Construct the API message */
13206 M (PG_INTERFACE_ENABLE_DISABLE_COALESCE, mp);
13207 mp->context = 0;
13208 mp->coalesce_enabled = enable;
13209 mp->sw_if_index = htonl (sw_if_index);
13210
13211 S (mp);
13212 W (ret);
13213 return ret;
13214}
13215
13216int
Damjan Marion7cd468a2016-12-19 23:05:39 +010013217api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
13218{
13219 unformat_input_t *input = vam->input;
13220 vl_api_ip_source_and_port_range_check_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013221
13222 u16 *low_ports = 0;
13223 u16 *high_ports = 0;
13224 u16 this_low;
13225 u16 this_hi;
Neale Ranns37029302018-08-10 05:30:06 -070013226 vl_api_prefix_t prefix;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013227 u32 tmp, tmp2;
13228 u8 prefix_set = 0;
13229 u32 vrf_id = ~0;
13230 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013231 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013232
13233 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13234 {
Neale Ranns37029302018-08-10 05:30:06 -070013235 if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
13236 prefix_set = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013237 else if (unformat (input, "vrf %d", &vrf_id))
13238 ;
13239 else if (unformat (input, "del"))
13240 is_add = 0;
13241 else if (unformat (input, "port %d", &tmp))
13242 {
13243 if (tmp == 0 || tmp > 65535)
13244 {
13245 errmsg ("port %d out of range", tmp);
13246 return -99;
13247 }
13248 this_low = tmp;
13249 this_hi = this_low + 1;
13250 vec_add1 (low_ports, this_low);
13251 vec_add1 (high_ports, this_hi);
13252 }
13253 else if (unformat (input, "range %d - %d", &tmp, &tmp2))
13254 {
13255 if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
13256 {
13257 errmsg ("incorrect range parameters");
13258 return -99;
13259 }
13260 this_low = tmp;
13261 /* Note: in debug CLI +1 is added to high before
13262 passing to real fn that does "the work"
13263 (ip_source_and_port_range_check_add_del).
13264 This fn is a wrapper around the binary API fn a
13265 control plane will call, which expects this increment
13266 to have occurred. Hence letting the binary API control
13267 plane fn do the increment for consistency between VAT
13268 and other control planes.
13269 */
13270 this_hi = tmp2;
13271 vec_add1 (low_ports, this_low);
13272 vec_add1 (high_ports, this_hi);
13273 }
13274 else
13275 break;
13276 }
13277
13278 if (prefix_set == 0)
13279 {
13280 errmsg ("<address>/<mask> not specified");
13281 return -99;
13282 }
13283
13284 if (vrf_id == ~0)
13285 {
13286 errmsg ("VRF ID required, not specified");
13287 return -99;
13288 }
13289
13290 if (vrf_id == 0)
13291 {
13292 errmsg
13293 ("VRF ID should not be default. Should be distinct VRF for this purpose.");
13294 return -99;
13295 }
13296
13297 if (vec_len (low_ports) == 0)
13298 {
13299 errmsg ("At least one port or port range required");
13300 return -99;
13301 }
13302
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013303 M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013304
13305 mp->is_add = is_add;
13306
Neale Ranns37029302018-08-10 05:30:06 -070013307 clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
Damjan Marion7cd468a2016-12-19 23:05:39 +010013308
Damjan Marion7cd468a2016-12-19 23:05:39 +010013309 mp->number_of_ranges = vec_len (low_ports);
13310
13311 clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
13312 vec_free (low_ports);
13313
13314 clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
13315 vec_free (high_ports);
13316
13317 mp->vrf_id = ntohl (vrf_id);
13318
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013319 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013320 W (ret);
13321 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013322}
13323
13324int
13325api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
13326{
13327 unformat_input_t *input = vam->input;
13328 vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013329 u32 sw_if_index = ~0;
13330 int vrf_set = 0;
13331 u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
13332 u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
13333 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013334 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013335
13336 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13337 {
13338 if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13339 ;
13340 else if (unformat (input, "sw_if_index %d", &sw_if_index))
13341 ;
13342 else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
13343 vrf_set = 1;
13344 else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
13345 vrf_set = 1;
13346 else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
13347 vrf_set = 1;
13348 else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
13349 vrf_set = 1;
13350 else if (unformat (input, "del"))
13351 is_add = 0;
13352 else
13353 break;
13354 }
13355
13356 if (sw_if_index == ~0)
13357 {
13358 errmsg ("Interface required but not specified");
13359 return -99;
13360 }
13361
13362 if (vrf_set == 0)
13363 {
13364 errmsg ("VRF ID required but not specified");
13365 return -99;
13366 }
13367
13368 if (tcp_out_vrf_id == 0
13369 || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
13370 {
13371 errmsg
13372 ("VRF ID should not be default. Should be distinct VRF for this purpose.");
13373 return -99;
13374 }
13375
13376 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013377 M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013378
13379 mp->sw_if_index = ntohl (sw_if_index);
13380 mp->is_add = is_add;
13381 mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
13382 mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
13383 mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
13384 mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
13385
13386 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013387 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013388
13389 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060013390 W (ret);
13391 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013392}
13393
13394static int
Pavel Kotuceke88865d2018-11-28 07:42:11 +010013395api_set_punt (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010013396{
13397 unformat_input_t *i = vam->input;
Neale Ranns50f0ac02019-05-15 02:13:37 -070013398 vl_api_address_family_t af;
Pavel Kotuceke88865d2018-11-28 07:42:11 +010013399 vl_api_set_punt_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013400 u32 protocol = ~0;
13401 u32 port = ~0;
13402 int is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013403 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013404
13405 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13406 {
Neale Ranns50f0ac02019-05-15 02:13:37 -070013407 if (unformat (i, "%U", unformat_vl_api_address_family, &af))
Damjan Marion7cd468a2016-12-19 23:05:39 +010013408 ;
13409 else if (unformat (i, "protocol %d", &protocol))
13410 ;
13411 else if (unformat (i, "port %d", &port))
13412 ;
13413 else if (unformat (i, "del"))
13414 is_add = 0;
13415 else
13416 {
13417 clib_warning ("parse error '%U'", format_unformat_error, i);
13418 return -99;
13419 }
13420 }
13421
Pavel Kotuceke88865d2018-11-28 07:42:11 +010013422 M (SET_PUNT, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013423
13424 mp->is_add = (u8) is_add;
Neale Ranns50f0ac02019-05-15 02:13:37 -070013425 mp->punt.type = PUNT_API_TYPE_L4;
13426 mp->punt.punt.l4.af = af;
13427 mp->punt.punt.l4.protocol = (u8) protocol;
13428 mp->punt.punt.l4.port = htons ((u16) port);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013429
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013430 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013431 W (ret);
13432 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013433}
13434
Damjan Marion7cd468a2016-12-19 23:05:39 +010013435static int
13436api_delete_subif (vat_main_t * vam)
13437{
13438 unformat_input_t *i = vam->input;
13439 vl_api_delete_subif_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013440 u32 sw_if_index = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013441 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013442
13443 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13444 {
13445 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13446 ;
13447 if (unformat (i, "sw_if_index %d", &sw_if_index))
13448 ;
13449 else
13450 break;
13451 }
13452
13453 if (sw_if_index == ~0)
13454 {
13455 errmsg ("missing sw_if_index");
13456 return -99;
13457 }
13458
13459 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013460 M (DELETE_SUBIF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013461 mp->sw_if_index = ntohl (sw_if_index);
13462
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013463 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013464 W (ret);
13465 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013466}
13467
13468#define foreach_pbb_vtr_op \
13469_("disable", L2_VTR_DISABLED) \
13470_("pop", L2_VTR_POP_2) \
13471_("push", L2_VTR_PUSH_2)
13472
13473static int
13474api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
13475{
13476 unformat_input_t *i = vam->input;
13477 vl_api_l2_interface_pbb_tag_rewrite_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013478 u32 sw_if_index = ~0, vtr_op = ~0;
13479 u16 outer_tag = ~0;
13480 u8 dmac[6], smac[6];
13481 u8 dmac_set = 0, smac_set = 0;
13482 u16 vlanid = 0;
13483 u32 sid = ~0;
13484 u32 tmp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013485 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013486
13487 /* Shut up coverity */
Dave Barachb7b92992018-10-17 10:38:51 -040013488 clib_memset (dmac, 0, sizeof (dmac));
13489 clib_memset (smac, 0, sizeof (smac));
Damjan Marion7cd468a2016-12-19 23:05:39 +010013490
13491 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13492 {
13493 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13494 ;
13495 else if (unformat (i, "sw_if_index %d", &sw_if_index))
13496 ;
13497 else if (unformat (i, "vtr_op %d", &vtr_op))
13498 ;
13499#define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
13500 foreach_pbb_vtr_op
13501#undef _
13502 else if (unformat (i, "translate_pbb_stag"))
13503 {
13504 if (unformat (i, "%d", &tmp))
13505 {
13506 vtr_op = L2_VTR_TRANSLATE_2_1;
13507 outer_tag = tmp;
13508 }
13509 else
13510 {
13511 errmsg
13512 ("translate_pbb_stag operation requires outer tag definition");
13513 return -99;
13514 }
13515 }
13516 else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
13517 dmac_set++;
13518 else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
13519 smac_set++;
13520 else if (unformat (i, "sid %d", &sid))
13521 ;
13522 else if (unformat (i, "vlanid %d", &tmp))
13523 vlanid = tmp;
13524 else
13525 {
13526 clib_warning ("parse error '%U'", format_unformat_error, i);
13527 return -99;
13528 }
13529 }
13530
13531 if ((sw_if_index == ~0) || (vtr_op == ~0))
13532 {
13533 errmsg ("missing sw_if_index or vtr operation");
13534 return -99;
13535 }
13536 if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
13537 && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
13538 {
13539 errmsg
13540 ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
13541 return -99;
13542 }
13543
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013544 M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013545 mp->sw_if_index = ntohl (sw_if_index);
13546 mp->vtr_op = ntohl (vtr_op);
13547 mp->outer_tag = ntohs (outer_tag);
13548 clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
13549 clib_memcpy (mp->b_smac, smac, sizeof (smac));
13550 mp->b_vlanid = ntohs (vlanid);
13551 mp->i_sid = ntohl (sid);
13552
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013553 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013554 W (ret);
13555 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013556}
13557
13558static int
13559api_flow_classify_set_interface (vat_main_t * vam)
13560{
13561 unformat_input_t *i = vam->input;
13562 vl_api_flow_classify_set_interface_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013563 u32 sw_if_index;
13564 int sw_if_index_set;
13565 u32 ip4_table_index = ~0;
13566 u32 ip6_table_index = ~0;
13567 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013568 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013569
13570 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13571 {
13572 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13573 sw_if_index_set = 1;
13574 else if (unformat (i, "sw_if_index %d", &sw_if_index))
13575 sw_if_index_set = 1;
13576 else if (unformat (i, "del"))
13577 is_add = 0;
13578 else if (unformat (i, "ip4-table %d", &ip4_table_index))
13579 ;
13580 else if (unformat (i, "ip6-table %d", &ip6_table_index))
13581 ;
13582 else
13583 {
13584 clib_warning ("parse error '%U'", format_unformat_error, i);
13585 return -99;
13586 }
13587 }
13588
13589 if (sw_if_index_set == 0)
13590 {
13591 errmsg ("missing interface name or sw_if_index");
13592 return -99;
13593 }
13594
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013595 M (FLOW_CLASSIFY_SET_INTERFACE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013596
13597 mp->sw_if_index = ntohl (sw_if_index);
13598 mp->ip4_table_index = ntohl (ip4_table_index);
13599 mp->ip6_table_index = ntohl (ip6_table_index);
13600 mp->is_add = is_add;
13601
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013602 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013603 W (ret);
13604 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013605}
13606
13607static int
13608api_flow_classify_dump (vat_main_t * vam)
13609{
13610 unformat_input_t *i = vam->input;
13611 vl_api_flow_classify_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060013612 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013613 u8 type = FLOW_CLASSIFY_N_TABLES;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013614 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013615
13616 if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
13617 ;
13618 else
13619 {
13620 errmsg ("classify table type must be specified");
13621 return -99;
13622 }
13623
13624 if (!vam->json_output)
13625 {
13626 print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
13627 }
13628
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013629 M (FLOW_CLASSIFY_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013630 mp->type = type;
13631 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013632 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013633
13634 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040013635 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060013636 S (mp_ping);
13637
Damjan Marion7cd468a2016-12-19 23:05:39 +010013638 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060013639 W (ret);
13640 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013641}
13642
13643static int
13644api_feature_enable_disable (vat_main_t * vam)
13645{
13646 unformat_input_t *i = vam->input;
13647 vl_api_feature_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013648 u8 *arc_name = 0;
13649 u8 *feature_name = 0;
13650 u32 sw_if_index = ~0;
13651 u8 enable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013652 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013653
13654 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13655 {
13656 if (unformat (i, "arc_name %s", &arc_name))
13657 ;
13658 else if (unformat (i, "feature_name %s", &feature_name))
13659 ;
13660 else
13661 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13662 ;
13663 else if (unformat (i, "sw_if_index %d", &sw_if_index))
13664 ;
13665 else if (unformat (i, "disable"))
13666 enable = 0;
13667 else
13668 break;
13669 }
13670
13671 if (arc_name == 0)
13672 {
13673 errmsg ("missing arc name");
13674 return -99;
13675 }
13676 if (vec_len (arc_name) > 63)
13677 {
13678 errmsg ("arc name too long");
13679 }
13680
13681 if (feature_name == 0)
13682 {
13683 errmsg ("missing feature name");
13684 return -99;
13685 }
13686 if (vec_len (feature_name) > 63)
13687 {
13688 errmsg ("feature name too long");
13689 }
13690
13691 if (sw_if_index == ~0)
13692 {
13693 errmsg ("missing interface name or sw_if_index");
13694 return -99;
13695 }
13696
13697 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013698 M (FEATURE_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013699 mp->sw_if_index = ntohl (sw_if_index);
13700 mp->enable = enable;
13701 clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
13702 clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
13703 vec_free (arc_name);
13704 vec_free (feature_name);
13705
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013706 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013707 W (ret);
13708 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013709}
13710
13711static int
Mohsin Kazmi29467b52019-10-08 19:42:38 +020013712api_feature_gso_enable_disable (vat_main_t * vam)
13713{
13714 unformat_input_t *i = vam->input;
13715 vl_api_feature_gso_enable_disable_t *mp;
13716 u32 sw_if_index = ~0;
13717 u8 enable = 1;
13718 int ret;
13719
13720 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13721 {
13722 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13723 ;
13724 else if (unformat (i, "sw_if_index %d", &sw_if_index))
13725 ;
13726 else if (unformat (i, "enable"))
13727 enable = 1;
13728 else if (unformat (i, "disable"))
13729 enable = 0;
13730 else
13731 break;
13732 }
13733
13734 if (sw_if_index == ~0)
13735 {
13736 errmsg ("missing interface name or sw_if_index");
13737 return -99;
13738 }
13739
13740 /* Construct the API message */
13741 M (FEATURE_GSO_ENABLE_DISABLE, mp);
13742 mp->sw_if_index = ntohl (sw_if_index);
13743 mp->enable_disable = enable;
13744
13745 S (mp);
13746 W (ret);
13747 return ret;
13748}
13749
13750static int
Damjan Marion7cd468a2016-12-19 23:05:39 +010013751api_sw_interface_tag_add_del (vat_main_t * vam)
13752{
13753 unformat_input_t *i = vam->input;
13754 vl_api_sw_interface_tag_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013755 u32 sw_if_index = ~0;
13756 u8 *tag = 0;
13757 u8 enable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013758 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013759
13760 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13761 {
13762 if (unformat (i, "tag %s", &tag))
13763 ;
13764 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13765 ;
13766 else if (unformat (i, "sw_if_index %d", &sw_if_index))
13767 ;
13768 else if (unformat (i, "del"))
13769 enable = 0;
13770 else
13771 break;
13772 }
13773
13774 if (sw_if_index == ~0)
13775 {
13776 errmsg ("missing interface name or sw_if_index");
13777 return -99;
13778 }
13779
13780 if (enable && (tag == 0))
13781 {
13782 errmsg ("no tag specified");
13783 return -99;
13784 }
13785
13786 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013787 M (SW_INTERFACE_TAG_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013788 mp->sw_if_index = ntohl (sw_if_index);
13789 mp->is_add = enable;
13790 if (enable)
Ole Troane5ff5a32019-08-23 22:55:18 +020013791 strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013792 vec_free (tag);
13793
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013794 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013795 W (ret);
13796 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013797}
13798
Matthew Smithe0792fd2019-07-12 11:48:24 -050013799static int
13800api_sw_interface_add_del_mac_address (vat_main_t * vam)
13801{
13802 unformat_input_t *i = vam->input;
13803 vl_api_mac_address_t mac = { 0 };
13804 vl_api_sw_interface_add_del_mac_address_t *mp;
13805 u32 sw_if_index = ~0;
13806 u8 is_add = 1;
13807 u8 mac_set = 0;
13808 int ret;
13809
13810 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13811 {
13812 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13813 ;
13814 else if (unformat (i, "sw_if_index %d", &sw_if_index))
13815 ;
13816 else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
13817 mac_set++;
13818 else if (unformat (i, "del"))
13819 is_add = 0;
13820 else
13821 break;
13822 }
13823
13824 if (sw_if_index == ~0)
13825 {
13826 errmsg ("missing interface name or sw_if_index");
13827 return -99;
13828 }
13829
13830 if (!mac_set)
13831 {
13832 errmsg ("missing MAC address");
13833 return -99;
13834 }
13835
13836 /* Construct the API message */
13837 M (SW_INTERFACE_ADD_DEL_MAC_ADDRESS, mp);
13838 mp->sw_if_index = ntohl (sw_if_index);
13839 mp->is_add = is_add;
13840 clib_memcpy (&mp->addr, &mac, sizeof (mac));
13841
13842 S (mp);
13843 W (ret);
13844 return ret;
13845}
13846
Damjan Marion7cd468a2016-12-19 23:05:39 +010013847static void vl_api_l2_xconnect_details_t_handler
13848 (vl_api_l2_xconnect_details_t * mp)
13849{
13850 vat_main_t *vam = &vat_main;
13851
13852 print (vam->ofp, "%15d%15d",
13853 ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
13854}
13855
13856static void vl_api_l2_xconnect_details_t_handler_json
13857 (vl_api_l2_xconnect_details_t * mp)
13858{
13859 vat_main_t *vam = &vat_main;
13860 vat_json_node_t *node = NULL;
13861
13862 if (VAT_JSON_ARRAY != vam->json_tree.type)
13863 {
13864 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13865 vat_json_init_array (&vam->json_tree);
13866 }
13867 node = vat_json_array_add (&vam->json_tree);
13868
13869 vat_json_init_object (node);
13870 vat_json_object_add_uint (node, "rx_sw_if_index",
13871 ntohl (mp->rx_sw_if_index));
13872 vat_json_object_add_uint (node, "tx_sw_if_index",
13873 ntohl (mp->tx_sw_if_index));
13874}
13875
13876static int
13877api_l2_xconnect_dump (vat_main_t * vam)
13878{
13879 vl_api_l2_xconnect_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060013880 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013881 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013882
13883 if (!vam->json_output)
13884 {
13885 print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
13886 }
13887
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013888 M (L2_XCONNECT_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013889
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013890 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013891
13892 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040013893 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060013894 S (mp_ping);
13895
Jon Loeliger56c7b012017-02-01 12:31:41 -060013896 W (ret);
13897 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013898}
13899
13900static int
Ole Troand7231612018-06-07 10:17:57 +020013901api_hw_interface_set_mtu (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010013902{
13903 unformat_input_t *i = vam->input;
Ole Troand7231612018-06-07 10:17:57 +020013904 vl_api_hw_interface_set_mtu_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013905 u32 sw_if_index = ~0;
13906 u32 mtu = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013907 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013908
13909 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13910 {
13911 if (unformat (i, "mtu %d", &mtu))
13912 ;
13913 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13914 ;
13915 else if (unformat (i, "sw_if_index %d", &sw_if_index))
13916 ;
13917 else
13918 break;
13919 }
13920
13921 if (sw_if_index == ~0)
13922 {
13923 errmsg ("missing interface name or sw_if_index");
13924 return -99;
13925 }
13926
13927 if (mtu == 0)
13928 {
13929 errmsg ("no mtu specified");
13930 return -99;
13931 }
13932
13933 /* Construct the API message */
Ole Troand7231612018-06-07 10:17:57 +020013934 M (HW_INTERFACE_SET_MTU, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013935 mp->sw_if_index = ntohl (sw_if_index);
13936 mp->mtu = ntohs ((u16) mtu);
13937
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013938 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013939 W (ret);
13940 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013941}
13942
Pavel Kotucek6899a302017-06-08 08:46:10 +020013943static int
13944api_p2p_ethernet_add (vat_main_t * vam)
13945{
13946 unformat_input_t *i = vam->input;
13947 vl_api_p2p_ethernet_add_t *mp;
13948 u32 parent_if_index = ~0;
Pavel Kotucek15ac81c2017-06-20 14:00:26 +020013949 u32 sub_id = ~0;
Pavel Kotucek6899a302017-06-08 08:46:10 +020013950 u8 remote_mac[6];
13951 u8 mac_set = 0;
13952 int ret;
13953
Dave Barachb7b92992018-10-17 10:38:51 -040013954 clib_memset (remote_mac, 0, sizeof (remote_mac));
Pavel Kotucek6899a302017-06-08 08:46:10 +020013955 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13956 {
13957 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
13958 ;
13959 else if (unformat (i, "sw_if_index %d", &parent_if_index))
13960 ;
13961 else
13962 if (unformat
13963 (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
13964 mac_set++;
Pavel Kotucek15ac81c2017-06-20 14:00:26 +020013965 else if (unformat (i, "sub_id %d", &sub_id))
13966 ;
Pavel Kotucek6899a302017-06-08 08:46:10 +020013967 else
13968 {
13969 clib_warning ("parse error '%U'", format_unformat_error, i);
13970 return -99;
13971 }
13972 }
13973
13974 if (parent_if_index == ~0)
13975 {
13976 errmsg ("missing interface name or sw_if_index");
13977 return -99;
13978 }
13979 if (mac_set == 0)
13980 {
13981 errmsg ("missing remote mac address");
13982 return -99;
13983 }
Pavel Kotucek15ac81c2017-06-20 14:00:26 +020013984 if (sub_id == ~0)
13985 {
13986 errmsg ("missing sub-interface id");
13987 return -99;
13988 }
Pavel Kotucek6899a302017-06-08 08:46:10 +020013989
13990 M (P2P_ETHERNET_ADD, mp);
13991 mp->parent_if_index = ntohl (parent_if_index);
Pavel Kotucek15ac81c2017-06-20 14:00:26 +020013992 mp->subif_id = ntohl (sub_id);
Pavel Kotucek6899a302017-06-08 08:46:10 +020013993 clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
13994
13995 S (mp);
13996 W (ret);
13997 return ret;
13998}
13999
14000static int
14001api_p2p_ethernet_del (vat_main_t * vam)
14002{
14003 unformat_input_t *i = vam->input;
14004 vl_api_p2p_ethernet_del_t *mp;
14005 u32 parent_if_index = ~0;
14006 u8 remote_mac[6];
14007 u8 mac_set = 0;
14008 int ret;
14009
Dave Barachb7b92992018-10-17 10:38:51 -040014010 clib_memset (remote_mac, 0, sizeof (remote_mac));
Pavel Kotucek6899a302017-06-08 08:46:10 +020014011 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14012 {
14013 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
14014 ;
14015 else if (unformat (i, "sw_if_index %d", &parent_if_index))
14016 ;
14017 else
14018 if (unformat
14019 (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
14020 mac_set++;
14021 else
14022 {
14023 clib_warning ("parse error '%U'", format_unformat_error, i);
14024 return -99;
14025 }
14026 }
14027
14028 if (parent_if_index == ~0)
14029 {
14030 errmsg ("missing interface name or sw_if_index");
14031 return -99;
14032 }
14033 if (mac_set == 0)
14034 {
14035 errmsg ("missing remote mac address");
14036 return -99;
14037 }
14038
14039 M (P2P_ETHERNET_DEL, mp);
14040 mp->parent_if_index = ntohl (parent_if_index);
14041 clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
14042
14043 S (mp);
14044 W (ret);
14045 return ret;
14046}
Damjan Marion7cd468a2016-12-19 23:05:39 +010014047
14048static int
Dave Barach3bbcfab2017-08-15 19:03:44 -040014049api_tcp_configure_src_addresses (vat_main_t * vam)
14050{
14051 vl_api_tcp_configure_src_addresses_t *mp;
14052 unformat_input_t *i = vam->input;
Neale Rannscbe25aa2019-09-30 10:53:31 +000014053 vl_api_address_t first, last;
Dave Barach3bbcfab2017-08-15 19:03:44 -040014054 u8 range_set = 0;
14055 u32 vrf_id = 0;
14056 int ret;
14057
14058 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14059 {
14060 if (unformat (i, "%U - %U",
Neale Rannscbe25aa2019-09-30 10:53:31 +000014061 unformat_vl_api_address, &first,
14062 unformat_vl_api_address, &last))
Dave Barach3bbcfab2017-08-15 19:03:44 -040014063 {
14064 if (range_set)
14065 {
14066 errmsg ("one range per message (range already set)");
14067 return -99;
14068 }
14069 range_set = 1;
14070 }
Dave Barach3bbcfab2017-08-15 19:03:44 -040014071 else if (unformat (i, "vrf %d", &vrf_id))
14072 ;
14073 else
14074 break;
14075 }
14076
14077 if (range_set == 0)
14078 {
14079 errmsg ("address range not set");
14080 return -99;
14081 }
14082
14083 M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
Neale Rannscbe25aa2019-09-30 10:53:31 +000014084
Dave Barach3bbcfab2017-08-15 19:03:44 -040014085 mp->vrf_id = ntohl (vrf_id);
Neale Rannscbe25aa2019-09-30 10:53:31 +000014086 clib_memcpy (&mp->first_address, &first, sizeof (first));
14087 clib_memcpy (&mp->last_address, &last, sizeof (last));
14088
Dave Barach3bbcfab2017-08-15 19:03:44 -040014089 S (mp);
14090 W (ret);
14091 return ret;
14092}
14093
Florin Coras6e8c6672017-11-10 09:03:54 -080014094static void vl_api_app_namespace_add_del_reply_t_handler
14095 (vl_api_app_namespace_add_del_reply_t * mp)
14096{
14097 vat_main_t *vam = &vat_main;
14098 i32 retval = ntohl (mp->retval);
14099 if (vam->async_mode)
14100 {
14101 vam->async_errors += (retval < 0);
14102 }
14103 else
14104 {
14105 vam->retval = retval;
14106 if (retval == 0)
14107 errmsg ("app ns index %d\n", ntohl (mp->appns_index));
14108 vam->result_ready = 1;
14109 }
14110}
14111
14112static void vl_api_app_namespace_add_del_reply_t_handler_json
14113 (vl_api_app_namespace_add_del_reply_t * mp)
14114{
14115 vat_main_t *vam = &vat_main;
14116 vat_json_node_t node;
14117
14118 vat_json_init_object (&node);
14119 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
14120 vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
14121
14122 vat_json_print (vam->ofp, &node);
14123 vat_json_free (&node);
14124
14125 vam->retval = ntohl (mp->retval);
14126 vam->result_ready = 1;
14127}
14128
Dave Barach3bbcfab2017-08-15 19:03:44 -040014129static int
Florin Corascea194d2017-10-02 00:18:51 -070014130api_app_namespace_add_del (vat_main_t * vam)
14131{
14132 vl_api_app_namespace_add_del_t *mp;
14133 unformat_input_t *i = vam->input;
14134 u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
14135 u32 sw_if_index, ip4_fib_id, ip6_fib_id;
14136 u64 secret;
14137 int ret;
14138
14139 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14140 {
14141 if (unformat (i, "id %_%v%_", &ns_id))
14142 ;
14143 else if (unformat (i, "secret %lu", &secret))
14144 secret_set = 1;
14145 else if (unformat (i, "sw_if_index %d", &sw_if_index))
14146 sw_if_index_set = 1;
14147 else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
14148 ;
14149 else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
14150 ;
14151 else
14152 break;
14153 }
14154 if (!ns_id || !secret_set || !sw_if_index_set)
14155 {
14156 errmsg ("namespace id, secret and sw_if_index must be set");
14157 return -99;
14158 }
14159 if (vec_len (ns_id) > 64)
14160 {
14161 errmsg ("namespace id too long");
14162 return -99;
14163 }
14164 M (APP_NAMESPACE_ADD_DEL, mp);
14165
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014166 vl_api_vec_to_api_string (ns_id, &mp->namespace_id);
Florin Coras9a9adb22017-10-26 08:16:59 -070014167 mp->secret = clib_host_to_net_u64 (secret);
Florin Corascea194d2017-10-02 00:18:51 -070014168 mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
14169 mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
14170 mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
14171 vec_free (ns_id);
14172 S (mp);
14173 W (ret);
14174 return ret;
14175}
14176
14177static int
Florin Coras90a63982017-12-19 04:50:01 -080014178api_sock_init_shm (vat_main_t * vam)
14179{
14180#if VPP_API_TEST_BUILTIN == 0
14181 unformat_input_t *i = vam->input;
14182 vl_api_shm_elem_config_t *config = 0;
14183 u64 size = 64 << 20;
14184 int rv;
14185
14186 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14187 {
14188 if (unformat (i, "size %U", unformat_memory_size, &size))
14189 ;
14190 else
14191 break;
14192 }
14193
Dave Barach78958722018-05-10 16:44:27 -040014194 /*
14195 * Canned custom ring allocator config.
14196 * Should probably parse all of this
14197 */
14198 vec_validate (config, 6);
Florin Coras90a63982017-12-19 04:50:01 -080014199 config[0].type = VL_API_VLIB_RING;
Florin Coras90a63982017-12-19 04:50:01 -080014200 config[0].size = 256;
Dave Barach78958722018-05-10 16:44:27 -040014201 config[0].count = 32;
14202
14203 config[1].type = VL_API_VLIB_RING;
Florin Coras90a63982017-12-19 04:50:01 -080014204 config[1].size = 1024;
Dave Barach78958722018-05-10 16:44:27 -040014205 config[1].count = 16;
14206
14207 config[2].type = VL_API_VLIB_RING;
Florin Coras90a63982017-12-19 04:50:01 -080014208 config[2].size = 4096;
Dave Barach78958722018-05-10 16:44:27 -040014209 config[2].count = 2;
14210
14211 config[3].type = VL_API_CLIENT_RING;
14212 config[3].size = 256;
14213 config[3].count = 32;
14214
14215 config[4].type = VL_API_CLIENT_RING;
14216 config[4].size = 1024;
14217 config[4].count = 16;
14218
14219 config[5].type = VL_API_CLIENT_RING;
14220 config[5].size = 4096;
14221 config[5].count = 2;
14222
14223 config[6].type = VL_API_QUEUE;
14224 config[6].count = 128;
14225 config[6].size = sizeof (uword);
14226
Tomasz Kulasek97dcf5b2019-01-31 18:26:32 +010014227 rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
Florin Coras90a63982017-12-19 04:50:01 -080014228 if (!rv)
14229 vam->client_index_invalid = 1;
14230 return rv;
14231#else
14232 return -99;
14233#endif
14234}
14235
Florin Coras6c36f532017-11-03 18:32:34 -070014236static void
14237vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
14238{
14239 vat_main_t *vam = &vat_main;
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014240 fib_prefix_t lcl, rmt;
Florin Coras6c36f532017-11-03 18:32:34 -070014241
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014242 ip_prefix_decode (&mp->lcl, &lcl);
14243 ip_prefix_decode (&mp->rmt, &rmt);
14244
14245 if (lcl.fp_proto == FIB_PROTOCOL_IP4)
Florin Coras6c36f532017-11-03 18:32:34 -070014246 {
Florin Corasc97a7392017-11-05 23:07:07 -080014247 print (vam->ofp,
14248 "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
Steven85dbac02017-11-07 16:29:53 -080014249 clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014250 mp->scope, format_ip4_address, &lcl.fp_addr.ip4, lcl.fp_len,
Steven85dbac02017-11-07 16:29:53 -080014251 clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014252 &rmt.fp_addr.ip4, rmt.fp_len,
14253 clib_net_to_host_u16 (mp->rmt_port),
Steven85dbac02017-11-07 16:29:53 -080014254 clib_net_to_host_u32 (mp->action_index), mp->tag);
Florin Coras6c36f532017-11-03 18:32:34 -070014255 }
14256 else
14257 {
Florin Corasc97a7392017-11-05 23:07:07 -080014258 print (vam->ofp,
14259 "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
Steven85dbac02017-11-07 16:29:53 -080014260 clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014261 mp->scope, format_ip6_address, &lcl.fp_addr.ip6, lcl.fp_len,
Steven85dbac02017-11-07 16:29:53 -080014262 clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014263 &rmt.fp_addr.ip6, rmt.fp_len,
14264 clib_net_to_host_u16 (mp->rmt_port),
Steven85dbac02017-11-07 16:29:53 -080014265 clib_net_to_host_u32 (mp->action_index), mp->tag);
Florin Coras6c36f532017-11-03 18:32:34 -070014266 }
14267}
14268
14269static void
14270vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
14271 mp)
14272{
14273 vat_main_t *vam = &vat_main;
14274 vat_json_node_t *node = NULL;
14275 struct in6_addr ip6;
14276 struct in_addr ip4;
14277
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014278 fib_prefix_t lcl, rmt;
14279
14280 ip_prefix_decode (&mp->lcl, &lcl);
14281 ip_prefix_decode (&mp->rmt, &rmt);
14282
Florin Coras6c36f532017-11-03 18:32:34 -070014283 if (VAT_JSON_ARRAY != vam->json_tree.type)
14284 {
14285 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14286 vat_json_init_array (&vam->json_tree);
14287 }
14288 node = vat_json_array_add (&vam->json_tree);
14289 vat_json_init_object (node);
14290
Florin Coras6c36f532017-11-03 18:32:34 -070014291 vat_json_object_add_uint (node, "appns_index",
14292 clib_net_to_host_u32 (mp->appns_index));
14293 vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
14294 vat_json_object_add_uint (node, "scope", mp->scope);
14295 vat_json_object_add_uint (node, "action_index",
14296 clib_net_to_host_u32 (mp->action_index));
14297 vat_json_object_add_uint (node, "lcl_port",
14298 clib_net_to_host_u16 (mp->lcl_port));
14299 vat_json_object_add_uint (node, "rmt_port",
14300 clib_net_to_host_u16 (mp->rmt_port));
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014301 vat_json_object_add_uint (node, "lcl_plen", lcl.fp_len);
14302 vat_json_object_add_uint (node, "rmt_plen", rmt.fp_len);
Florin Corasc97a7392017-11-05 23:07:07 -080014303 vat_json_object_add_string_copy (node, "tag", mp->tag);
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014304 if (lcl.fp_proto == FIB_PROTOCOL_IP4)
Florin Coras6c36f532017-11-03 18:32:34 -070014305 {
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014306 clib_memcpy (&ip4, &lcl.fp_addr.ip4, sizeof (ip4));
Florin Coras6c36f532017-11-03 18:32:34 -070014307 vat_json_object_add_ip4 (node, "lcl_ip", ip4);
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014308 clib_memcpy (&ip4, &rmt.fp_addr.ip4, sizeof (ip4));
Florin Coras6c36f532017-11-03 18:32:34 -070014309 vat_json_object_add_ip4 (node, "rmt_ip", ip4);
14310 }
14311 else
14312 {
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014313 clib_memcpy (&ip6, &lcl.fp_addr.ip6, sizeof (ip6));
Florin Coras6c36f532017-11-03 18:32:34 -070014314 vat_json_object_add_ip6 (node, "lcl_ip", ip6);
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014315 clib_memcpy (&ip6, &rmt.fp_addr.ip6, sizeof (ip6));
Florin Coras6c36f532017-11-03 18:32:34 -070014316 vat_json_object_add_ip6 (node, "rmt_ip", ip6);
14317 }
14318}
14319
Florin Coras1c710452017-10-17 00:03:13 -070014320static int
14321api_session_rule_add_del (vat_main_t * vam)
14322{
14323 vl_api_session_rule_add_del_t *mp;
14324 unformat_input_t *i = vam->input;
14325 u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
14326 u32 appns_index = 0, scope = 0;
14327 ip4_address_t lcl_ip4, rmt_ip4;
14328 ip6_address_t lcl_ip6, rmt_ip6;
14329 u8 is_ip4 = 1, conn_set = 0;
Florin Corasc97a7392017-11-05 23:07:07 -080014330 u8 is_add = 1, *tag = 0;
Florin Coras1c710452017-10-17 00:03:13 -070014331 int ret;
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014332 fib_prefix_t lcl, rmt;
Florin Coras1c710452017-10-17 00:03:13 -070014333
14334 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14335 {
14336 if (unformat (i, "del"))
14337 is_add = 0;
14338 else if (unformat (i, "add"))
14339 ;
14340 else if (unformat (i, "proto tcp"))
14341 proto = 0;
14342 else if (unformat (i, "proto udp"))
14343 proto = 1;
14344 else if (unformat (i, "appns %d", &appns_index))
14345 ;
14346 else if (unformat (i, "scope %d", &scope))
14347 ;
Florin Corasc97a7392017-11-05 23:07:07 -080014348 else if (unformat (i, "tag %_%v%_", &tag))
14349 ;
Florin Coras1c710452017-10-17 00:03:13 -070014350 else
14351 if (unformat
14352 (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
14353 &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
14354 &rmt_port))
14355 {
14356 is_ip4 = 1;
14357 conn_set = 1;
14358 }
14359 else
14360 if (unformat
14361 (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
14362 &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
14363 &rmt_port))
14364 {
14365 is_ip4 = 0;
14366 conn_set = 1;
14367 }
14368 else if (unformat (i, "action %d", &action))
14369 ;
14370 else
14371 break;
14372 }
14373 if (proto == ~0 || !conn_set || action == ~0)
14374 {
14375 errmsg ("transport proto, connection and action must be set");
14376 return -99;
14377 }
14378
14379 if (scope > 3)
14380 {
14381 errmsg ("scope should be 0-3");
14382 return -99;
14383 }
14384
14385 M (SESSION_RULE_ADD_DEL, mp);
14386
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014387 clib_memset (&lcl, 0, sizeof (lcl));
14388 clib_memset (&rmt, 0, sizeof (rmt));
14389 if (is_ip4)
14390 {
14391 ip_set (&lcl.fp_addr, &lcl_ip4, 1);
14392 ip_set (&rmt.fp_addr, &rmt_ip4, 1);
14393 lcl.fp_len = lcl_plen;
14394 rmt.fp_len = rmt_plen;
14395 }
14396 else
14397 {
14398 ip_set (&lcl.fp_addr, &lcl_ip6, 0);
14399 ip_set (&rmt.fp_addr, &rmt_ip6, 0);
14400 lcl.fp_len = lcl_plen;
14401 rmt.fp_len = rmt_plen;
14402 }
14403
14404
14405 ip_prefix_encode (&lcl, &mp->lcl);
14406 ip_prefix_encode (&rmt, &mp->rmt);
Florin Corasc97a7392017-11-05 23:07:07 -080014407 mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
14408 mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014409 mp->transport_proto =
14410 proto ? TRANSPORT_PROTO_API_UDP : TRANSPORT_PROTO_API_TCP;
Florin Coras1c710452017-10-17 00:03:13 -070014411 mp->action_index = clib_host_to_net_u32 (action);
14412 mp->appns_index = clib_host_to_net_u32 (appns_index);
14413 mp->scope = scope;
14414 mp->is_add = is_add;
Florin Corasc97a7392017-11-05 23:07:07 -080014415 if (tag)
14416 {
14417 clib_memcpy (mp->tag, tag, vec_len (tag));
14418 vec_free (tag);
14419 }
Florin Coras1c710452017-10-17 00:03:13 -070014420
14421 S (mp);
14422 W (ret);
14423 return ret;
14424}
Dave Barach65457162017-10-10 17:53:14 -040014425
14426static int
Florin Coras6c36f532017-11-03 18:32:34 -070014427api_session_rules_dump (vat_main_t * vam)
14428{
14429 vl_api_session_rules_dump_t *mp;
14430 vl_api_control_ping_t *mp_ping;
14431 int ret;
14432
14433 if (!vam->json_output)
14434 {
14435 print (vam->ofp, "%=20s", "Session Rules");
14436 }
14437
14438 M (SESSION_RULES_DUMP, mp);
14439 /* send it... */
14440 S (mp);
14441
14442 /* Use a control ping for synchronization */
14443 MPING (CONTROL_PING, mp_ping);
14444 S (mp_ping);
14445
14446 /* Wait for a reply... */
14447 W (ret);
14448 return ret;
14449}
14450
14451static int
Florin Coras595992c2017-11-06 17:17:08 -080014452api_ip_container_proxy_add_del (vat_main_t * vam)
14453{
14454 vl_api_ip_container_proxy_add_del_t *mp;
14455 unformat_input_t *i = vam->input;
Neale Ranns37029302018-08-10 05:30:06 -070014456 u32 sw_if_index = ~0;
14457 vl_api_prefix_t pfx = { };
Florin Coras595992c2017-11-06 17:17:08 -080014458 u8 is_add = 1;
14459 int ret;
14460
14461 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14462 {
14463 if (unformat (i, "del"))
14464 is_add = 0;
14465 else if (unformat (i, "add"))
14466 ;
Neale Ranns37029302018-08-10 05:30:06 -070014467 if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
14468 ;
Florin Coras595992c2017-11-06 17:17:08 -080014469 else if (unformat (i, "sw_if_index %u", &sw_if_index))
14470 ;
14471 else
14472 break;
14473 }
Paul Vinciguerraab055082019-06-06 14:07:55 -040014474 if (sw_if_index == ~0 || pfx.len == 0)
Florin Coras595992c2017-11-06 17:17:08 -080014475 {
14476 errmsg ("address and sw_if_index must be set");
14477 return -99;
14478 }
14479
14480 M (IP_CONTAINER_PROXY_ADD_DEL, mp);
14481
Florin Coras595992c2017-11-06 17:17:08 -080014482 mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
Florin Coras595992c2017-11-06 17:17:08 -080014483 mp->is_add = is_add;
Neale Ranns37029302018-08-10 05:30:06 -070014484 clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
Florin Coras595992c2017-11-06 17:17:08 -080014485
14486 S (mp);
14487 W (ret);
14488 return ret;
14489}
14490
14491static int
Igor Mikhailov (imichail)582caa32018-04-26 21:33:02 -070014492api_qos_record_enable_disable (vat_main_t * vam)
14493{
14494 unformat_input_t *i = vam->input;
14495 vl_api_qos_record_enable_disable_t *mp;
14496 u32 sw_if_index, qs = 0xff;
14497 u8 sw_if_index_set = 0;
14498 u8 enable = 1;
14499 int ret;
14500
14501 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14502 {
14503 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14504 sw_if_index_set = 1;
14505 else if (unformat (i, "sw_if_index %d", &sw_if_index))
14506 sw_if_index_set = 1;
14507 else if (unformat (i, "%U", unformat_qos_source, &qs))
14508 ;
14509 else if (unformat (i, "disable"))
14510 enable = 0;
14511 else
14512 {
14513 clib_warning ("parse error '%U'", format_unformat_error, i);
14514 return -99;
14515 }
14516 }
14517
14518 if (sw_if_index_set == 0)
14519 {
14520 errmsg ("missing interface name or sw_if_index");
14521 return -99;
14522 }
14523 if (qs == 0xff)
14524 {
14525 errmsg ("input location must be specified");
14526 return -99;
14527 }
14528
14529 M (QOS_RECORD_ENABLE_DISABLE, mp);
14530
Neale Ranns5281a902019-07-23 08:16:19 -070014531 mp->record.sw_if_index = ntohl (sw_if_index);
14532 mp->record.input_source = qs;
Igor Mikhailov (imichail)582caa32018-04-26 21:33:02 -070014533 mp->enable = enable;
14534
14535 S (mp);
14536 W (ret);
14537 return ret;
14538}
14539
Dave Barach048a4e52018-06-01 18:52:25 -040014540
Igor Mikhailov (imichail)582caa32018-04-26 21:33:02 -070014541static int
Damjan Marion7cd468a2016-12-19 23:05:39 +010014542q_or_quit (vat_main_t * vam)
14543{
Dave Barachdef19da2017-02-22 17:29:20 -050014544#if VPP_API_TEST_BUILTIN == 0
Damjan Marion7cd468a2016-12-19 23:05:39 +010014545 longjmp (vam->jump_buf, 1);
Dave Barachdef19da2017-02-22 17:29:20 -050014546#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +010014547 return 0; /* not so much */
14548}
14549
14550static int
14551q (vat_main_t * vam)
14552{
14553 return q_or_quit (vam);
14554}
14555
14556static int
14557quit (vat_main_t * vam)
14558{
14559 return q_or_quit (vam);
14560}
14561
14562static int
14563comment (vat_main_t * vam)
14564{
14565 return 0;
14566}
14567
14568static int
Dave Barachb09f4d02019-07-15 16:00:03 -040014569elog_save (vat_main_t * vam)
14570{
14571#if VPP_API_TEST_BUILTIN == 0
14572 elog_main_t *em = &vam->elog_main;
14573 unformat_input_t *i = vam->input;
14574 char *file, *chroot_file;
14575 clib_error_t *error;
14576
14577 if (!unformat (i, "%s", &file))
14578 {
14579 errmsg ("expected file name, got `%U'", format_unformat_error, i);
14580 return 0;
14581 }
14582
14583 /* It's fairly hard to get "../oopsie" through unformat; just in case */
14584 if (strstr (file, "..") || index (file, '/'))
14585 {
14586 errmsg ("illegal characters in filename '%s'", file);
14587 return 0;
14588 }
14589
14590 chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
14591
14592 vec_free (file);
14593
14594 errmsg ("Saving %wd of %wd events to %s",
14595 elog_n_events_in_buffer (em),
14596 elog_buffer_capacity (em), chroot_file);
14597
14598 error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
14599 vec_free (chroot_file);
14600
14601 if (error)
14602 clib_error_report (error);
14603#else
14604 errmsg ("Use the vpp event loger...");
14605#endif
14606
14607 return 0;
14608}
14609
14610static int
14611elog_setup (vat_main_t * vam)
14612{
14613#if VPP_API_TEST_BUILTIN == 0
14614 elog_main_t *em = &vam->elog_main;
14615 unformat_input_t *i = vam->input;
14616 u32 nevents = 128 << 10;
14617
14618 (void) unformat (i, "nevents %d", &nevents);
14619
14620 elog_init (em, nevents);
14621 vl_api_set_elog_main (em);
14622 vl_api_set_elog_trace_api_messages (1);
14623 errmsg ("Event logger initialized with %u events", nevents);
14624#else
14625 errmsg ("Use the vpp event loger...");
14626#endif
14627 return 0;
14628}
14629
14630static int
14631elog_enable (vat_main_t * vam)
14632{
14633#if VPP_API_TEST_BUILTIN == 0
14634 elog_main_t *em = &vam->elog_main;
14635
14636 elog_enable_disable (em, 1 /* enable */ );
14637 vl_api_set_elog_trace_api_messages (1);
14638 errmsg ("Event logger enabled...");
14639#else
14640 errmsg ("Use the vpp event loger...");
14641#endif
14642 return 0;
14643}
14644
14645static int
14646elog_disable (vat_main_t * vam)
14647{
14648#if VPP_API_TEST_BUILTIN == 0
14649 elog_main_t *em = &vam->elog_main;
14650
14651 elog_enable_disable (em, 0 /* enable */ );
14652 vl_api_set_elog_trace_api_messages (1);
14653 errmsg ("Event logger disabled...");
14654#else
14655 errmsg ("Use the vpp event loger...");
14656#endif
14657 return 0;
14658}
14659
14660static int
Dave Barach048a4e52018-06-01 18:52:25 -040014661statseg (vat_main_t * vam)
14662{
14663 ssvm_private_t *ssvmp = &vam->stat_segment;
14664 ssvm_shared_header_t *shared_header = ssvmp->sh;
14665 vlib_counter_t **counters;
14666 u64 thread0_index1_packets;
14667 u64 thread0_index1_bytes;
14668 f64 vector_rate, input_rate;
14669 uword *p;
14670
14671 uword *counter_vector_by_name;
14672 if (vam->stat_segment_lockp == 0)
14673 {
14674 errmsg ("Stat segment not mapped...");
14675 return -99;
14676 }
14677
14678 /* look up "/if/rx for sw_if_index 1 as a test */
14679
14680 clib_spinlock_lock (vam->stat_segment_lockp);
14681
14682 counter_vector_by_name = (uword *) shared_header->opaque[1];
14683
14684 p = hash_get_mem (counter_vector_by_name, "/if/rx");
14685 if (p == 0)
14686 {
14687 clib_spinlock_unlock (vam->stat_segment_lockp);
14688 errmsg ("/if/tx not found?");
14689 return -99;
14690 }
14691
14692 /* Fish per-thread vector of combined counters from shared memory */
14693 counters = (vlib_counter_t **) p[0];
14694
14695 if (vec_len (counters[0]) < 2)
14696 {
14697 clib_spinlock_unlock (vam->stat_segment_lockp);
14698 errmsg ("/if/tx vector length %d", vec_len (counters[0]));
14699 return -99;
14700 }
14701
14702 /* Read thread 0 sw_if_index 1 counter */
14703 thread0_index1_packets = counters[0][1].packets;
14704 thread0_index1_bytes = counters[0][1].bytes;
14705
14706 p = hash_get_mem (counter_vector_by_name, "vector_rate");
14707 if (p == 0)
14708 {
14709 clib_spinlock_unlock (vam->stat_segment_lockp);
14710 errmsg ("vector_rate not found?");
14711 return -99;
14712 }
14713
14714 vector_rate = *(f64 *) (p[0]);
14715 p = hash_get_mem (counter_vector_by_name, "input_rate");
14716 if (p == 0)
14717 {
14718 clib_spinlock_unlock (vam->stat_segment_lockp);
14719 errmsg ("input_rate not found?");
14720 return -99;
14721 }
14722 input_rate = *(f64 *) (p[0]);
14723
14724 clib_spinlock_unlock (vam->stat_segment_lockp);
14725
14726 print (vam->ofp, "vector_rate %.2f input_rate %.2f",
14727 vector_rate, input_rate);
14728 print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
14729 thread0_index1_packets, thread0_index1_bytes);
14730
14731 return 0;
14732}
14733
14734static int
Damjan Marion7cd468a2016-12-19 23:05:39 +010014735cmd_cmp (void *a1, void *a2)
14736{
14737 u8 **c1 = a1;
14738 u8 **c2 = a2;
14739
14740 return strcmp ((char *) (c1[0]), (char *) (c2[0]));
14741}
14742
14743static int
14744help (vat_main_t * vam)
14745{
14746 u8 **cmds = 0;
14747 u8 *name = 0;
14748 hash_pair_t *p;
14749 unformat_input_t *i = vam->input;
14750 int j;
14751
14752 if (unformat (i, "%s", &name))
14753 {
14754 uword *hs;
14755
14756 vec_add1 (name, 0);
14757
14758 hs = hash_get_mem (vam->help_by_name, name);
14759 if (hs)
14760 print (vam->ofp, "usage: %s %s", name, hs[0]);
14761 else
14762 print (vam->ofp, "No such msg / command '%s'", name);
14763 vec_free (name);
14764 return 0;
14765 }
14766
14767 print (vam->ofp, "Help is available for the following:");
14768
14769 /* *INDENT-OFF* */
14770 hash_foreach_pair (p, vam->function_by_name,
14771 ({
14772 vec_add1 (cmds, (u8 *)(p->key));
14773 }));
14774 /* *INDENT-ON* */
14775
14776 vec_sort_with_function (cmds, cmd_cmp);
14777
14778 for (j = 0; j < vec_len (cmds); j++)
14779 print (vam->ofp, "%s", cmds[j]);
14780
14781 vec_free (cmds);
14782 return 0;
14783}
14784
14785static int
14786set (vat_main_t * vam)
14787{
14788 u8 *name = 0, *value = 0;
14789 unformat_input_t *i = vam->input;
14790
14791 if (unformat (i, "%s", &name))
14792 {
14793 /* The input buffer is a vector, not a string. */
14794 value = vec_dup (i->buffer);
14795 vec_delete (value, i->index, 0);
14796 /* Almost certainly has a trailing newline */
14797 if (value[vec_len (value) - 1] == '\n')
14798 value[vec_len (value) - 1] = 0;
14799 /* Make sure it's a proper string, one way or the other */
14800 vec_add1 (value, 0);
14801 (void) clib_macro_set_value (&vam->macro_main,
14802 (char *) name, (char *) value);
14803 }
14804 else
14805 errmsg ("usage: set <name> <value>");
14806
14807 vec_free (name);
14808 vec_free (value);
14809 return 0;
14810}
14811
14812static int
14813unset (vat_main_t * vam)
14814{
14815 u8 *name = 0;
14816
14817 if (unformat (vam->input, "%s", &name))
14818 if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
14819 errmsg ("unset: %s wasn't set", name);
14820 vec_free (name);
14821 return 0;
14822}
14823
14824typedef struct
14825{
14826 u8 *name;
14827 u8 *value;
14828} macro_sort_t;
14829
14830
14831static int
14832macro_sort_cmp (void *a1, void *a2)
14833{
14834 macro_sort_t *s1 = a1;
14835 macro_sort_t *s2 = a2;
14836
14837 return strcmp ((char *) (s1->name), (char *) (s2->name));
14838}
14839
14840static int
14841dump_macro_table (vat_main_t * vam)
14842{
14843 macro_sort_t *sort_me = 0, *sm;
14844 int i;
14845 hash_pair_t *p;
14846
14847 /* *INDENT-OFF* */
14848 hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
14849 ({
14850 vec_add2 (sort_me, sm, 1);
14851 sm->name = (u8 *)(p->key);
14852 sm->value = (u8 *) (p->value[0]);
14853 }));
14854 /* *INDENT-ON* */
14855
14856 vec_sort_with_function (sort_me, macro_sort_cmp);
14857
14858 if (vec_len (sort_me))
14859 print (vam->ofp, "%-15s%s", "Name", "Value");
14860 else
14861 print (vam->ofp, "The macro table is empty...");
14862
14863 for (i = 0; i < vec_len (sort_me); i++)
14864 print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
14865 return 0;
14866}
14867
14868static int
14869dump_node_table (vat_main_t * vam)
14870{
14871 int i, j;
14872 vlib_node_t *node, *next_node;
14873
14874 if (vec_len (vam->graph_nodes) == 0)
14875 {
14876 print (vam->ofp, "Node table empty, issue get_node_graph...");
14877 return 0;
14878 }
14879
Dave Barach1ddbc012018-06-13 09:26:05 -040014880 for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
Damjan Marion7cd468a2016-12-19 23:05:39 +010014881 {
Dave Barach1ddbc012018-06-13 09:26:05 -040014882 node = vam->graph_nodes[0][i];
Damjan Marion7cd468a2016-12-19 23:05:39 +010014883 print (vam->ofp, "[%d] %s", i, node->name);
14884 for (j = 0; j < vec_len (node->next_nodes); j++)
14885 {
14886 if (node->next_nodes[j] != ~0)
14887 {
Dave Barach1ddbc012018-06-13 09:26:05 -040014888 next_node = vam->graph_nodes[0][node->next_nodes[j]];
Damjan Marion7cd468a2016-12-19 23:05:39 +010014889 print (vam->ofp, " [%d] %s", j, next_node->name);
14890 }
14891 }
14892 }
14893 return 0;
14894}
14895
14896static int
14897value_sort_cmp (void *a1, void *a2)
14898{
14899 name_sort_t *n1 = a1;
14900 name_sort_t *n2 = a2;
14901
14902 if (n1->value < n2->value)
14903 return -1;
14904 if (n1->value > n2->value)
14905 return 1;
14906 return 0;
14907}
14908
14909
14910static int
14911dump_msg_api_table (vat_main_t * vam)
14912{
Dave Barach39d69112019-11-27 11:42:13 -050014913 api_main_t *am = vlibapi_get_main ();
Damjan Marion7cd468a2016-12-19 23:05:39 +010014914 name_sort_t *nses = 0, *ns;
14915 hash_pair_t *hp;
14916 int i;
14917
14918 /* *INDENT-OFF* */
14919 hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
14920 ({
14921 vec_add2 (nses, ns, 1);
14922 ns->name = (u8 *)(hp->key);
14923 ns->value = (u32) hp->value[0];
14924 }));
14925 /* *INDENT-ON* */
14926
14927 vec_sort_with_function (nses, value_sort_cmp);
14928
14929 for (i = 0; i < vec_len (nses); i++)
14930 print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
14931 vec_free (nses);
14932 return 0;
14933}
14934
14935static int
14936get_msg_id (vat_main_t * vam)
14937{
14938 u8 *name_and_crc;
14939 u32 message_index;
14940
14941 if (unformat (vam->input, "%s", &name_and_crc))
14942 {
Florin Corase86a8ed2018-01-05 03:20:25 -080014943 message_index = vl_msg_api_get_msg_index (name_and_crc);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014944 if (message_index == ~0)
14945 {
14946 print (vam->ofp, " '%s' not found", name_and_crc);
14947 return 0;
14948 }
14949 print (vam->ofp, " '%s' has message index %d",
14950 name_and_crc, message_index);
14951 return 0;
14952 }
14953 errmsg ("name_and_crc required...");
14954 return 0;
14955}
14956
14957static int
14958search_node_table (vat_main_t * vam)
14959{
14960 unformat_input_t *line_input = vam->input;
14961 u8 *node_to_find;
14962 int j;
14963 vlib_node_t *node, *next_node;
14964 uword *p;
14965
14966 if (vam->graph_node_index_by_name == 0)
14967 {
14968 print (vam->ofp, "Node table empty, issue get_node_graph...");
14969 return 0;
14970 }
14971
14972 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14973 {
14974 if (unformat (line_input, "%s", &node_to_find))
14975 {
14976 vec_add1 (node_to_find, 0);
14977 p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
14978 if (p == 0)
14979 {
14980 print (vam->ofp, "%s not found...", node_to_find);
14981 goto out;
14982 }
Dave Barach1ddbc012018-06-13 09:26:05 -040014983 node = vam->graph_nodes[0][p[0]];
Damjan Marion7cd468a2016-12-19 23:05:39 +010014984 print (vam->ofp, "[%d] %s", p[0], node->name);
14985 for (j = 0; j < vec_len (node->next_nodes); j++)
14986 {
14987 if (node->next_nodes[j] != ~0)
14988 {
Dave Barach1ddbc012018-06-13 09:26:05 -040014989 next_node = vam->graph_nodes[0][node->next_nodes[j]];
Damjan Marion7cd468a2016-12-19 23:05:39 +010014990 print (vam->ofp, " [%d] %s", j, next_node->name);
14991 }
14992 }
14993 }
14994
14995 else
14996 {
14997 clib_warning ("parse error '%U'", format_unformat_error,
14998 line_input);
14999 return -99;
15000 }
15001
15002 out:
15003 vec_free (node_to_find);
15004
15005 }
15006
15007 return 0;
15008}
15009
15010
15011static int
15012script (vat_main_t * vam)
15013{
15014#if (VPP_API_TEST_BUILTIN==0)
15015 u8 *s = 0;
15016 char *save_current_file;
15017 unformat_input_t save_input;
15018 jmp_buf save_jump_buf;
15019 u32 save_line_number;
15020
15021 FILE *new_fp, *save_ifp;
15022
15023 if (unformat (vam->input, "%s", &s))
15024 {
15025 new_fp = fopen ((char *) s, "r");
15026 if (new_fp == 0)
15027 {
15028 errmsg ("Couldn't open script file %s", s);
15029 vec_free (s);
15030 return -99;
15031 }
15032 }
15033 else
15034 {
15035 errmsg ("Missing script name");
15036 return -99;
15037 }
15038
15039 clib_memcpy (&save_input, &vam->input, sizeof (save_input));
15040 clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
15041 save_ifp = vam->ifp;
15042 save_line_number = vam->input_line_number;
15043 save_current_file = (char *) vam->current_file;
15044
15045 vam->input_line_number = 0;
15046 vam->ifp = new_fp;
15047 vam->current_file = s;
15048 do_one_file (vam);
15049
Sirshak Dasb0861822018-05-29 21:13:21 -050015050 clib_memcpy (&vam->input, &save_input, sizeof (save_input));
Damjan Marion7cd468a2016-12-19 23:05:39 +010015051 clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
15052 vam->ifp = save_ifp;
15053 vam->input_line_number = save_line_number;
15054 vam->current_file = (u8 *) save_current_file;
15055 vec_free (s);
15056
15057 return 0;
15058#else
15059 clib_warning ("use the exec command...");
15060 return -99;
15061#endif
15062}
15063
15064static int
15065echo (vat_main_t * vam)
15066{
15067 print (vam->ofp, "%v", vam->input->buffer);
15068 return 0;
15069}
15070
15071/* List of API message constructors, CLI names map to api_xxx */
15072#define foreach_vpe_api_msg \
Jon Loeligerc83c3b72017-02-23 13:57:35 -060015073_(create_loopback,"[mac <mac-addr>] [instance <instance>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015074_(sw_interface_dump,"") \
15075_(sw_interface_set_flags, \
15076 "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
15077_(sw_interface_add_del_address, \
15078 "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
Stevenad8015b2017-10-29 22:10:46 -070015079_(sw_interface_set_rx_mode, \
15080 "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
Mohsin Kazmi54f7c512018-08-23 18:28:11 +020015081_(sw_interface_set_rx_placement, \
15082 "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]") \
Mohsin Kazmif0b42f42018-09-10 18:11:00 +020015083_(sw_interface_rx_placement_dump, \
15084 "[<intfc> | sw_if_index <id>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015085_(sw_interface_set_table, \
15086 "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]") \
15087_(sw_interface_set_mpls_enable, \
15088 "<intfc> | sw_if_index [disable | dis]") \
15089_(sw_interface_set_vpath, \
15090 "<intfc> | sw_if_index <id> enable | disable") \
15091_(sw_interface_set_vxlan_bypass, \
John Lo2b81eb82017-01-30 13:12:10 -050015092 "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015093_(sw_interface_set_l2_xconnect, \
15094 "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
15095 "enable | disable") \
15096_(sw_interface_set_l2_bridge, \
Eyal Barif24991c2017-04-05 05:33:21 +030015097 "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n" \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015098 "[shg <split-horizon-group>] [bvi]\n" \
15099 "enable | disable") \
Eyal Barif24991c2017-04-05 05:33:21 +030015100_(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015101_(bridge_domain_add_del, \
John Lo70bfcaf2017-11-14 13:19:26 -050015102 "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 +010015103_(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n") \
15104_(l2fib_add_del, \
15105 "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 +030015106_(l2fib_flush_bd, "bd_id <bridge-domain-id>") \
15107_(l2fib_flush_int, "<intfc> | sw_if_index <id>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015108_(l2_flags, \
John Lo8d00fff2017-08-03 00:35:36 -040015109 "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015110_(bridge_flags, \
15111 "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
Damjan Marion8389fb92017-10-13 18:29:53 +020015112_(tap_create_v2, \
Mohsin Kazmi50bd1652020-08-26 11:07:48 +020015113 "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 +020015114_(tap_delete_v2, \
15115 "<vpp-if-name> | sw_if_index <id>") \
15116_(sw_interface_tap_v2_dump, "") \
Mohsin Kazmi518251b2020-09-01 17:17:44 +000015117_(virtio_pci_create_v2, \
Mohsin Kazmie347acb2020-09-28 10:26:33 +000015118 "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 +010015119_(virtio_pci_delete, \
15120 "<vpp-if-name> | sw_if_index <id>") \
15121_(sw_interface_virtio_pci_dump, "") \
Steven9cd2d7a2017-12-20 12:43:01 -080015122_(bond_create, \
15123 "[hw-addr <mac-addr>] {round-robin | active-backup | " \
Alexander Chernavinad9d5282018-12-13 09:08:09 -050015124 "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} " \
Steven Luonga1876b82019-08-20 16:58:00 -070015125 "[id <if-id>]") \
Steven Luongea717862020-07-30 07:31:40 -070015126_(bond_create2, \
15127 "[hw-addr <mac-addr>] {mode round-robin | active-backup | " \
15128 "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} " \
15129 "[id <if-id>] [gso]") \
Steven9cd2d7a2017-12-20 12:43:01 -080015130_(bond_delete, \
15131 "<vpp-if-name> | sw_if_index <id>") \
Steven Luong4c4223e2020-07-15 08:44:54 -070015132_(bond_add_member, \
Steven Luonga1876b82019-08-20 16:58:00 -070015133 "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]") \
Steven Luong4c4223e2020-07-15 08:44:54 -070015134_(bond_detach_member, \
Steven9cd2d7a2017-12-20 12:43:01 -080015135 "sw_if_index <n>") \
Steven Luonga1876b82019-08-20 16:58:00 -070015136 _(sw_interface_set_bond_weight, "<intfc> | sw_if_index <nn> weight <value>") \
Steven Luong4c4223e2020-07-15 08:44:54 -070015137 _(sw_bond_interface_dump, "<intfc> | sw_if_index <nn>") \
15138 _(sw_member_interface_dump, \
Steven9cd2d7a2017-12-20 12:43:01 -080015139 "<vpp-if-name> | sw_if_index <id>") \
Neale Ranns28ab9cc2017-08-14 07:18:42 -070015140_(ip_table_add_del, \
John Loe166fd92018-09-13 14:08:59 -040015141 "table <n> [ipv6] [add | del]\n") \
Neale Ranns097fa662018-05-01 05:17:55 -070015142_(ip_route_add_del, \
John Lo22030432018-09-20 16:07:00 -040015143 "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
15144 "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
John Lo06fda9c2018-10-03 16:32:44 -040015145 "[weight <n>] [drop] [local] [classify <n>] [out-label <n>]\n" \
15146 "[multipath] [count <n>] [del]") \
Neale Ranns32e1c012016-11-22 17:07:28 +000015147_(ip_mroute_add_del, \
15148 "<src> <grp>/<mask> [table-id <n>]\n" \
15149 "[<intfc> | sw_if_index <id>] [local] [del]") \
Neale Ranns28ab9cc2017-08-14 07:18:42 -070015150_(mpls_table_add_del, \
John Loe166fd92018-09-13 14:08:59 -040015151 "table <n> [add | del]\n") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015152_(mpls_route_add_del, \
John Loe166fd92018-09-13 14:08:59 -040015153 "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n" \
15154 "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n" \
15155 "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n" \
15156 "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n" \
John Lo06fda9c2018-10-03 16:32:44 -040015157 "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n" \
15158 "[count <n>] [del]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015159_(mpls_ip_bind_unbind, \
15160 "<label> <addr/len>") \
15161_(mpls_tunnel_add_del, \
John Lo06fda9c2018-10-03 16:32:44 -040015162 "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
15163 "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n" \
15164 "[l2-only] [out-label <n>]") \
John Loe166fd92018-09-13 14:08:59 -040015165_(sr_mpls_policy_add, \
15166 "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]") \
15167_(sr_mpls_policy_del, \
15168 "bsid <id>") \
Neale Rannsd792d9c2017-10-21 10:53:20 -070015169_(bier_table_add_del, \
15170 "<label> <sub-domain> <set> <bsl> [del]") \
15171_(bier_route_add_del, \
15172 "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
15173 "[<intfc> | sw_if_index <id>]" \
15174 "[weight <n>] [del] [multipath]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015175_(sw_interface_set_unnumbered, \
15176 "<intfc> | sw_if_index <id> unnum_if_index <id> [del]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015177_(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>") \
15178_(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n" \
15179 "[outer_vlan_id <n>][inner_vlan_id <n>]\n" \
15180 "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n" \
15181 "[outer_vlan_id_any][inner_vlan_id_any]") \
Neale Ranns9db6ada2019-11-08 12:42:31 +000015182_(ip_table_replace_begin, "table <n> [ipv6]") \
15183_(ip_table_flush, "table <n> [ipv6]") \
15184_(ip_table_replace_end, "table <n> [ipv6]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015185_(set_ip_flow_hash, \
15186 "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]") \
15187_(sw_interface_ip6_enable_disable, \
15188 "<intfc> | sw_if_index <id> enable | disable") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015189_(l2_patch_add_del, \
15190 "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
15191 "enable | disable") \
Pablo Camarillofb380952016-12-07 18:34:18 +010015192_(sr_localsid_add_del, \
15193 "(del) address <addr> next_hop <addr> behavior <beh>\n" \
15194 "fib-table <num> (end.psp) sw_if_index <num>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015195_(classify_add_del_table, \
15196 "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n" \
15197 " [del] [del-chain] mask <mask-value>\n" \
15198 " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n" \
15199 " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]") \
15200_(classify_add_del_session, \
15201 "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n" \
15202 " table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n" \
15203 " [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n" \
15204 " [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]") \
15205_(classify_set_interface_ip_table, \
15206 "<intfc> | sw_if_index <nn> table <nn>") \
15207_(classify_set_interface_l2_tables, \
15208 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
15209 " [other-table <nn>]") \
15210_(get_node_index, "node <node-name") \
15211_(add_node_next, "node <node-name> next <next-node-name>") \
eyal bariaf86a482018-04-17 11:20:27 +030015212_(vxlan_offload_rx, \
15213 "hw { <interface name> | hw_if_index <nn>} " \
15214 "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015215_(vxlan_add_del_tunnel, \
15216 "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n" \
Jon Loeliger3d460bd2018-02-01 16:36:12 -060015217 "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n" \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015218 "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]") \
15219_(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]") \
Neale Ranns5a8844b2019-04-16 07:15:35 +000015220_(gre_tunnel_add_del, \
John Loa43ccae2018-02-13 17:15:23 -050015221 "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n" \
15222 "[teb | erspan <session-id>] [del]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015223_(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]") \
15224_(l2_fib_clear_table, "") \
15225_(l2_interface_efp_filter, "sw_if_index <nn> enable | disable") \
15226_(l2_interface_vlan_tag_rewrite, \
15227 "<intfc> | sw_if_index <nn> \n" \
15228 "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n" \
15229 "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>") \
15230_(create_vhost_user_if, \
15231 "socket <filename> [server] [renumber <dev_instance>] " \
Steven Luong4208a4c2019-05-06 08:51:56 -070015232 "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] " \
Steven Luongbc0d9ff2020-03-23 09:34:59 -070015233 "[mac <mac_address>] [packed]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015234_(modify_vhost_user_if, \
15235 "<intfc> | sw_if_index <nn> socket <filename>\n" \
Steven Luongbc0d9ff2020-03-23 09:34:59 -070015236 "[server] [renumber <dev_instance>] [gso] [packed]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015237_(delete_vhost_user_if, "<intfc> | sw_if_index <nn>") \
Steven Luonga0e8d962020-05-18 17:12:56 -070015238_(sw_interface_vhost_user_dump, "<intfc> | sw_if_index <nn>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015239_(show_version, "") \
Mohsin Kazmi5d64c782018-09-11 20:27:09 +020015240_(show_threads, "") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015241_(vxlan_gpe_add_del_tunnel, \
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080015242 "local <addr> remote <addr> | group <mcast-ip-addr>\n" \
15243 "{ <intfc> | mcast_sw_if_index <nn> } }\n" \
15244 "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n" \
15245 "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015246_(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]") \
15247_(l2_fib_table_dump, "bd_id <bridge-domain-id>") \
15248_(interface_name_renumber, \
15249 "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>") \
15250_(input_acl_set_interface, \
15251 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
15252 " [l2-table <nn>] [del]") \
John Lo8d00fff2017-08-03 00:35:36 -040015253_(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015254_(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)") \
15255_(ip_dump, "ipv4 | ipv6") \
15256_(ipsec_spd_add_del, "spd_id <n> [del]") \
15257_(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n" \
15258 " spid_id <n> ") \
Neale Ranns17dcec02019-01-09 21:22:20 -080015259_(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n" \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015260 " crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n" \
15261 " integ_alg <alg> integ_key <hex>") \
Neale Ranns17dcec02019-01-09 21:22:20 -080015262_(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n" \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015263 " (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n" \
15264 " laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
15265 " [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
Matthew Smithb0972cb2017-05-02 16:20:41 -050015266_(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n" \
15267 " crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
15268 " integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n" \
Matthew Smith8e1039a2018-04-12 07:32:56 -050015269 " local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n" \
15270 " [instance <n>]") \
Matthew Smith28029532017-09-26 13:33:44 -050015271_(ipsec_sa_dump, "[sa_id <n>]") \
Matthew Smithca514fd2017-10-12 12:06:59 -050015272_(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015273_(delete_loopback,"sw_if_index <nn>") \
15274_(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
John Loe26c81f2019-01-07 15:16:33 -050015275_(bd_ip_mac_flush, "bd_id <bridge-domain-id>") \
15276_(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015277_(want_interface_events, "enable|disable") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015278_(get_first_msg_id, "client <name>") \
15279_(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
15280_(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n" \
15281 "fib-id <nn> [ip4][ip6][default]") \
15282_(get_node_graph, " ") \
15283_(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>") \
15284_(ioam_enable, "[trace] [pow] [ppc <encap|decap>]") \
15285_(ioam_disable, "") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015286_(af_packet_create, "name <host interface name> [hw_addr <mac>]") \
15287_(af_packet_delete, "name <host interface name>") \
Mohsin Kazmi04e0bb22018-05-28 18:55:37 +020015288_(af_packet_dump, "") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015289_(policer_add_del, "name <policer name> <params> [del]") \
15290_(policer_dump, "[name <policer name>]") \
15291_(policer_classify_set_interface, \
15292 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
15293 " [l2-table <nn>] [del]") \
15294_(policer_classify_dump, "type [ip4|ip6|l2]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015295_(mpls_tunnel_dump, "tunnel_index <tunnel-id>") \
Neale Ranns097fa662018-05-01 05:17:55 -070015296_(mpls_table_dump, "") \
15297_(mpls_route_dump, "table-id <ID>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015298_(classify_table_ids, "") \
15299_(classify_table_by_interface, "sw_if_index <sw_if_index>") \
15300_(classify_table_info, "table_id <nn>") \
15301_(classify_session_dump, "table_id <nn>") \
15302_(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] " \
15303 "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] " \
15304 "[template_interval <nn>] [udp_checksum]") \
15305_(ipfix_exporter_dump, "") \
15306_(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
15307_(ipfix_classify_stream_dump, "") \
15308_(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
15309_(ipfix_classify_table_dump, "") \
Eyal Bari001fd402017-07-16 09:34:53 +030015310_(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 +030015311_(sw_interface_span_dump, "[l2]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015312_(get_next_index, "node-name <node-name> next-node-name <node-name>") \
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +020015313_(pg_create_interface, "if_id <nn> [gso-enabled gso-size <size>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015314_(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]") \
15315_(pg_enable_disable, "[stream <id>] disable") \
Mohsin Kazmif382b062020-08-11 15:00:44 +020015316_(pg_interface_enable_disable_coalesce, "<intf> | sw_if_index <nn> enable | disable") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015317_(ip_source_and_port_range_check_add_del, \
15318 "<ip-addr>/<mask> range <nn>-<nn> vrf <id>") \
15319_(ip_source_and_port_range_check_interface_add_del, \
15320 "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]" \
15321 "[udp-in-vrf <id>] [udp-out-vrf <id>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015322_(delete_subif,"<intfc> | sw_if_index <nn>") \
15323_(l2_interface_pbb_tag_rewrite, \
15324 "<intfc> | sw_if_index <nn> \n" \
15325 "[disable | push | pop | translate_pbb_stag <outer_tag>] \n" \
15326 "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]") \
Pavel Kotuceke88865d2018-11-28 07:42:11 +010015327_(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015328_(flow_classify_set_interface, \
15329 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
15330_(flow_classify_dump, "type [ip4|ip6]") \
Neale Ranns097fa662018-05-01 05:17:55 -070015331_(ip_table_dump, "") \
15332_(ip_route_dump, "table-id [ip4|ip6]") \
15333_(ip_mtable_dump, "") \
15334_(ip_mroute_dump, "table-id [ip4|ip6]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015335_(feature_enable_disable, "arc_name <arc_name> " \
15336 "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]") \
Mohsin Kazmi29467b52019-10-08 19:42:38 +020015337_(feature_gso_enable_disable, "<intfc> | sw_if_index <nn> " \
15338 "[enable | disable] ") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015339_(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>" \
15340"[disable]") \
Matthew Smithe0792fd2019-07-12 11:48:24 -050015341_(sw_interface_add_del_mac_address, "<intfc> | sw_if_index <nn> " \
15342 "mac <mac-address> [del]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015343_(l2_xconnect_dump, "") \
Ole Troand7231612018-06-07 10:17:57 +020015344_(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>") \
Pavel Kotucek6899a302017-06-08 08:46:10 +020015345_(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]") \
Pavel Kotucek15ac81c2017-06-20 14:00:26 +020015346_(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
Steve Shin99a0e602017-07-01 04:16:20 +000015347_(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
Dave Barach59b25652017-09-10 15:04:27 -040015348_(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]") \
Florin Coras90a63982017-12-19 04:50:01 -080015349_(sock_init_shm, "size <nnn>") \
Florin Corascea194d2017-10-02 00:18:51 -070015350_(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
Florin Coras1c710452017-10-17 00:03:13 -070015351_(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> " \
15352 "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>") \
Florin Coras6c36f532017-11-03 18:32:34 -070015353_(session_rules_dump, "") \
Florin Coras595992c2017-11-06 17:17:08 -080015354_(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>") \
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +010015355_(output_acl_set_interface, \
15356 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
15357 " [l2-table <nn>] [del]") \
Ole Troane906aac2018-06-14 14:42:14 +020015358_(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
Damjan Marion7cd468a2016-12-19 23:05:39 +010015359
15360/* List of command functions, CLI names map directly to functions */
15361#define foreach_cli_function \
15362_(comment, "usage: comment <ignore-rest-of-line>") \
15363_(dump_interface_table, "usage: dump_interface_table") \
15364_(dump_sub_interface_table, "usage: dump_sub_interface_table") \
15365_(dump_ipv4_table, "usage: dump_ipv4_table") \
15366_(dump_ipv6_table, "usage: dump_ipv6_table") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015367_(dump_macro_table, "usage: dump_macro_table ") \
15368_(dump_node_table, "usage: dump_node_table") \
15369_(dump_msg_api_table, "usage: dump_msg_api_table") \
Dave Barachb09f4d02019-07-15 16:00:03 -040015370_(elog_setup, "usage: elog_setup [nevents, default 128K]") \
15371_(elog_disable, "usage: elog_disable") \
15372_(elog_enable, "usage: elog_enable") \
15373_(elog_save, "usage: elog_save <filename>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015374_(get_msg_id, "usage: get_msg_id name_and_crc") \
15375_(echo, "usage: echo <message>") \
15376_(exec, "usage: exec <vpe-debug-CLI-command>") \
15377_(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>") \
15378_(help, "usage: help") \
15379_(q, "usage: quit") \
15380_(quit, "usage: quit") \
15381_(search_node_table, "usage: search_node_table <name>...") \
15382_(set, "usage: set <variable-name> <value>") \
15383_(script, "usage: script <file-name>") \
Neale Ranns097fa662018-05-01 05:17:55 -070015384_(statseg, "usage: statseg") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015385_(unset, "usage: unset <variable-name>")
Dave Barach048a4e52018-06-01 18:52:25 -040015386
Damjan Marion7cd468a2016-12-19 23:05:39 +010015387#define _(N,n) \
15388 static void vl_api_##n##_t_handler_uni \
15389 (vl_api_##n##_t * mp) \
15390 { \
15391 vat_main_t * vam = &vat_main; \
15392 if (vam->json_output) { \
15393 vl_api_##n##_t_handler_json(mp); \
15394 } else { \
15395 vl_api_##n##_t_handler(mp); \
15396 } \
15397 }
15398foreach_vpe_api_reply_msg;
Dave Baracha1a093d2017-03-02 13:13:23 -050015399#if VPP_API_TEST_BUILTIN == 0
15400foreach_standalone_reply_msg;
15401#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +010015402#undef _
15403
15404void
15405vat_api_hookup (vat_main_t * vam)
15406{
15407#define _(N,n) \
15408 vl_msg_api_set_handlers(VL_API_##N, #n, \
15409 vl_api_##n##_t_handler_uni, \
15410 vl_noop_handler, \
15411 vl_api_##n##_t_endian, \
15412 vl_api_##n##_t_print, \
15413 sizeof(vl_api_##n##_t), 1);
15414 foreach_vpe_api_reply_msg;
Dave Baracha1a093d2017-03-02 13:13:23 -050015415#if VPP_API_TEST_BUILTIN == 0
15416 foreach_standalone_reply_msg;
15417#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +010015418#undef _
15419
15420#if (VPP_API_TEST_BUILTIN==0)
15421 vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015422
15423 vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
15424
15425 vam->function_by_name = hash_create_string (0, sizeof (uword));
15426
15427 vam->help_by_name = hash_create_string (0, sizeof (uword));
Dave Barach45e4f362017-03-07 12:52:31 -050015428#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +010015429
15430 /* API messages we can send */
15431#define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
15432 foreach_vpe_api_msg;
15433#undef _
15434
15435 /* Help strings */
15436#define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
15437 foreach_vpe_api_msg;
15438#undef _
Damjan Marion7cd468a2016-12-19 23:05:39 +010015439
15440 /* CLI functions */
15441#define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
15442 foreach_cli_function;
15443#undef _
15444
15445 /* Help strings */
15446#define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
15447 foreach_cli_function;
15448#undef _
15449}
15450
Dave Baracha1a093d2017-03-02 13:13:23 -050015451#if VPP_API_TEST_BUILTIN
15452static clib_error_t *
15453vat_api_hookup_shim (vlib_main_t * vm)
15454{
15455 vat_api_hookup (&vat_main);
15456 return 0;
15457}
15458
15459VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
15460#endif
15461
Damjan Marion7cd468a2016-12-19 23:05:39 +010015462/*
15463 * fd.io coding-style-patch-verification: ON
15464 *
15465 * Local Variables:
15466 * eval: (c-set-style "gnu")
15467 * End:
15468 */