blob: a1c5e8ef5d828dda8077a096d67a5d8701e4964d [file] [log] [blame]
Damjan Marion7cd468a2016-12-19 23:05:39 +01001/*
2 *------------------------------------------------------------------
3 * api_format.c
4 *
Dave Barachac0326f2020-07-14 18:30:05 -04005 * Copyright (c) 2014-2020 Cisco and/or its affiliates.
Damjan Marion7cd468a2016-12-19 23:05:39 +01006 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at:
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *------------------------------------------------------------------
18 */
19
20#include <vat/vat.h>
jialv01082ebeb2019-09-10 00:23:55 +080021#include <vlib/pci/pci.h>
Neale Ranns86327be2018-11-02 09:14:01 -070022#include <vpp/api/types.h>
Dave Barach59b25652017-09-10 15:04:27 -040023#include <vppinfra/socket.h>
Damjan Marion7cd468a2016-12-19 23:05:39 +010024#include <vlibapi/api.h>
25#include <vlibmemory/api.h>
Damjan Marion7cd468a2016-12-19 23:05:39 +010026#include <vnet/ip/ip.h>
Neale Rannscbe25aa2019-09-30 10:53:31 +000027#include <vnet/ip-neighbor/ip_neighbor.h>
Neale Ranns37029302018-08-10 05:30:06 -070028#include <vnet/ip/ip_types_api.h>
Damjan Marion7cd468a2016-12-19 23:05:39 +010029#include <vnet/l2/l2_input.h>
Damjan Marion7cd468a2016-12-19 23:05:39 +010030#include <vnet/vxlan/vxlan.h>
Damjan Marion7cd468a2016-12-19 23:05:39 +010031#include <vnet/vxlan-gpe/vxlan_gpe.h>
Florin Corasb040f982020-10-20 14:59:43 -070032#include <vnet/udp/udp_local.h>
Damjan Marion7cd468a2016-12-19 23:05:39 +010033
34#include <vpp/api/vpe_msg_enum.h>
35#include <vnet/l2/l2_classify.h>
36#include <vnet/l2/l2_vtr.h>
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +010037#include <vnet/classify/in_out_acl.h>
Damjan Marion7cd468a2016-12-19 23:05:39 +010038#include <vnet/classify/policer_classify.h>
39#include <vnet/classify/flow_classify.h>
40#include <vnet/mpls/mpls.h>
41#include <vnet/ipsec/ipsec.h>
Damjan Marion7cd468a2016-12-19 23:05:39 +010042#include <inttypes.h>
Damjan Marion7cd468a2016-12-19 23:05:39 +010043#include <vnet/ip/ip6_hop_by_hop.h>
44#include <vnet/ip/ip_source_and_port_range_check.h>
45#include <vnet/policer/xlate.h>
46#include <vnet/span/span.h>
47#include <vnet/policer/policer.h>
48#include <vnet/policer/police.h>
Neale Ranns32e1c012016-11-22 17:07:28 +000049#include <vnet/mfib/mfib_types.h>
Steven9cd2d7a2017-12-20 12:43:01 -080050#include <vnet/bonding/node.h>
Igor Mikhailov (imichail)582caa32018-04-26 21:33:02 -070051#include <vnet/qos/qos_types.h>
Neale Ranns37029302018-08-10 05:30:06 -070052#include <vnet/ethernet/ethernet_types_api.h>
53#include <vnet/ip/ip_types_api.h>
Damjan Marion7cd468a2016-12-19 23:05:39 +010054#include "vat/json_format.h"
Neale Ranns86327be2018-11-02 09:14:01 -070055#include <vnet/ip/ip_types_api.h>
56#include <vnet/ethernet/ethernet_types_api.h>
Damjan Marion7cd468a2016-12-19 23:05:39 +010057
58#include <inttypes.h>
59#include <sys/stat.h>
60
61#define vl_typedefs /* define message structures */
62#include <vpp/api/vpe_all_api_h.h>
63#undef vl_typedefs
64
65/* declare message handlers for each api */
66
67#define vl_endianfun /* define message structures */
68#include <vpp/api/vpe_all_api_h.h>
69#undef vl_endianfun
70
71/* instantiate all the print functions we know about */
Dave Barachf35a0722019-06-12 16:50:38 -040072#if VPP_API_TEST_BUILTIN == 0
Damjan Marion7cd468a2016-12-19 23:05:39 +010073#define vl_print(handle, ...)
Dave Barachf35a0722019-06-12 16:50:38 -040074#else
75#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
76#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +010077#define vl_printfun
78#include <vpp/api/vpe_all_api_h.h>
79#undef vl_printfun
80
Dave Barach2d6b2d62017-01-25 16:32:08 -050081#define __plugin_msg_base 0
Dave Barachfe6bdfd2017-01-20 19:50:09 -050082#include <vlibapi/vat_helper_macros.h>
83
Ole Troan33a58172019-09-04 09:12:29 +020084#include <vnet/format_fns.h>
85
Dave Barachb09f4d02019-07-15 16:00:03 -040086void vl_api_set_elog_main (elog_main_t * m);
87int vl_api_set_elog_trace_api_messages (int enable);
88
Dave Barach59b25652017-09-10 15:04:27 -040089#if VPP_API_TEST_BUILTIN == 0
90#include <netdb.h>
91
92u32
93vl (void *p)
94{
95 return vec_len (p);
96}
97
98int
99vat_socket_connect (vat_main_t * vam)
100{
Florin Coras66a10032018-12-21 16:23:09 -0800101 int rv;
Dave Barach69eeadc2020-04-14 09:52:26 -0400102 api_main_t *am = vlibapi_get_main ();
Florin Coras90a63982017-12-19 04:50:01 -0800103 vam->socket_client_main = &socket_client_main;
Florin Coras66a10032018-12-21 16:23:09 -0800104 if ((rv = vl_socket_client_connect ((char *) vam->socket_name,
105 "vpp_api_test",
106 0 /* default socket rx, tx buffer */ )))
107 return rv;
Dave Barach69eeadc2020-04-14 09:52:26 -0400108
Florin Coras66a10032018-12-21 16:23:09 -0800109 /* vpp expects the client index in network order */
110 vam->my_client_index = htonl (socket_client_main.client_index);
Dave Barach69eeadc2020-04-14 09:52:26 -0400111 am->my_client_index = vam->my_client_index;
Florin Coras66a10032018-12-21 16:23:09 -0800112 return 0;
Dave Barach59b25652017-09-10 15:04:27 -0400113}
114#else /* vpp built-in case, we don't do sockets... */
115int
116vat_socket_connect (vat_main_t * vam)
117{
118 return 0;
119}
120
Florin Coras90a63982017-12-19 04:50:01 -0800121int
122vl_socket_client_read (int wait)
Dave Barach59b25652017-09-10 15:04:27 -0400123{
Florin Coras90a63982017-12-19 04:50:01 -0800124 return -1;
Dave Barach59b25652017-09-10 15:04:27 -0400125};
Florin Coras90a63982017-12-19 04:50:01 -0800126
127int
128vl_socket_client_write ()
129{
130 return -1;
131};
132
133void *
134vl_socket_client_msg_alloc (int nbytes)
135{
136 return 0;
137}
Dave Barach59b25652017-09-10 15:04:27 -0400138#endif
139
140
Dave Barachfe6bdfd2017-01-20 19:50:09 -0500141f64
142vat_time_now (vat_main_t * vam)
143{
144#if VPP_API_TEST_BUILTIN
145 return vlib_time_now (vam->vlib_main);
146#else
147 return clib_time_now (&vam->clib_time);
148#endif
149}
150
151void
152errmsg (char *fmt, ...)
153{
154 vat_main_t *vam = &vat_main;
155 va_list va;
156 u8 *s;
157
158 va_start (va, fmt);
159 s = va_format (0, fmt, &va);
160 va_end (va);
161
162 vec_add1 (s, 0);
163
164#if VPP_API_TEST_BUILTIN
165 vlib_cli_output (vam->vlib_main, (char *) s);
166#else
167 {
168 if (vam->ifp != stdin)
169 fformat (vam->ofp, "%s(%d): \n", vam->current_file,
170 vam->input_line_number);
Dave Barachb09f4d02019-07-15 16:00:03 -0400171 else
172 fformat (vam->ofp, "%s\n", (char *) s);
Dave Barachfe6bdfd2017-01-20 19:50:09 -0500173 fflush (vam->ofp);
174 }
175#endif
176
177 vec_free (s);
178}
179
Dave Barach4a3f69c2017-02-22 12:44:56 -0500180#if VPP_API_TEST_BUILTIN == 0
Damjan Marion7cd468a2016-12-19 23:05:39 +0100181static uword
182api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
183{
184 vat_main_t *vam = va_arg (*args, vat_main_t *);
185 u32 *result = va_arg (*args, u32 *);
186 u8 *if_name;
187 uword *p;
188
189 if (!unformat (input, "%s", &if_name))
190 return 0;
191
192 p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
193 if (p == 0)
194 return 0;
195 *result = p[0];
196 return 1;
197}
198
eyal bariaf86a482018-04-17 11:20:27 +0300199static uword
200api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
201{
202 return 0;
203}
204
Damjan Marion7cd468a2016-12-19 23:05:39 +0100205/* Parse an IP4 address %d.%d.%d.%d. */
206uword
207unformat_ip4_address (unformat_input_t * input, va_list * args)
208{
209 u8 *result = va_arg (*args, u8 *);
210 unsigned a[4];
211
212 if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
213 return 0;
214
215 if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
216 return 0;
217
218 result[0] = a[0];
219 result[1] = a[1];
220 result[2] = a[2];
221 result[3] = a[3];
222
223 return 1;
224}
225
226uword
227unformat_ethernet_address (unformat_input_t * input, va_list * args)
228{
229 u8 *result = va_arg (*args, u8 *);
230 u32 i, a[6];
231
232 if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
233 &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
234 return 0;
235
236 /* Check range. */
237 for (i = 0; i < 6; i++)
238 if (a[i] >= (1 << 8))
239 return 0;
240
241 for (i = 0; i < 6; i++)
242 result[i] = a[i];
243
244 return 1;
245}
246
247/* Returns ethernet type as an int in host byte order. */
248uword
249unformat_ethernet_type_host_byte_order (unformat_input_t * input,
250 va_list * args)
251{
252 u16 *result = va_arg (*args, u16 *);
253 int type;
254
255 /* Numeric type. */
256 if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
257 {
258 if (type >= (1 << 16))
259 return 0;
260 *result = type;
261 return 1;
262 }
263 return 0;
264}
265
Jakub Grajciar23a386b2020-02-26 11:01:43 +0100266/* Parse an IP46 address. */
267uword
268unformat_ip46_address (unformat_input_t * input, va_list * args)
269{
270 ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
271 ip46_type_t type = va_arg (*args, ip46_type_t);
272 if ((type != IP46_TYPE_IP6) &&
273 unformat (input, "%U", unformat_ip4_address, &ip46->ip4))
274 {
275 ip46_address_mask_ip4 (ip46);
276 return 1;
277 }
278 else if ((type != IP46_TYPE_IP4) &&
279 unformat (input, "%U", unformat_ip6_address, &ip46->ip6))
280 {
281 return 1;
282 }
283 return 0;
284}
285
Damjan Marion7cd468a2016-12-19 23:05:39 +0100286/* Parse an IP6 address. */
287uword
288unformat_ip6_address (unformat_input_t * input, va_list * args)
289{
290 ip6_address_t *result = va_arg (*args, ip6_address_t *);
291 u16 hex_quads[8];
292 uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
293 uword c, n_colon, double_colon_index;
294
295 n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
296 double_colon_index = ARRAY_LEN (hex_quads);
297 while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
298 {
299 hex_digit = 16;
300 if (c >= '0' && c <= '9')
301 hex_digit = c - '0';
302 else if (c >= 'a' && c <= 'f')
303 hex_digit = c + 10 - 'a';
304 else if (c >= 'A' && c <= 'F')
305 hex_digit = c + 10 - 'A';
306 else if (c == ':' && n_colon < 2)
307 n_colon++;
308 else
309 {
310 unformat_put_input (input);
311 break;
312 }
313
314 /* Too many hex quads. */
315 if (n_hex_quads >= ARRAY_LEN (hex_quads))
316 return 0;
317
318 if (hex_digit < 16)
319 {
320 hex_quad = (hex_quad << 4) | hex_digit;
321
322 /* Hex quad must fit in 16 bits. */
323 if (n_hex_digits >= 4)
324 return 0;
325
326 n_colon = 0;
327 n_hex_digits++;
328 }
329
330 /* Save position of :: */
331 if (n_colon == 2)
332 {
333 /* More than one :: ? */
334 if (double_colon_index < ARRAY_LEN (hex_quads))
335 return 0;
336 double_colon_index = n_hex_quads;
337 }
338
339 if (n_colon > 0 && n_hex_digits > 0)
340 {
341 hex_quads[n_hex_quads++] = hex_quad;
342 hex_quad = 0;
343 n_hex_digits = 0;
344 }
345 }
346
347 if (n_hex_digits > 0)
348 hex_quads[n_hex_quads++] = hex_quad;
349
350 {
351 word i;
352
353 /* Expand :: to appropriate number of zero hex quads. */
354 if (double_colon_index < ARRAY_LEN (hex_quads))
355 {
356 word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
357
358 for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
359 hex_quads[n_zero + i] = hex_quads[i];
360
361 for (i = 0; i < n_zero; i++)
362 hex_quads[double_colon_index + i] = 0;
363
364 n_hex_quads = ARRAY_LEN (hex_quads);
365 }
366
367 /* Too few hex quads given. */
368 if (n_hex_quads < ARRAY_LEN (hex_quads))
369 return 0;
370
371 for (i = 0; i < ARRAY_LEN (hex_quads); i++)
372 result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
373
374 return 1;
375 }
376}
377
378uword
379unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
380{
381 u32 *r = va_arg (*args, u32 *);
382
383 if (0);
384#define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
385 foreach_ipsec_policy_action
386#undef _
387 else
388 return 0;
389 return 1;
390}
391
Damjan Marion7cd468a2016-12-19 23:05:39 +0100392u8 *
393format_ipsec_crypto_alg (u8 * s, va_list * args)
394{
395 u32 i = va_arg (*args, u32);
396 u8 *t = 0;
397
398 switch (i)
399 {
400#define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
401 foreach_ipsec_crypto_alg
402#undef _
403 default:
404 return format (s, "unknown");
405 }
406 return format (s, "%s", t);
407}
408
Damjan Marion7cd468a2016-12-19 23:05:39 +0100409u8 *
410format_ipsec_integ_alg (u8 * s, va_list * args)
411{
412 u32 i = va_arg (*args, u32);
413 u8 *t = 0;
414
415 switch (i)
416 {
417#define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
418 foreach_ipsec_integ_alg
419#undef _
420 default:
421 return format (s, "unknown");
422 }
423 return format (s, "%s", t);
424}
425
Dave Barach4a3f69c2017-02-22 12:44:56 -0500426#else /* VPP_API_TEST_BUILTIN == 1 */
427static uword
428api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
429{
Benoît Ganne49ee6842019-04-30 11:50:46 +0200430 vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
Dave Barach4a3f69c2017-02-22 12:44:56 -0500431 vnet_main_t *vnm = vnet_get_main ();
432 u32 *result = va_arg (*args, u32 *);
Dave Barach4a3f69c2017-02-22 12:44:56 -0500433
eyal bariaf86a482018-04-17 11:20:27 +0300434 return unformat (input, "%U", unformat_vnet_sw_interface, vnm, result);
Dave Barach4a3f69c2017-02-22 12:44:56 -0500435}
eyal bariaf86a482018-04-17 11:20:27 +0300436
437static uword
438api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
439{
Benoît Ganne49ee6842019-04-30 11:50:46 +0200440 vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
eyal bariaf86a482018-04-17 11:20:27 +0300441 vnet_main_t *vnm = vnet_get_main ();
442 u32 *result = va_arg (*args, u32 *);
443
444 return unformat (input, "%U", unformat_vnet_hw_interface, vnm, result);
445}
446
Damjan Marion7cd468a2016-12-19 23:05:39 +0100447#endif /* VPP_API_TEST_BUILTIN */
448
Neale Ranns17dcec02019-01-09 21:22:20 -0800449uword
450unformat_ipsec_api_crypto_alg (unformat_input_t * input, va_list * args)
451{
452 u32 *r = va_arg (*args, u32 *);
453
454 if (0);
455#define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_CRYPTO_ALG_##f;
456 foreach_ipsec_crypto_alg
457#undef _
458 else
459 return 0;
460 return 1;
461}
462
463uword
464unformat_ipsec_api_integ_alg (unformat_input_t * input, va_list * args)
465{
466 u32 *r = va_arg (*args, u32 *);
467
468 if (0);
469#define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_INTEG_ALG_##f;
470 foreach_ipsec_integ_alg
471#undef _
472 else
473 return 0;
474 return 1;
475}
476
Damjan Marion7cd468a2016-12-19 23:05:39 +0100477static uword
478unformat_policer_rate_type (unformat_input_t * input, va_list * args)
479{
480 u8 *r = va_arg (*args, u8 *);
481
482 if (unformat (input, "kbps"))
Brian Russellc5299ff2021-02-09 10:16:58 +0000483 *r = QOS_RATE_KBPS;
Damjan Marion7cd468a2016-12-19 23:05:39 +0100484 else if (unformat (input, "pps"))
Brian Russellc5299ff2021-02-09 10:16:58 +0000485 *r = QOS_RATE_PPS;
Damjan Marion7cd468a2016-12-19 23:05:39 +0100486 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"))
Brian Russellc5299ff2021-02-09 10:16:58 +0000497 *r = QOS_ROUND_TO_CLOSEST;
Damjan Marion7cd468a2016-12-19 23:05:39 +0100498 else if (unformat (input, "up"))
Brian Russellc5299ff2021-02-09 10:16:58 +0000499 *r = QOS_ROUND_TO_UP;
Damjan Marion7cd468a2016-12-19 23:05:39 +0100500 else if (unformat (input, "down"))
Brian Russellc5299ff2021-02-09 10:16:58 +0000501 *r = QOS_ROUND_TO_DOWN;
Damjan Marion7cd468a2016-12-19 23:05:39 +0100502 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"))
Brian Russellc5299ff2021-02-09 10:16:58 +0000513 *r = QOS_POLICER_TYPE_1R2C;
Damjan Marion7cd468a2016-12-19 23:05:39 +0100514 else if (unformat (input, "1r3c"))
Brian Russellc5299ff2021-02-09 10:16:58 +0000515 *r = QOS_POLICER_TYPE_1R3C_RFC_2697;
Damjan Marion7cd468a2016-12-19 23:05:39 +0100516 else if (unformat (input, "2r3c-2698"))
Brian Russellc5299ff2021-02-09 10:16:58 +0000517 *r = QOS_POLICER_TYPE_2R3C_RFC_2698;
Damjan Marion7cd468a2016-12-19 23:05:39 +0100518 else if (unformat (input, "2r3c-4115"))
Brian Russellc5299ff2021-02-09 10:16:58 +0000519 *r = QOS_POLICER_TYPE_2R3C_RFC_4115;
Damjan Marion7cd468a2016-12-19 23:05:39 +0100520 else if (unformat (input, "2r3c-mef5cf1"))
Brian Russellc5299ff2021-02-09 10:16:58 +0000521 *r = QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
Damjan Marion7cd468a2016-12-19 23:05:39 +0100522 else
523 return 0;
524 return 1;
525}
526
527static uword
528unformat_dscp (unformat_input_t * input, va_list * va)
529{
530 u8 *r = va_arg (*va, u8 *);
531
532 if (0);
Brian Russelle3845d72021-02-08 15:33:18 +0000533#define _(v, f) else if (unformat (input, #f)) *r = IP_DSCP_##f;
534 foreach_ip_dscp
Damjan Marion7cd468a2016-12-19 23:05:39 +0100535#undef _
Brian Russelle3845d72021-02-08 15:33:18 +0000536 else return 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +0100537 return 1;
538}
539
540static uword
541unformat_policer_action_type (unformat_input_t * input, va_list * va)
542{
Brian Russellc5299ff2021-02-09 10:16:58 +0000543 qos_pol_action_params_st *a = va_arg (*va, qos_pol_action_params_st *);
Damjan Marion7cd468a2016-12-19 23:05:39 +0100544
545 if (unformat (input, "drop"))
Brian Russellc5299ff2021-02-09 10:16:58 +0000546 a->action_type = QOS_ACTION_DROP;
Damjan Marion7cd468a2016-12-19 23:05:39 +0100547 else if (unformat (input, "transmit"))
Brian Russellc5299ff2021-02-09 10:16:58 +0000548 a->action_type = QOS_ACTION_TRANSMIT;
Damjan Marion7cd468a2016-12-19 23:05:39 +0100549 else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
Brian Russellc5299ff2021-02-09 10:16:58 +0000550 a->action_type = QOS_ACTION_MARK_AND_TRANSMIT;
Damjan Marion7cd468a2016-12-19 23:05:39 +0100551 else
552 return 0;
553 return 1;
554}
555
556static uword
557unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
558{
559 u32 *r = va_arg (*va, u32 *);
560 u32 tid;
561
562 if (unformat (input, "ip4"))
563 tid = POLICER_CLASSIFY_TABLE_IP4;
564 else if (unformat (input, "ip6"))
565 tid = POLICER_CLASSIFY_TABLE_IP6;
566 else if (unformat (input, "l2"))
567 tid = POLICER_CLASSIFY_TABLE_L2;
568 else
569 return 0;
570
571 *r = tid;
572 return 1;
573}
574
575static uword
576unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
577{
578 u32 *r = va_arg (*va, u32 *);
579 u32 tid;
580
581 if (unformat (input, "ip4"))
582 tid = FLOW_CLASSIFY_TABLE_IP4;
583 else if (unformat (input, "ip6"))
584 tid = FLOW_CLASSIFY_TABLE_IP6;
585 else
586 return 0;
587
588 *r = tid;
589 return 1;
590}
591
Benoît Ganne49ee6842019-04-30 11:50:46 +0200592#if (VPP_API_TEST_BUILTIN==0)
593
Neale Ranns32e1c012016-11-22 17:07:28 +0000594static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
595static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
596static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
597static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
598
599uword
600unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
601{
602 mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
603 mfib_itf_attribute_t attr;
604
605 old = *iflags;
606 FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
607 {
608 if (unformat (input, mfib_itf_flag_long_names[attr]))
609 *iflags |= (1 << attr);
610 }
611 FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
612 {
613 if (unformat (input, mfib_itf_flag_names[attr]))
614 *iflags |= (1 << attr);
615 }
616
617 return (old == *iflags ? 0 : 1);
618}
619
620uword
621unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
622{
623 mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
624 mfib_entry_attribute_t attr;
625
626 old = *eflags;
627 FOR_EACH_MFIB_ATTRIBUTE (attr)
628 {
629 if (unformat (input, mfib_flag_long_names[attr]))
630 *eflags |= (1 << attr);
631 }
632 FOR_EACH_MFIB_ATTRIBUTE (attr)
633 {
634 if (unformat (input, mfib_flag_names[attr]))
635 *eflags |= (1 << attr);
636 }
637
638 return (old == *eflags ? 0 : 1);
639}
640
Damjan Marion7cd468a2016-12-19 23:05:39 +0100641u8 *
642format_ip4_address (u8 * s, va_list * args)
643{
644 u8 *a = va_arg (*args, u8 *);
645 return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
646}
647
648u8 *
649format_ip6_address (u8 * s, va_list * args)
650{
651 ip6_address_t *a = va_arg (*args, ip6_address_t *);
652 u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
653
654 i_max_n_zero = ARRAY_LEN (a->as_u16);
655 max_n_zeros = 0;
656 i_first_zero = i_max_n_zero;
657 n_zeros = 0;
658 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
659 {
660 u32 is_zero = a->as_u16[i] == 0;
661 if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
662 {
663 i_first_zero = i;
664 n_zeros = 0;
665 }
666 n_zeros += is_zero;
667 if ((!is_zero && n_zeros > max_n_zeros)
668 || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
669 {
670 i_max_n_zero = i_first_zero;
671 max_n_zeros = n_zeros;
672 i_first_zero = ARRAY_LEN (a->as_u16);
673 n_zeros = 0;
674 }
675 }
676
677 last_double_colon = 0;
678 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
679 {
680 if (i == i_max_n_zero && max_n_zeros > 1)
681 {
682 s = format (s, "::");
683 i += max_n_zeros - 1;
684 last_double_colon = 1;
685 }
686 else
687 {
688 s = format (s, "%s%x",
689 (last_double_colon || i == 0) ? "" : ":",
690 clib_net_to_host_u16 (a->as_u16[i]));
691 last_double_colon = 0;
692 }
693 }
694
695 return s;
696}
697
698/* Format an IP46 address. */
699u8 *
700format_ip46_address (u8 * s, va_list * args)
701{
702 ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
703 ip46_type_t type = va_arg (*args, ip46_type_t);
704 int is_ip4 = 1;
705
706 switch (type)
707 {
708 case IP46_TYPE_ANY:
709 is_ip4 = ip46_address_is_ip4 (ip46);
710 break;
711 case IP46_TYPE_IP4:
712 is_ip4 = 1;
713 break;
714 case IP46_TYPE_IP6:
715 is_ip4 = 0;
716 break;
717 }
718
719 return is_ip4 ?
720 format (s, "%U", format_ip4_address, &ip46->ip4) :
721 format (s, "%U", format_ip6_address, &ip46->ip6);
722}
723
724u8 *
725format_ethernet_address (u8 * s, va_list * args)
726{
727 u8 *a = va_arg (*args, u8 *);
728
729 return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
730 a[0], a[1], a[2], a[3], a[4], a[5]);
731}
732#endif
733
734static void
Neale Ranns097fa662018-05-01 05:17:55 -0700735increment_v4_address (vl_api_ip4_address_t * i)
Damjan Marion7cd468a2016-12-19 23:05:39 +0100736{
Neale Ranns097fa662018-05-01 05:17:55 -0700737 ip4_address_t *a = (ip4_address_t *) i;
Damjan Marion7cd468a2016-12-19 23:05:39 +0100738 u32 v;
739
740 v = ntohl (a->as_u32) + 1;
741 a->as_u32 = ntohl (v);
742}
743
744static void
Neale Ranns097fa662018-05-01 05:17:55 -0700745increment_v6_address (vl_api_ip6_address_t * i)
Neale Ranns2b5ba952019-04-02 10:15:40 +0000746{
Neale Ranns097fa662018-05-01 05:17:55 -0700747 ip6_address_t *a = (ip6_address_t *) i;
Damjan Marion7cd468a2016-12-19 23:05:39 +0100748 u64 v0, v1;
749
750 v0 = clib_net_to_host_u64 (a->as_u64[0]);
751 v1 = clib_net_to_host_u64 (a->as_u64[1]);
752
753 v1 += 1;
754 if (v1 == 0)
755 v0 += 1;
756 a->as_u64[0] = clib_net_to_host_u64 (v0);
757 a->as_u64[1] = clib_net_to_host_u64 (v1);
758}
759
760static void
Neale Ranns097fa662018-05-01 05:17:55 -0700761increment_address (vl_api_address_t * a)
762{
Dave Barach54582662020-04-21 08:01:16 -0400763 if (a->af == ADDRESS_IP4)
Neale Ranns097fa662018-05-01 05:17:55 -0700764 increment_v4_address (&a->un.ip4);
Dave Barach54582662020-04-21 08:01:16 -0400765 else if (a->af == ADDRESS_IP6)
Neale Ranns097fa662018-05-01 05:17:55 -0700766 increment_v6_address (&a->un.ip6);
767}
768
769static void
770set_ip4_address (vl_api_address_t * a, u32 v)
771{
772 if (a->af == ADDRESS_IP4)
773 {
774 ip4_address_t *i = (ip4_address_t *) & a->un.ip4;
775 i->as_u32 = v;
776 }
777}
778
Jakub Grajciar23a386b2020-02-26 11:01:43 +0100779void
780ip_set (ip46_address_t * dst, void *src, u8 is_ip4)
781{
782 if (is_ip4)
783 dst->ip4.as_u32 = ((ip4_address_t *) src)->as_u32;
784 else
785 clib_memcpy_fast (&dst->ip6, (ip6_address_t *) src,
786 sizeof (ip6_address_t));
787}
788
Neale Ranns097fa662018-05-01 05:17:55 -0700789static void
Mohsin Kazmi57938f62017-10-27 21:28:07 +0200790increment_mac_address (u8 * mac)
Damjan Marion7cd468a2016-12-19 23:05:39 +0100791{
Mohsin Kazmi57938f62017-10-27 21:28:07 +0200792 u64 tmp = *((u64 *) mac);
Damjan Marion7cd468a2016-12-19 23:05:39 +0100793 tmp = clib_net_to_host_u64 (tmp);
794 tmp += 1 << 16; /* skip unused (least significant) octets */
795 tmp = clib_host_to_net_u64 (tmp);
Mohsin Kazmi57938f62017-10-27 21:28:07 +0200796
797 clib_memcpy (mac, &tmp, 6);
Damjan Marion7cd468a2016-12-19 23:05:39 +0100798}
799
Neale Ranns097fa662018-05-01 05:17:55 -0700800static void
801vat_json_object_add_address (vat_json_node_t * node,
802 const char *str, const vl_api_address_t * addr)
803{
804 if (ADDRESS_IP6 == addr->af)
805 {
806 struct in6_addr ip6;
807
808 clib_memcpy (&ip6, &addr->un.ip6, sizeof (ip6));
809 vat_json_object_add_ip6 (node, str, ip6);
810 }
811 else
812 {
813 struct in_addr ip4;
814
815 clib_memcpy (&ip4, &addr->un.ip4, sizeof (ip4));
816 vat_json_object_add_ip4 (node, str, ip4);
817 }
818}
819
820static void
821vat_json_object_add_prefix (vat_json_node_t * node,
822 const vl_api_prefix_t * prefix)
823{
Paul Vinciguerraab055082019-06-06 14:07:55 -0400824 vat_json_object_add_uint (node, "len", prefix->len);
825 vat_json_object_add_address (node, "address", &prefix->address);
Neale Ranns097fa662018-05-01 05:17:55 -0700826}
827
Damjan Marion7cd468a2016-12-19 23:05:39 +0100828static void vl_api_create_loopback_reply_t_handler
829 (vl_api_create_loopback_reply_t * mp)
830{
831 vat_main_t *vam = &vat_main;
832 i32 retval = ntohl (mp->retval);
833
834 vam->retval = retval;
835 vam->regenerate_interface_table = 1;
836 vam->sw_if_index = ntohl (mp->sw_if_index);
837 vam->result_ready = 1;
838}
839
840static void vl_api_create_loopback_reply_t_handler_json
841 (vl_api_create_loopback_reply_t * mp)
842{
843 vat_main_t *vam = &vat_main;
844 vat_json_node_t node;
845
846 vat_json_init_object (&node);
847 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
848 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
849
850 vat_json_print (vam->ofp, &node);
851 vat_json_free (&node);
852 vam->retval = ntohl (mp->retval);
853 vam->result_ready = 1;
854}
855
Jon Loeligerc83c3b72017-02-23 13:57:35 -0600856static void vl_api_create_loopback_instance_reply_t_handler
857 (vl_api_create_loopback_instance_reply_t * mp)
858{
859 vat_main_t *vam = &vat_main;
860 i32 retval = ntohl (mp->retval);
861
862 vam->retval = retval;
863 vam->regenerate_interface_table = 1;
864 vam->sw_if_index = ntohl (mp->sw_if_index);
865 vam->result_ready = 1;
866}
867
868static void vl_api_create_loopback_instance_reply_t_handler_json
869 (vl_api_create_loopback_instance_reply_t * mp)
870{
871 vat_main_t *vam = &vat_main;
872 vat_json_node_t node;
873
874 vat_json_init_object (&node);
875 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
876 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
877
878 vat_json_print (vam->ofp, &node);
879 vat_json_free (&node);
880 vam->retval = ntohl (mp->retval);
881 vam->result_ready = 1;
882}
883
Damjan Marion7cd468a2016-12-19 23:05:39 +0100884static void vl_api_af_packet_create_reply_t_handler
885 (vl_api_af_packet_create_reply_t * mp)
886{
887 vat_main_t *vam = &vat_main;
888 i32 retval = ntohl (mp->retval);
889
890 vam->retval = retval;
891 vam->regenerate_interface_table = 1;
892 vam->sw_if_index = ntohl (mp->sw_if_index);
893 vam->result_ready = 1;
894}
895
896static void vl_api_af_packet_create_reply_t_handler_json
897 (vl_api_af_packet_create_reply_t * mp)
898{
899 vat_main_t *vam = &vat_main;
900 vat_json_node_t node;
901
902 vat_json_init_object (&node);
903 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
904 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
905
906 vat_json_print (vam->ofp, &node);
907 vat_json_free (&node);
908
909 vam->retval = ntohl (mp->retval);
910 vam->result_ready = 1;
911}
912
913static void vl_api_create_vlan_subif_reply_t_handler
914 (vl_api_create_vlan_subif_reply_t * mp)
915{
916 vat_main_t *vam = &vat_main;
917 i32 retval = ntohl (mp->retval);
918
919 vam->retval = retval;
920 vam->regenerate_interface_table = 1;
921 vam->sw_if_index = ntohl (mp->sw_if_index);
922 vam->result_ready = 1;
923}
924
925static void vl_api_create_vlan_subif_reply_t_handler_json
926 (vl_api_create_vlan_subif_reply_t * mp)
927{
928 vat_main_t *vam = &vat_main;
929 vat_json_node_t node;
930
931 vat_json_init_object (&node);
932 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
933 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
934
935 vat_json_print (vam->ofp, &node);
936 vat_json_free (&node);
937
938 vam->retval = ntohl (mp->retval);
939 vam->result_ready = 1;
940}
941
942static void vl_api_create_subif_reply_t_handler
943 (vl_api_create_subif_reply_t * mp)
944{
945 vat_main_t *vam = &vat_main;
946 i32 retval = ntohl (mp->retval);
947
948 vam->retval = retval;
949 vam->regenerate_interface_table = 1;
950 vam->sw_if_index = ntohl (mp->sw_if_index);
951 vam->result_ready = 1;
952}
953
954static void vl_api_create_subif_reply_t_handler_json
955 (vl_api_create_subif_reply_t * mp)
956{
957 vat_main_t *vam = &vat_main;
958 vat_json_node_t node;
959
960 vat_json_init_object (&node);
961 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
962 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
963
964 vat_json_print (vam->ofp, &node);
965 vat_json_free (&node);
966
967 vam->retval = ntohl (mp->retval);
968 vam->result_ready = 1;
969}
970
971static void vl_api_interface_name_renumber_reply_t_handler
972 (vl_api_interface_name_renumber_reply_t * mp)
973{
974 vat_main_t *vam = &vat_main;
975 i32 retval = ntohl (mp->retval);
976
977 vam->retval = retval;
978 vam->regenerate_interface_table = 1;
979 vam->result_ready = 1;
980}
981
982static void vl_api_interface_name_renumber_reply_t_handler_json
983 (vl_api_interface_name_renumber_reply_t * mp)
984{
985 vat_main_t *vam = &vat_main;
986 vat_json_node_t node;
987
988 vat_json_init_object (&node);
989 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
990
991 vat_json_print (vam->ofp, &node);
992 vat_json_free (&node);
993
994 vam->retval = ntohl (mp->retval);
995 vam->result_ready = 1;
996}
997
998/*
999 * Special-case: build the interface table, maintain
1000 * the next loopback sw_if_index vbl.
1001 */
1002static void vl_api_sw_interface_details_t_handler
1003 (vl_api_sw_interface_details_t * mp)
1004{
1005 vat_main_t *vam = &vat_main;
Ole Troane5ff5a32019-08-23 22:55:18 +02001006 u8 *s = format (0, "%s%c", mp->interface_name, 0);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001007
1008 hash_set_mem (vam->sw_if_index_by_interface_name, s,
1009 ntohl (mp->sw_if_index));
1010
1011 /* In sub interface case, fill the sub interface table entry */
1012 if (mp->sw_if_index != mp->sup_sw_if_index)
1013 {
1014 sw_interface_subif_t *sub = NULL;
1015
1016 vec_add2 (vam->sw_if_subif_table, sub, 1);
1017
1018 vec_validate (sub->interface_name, strlen ((char *) s) + 1);
1019 strncpy ((char *) sub->interface_name, (char *) s,
1020 vec_len (sub->interface_name));
1021 sub->sw_if_index = ntohl (mp->sw_if_index);
1022 sub->sub_id = ntohl (mp->sub_id);
1023
Jakub Grajciar053204a2019-03-18 13:17:53 +01001024 sub->raw_flags = ntohl (mp->sub_if_flags & SUB_IF_API_FLAG_MASK_VNET);
1025
Damjan Marion7cd468a2016-12-19 23:05:39 +01001026 sub->sub_number_of_tags = mp->sub_number_of_tags;
1027 sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
1028 sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001029
1030 /* vlan tag rewrite */
1031 sub->vtr_op = ntohl (mp->vtr_op);
1032 sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
1033 sub->vtr_tag1 = ntohl (mp->vtr_tag1);
1034 sub->vtr_tag2 = ntohl (mp->vtr_tag2);
1035 }
1036}
1037
1038static void vl_api_sw_interface_details_t_handler_json
1039 (vl_api_sw_interface_details_t * mp)
1040{
1041 vat_main_t *vam = &vat_main;
1042 vat_json_node_t *node = NULL;
1043
1044 if (VAT_JSON_ARRAY != vam->json_tree.type)
1045 {
1046 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1047 vat_json_init_array (&vam->json_tree);
1048 }
1049 node = vat_json_array_add (&vam->json_tree);
1050
1051 vat_json_init_object (node);
1052 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1053 vat_json_object_add_uint (node, "sup_sw_if_index",
1054 ntohl (mp->sup_sw_if_index));
Damjan Marion7cd468a2016-12-19 23:05:39 +01001055 vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
1056 sizeof (mp->l2_address));
1057 vat_json_object_add_string_copy (node, "interface_name",
Ole Troane5ff5a32019-08-23 22:55:18 +02001058 mp->interface_name);
Mohsin Kazmide312c22019-09-27 13:44:28 +02001059 vat_json_object_add_string_copy (node, "interface_dev_type",
1060 mp->interface_dev_type);
Jakub Grajciar053204a2019-03-18 13:17:53 +01001061 vat_json_object_add_uint (node, "flags", mp->flags);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001062 vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
1063 vat_json_object_add_uint (node, "link_speed", mp->link_speed);
Damjan Marionfe7d4a22018-04-13 19:43:39 +02001064 vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
Damjan Marion7cd468a2016-12-19 23:05:39 +01001065 vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
Damjan Marion7cd468a2016-12-19 23:05:39 +01001066 vat_json_object_add_uint (node, "sub_number_of_tags",
1067 mp->sub_number_of_tags);
1068 vat_json_object_add_uint (node, "sub_outer_vlan_id",
1069 ntohs (mp->sub_outer_vlan_id));
1070 vat_json_object_add_uint (node, "sub_inner_vlan_id",
1071 ntohs (mp->sub_inner_vlan_id));
Jakub Grajciar053204a2019-03-18 13:17:53 +01001072 vat_json_object_add_uint (node, "sub_if_flags", ntohl (mp->sub_if_flags));
Damjan Marion7cd468a2016-12-19 23:05:39 +01001073 vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1074 vat_json_object_add_uint (node, "vtr_push_dot1q",
1075 ntohl (mp->vtr_push_dot1q));
1076 vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1077 vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
Jakub Grajciar053204a2019-03-18 13:17:53 +01001078 if (ntohl (mp->sub_if_flags) & SUB_IF_API_FLAG_DOT1AH)
Pavel Kotucek65e84572017-01-16 17:01:56 +01001079 {
1080 vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1081 format (0, "%U",
1082 format_ethernet_address,
1083 &mp->b_dmac));
1084 vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1085 format (0, "%U",
1086 format_ethernet_address,
1087 &mp->b_smac));
1088 vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1089 vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1090 }
Damjan Marion7cd468a2016-12-19 23:05:39 +01001091}
1092
Dave Baracha1a093d2017-03-02 13:13:23 -05001093#if VPP_API_TEST_BUILTIN == 0
Neale Rannsa07bd702017-08-07 07:53:49 -07001094static void vl_api_sw_interface_event_t_handler
1095 (vl_api_sw_interface_event_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01001096{
1097 vat_main_t *vam = &vat_main;
1098 if (vam->interface_event_display)
1099 errmsg ("interface flags: sw_if_index %d %s %s",
1100 ntohl (mp->sw_if_index),
Jakub Grajciar053204a2019-03-18 13:17:53 +01001101 ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_ADMIN_UP) ?
1102 "admin-up" : "admin-down",
1103 ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_LINK_UP) ?
1104 "link-up" : "link-down");
Damjan Marion7cd468a2016-12-19 23:05:39 +01001105}
Dave Baracha1a093d2017-03-02 13:13:23 -05001106#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +01001107
Benoît Ganne49ee6842019-04-30 11:50:46 +02001108__clib_unused static void
1109vl_api_sw_interface_event_t_handler_json (vl_api_sw_interface_event_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01001110{
1111 /* JSON output not supported */
1112}
1113
1114static void
1115vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1116{
1117 vat_main_t *vam = &vat_main;
1118 i32 retval = ntohl (mp->retval);
1119
1120 vam->retval = retval;
Damjan Marion7bee80c2017-04-26 15:32:12 +02001121 vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001122 vam->result_ready = 1;
1123}
1124
1125static void
1126vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1127{
1128 vat_main_t *vam = &vat_main;
1129 vat_json_node_t node;
Damjan Marion7cd468a2016-12-19 23:05:39 +01001130 void *oldheap;
1131 u8 *reply;
1132
1133 vat_json_init_object (&node);
1134 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1135 vat_json_object_add_uint (&node, "reply_in_shmem",
1136 ntohl (mp->reply_in_shmem));
1137 /* Toss the shared-memory original... */
Nathan Skrzypczak0aa40132019-11-25 16:29:38 +01001138 oldheap = vl_msg_push_heap ();
Damjan Marion7cd468a2016-12-19 23:05:39 +01001139
Damjan Marion7bee80c2017-04-26 15:32:12 +02001140 reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001141 vec_free (reply);
1142
Nathan Skrzypczak0aa40132019-11-25 16:29:38 +01001143 vl_msg_pop_heap (oldheap);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001144
1145 vat_json_print (vam->ofp, &node);
1146 vat_json_free (&node);
1147
1148 vam->retval = ntohl (mp->retval);
1149 vam->result_ready = 1;
1150}
1151
1152static void
1153vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1154{
1155 vat_main_t *vam = &vat_main;
1156 i32 retval = ntohl (mp->retval);
Dave Barach59b25652017-09-10 15:04:27 -04001157
1158 vec_reset_length (vam->cmd_reply);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001159
1160 vam->retval = retval;
Dave Barach59b25652017-09-10 15:04:27 -04001161 if (retval == 0)
Dave Barach77841402020-04-29 17:04:10 -04001162 vam->cmd_reply = vl_api_from_api_to_new_vec (mp, &mp->reply);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001163 vam->result_ready = 1;
1164}
1165
1166static void
1167vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1168{
1169 vat_main_t *vam = &vat_main;
1170 vat_json_node_t node;
Jakub Grajciar2dbee932020-02-07 11:30:26 +01001171 u8 *reply = 0; /* reply vector */
Damjan Marion7cd468a2016-12-19 23:05:39 +01001172
Dave Barach77841402020-04-29 17:04:10 -04001173 reply = vl_api_from_api_to_new_vec (mp, &mp->reply);
Dave Barach59b25652017-09-10 15:04:27 -04001174 vec_reset_length (vam->cmd_reply);
1175
Damjan Marion7cd468a2016-12-19 23:05:39 +01001176 vat_json_init_object (&node);
1177 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
Jakub Grajciar2dbee932020-02-07 11:30:26 +01001178 vat_json_object_add_string_copy (&node, "reply", reply);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001179
1180 vat_json_print (vam->ofp, &node);
1181 vat_json_free (&node);
Jakub Grajciar2dbee932020-02-07 11:30:26 +01001182 vec_free (reply);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001183
1184 vam->retval = ntohl (mp->retval);
1185 vam->result_ready = 1;
1186}
1187
1188static void vl_api_classify_add_del_table_reply_t_handler
1189 (vl_api_classify_add_del_table_reply_t * mp)
1190{
1191 vat_main_t *vam = &vat_main;
1192 i32 retval = ntohl (mp->retval);
1193 if (vam->async_mode)
1194 {
1195 vam->async_errors += (retval < 0);
1196 }
1197 else
1198 {
1199 vam->retval = retval;
1200 if (retval == 0 &&
1201 ((mp->new_table_index != 0xFFFFFFFF) ||
1202 (mp->skip_n_vectors != 0xFFFFFFFF) ||
1203 (mp->match_n_vectors != 0xFFFFFFFF)))
1204 /*
1205 * Note: this is just barely thread-safe, depends on
1206 * the main thread spinning waiting for an answer...
1207 */
1208 errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1209 ntohl (mp->new_table_index),
1210 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1211 vam->result_ready = 1;
1212 }
1213}
1214
1215static void vl_api_classify_add_del_table_reply_t_handler_json
1216 (vl_api_classify_add_del_table_reply_t * mp)
1217{
1218 vat_main_t *vam = &vat_main;
1219 vat_json_node_t node;
1220
1221 vat_json_init_object (&node);
1222 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1223 vat_json_object_add_uint (&node, "new_table_index",
1224 ntohl (mp->new_table_index));
1225 vat_json_object_add_uint (&node, "skip_n_vectors",
1226 ntohl (mp->skip_n_vectors));
1227 vat_json_object_add_uint (&node, "match_n_vectors",
1228 ntohl (mp->match_n_vectors));
1229
1230 vat_json_print (vam->ofp, &node);
1231 vat_json_free (&node);
1232
1233 vam->retval = ntohl (mp->retval);
1234 vam->result_ready = 1;
1235}
1236
1237static void vl_api_get_node_index_reply_t_handler
1238 (vl_api_get_node_index_reply_t * mp)
1239{
1240 vat_main_t *vam = &vat_main;
1241 i32 retval = ntohl (mp->retval);
1242 if (vam->async_mode)
1243 {
1244 vam->async_errors += (retval < 0);
1245 }
1246 else
1247 {
1248 vam->retval = retval;
1249 if (retval == 0)
1250 errmsg ("node index %d", ntohl (mp->node_index));
1251 vam->result_ready = 1;
1252 }
1253}
1254
1255static void vl_api_get_node_index_reply_t_handler_json
1256 (vl_api_get_node_index_reply_t * mp)
1257{
1258 vat_main_t *vam = &vat_main;
1259 vat_json_node_t node;
1260
1261 vat_json_init_object (&node);
1262 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1263 vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1264
1265 vat_json_print (vam->ofp, &node);
1266 vat_json_free (&node);
1267
1268 vam->retval = ntohl (mp->retval);
1269 vam->result_ready = 1;
1270}
1271
1272static void vl_api_get_next_index_reply_t_handler
1273 (vl_api_get_next_index_reply_t * mp)
1274{
1275 vat_main_t *vam = &vat_main;
1276 i32 retval = ntohl (mp->retval);
1277 if (vam->async_mode)
1278 {
1279 vam->async_errors += (retval < 0);
1280 }
1281 else
1282 {
1283 vam->retval = retval;
1284 if (retval == 0)
1285 errmsg ("next node index %d", ntohl (mp->next_index));
1286 vam->result_ready = 1;
1287 }
1288}
1289
1290static void vl_api_get_next_index_reply_t_handler_json
1291 (vl_api_get_next_index_reply_t * mp)
1292{
1293 vat_main_t *vam = &vat_main;
1294 vat_json_node_t node;
1295
1296 vat_json_init_object (&node);
1297 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1298 vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1299
1300 vat_json_print (vam->ofp, &node);
1301 vat_json_free (&node);
1302
1303 vam->retval = ntohl (mp->retval);
1304 vam->result_ready = 1;
1305}
1306
1307static void vl_api_add_node_next_reply_t_handler
1308 (vl_api_add_node_next_reply_t * mp)
1309{
1310 vat_main_t *vam = &vat_main;
1311 i32 retval = ntohl (mp->retval);
1312 if (vam->async_mode)
1313 {
1314 vam->async_errors += (retval < 0);
1315 }
1316 else
1317 {
1318 vam->retval = retval;
1319 if (retval == 0)
1320 errmsg ("next index %d", ntohl (mp->next_index));
1321 vam->result_ready = 1;
1322 }
1323}
1324
1325static void vl_api_add_node_next_reply_t_handler_json
1326 (vl_api_add_node_next_reply_t * mp)
1327{
1328 vat_main_t *vam = &vat_main;
1329 vat_json_node_t node;
1330
1331 vat_json_init_object (&node);
1332 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1333 vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1334
1335 vat_json_print (vam->ofp, &node);
1336 vat_json_free (&node);
1337
1338 vam->retval = ntohl (mp->retval);
1339 vam->result_ready = 1;
1340}
1341
1342static void vl_api_show_version_reply_t_handler
1343 (vl_api_show_version_reply_t * mp)
1344{
1345 vat_main_t *vam = &vat_main;
1346 i32 retval = ntohl (mp->retval);
1347
1348 if (retval >= 0)
1349 {
Ole Troane5ff5a32019-08-23 22:55:18 +02001350 errmsg (" program: %s", mp->program);
1351 errmsg (" version: %s", mp->version);
1352 errmsg (" build date: %s", mp->build_date);
1353 errmsg ("build directory: %s", mp->build_directory);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001354 }
1355 vam->retval = retval;
1356 vam->result_ready = 1;
1357}
1358
1359static void vl_api_show_version_reply_t_handler_json
1360 (vl_api_show_version_reply_t * mp)
1361{
1362 vat_main_t *vam = &vat_main;
1363 vat_json_node_t node;
1364
1365 vat_json_init_object (&node);
1366 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
Ole Troane5ff5a32019-08-23 22:55:18 +02001367 vat_json_object_add_string_copy (&node, "program", mp->program);
1368 vat_json_object_add_string_copy (&node, "version", mp->version);
1369 vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001370 vat_json_object_add_string_copy (&node, "build_directory",
Ole Troane5ff5a32019-08-23 22:55:18 +02001371 mp->build_directory);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001372
1373 vat_json_print (vam->ofp, &node);
1374 vat_json_free (&node);
1375
1376 vam->retval = ntohl (mp->retval);
1377 vam->result_ready = 1;
1378}
1379
Mohsin Kazmi5d64c782018-09-11 20:27:09 +02001380static void vl_api_show_threads_reply_t_handler
1381 (vl_api_show_threads_reply_t * mp)
1382{
1383 vat_main_t *vam = &vat_main;
1384 i32 retval = ntohl (mp->retval);
1385 int i, count = 0;
1386
1387 if (retval >= 0)
1388 count = ntohl (mp->count);
1389
1390 for (i = 0; i < count; i++)
1391 print (vam->ofp,
1392 "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1393 ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1394 mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1395 ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1396 ntohl (mp->thread_data[i].cpu_socket));
1397
1398 vam->retval = retval;
1399 vam->result_ready = 1;
1400}
1401
1402static void vl_api_show_threads_reply_t_handler_json
1403 (vl_api_show_threads_reply_t * mp)
1404{
1405 vat_main_t *vam = &vat_main;
1406 vat_json_node_t node;
1407 vl_api_thread_data_t *td;
Mohsin Kazmi5df628b2018-10-01 17:41:08 +02001408 i32 retval = ntohl (mp->retval);
1409 int i, count = 0;
1410
1411 if (retval >= 0)
1412 count = ntohl (mp->count);
Mohsin Kazmi5d64c782018-09-11 20:27:09 +02001413
1414 vat_json_init_object (&node);
Mohsin Kazmi5df628b2018-10-01 17:41:08 +02001415 vat_json_object_add_int (&node, "retval", retval);
Mohsin Kazmi5d64c782018-09-11 20:27:09 +02001416 vat_json_object_add_uint (&node, "count", count);
1417
1418 for (i = 0; i < count; i++)
1419 {
1420 td = &mp->thread_data[i];
1421 vat_json_object_add_uint (&node, "id", ntohl (td->id));
1422 vat_json_object_add_string_copy (&node, "name", td->name);
1423 vat_json_object_add_string_copy (&node, "type", td->type);
1424 vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1425 vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1426 vat_json_object_add_int (&node, "core", ntohl (td->id));
1427 vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1428 }
1429
1430 vat_json_print (vam->ofp, &node);
1431 vat_json_free (&node);
1432
Mohsin Kazmi5df628b2018-10-01 17:41:08 +02001433 vam->retval = retval;
Mohsin Kazmi5d64c782018-09-11 20:27:09 +02001434 vam->result_ready = 1;
1435}
1436
1437static int
1438api_show_threads (vat_main_t * vam)
1439{
1440 vl_api_show_threads_t *mp;
1441 int ret;
1442
1443 print (vam->ofp,
1444 "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1445 "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1446
1447 M (SHOW_THREADS, mp);
1448
1449 S (mp);
1450 W (ret);
1451 return ret;
1452}
1453
Damjan Marion7cd468a2016-12-19 23:05:39 +01001454static void
John Lo8d00fff2017-08-03 00:35:36 -04001455vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1456{
1457 u32 n_macs = ntohl (mp->n_macs);
Paul Vinciguerraec11b132018-09-24 05:25:00 -07001458 errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
John Lo8d00fff2017-08-03 00:35:36 -04001459 ntohl (mp->pid), mp->client_index, n_macs);
1460 int i;
1461 for (i = 0; i < n_macs; i++)
1462 {
1463 vl_api_mac_entry_t *mac = &mp->mac[i];
John Loe23c99e2018-03-13 21:53:18 -04001464 errmsg (" [%d] sw_if_index %d mac_addr %U action %d \n",
John Lo8d00fff2017-08-03 00:35:36 -04001465 i + 1, ntohl (mac->sw_if_index),
John Loe23c99e2018-03-13 21:53:18 -04001466 format_ethernet_address, mac->mac_addr, mac->action);
John Lo8d00fff2017-08-03 00:35:36 -04001467 if (i == 1000)
1468 break;
1469 }
1470}
1471
1472static void
1473vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1474{
1475 /* JSON output not supported */
1476}
1477
Ole Troan01384fe2017-05-12 11:55:35 +02001478#define vl_api_bridge_domain_details_t_endian vl_noop_handler
1479#define vl_api_bridge_domain_details_t_print vl_noop_handler
1480
Damjan Marion7cd468a2016-12-19 23:05:39 +01001481/*
1482 * Special-case: build the bridge domain table, maintain
1483 * the next bd id vbl.
1484 */
1485static void vl_api_bridge_domain_details_t_handler
1486 (vl_api_bridge_domain_details_t * mp)
1487{
1488 vat_main_t *vam = &vat_main;
1489 u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
Ole Troan01384fe2017-05-12 11:55:35 +02001490 int i;
Damjan Marion7cd468a2016-12-19 23:05:39 +01001491
Mohsin Kazmi762d83c2018-09-27 15:00:32 +02001492 print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1493 " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
Damjan Marion7cd468a2016-12-19 23:05:39 +01001494
Mohsin Kazmi762d83c2018-09-27 15:00:32 +02001495 print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
Damjan Marion7cd468a2016-12-19 23:05:39 +01001496 ntohl (mp->bd_id), mp->learn, mp->forward,
Mohsin Kazmi762d83c2018-09-27 15:00:32 +02001497 mp->flood, ntohl (mp->bvi_sw_if_index),
1498 ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001499
1500 if (n_sw_ifs)
Ole Troan01384fe2017-05-12 11:55:35 +02001501 {
1502 vl_api_bridge_domain_sw_if_t *sw_ifs;
1503 print (vam->ofp, "\n\n%s %s %s", "sw_if_index", "SHG",
1504 "Interface Name");
1505
1506 sw_ifs = mp->sw_if_details;
1507 for (i = 0; i < n_sw_ifs; i++)
1508 {
1509 u8 *sw_if_name = 0;
1510 u32 sw_if_index;
1511 hash_pair_t *p;
1512
1513 sw_if_index = ntohl (sw_ifs->sw_if_index);
1514
1515 /* *INDENT-OFF* */
1516 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1517 ({
1518 if ((u32) p->value[0] == sw_if_index)
1519 {
1520 sw_if_name = (u8 *)(p->key);
1521 break;
1522 }
1523 }));
1524 /* *INDENT-ON* */
1525 print (vam->ofp, "%7d %3d %s", sw_if_index,
1526 sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1527 "sw_if_index not found!");
1528
1529 sw_ifs++;
1530 }
1531 }
Damjan Marion7cd468a2016-12-19 23:05:39 +01001532}
1533
1534static void vl_api_bridge_domain_details_t_handler_json
1535 (vl_api_bridge_domain_details_t * mp)
1536{
1537 vat_main_t *vam = &vat_main;
1538 vat_json_node_t *node, *array = NULL;
Ole Troan01384fe2017-05-12 11:55:35 +02001539 u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001540
1541 if (VAT_JSON_ARRAY != vam->json_tree.type)
1542 {
1543 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1544 vat_json_init_array (&vam->json_tree);
1545 }
1546 node = vat_json_array_add (&vam->json_tree);
1547
1548 vat_json_init_object (node);
1549 vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1550 vat_json_object_add_uint (node, "flood", mp->flood);
1551 vat_json_object_add_uint (node, "forward", mp->forward);
1552 vat_json_object_add_uint (node, "learn", mp->learn);
1553 vat_json_object_add_uint (node, "bvi_sw_if_index",
1554 ntohl (mp->bvi_sw_if_index));
Ole Troan01384fe2017-05-12 11:55:35 +02001555 vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001556 array = vat_json_object_add (node, "sw_if");
1557 vat_json_init_array (array);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001558
Damjan Marion7cd468a2016-12-19 23:05:39 +01001559
Damjan Marion7cd468a2016-12-19 23:05:39 +01001560
Ole Troan01384fe2017-05-12 11:55:35 +02001561 if (n_sw_ifs)
1562 {
1563 vl_api_bridge_domain_sw_if_t *sw_ifs;
1564 int i;
Damjan Marion7cd468a2016-12-19 23:05:39 +01001565
Ole Troan01384fe2017-05-12 11:55:35 +02001566 sw_ifs = mp->sw_if_details;
1567 for (i = 0; i < n_sw_ifs; i++)
1568 {
1569 node = vat_json_array_add (array);
1570 vat_json_init_object (node);
1571 vat_json_object_add_uint (node, "sw_if_index",
1572 ntohl (sw_ifs->sw_if_index));
1573 vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1574 sw_ifs++;
1575 }
1576 }
Damjan Marion7cd468a2016-12-19 23:05:39 +01001577}
1578
1579static void vl_api_control_ping_reply_t_handler
1580 (vl_api_control_ping_reply_t * mp)
1581{
1582 vat_main_t *vam = &vat_main;
1583 i32 retval = ntohl (mp->retval);
1584 if (vam->async_mode)
1585 {
1586 vam->async_errors += (retval < 0);
1587 }
1588 else
1589 {
1590 vam->retval = retval;
1591 vam->result_ready = 1;
1592 }
Florin Coras90a63982017-12-19 04:50:01 -08001593 if (vam->socket_client_main)
1594 vam->socket_client_main->control_pings_outstanding--;
Damjan Marion7cd468a2016-12-19 23:05:39 +01001595}
1596
1597static void vl_api_control_ping_reply_t_handler_json
1598 (vl_api_control_ping_reply_t * mp)
1599{
1600 vat_main_t *vam = &vat_main;
1601 i32 retval = ntohl (mp->retval);
1602
1603 if (VAT_JSON_NONE != vam->json_tree.type)
1604 {
1605 vat_json_print (vam->ofp, &vam->json_tree);
1606 vat_json_free (&vam->json_tree);
1607 vam->json_tree.type = VAT_JSON_NONE;
1608 }
1609 else
1610 {
1611 /* just print [] */
1612 vat_json_init_array (&vam->json_tree);
1613 vat_json_print (vam->ofp, &vam->json_tree);
1614 vam->json_tree.type = VAT_JSON_NONE;
1615 }
1616
1617 vam->retval = retval;
1618 vam->result_ready = 1;
1619}
1620
1621static void
Eyal Barifead6702017-04-04 04:46:32 +03001622 vl_api_bridge_domain_set_mac_age_reply_t_handler
1623 (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1624{
1625 vat_main_t *vam = &vat_main;
1626 i32 retval = ntohl (mp->retval);
1627 if (vam->async_mode)
1628 {
1629 vam->async_errors += (retval < 0);
1630 }
1631 else
1632 {
1633 vam->retval = retval;
1634 vam->result_ready = 1;
1635 }
1636}
1637
1638static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1639 (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1640{
1641 vat_main_t *vam = &vat_main;
1642 vat_json_node_t node;
1643
1644 vat_json_init_object (&node);
1645 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1646
1647 vat_json_print (vam->ofp, &node);
1648 vat_json_free (&node);
1649
1650 vam->retval = ntohl (mp->retval);
1651 vam->result_ready = 1;
1652}
1653
1654static void
Damjan Marion7cd468a2016-12-19 23:05:39 +01001655vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1656{
1657 vat_main_t *vam = &vat_main;
1658 i32 retval = ntohl (mp->retval);
1659 if (vam->async_mode)
1660 {
1661 vam->async_errors += (retval < 0);
1662 }
1663 else
1664 {
1665 vam->retval = retval;
1666 vam->result_ready = 1;
1667 }
1668}
1669
1670static void vl_api_l2_flags_reply_t_handler_json
1671 (vl_api_l2_flags_reply_t * mp)
1672{
1673 vat_main_t *vam = &vat_main;
1674 vat_json_node_t node;
1675
1676 vat_json_init_object (&node);
1677 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1678 vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1679 ntohl (mp->resulting_feature_bitmap));
1680
1681 vat_json_print (vam->ofp, &node);
1682 vat_json_free (&node);
1683
1684 vam->retval = ntohl (mp->retval);
1685 vam->result_ready = 1;
1686}
1687
1688static void vl_api_bridge_flags_reply_t_handler
1689 (vl_api_bridge_flags_reply_t * mp)
1690{
1691 vat_main_t *vam = &vat_main;
1692 i32 retval = ntohl (mp->retval);
1693 if (vam->async_mode)
1694 {
1695 vam->async_errors += (retval < 0);
1696 }
1697 else
1698 {
1699 vam->retval = retval;
1700 vam->result_ready = 1;
1701 }
1702}
1703
1704static void vl_api_bridge_flags_reply_t_handler_json
1705 (vl_api_bridge_flags_reply_t * mp)
1706{
1707 vat_main_t *vam = &vat_main;
1708 vat_json_node_t node;
1709
1710 vat_json_init_object (&node);
1711 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1712 vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1713 ntohl (mp->resulting_feature_bitmap));
1714
1715 vat_json_print (vam->ofp, &node);
1716 vat_json_free (&node);
1717
1718 vam->retval = ntohl (mp->retval);
1719 vam->result_ready = 1;
1720}
1721
Damjan Marion8389fb92017-10-13 18:29:53 +02001722static void
1723vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1724{
1725 vat_main_t *vam = &vat_main;
1726 i32 retval = ntohl (mp->retval);
1727 if (vam->async_mode)
1728 {
1729 vam->async_errors += (retval < 0);
1730 }
1731 else
1732 {
1733 vam->retval = retval;
1734 vam->sw_if_index = ntohl (mp->sw_if_index);
1735 vam->result_ready = 1;
1736 }
1737
1738}
1739
1740static void vl_api_tap_create_v2_reply_t_handler_json
1741 (vl_api_tap_create_v2_reply_t * mp)
1742{
1743 vat_main_t *vam = &vat_main;
1744 vat_json_node_t node;
1745
1746 vat_json_init_object (&node);
1747 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1748 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1749
1750 vat_json_print (vam->ofp, &node);
1751 vat_json_free (&node);
1752
1753 vam->retval = ntohl (mp->retval);
1754 vam->result_ready = 1;
1755
1756}
1757
1758static void
1759vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1760{
1761 vat_main_t *vam = &vat_main;
1762 i32 retval = ntohl (mp->retval);
1763 if (vam->async_mode)
1764 {
1765 vam->async_errors += (retval < 0);
1766 }
1767 else
1768 {
1769 vam->retval = retval;
1770 vam->result_ready = 1;
1771 }
1772}
1773
1774static void vl_api_tap_delete_v2_reply_t_handler_json
1775 (vl_api_tap_delete_v2_reply_t * mp)
1776{
1777 vat_main_t *vam = &vat_main;
1778 vat_json_node_t node;
1779
1780 vat_json_init_object (&node);
1781 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1782
1783 vat_json_print (vam->ofp, &node);
1784 vat_json_free (&node);
1785
1786 vam->retval = ntohl (mp->retval);
1787 vam->result_ready = 1;
1788}
1789
Steven9cd2d7a2017-12-20 12:43:01 -08001790static void
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01001791vl_api_virtio_pci_create_reply_t_handler (vl_api_virtio_pci_create_reply_t *
1792 mp)
1793{
1794 vat_main_t *vam = &vat_main;
1795 i32 retval = ntohl (mp->retval);
1796 if (vam->async_mode)
1797 {
1798 vam->async_errors += (retval < 0);
1799 }
1800 else
1801 {
1802 vam->retval = retval;
1803 vam->sw_if_index = ntohl (mp->sw_if_index);
1804 vam->result_ready = 1;
1805 }
1806}
1807
1808static void vl_api_virtio_pci_create_reply_t_handler_json
1809 (vl_api_virtio_pci_create_reply_t * mp)
1810{
1811 vat_main_t *vam = &vat_main;
1812 vat_json_node_t node;
1813
1814 vat_json_init_object (&node);
1815 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1816 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1817
1818 vat_json_print (vam->ofp, &node);
1819 vat_json_free (&node);
1820
1821 vam->retval = ntohl (mp->retval);
1822 vam->result_ready = 1;
1823
1824}
1825
1826static void
Mohsin Kazmi518251b2020-09-01 17:17:44 +00001827 vl_api_virtio_pci_create_v2_reply_t_handler
1828 (vl_api_virtio_pci_create_v2_reply_t * mp)
1829{
1830 vat_main_t *vam = &vat_main;
1831 i32 retval = ntohl (mp->retval);
1832 if (vam->async_mode)
1833 {
1834 vam->async_errors += (retval < 0);
1835 }
1836 else
1837 {
1838 vam->retval = retval;
1839 vam->sw_if_index = ntohl (mp->sw_if_index);
1840 vam->result_ready = 1;
1841 }
1842}
1843
1844static void vl_api_virtio_pci_create_v2_reply_t_handler_json
1845 (vl_api_virtio_pci_create_v2_reply_t * mp)
1846{
1847 vat_main_t *vam = &vat_main;
1848 vat_json_node_t node;
1849
1850 vat_json_init_object (&node);
1851 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1852 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1853
1854 vat_json_print (vam->ofp, &node);
1855 vat_json_free (&node);
1856
1857 vam->retval = ntohl (mp->retval);
1858 vam->result_ready = 1;
1859}
1860
1861static void
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01001862vl_api_virtio_pci_delete_reply_t_handler (vl_api_virtio_pci_delete_reply_t *
1863 mp)
1864{
1865 vat_main_t *vam = &vat_main;
1866 i32 retval = ntohl (mp->retval);
1867 if (vam->async_mode)
1868 {
1869 vam->async_errors += (retval < 0);
1870 }
1871 else
1872 {
1873 vam->retval = retval;
1874 vam->result_ready = 1;
1875 }
1876}
1877
1878static void vl_api_virtio_pci_delete_reply_t_handler_json
1879 (vl_api_virtio_pci_delete_reply_t * mp)
1880{
1881 vat_main_t *vam = &vat_main;
1882 vat_json_node_t node;
1883
1884 vat_json_init_object (&node);
1885 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1886
1887 vat_json_print (vam->ofp, &node);
1888 vat_json_free (&node);
1889
1890 vam->retval = ntohl (mp->retval);
1891 vam->result_ready = 1;
1892}
1893
1894static void
Steven9cd2d7a2017-12-20 12:43:01 -08001895vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1896{
1897 vat_main_t *vam = &vat_main;
1898 i32 retval = ntohl (mp->retval);
1899
1900 if (vam->async_mode)
1901 {
1902 vam->async_errors += (retval < 0);
1903 }
1904 else
1905 {
1906 vam->retval = retval;
1907 vam->sw_if_index = ntohl (mp->sw_if_index);
1908 vam->result_ready = 1;
1909 }
1910}
1911
1912static void vl_api_bond_create_reply_t_handler_json
1913 (vl_api_bond_create_reply_t * mp)
1914{
1915 vat_main_t *vam = &vat_main;
1916 vat_json_node_t node;
1917
1918 vat_json_init_object (&node);
1919 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1920 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1921
1922 vat_json_print (vam->ofp, &node);
1923 vat_json_free (&node);
1924
1925 vam->retval = ntohl (mp->retval);
1926 vam->result_ready = 1;
1927}
1928
1929static void
Steven Luongea717862020-07-30 07:31:40 -07001930vl_api_bond_create2_reply_t_handler (vl_api_bond_create2_reply_t * mp)
1931{
1932 vat_main_t *vam = &vat_main;
1933 i32 retval = ntohl (mp->retval);
1934
1935 if (vam->async_mode)
1936 {
1937 vam->async_errors += (retval < 0);
1938 }
1939 else
1940 {
1941 vam->retval = retval;
1942 vam->sw_if_index = ntohl (mp->sw_if_index);
1943 vam->result_ready = 1;
1944 }
1945}
1946
1947static void vl_api_bond_create2_reply_t_handler_json
1948 (vl_api_bond_create2_reply_t * mp)
1949{
1950 vat_main_t *vam = &vat_main;
1951 vat_json_node_t node;
1952
1953 vat_json_init_object (&node);
1954 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1955 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1956
1957 vat_json_print (vam->ofp, &node);
1958 vat_json_free (&node);
1959
1960 vam->retval = ntohl (mp->retval);
1961 vam->result_ready = 1;
1962}
1963
1964static void
Steven9cd2d7a2017-12-20 12:43:01 -08001965vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1966{
1967 vat_main_t *vam = &vat_main;
1968 i32 retval = ntohl (mp->retval);
1969
1970 if (vam->async_mode)
1971 {
1972 vam->async_errors += (retval < 0);
1973 }
1974 else
1975 {
1976 vam->retval = retval;
1977 vam->result_ready = 1;
1978 }
1979}
1980
1981static void vl_api_bond_delete_reply_t_handler_json
1982 (vl_api_bond_delete_reply_t * mp)
1983{
1984 vat_main_t *vam = &vat_main;
1985 vat_json_node_t node;
1986
1987 vat_json_init_object (&node);
1988 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1989
1990 vat_json_print (vam->ofp, &node);
1991 vat_json_free (&node);
1992
1993 vam->retval = ntohl (mp->retval);
1994 vam->result_ready = 1;
1995}
1996
1997static void
Steven Luong4c4223e2020-07-15 08:44:54 -07001998vl_api_bond_add_member_reply_t_handler (vl_api_bond_add_member_reply_t * mp)
Steven9cd2d7a2017-12-20 12:43:01 -08001999{
2000 vat_main_t *vam = &vat_main;
2001 i32 retval = ntohl (mp->retval);
2002
2003 if (vam->async_mode)
2004 {
2005 vam->async_errors += (retval < 0);
2006 }
2007 else
2008 {
2009 vam->retval = retval;
2010 vam->result_ready = 1;
2011 }
2012}
2013
Steven Luong4c4223e2020-07-15 08:44:54 -07002014static void vl_api_bond_add_member_reply_t_handler_json
2015 (vl_api_bond_add_member_reply_t * mp)
Steven9cd2d7a2017-12-20 12:43:01 -08002016{
2017 vat_main_t *vam = &vat_main;
2018 vat_json_node_t node;
2019
2020 vat_json_init_object (&node);
2021 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2022
2023 vat_json_print (vam->ofp, &node);
2024 vat_json_free (&node);
2025
2026 vam->retval = ntohl (mp->retval);
2027 vam->result_ready = 1;
2028}
2029
2030static void
Steven Luong4c4223e2020-07-15 08:44:54 -07002031vl_api_bond_detach_member_reply_t_handler (vl_api_bond_detach_member_reply_t *
2032 mp)
Steven9cd2d7a2017-12-20 12:43:01 -08002033{
2034 vat_main_t *vam = &vat_main;
2035 i32 retval = ntohl (mp->retval);
2036
2037 if (vam->async_mode)
2038 {
2039 vam->async_errors += (retval < 0);
2040 }
2041 else
2042 {
2043 vam->retval = retval;
2044 vam->result_ready = 1;
2045 }
2046}
2047
Steven Luong4c4223e2020-07-15 08:44:54 -07002048static void vl_api_bond_detach_member_reply_t_handler_json
2049 (vl_api_bond_detach_member_reply_t * mp)
Steven9cd2d7a2017-12-20 12:43:01 -08002050{
2051 vat_main_t *vam = &vat_main;
2052 vat_json_node_t node;
2053
2054 vat_json_init_object (&node);
2055 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2056
2057 vat_json_print (vam->ofp, &node);
2058 vat_json_free (&node);
2059
2060 vam->retval = ntohl (mp->retval);
2061 vam->result_ready = 1;
2062}
2063
Steven Luonga1876b82019-08-20 16:58:00 -07002064static int
2065api_sw_interface_set_bond_weight (vat_main_t * vam)
2066{
2067 unformat_input_t *i = vam->input;
2068 vl_api_sw_interface_set_bond_weight_t *mp;
2069 u32 sw_if_index = ~0;
2070 u32 weight = 0;
2071 u8 weight_enter = 0;
2072 int ret;
2073
2074 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2075 {
2076 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2077 ;
2078 else if (unformat (i, "sw_if_index %d", &sw_if_index))
2079 ;
2080 else if (unformat (i, "weight %u", &weight))
2081 weight_enter = 1;
2082 else
2083 break;
2084 }
2085
2086 if (sw_if_index == ~0)
2087 {
2088 errmsg ("missing interface name or sw_if_index");
2089 return -99;
2090 }
2091 if (weight_enter == 0)
2092 {
2093 errmsg ("missing valid weight");
2094 return -99;
2095 }
2096
2097 /* Construct the API message */
2098 M (SW_INTERFACE_SET_BOND_WEIGHT, mp);
2099 mp->sw_if_index = ntohl (sw_if_index);
2100 mp->weight = ntohl (weight);
2101
2102 S (mp);
2103 W (ret);
2104 return ret;
2105}
2106
Steven Luong4c4223e2020-07-15 08:44:54 -07002107static void vl_api_sw_bond_interface_details_t_handler
2108 (vl_api_sw_bond_interface_details_t * mp)
Steven9cd2d7a2017-12-20 12:43:01 -08002109{
2110 vat_main_t *vam = &vat_main;
2111
2112 print (vam->ofp,
2113 "%-16s %-12d %-12U %-13U %-14u %-14u",
2114 mp->interface_name, ntohl (mp->sw_if_index),
Jakub Grajciar3d1ef872019-08-26 12:55:15 +02002115 format_bond_mode, ntohl (mp->mode), format_bond_load_balance,
Steven Luong4c4223e2020-07-15 08:44:54 -07002116 ntohl (mp->lb), ntohl (mp->active_members), ntohl (mp->members));
Steven9cd2d7a2017-12-20 12:43:01 -08002117}
2118
Steven Luong4c4223e2020-07-15 08:44:54 -07002119static void vl_api_sw_bond_interface_details_t_handler_json
2120 (vl_api_sw_bond_interface_details_t * mp)
Steven9cd2d7a2017-12-20 12:43:01 -08002121{
2122 vat_main_t *vam = &vat_main;
2123 vat_json_node_t *node = NULL;
2124
2125 if (VAT_JSON_ARRAY != vam->json_tree.type)
2126 {
2127 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2128 vat_json_init_array (&vam->json_tree);
2129 }
2130 node = vat_json_array_add (&vam->json_tree);
2131
2132 vat_json_init_object (node);
2133 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2134 vat_json_object_add_string_copy (node, "interface_name",
2135 mp->interface_name);
Jakub Grajciar3d1ef872019-08-26 12:55:15 +02002136 vat_json_object_add_uint (node, "mode", ntohl (mp->mode));
2137 vat_json_object_add_uint (node, "load_balance", ntohl (mp->lb));
Steven Luong4c4223e2020-07-15 08:44:54 -07002138 vat_json_object_add_uint (node, "active_members",
2139 ntohl (mp->active_members));
2140 vat_json_object_add_uint (node, "members", ntohl (mp->members));
Steven9cd2d7a2017-12-20 12:43:01 -08002141}
2142
2143static int
Steven Luong4c4223e2020-07-15 08:44:54 -07002144api_sw_bond_interface_dump (vat_main_t * vam)
Steven9cd2d7a2017-12-20 12:43:01 -08002145{
Steven Luong4c4223e2020-07-15 08:44:54 -07002146 unformat_input_t *i = vam->input;
2147 vl_api_sw_bond_interface_dump_t *mp;
Steven9cd2d7a2017-12-20 12:43:01 -08002148 vl_api_control_ping_t *mp_ping;
2149 int ret;
Steven Luong4c4223e2020-07-15 08:44:54 -07002150 u32 sw_if_index = ~0;
2151
2152 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2153 {
2154 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2155 ;
2156 else if (unformat (i, "sw_if_index %d", &sw_if_index))
2157 ;
2158 else
2159 break;
2160 }
Steven9cd2d7a2017-12-20 12:43:01 -08002161
2162 print (vam->ofp,
2163 "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2164 "interface name", "sw_if_index", "mode", "load balance",
Steven Luong4c4223e2020-07-15 08:44:54 -07002165 "active members", "members");
Steven9cd2d7a2017-12-20 12:43:01 -08002166
2167 /* Get list of bond interfaces */
Steven Luong4c4223e2020-07-15 08:44:54 -07002168 M (SW_BOND_INTERFACE_DUMP, mp);
2169 mp->sw_if_index = ntohl (sw_if_index);
Steven9cd2d7a2017-12-20 12:43:01 -08002170 S (mp);
2171
2172 /* Use a control ping for synchronization */
2173 MPING (CONTROL_PING, mp_ping);
2174 S (mp_ping);
2175
2176 W (ret);
2177 return ret;
2178}
2179
Steven Luong4c4223e2020-07-15 08:44:54 -07002180static void vl_api_sw_member_interface_details_t_handler
2181 (vl_api_sw_member_interface_details_t * mp)
Steven9cd2d7a2017-12-20 12:43:01 -08002182{
2183 vat_main_t *vam = &vat_main;
2184
2185 print (vam->ofp,
Steven Luonga1876b82019-08-20 16:58:00 -07002186 "%-25s %-12d %-7d %-12d %-10d %-10d", mp->interface_name,
2187 ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout,
2188 ntohl (mp->weight), mp->is_local_numa);
Steven9cd2d7a2017-12-20 12:43:01 -08002189}
2190
Steven Luong4c4223e2020-07-15 08:44:54 -07002191static void vl_api_sw_member_interface_details_t_handler_json
2192 (vl_api_sw_member_interface_details_t * mp)
Steven9cd2d7a2017-12-20 12:43:01 -08002193{
2194 vat_main_t *vam = &vat_main;
2195 vat_json_node_t *node = NULL;
2196
2197 if (VAT_JSON_ARRAY != vam->json_tree.type)
2198 {
2199 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2200 vat_json_init_array (&vam->json_tree);
2201 }
2202 node = vat_json_array_add (&vam->json_tree);
2203
2204 vat_json_init_object (node);
2205 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2206 vat_json_object_add_string_copy (node, "interface_name",
2207 mp->interface_name);
2208 vat_json_object_add_uint (node, "passive", mp->is_passive);
2209 vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
Steven Luonga1876b82019-08-20 16:58:00 -07002210 vat_json_object_add_uint (node, "weight", ntohl (mp->weight));
2211 vat_json_object_add_uint (node, "is_local_numa", mp->is_local_numa);
Steven9cd2d7a2017-12-20 12:43:01 -08002212}
2213
2214static int
Steven Luong4c4223e2020-07-15 08:44:54 -07002215api_sw_member_interface_dump (vat_main_t * vam)
Steven9cd2d7a2017-12-20 12:43:01 -08002216{
2217 unformat_input_t *i = vam->input;
Steven Luong4c4223e2020-07-15 08:44:54 -07002218 vl_api_sw_member_interface_dump_t *mp;
Steven9cd2d7a2017-12-20 12:43:01 -08002219 vl_api_control_ping_t *mp_ping;
2220 u32 sw_if_index = ~0;
2221 u8 sw_if_index_set = 0;
2222 int ret;
2223
2224 /* Parse args required to build the message */
2225 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2226 {
2227 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2228 sw_if_index_set = 1;
2229 else if (unformat (i, "sw_if_index %d", &sw_if_index))
2230 sw_if_index_set = 1;
2231 else
2232 break;
2233 }
2234
2235 if (sw_if_index_set == 0)
2236 {
2237 errmsg ("missing vpp interface name. ");
2238 return -99;
2239 }
2240
2241 print (vam->ofp,
Steven Luonga1876b82019-08-20 16:58:00 -07002242 "\n%-25s %-12s %-7s %-12s %-10s %-10s",
Steven Luong4c4223e2020-07-15 08:44:54 -07002243 "member interface name", "sw_if_index", "passive", "long_timeout",
Steven Luonga1876b82019-08-20 16:58:00 -07002244 "weight", "local numa");
Steven9cd2d7a2017-12-20 12:43:01 -08002245
2246 /* Get list of bond interfaces */
Steven Luong4c4223e2020-07-15 08:44:54 -07002247 M (SW_MEMBER_INTERFACE_DUMP, mp);
Steven9cd2d7a2017-12-20 12:43:01 -08002248 mp->sw_if_index = ntohl (sw_if_index);
2249 S (mp);
2250
2251 /* Use a control ping for synchronization */
2252 MPING (CONTROL_PING, mp_ping);
2253 S (mp_ping);
2254
2255 W (ret);
2256 return ret;
2257}
2258
Damjan Marion7cd468a2016-12-19 23:05:39 +01002259static void vl_api_mpls_tunnel_add_del_reply_t_handler
2260 (vl_api_mpls_tunnel_add_del_reply_t * mp)
2261{
2262 vat_main_t *vam = &vat_main;
2263 i32 retval = ntohl (mp->retval);
2264 if (vam->async_mode)
2265 {
2266 vam->async_errors += (retval < 0);
2267 }
2268 else
2269 {
2270 vam->retval = retval;
John Lo06fda9c2018-10-03 16:32:44 -04002271 vam->sw_if_index = ntohl (mp->sw_if_index);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002272 vam->result_ready = 1;
2273 }
John Lo06fda9c2018-10-03 16:32:44 -04002274 vam->regenerate_interface_table = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002275}
2276
2277static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2278 (vl_api_mpls_tunnel_add_del_reply_t * mp)
2279{
2280 vat_main_t *vam = &vat_main;
2281 vat_json_node_t node;
2282
2283 vat_json_init_object (&node);
2284 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2285 vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2286 ntohl (mp->sw_if_index));
2287
2288 vat_json_print (vam->ofp, &node);
2289 vat_json_free (&node);
2290
2291 vam->retval = ntohl (mp->retval);
2292 vam->result_ready = 1;
2293}
2294
Damjan Marion7cd468a2016-12-19 23:05:39 +01002295static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2296 (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2297{
2298 vat_main_t *vam = &vat_main;
2299 i32 retval = ntohl (mp->retval);
2300 if (vam->async_mode)
2301 {
2302 vam->async_errors += (retval < 0);
2303 }
2304 else
2305 {
2306 vam->retval = retval;
2307 vam->sw_if_index = ntohl (mp->sw_if_index);
2308 vam->result_ready = 1;
2309 }
Dave Barachf72212e2018-01-11 10:25:07 -05002310 vam->regenerate_interface_table = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002311}
2312
2313static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2314 (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2315{
2316 vat_main_t *vam = &vat_main;
2317 vat_json_node_t node;
2318
2319 vat_json_init_object (&node);
2320 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2321 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2322
2323 vat_json_print (vam->ofp, &node);
2324 vat_json_free (&node);
2325
2326 vam->retval = ntohl (mp->retval);
2327 vam->result_ready = 1;
2328}
2329
eyal bariaf86a482018-04-17 11:20:27 +03002330static void vl_api_vxlan_offload_rx_reply_t_handler
2331 (vl_api_vxlan_offload_rx_reply_t * mp)
2332{
2333 vat_main_t *vam = &vat_main;
2334 i32 retval = ntohl (mp->retval);
2335 if (vam->async_mode)
2336 {
2337 vam->async_errors += (retval < 0);
2338 }
2339 else
2340 {
2341 vam->retval = retval;
2342 vam->result_ready = 1;
2343 }
2344}
2345
2346static void vl_api_vxlan_offload_rx_reply_t_handler_json
2347 (vl_api_vxlan_offload_rx_reply_t * mp)
2348{
2349 vat_main_t *vam = &vat_main;
2350 vat_json_node_t node;
2351
2352 vat_json_init_object (&node);
2353 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2354
2355 vat_json_print (vam->ofp, &node);
2356 vat_json_free (&node);
2357
2358 vam->retval = ntohl (mp->retval);
2359 vam->result_ready = 1;
2360}
2361
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +08002362static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2363 (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2364{
2365 vat_main_t *vam = &vat_main;
2366 i32 retval = ntohl (mp->retval);
2367 if (vam->async_mode)
2368 {
2369 vam->async_errors += (retval < 0);
2370 }
2371 else
2372 {
2373 vam->retval = retval;
2374 vam->sw_if_index = ntohl (mp->sw_if_index);
2375 vam->result_ready = 1;
2376 }
Dave Barachf72212e2018-01-11 10:25:07 -05002377 vam->regenerate_interface_table = 1;
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +08002378}
2379
2380static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2381 (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2382{
2383 vat_main_t *vam = &vat_main;
2384 vat_json_node_t node;
2385
2386 vat_json_init_object (&node);
2387 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2388 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2389
2390 vat_json_print (vam->ofp, &node);
2391 vat_json_free (&node);
2392
2393 vam->retval = ntohl (mp->retval);
2394 vam->result_ready = 1;
2395}
2396
Damjan Marion7cd468a2016-12-19 23:05:39 +01002397static void vl_api_create_vhost_user_if_reply_t_handler
2398 (vl_api_create_vhost_user_if_reply_t * mp)
2399{
2400 vat_main_t *vam = &vat_main;
2401 i32 retval = ntohl (mp->retval);
2402 if (vam->async_mode)
2403 {
2404 vam->async_errors += (retval < 0);
2405 }
2406 else
2407 {
2408 vam->retval = retval;
2409 vam->sw_if_index = ntohl (mp->sw_if_index);
2410 vam->result_ready = 1;
2411 }
Dave Barachf72212e2018-01-11 10:25:07 -05002412 vam->regenerate_interface_table = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002413}
2414
2415static void vl_api_create_vhost_user_if_reply_t_handler_json
2416 (vl_api_create_vhost_user_if_reply_t * mp)
2417{
2418 vat_main_t *vam = &vat_main;
2419 vat_json_node_t node;
2420
2421 vat_json_init_object (&node);
2422 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2423 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2424
2425 vat_json_print (vam->ofp, &node);
2426 vat_json_free (&node);
2427
2428 vam->retval = ntohl (mp->retval);
2429 vam->result_ready = 1;
2430}
2431
Steven Luong27ba5002020-11-17 13:30:44 -08002432static void vl_api_create_vhost_user_if_v2_reply_t_handler
2433 (vl_api_create_vhost_user_if_v2_reply_t * mp)
2434{
2435 vat_main_t *vam = &vat_main;
2436 i32 retval = ntohl (mp->retval);
2437 if (vam->async_mode)
2438 {
2439 vam->async_errors += (retval < 0);
2440 }
2441 else
2442 {
2443 vam->retval = retval;
2444 vam->sw_if_index = ntohl (mp->sw_if_index);
2445 vam->result_ready = 1;
2446 }
2447 vam->regenerate_interface_table = 1;
2448}
2449
2450static void vl_api_create_vhost_user_if_v2_reply_t_handler_json
2451 (vl_api_create_vhost_user_if_v2_reply_t * mp)
2452{
2453 vat_main_t *vam = &vat_main;
2454 vat_json_node_t node;
2455
2456 vat_json_init_object (&node);
2457 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2458 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2459
2460 vat_json_print (vam->ofp, &node);
2461 vat_json_free (&node);
2462
2463 vam->retval = ntohl (mp->retval);
2464 vam->result_ready = 1;
2465}
2466
Damjan Marion7cd468a2016-12-19 23:05:39 +01002467static void vl_api_ip_address_details_t_handler
2468 (vl_api_ip_address_details_t * mp)
2469{
2470 vat_main_t *vam = &vat_main;
2471 static ip_address_details_t empty_ip_address_details = { {0} };
2472 ip_address_details_t *address = NULL;
2473 ip_details_t *current_ip_details = NULL;
2474 ip_details_t *details = NULL;
2475
2476 details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2477
2478 if (!details || vam->current_sw_if_index >= vec_len (details)
2479 || !details[vam->current_sw_if_index].present)
2480 {
2481 errmsg ("ip address details arrived but not stored");
2482 errmsg ("ip_dump should be called first");
2483 return;
2484 }
2485
2486 current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2487
2488#define addresses (current_ip_details->addr)
2489
2490 vec_validate_init_empty (addresses, vec_len (addresses),
2491 empty_ip_address_details);
2492
2493 address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2494
Neale Ranns097fa662018-05-01 05:17:55 -07002495 clib_memcpy (&address->ip, &mp->prefix.address.un, sizeof (address->ip));
Paul Vinciguerraab055082019-06-06 14:07:55 -04002496 address->prefix_length = mp->prefix.len;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002497#undef addresses
2498}
2499
2500static void vl_api_ip_address_details_t_handler_json
2501 (vl_api_ip_address_details_t * mp)
2502{
2503 vat_main_t *vam = &vat_main;
2504 vat_json_node_t *node = NULL;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002505
2506 if (VAT_JSON_ARRAY != vam->json_tree.type)
2507 {
2508 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2509 vat_json_init_array (&vam->json_tree);
2510 }
2511 node = vat_json_array_add (&vam->json_tree);
2512
2513 vat_json_init_object (node);
Neale Ranns097fa662018-05-01 05:17:55 -07002514 vat_json_object_add_prefix (node, &mp->prefix);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002515}
2516
2517static void
2518vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2519{
2520 vat_main_t *vam = &vat_main;
2521 static ip_details_t empty_ip_details = { 0 };
2522 ip_details_t *ip = NULL;
2523 u32 sw_if_index = ~0;
2524
2525 sw_if_index = ntohl (mp->sw_if_index);
2526
2527 vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2528 sw_if_index, empty_ip_details);
2529
2530 ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2531 sw_if_index);
2532
2533 ip->present = 1;
2534}
2535
2536static void
2537vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2538{
2539 vat_main_t *vam = &vat_main;
2540
2541 if (VAT_JSON_ARRAY != vam->json_tree.type)
2542 {
2543 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2544 vat_json_init_array (&vam->json_tree);
2545 }
2546 vat_json_array_add_uint (&vam->json_tree,
2547 clib_net_to_host_u32 (mp->sw_if_index));
2548}
2549
Damjan Marion7cd468a2016-12-19 23:05:39 +01002550static void vl_api_get_first_msg_id_reply_t_handler
2551 (vl_api_get_first_msg_id_reply_t * mp)
2552{
2553 vat_main_t *vam = &vat_main;
2554 i32 retval = ntohl (mp->retval);
2555
2556 if (vam->async_mode)
2557 {
2558 vam->async_errors += (retval < 0);
2559 }
2560 else
2561 {
2562 vam->retval = retval;
2563 vam->result_ready = 1;
2564 }
2565 if (retval >= 0)
2566 {
2567 errmsg ("first message id %d", ntohs (mp->first_msg_id));
2568 }
2569}
2570
2571static void vl_api_get_first_msg_id_reply_t_handler_json
2572 (vl_api_get_first_msg_id_reply_t * mp)
2573{
2574 vat_main_t *vam = &vat_main;
2575 vat_json_node_t node;
2576
2577 vat_json_init_object (&node);
2578 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2579 vat_json_object_add_uint (&node, "first_msg_id",
2580 (uint) ntohs (mp->first_msg_id));
2581
2582 vat_json_print (vam->ofp, &node);
2583 vat_json_free (&node);
2584
2585 vam->retval = ntohl (mp->retval);
2586 vam->result_ready = 1;
2587}
2588
2589static void vl_api_get_node_graph_reply_t_handler
2590 (vl_api_get_node_graph_reply_t * mp)
2591{
2592 vat_main_t *vam = &vat_main;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002593 i32 retval = ntohl (mp->retval);
2594 u8 *pvt_copy, *reply;
2595 void *oldheap;
2596 vlib_node_t *node;
2597 int i;
2598
2599 if (vam->async_mode)
2600 {
2601 vam->async_errors += (retval < 0);
2602 }
2603 else
2604 {
2605 vam->retval = retval;
2606 vam->result_ready = 1;
2607 }
2608
2609 /* "Should never happen..." */
2610 if (retval != 0)
2611 return;
2612
Damjan Marion7bee80c2017-04-26 15:32:12 +02002613 reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002614 pvt_copy = vec_dup (reply);
2615
2616 /* Toss the shared-memory original... */
Nathan Skrzypczak0aa40132019-11-25 16:29:38 +01002617 oldheap = vl_msg_push_heap ();
Damjan Marion7cd468a2016-12-19 23:05:39 +01002618
2619 vec_free (reply);
2620
Nathan Skrzypczak0aa40132019-11-25 16:29:38 +01002621 vl_msg_pop_heap (oldheap);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002622
2623 if (vam->graph_nodes)
2624 {
2625 hash_free (vam->graph_node_index_by_name);
2626
Dave Barach1ddbc012018-06-13 09:26:05 -04002627 for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002628 {
Dave Barach1ddbc012018-06-13 09:26:05 -04002629 node = vam->graph_nodes[0][i];
Damjan Marion7cd468a2016-12-19 23:05:39 +01002630 vec_free (node->name);
2631 vec_free (node->next_nodes);
2632 vec_free (node);
2633 }
Dave Barach1ddbc012018-06-13 09:26:05 -04002634 vec_free (vam->graph_nodes[0]);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002635 vec_free (vam->graph_nodes);
2636 }
2637
2638 vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2639 vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2640 vec_free (pvt_copy);
2641
Dave Barach1ddbc012018-06-13 09:26:05 -04002642 for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002643 {
Dave Barach1ddbc012018-06-13 09:26:05 -04002644 node = vam->graph_nodes[0][i];
Damjan Marion7cd468a2016-12-19 23:05:39 +01002645 hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2646 }
2647}
2648
2649static void vl_api_get_node_graph_reply_t_handler_json
2650 (vl_api_get_node_graph_reply_t * mp)
2651{
2652 vat_main_t *vam = &vat_main;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002653 void *oldheap;
2654 vat_json_node_t node;
2655 u8 *reply;
2656
2657 /* $$$$ make this real? */
2658 vat_json_init_object (&node);
2659 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2660 vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2661
Damjan Marion7bee80c2017-04-26 15:32:12 +02002662 reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002663
2664 /* Toss the shared-memory original... */
Nathan Skrzypczak0aa40132019-11-25 16:29:38 +01002665 oldheap = vl_msg_push_heap ();
Damjan Marion7cd468a2016-12-19 23:05:39 +01002666
2667 vec_free (reply);
2668
Nathan Skrzypczak0aa40132019-11-25 16:29:38 +01002669 vl_msg_pop_heap (oldheap);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002670
2671 vat_json_print (vam->ofp, &node);
2672 vat_json_free (&node);
2673
2674 vam->retval = ntohl (mp->retval);
2675 vam->result_ready = 1;
2676}
2677
Damjan Marion7cd468a2016-12-19 23:05:39 +01002678static u8 *
2679format_policer_type (u8 * s, va_list * va)
2680{
2681 u32 i = va_arg (*va, u32);
2682
Brian Russellc5299ff2021-02-09 10:16:58 +00002683 if (i == QOS_POLICER_TYPE_1R2C)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002684 s = format (s, "1r2c");
Brian Russellc5299ff2021-02-09 10:16:58 +00002685 else if (i == QOS_POLICER_TYPE_1R3C_RFC_2697)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002686 s = format (s, "1r3c");
Brian Russellc5299ff2021-02-09 10:16:58 +00002687 else if (i == QOS_POLICER_TYPE_2R3C_RFC_2698)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002688 s = format (s, "2r3c-2698");
Brian Russellc5299ff2021-02-09 10:16:58 +00002689 else if (i == QOS_POLICER_TYPE_2R3C_RFC_4115)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002690 s = format (s, "2r3c-4115");
Brian Russellc5299ff2021-02-09 10:16:58 +00002691 else if (i == QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002692 s = format (s, "2r3c-mef5cf1");
2693 else
2694 s = format (s, "ILLEGAL");
2695 return s;
2696}
2697
2698static u8 *
2699format_policer_rate_type (u8 * s, va_list * va)
2700{
2701 u32 i = va_arg (*va, u32);
2702
Brian Russellc5299ff2021-02-09 10:16:58 +00002703 if (i == QOS_RATE_KBPS)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002704 s = format (s, "kbps");
Brian Russellc5299ff2021-02-09 10:16:58 +00002705 else if (i == QOS_RATE_PPS)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002706 s = format (s, "pps");
2707 else
2708 s = format (s, "ILLEGAL");
2709 return s;
2710}
2711
2712static u8 *
2713format_policer_round_type (u8 * s, va_list * va)
2714{
2715 u32 i = va_arg (*va, u32);
2716
Brian Russellc5299ff2021-02-09 10:16:58 +00002717 if (i == QOS_ROUND_TO_CLOSEST)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002718 s = format (s, "closest");
Brian Russellc5299ff2021-02-09 10:16:58 +00002719 else if (i == QOS_ROUND_TO_UP)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002720 s = format (s, "up");
Brian Russellc5299ff2021-02-09 10:16:58 +00002721 else if (i == QOS_ROUND_TO_DOWN)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002722 s = format (s, "down");
2723 else
2724 s = format (s, "ILLEGAL");
2725 return s;
2726}
2727
2728static u8 *
2729format_policer_action_type (u8 * s, va_list * va)
2730{
2731 u32 i = va_arg (*va, u32);
2732
Brian Russellc5299ff2021-02-09 10:16:58 +00002733 if (i == QOS_ACTION_DROP)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002734 s = format (s, "drop");
Brian Russellc5299ff2021-02-09 10:16:58 +00002735 else if (i == QOS_ACTION_TRANSMIT)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002736 s = format (s, "transmit");
Brian Russellc5299ff2021-02-09 10:16:58 +00002737 else if (i == QOS_ACTION_MARK_AND_TRANSMIT)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002738 s = format (s, "mark-and-transmit");
2739 else
2740 s = format (s, "ILLEGAL");
2741 return s;
2742}
2743
2744static u8 *
2745format_dscp (u8 * s, va_list * va)
2746{
2747 u32 i = va_arg (*va, u32);
2748 char *t = 0;
2749
2750 switch (i)
2751 {
Brian Russelle3845d72021-02-08 15:33:18 +00002752#define _(v, f) \
2753 case IP_DSCP_##f: \
2754 return (format (s, "%s", #f));
2755 foreach_ip_dscp
Damjan Marion7cd468a2016-12-19 23:05:39 +01002756#undef _
Damjan Marion7cd468a2016-12-19 23:05:39 +01002757 }
2758 s = format (s, "%s", t);
Brian Russelle3845d72021-02-08 15:33:18 +00002759 return (format (s, "ILLEGAL"));
Damjan Marion7cd468a2016-12-19 23:05:39 +01002760}
2761
2762static void
2763vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
2764{
2765 vat_main_t *vam = &vat_main;
2766 u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
2767
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002768 if (mp->conform_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
2769 conform_dscp_str = format (0, "%U", format_dscp, mp->conform_action.dscp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002770 else
2771 conform_dscp_str = format (0, "");
2772
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002773 if (mp->exceed_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
2774 exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_action.dscp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002775 else
2776 exceed_dscp_str = format (0, "");
2777
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002778 if (mp->violate_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
2779 violate_dscp_str = format (0, "%U", format_dscp, mp->violate_action.dscp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002780 else
2781 violate_dscp_str = format (0, "");
2782
2783 print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
2784 "rate type %U, round type %U, %s rate, %s color-aware, "
2785 "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
2786 "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
2787 "conform action %U%s, exceed action %U%s, violate action %U%s",
2788 mp->name,
2789 format_policer_type, mp->type,
2790 ntohl (mp->cir),
2791 ntohl (mp->eir),
2792 clib_net_to_host_u64 (mp->cb),
2793 clib_net_to_host_u64 (mp->eb),
2794 format_policer_rate_type, mp->rate_type,
2795 format_policer_round_type, mp->round_type,
2796 mp->single_rate ? "single" : "dual",
2797 mp->color_aware ? "is" : "not",
2798 ntohl (mp->cir_tokens_per_period),
2799 ntohl (mp->pir_tokens_per_period),
2800 ntohl (mp->scale),
2801 ntohl (mp->current_limit),
2802 ntohl (mp->current_bucket),
2803 ntohl (mp->extended_limit),
2804 ntohl (mp->extended_bucket),
2805 clib_net_to_host_u64 (mp->last_update_time),
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002806 format_policer_action_type, mp->conform_action.type,
Damjan Marion7cd468a2016-12-19 23:05:39 +01002807 conform_dscp_str,
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002808 format_policer_action_type, mp->exceed_action.type,
Damjan Marion7cd468a2016-12-19 23:05:39 +01002809 exceed_dscp_str,
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002810 format_policer_action_type, mp->violate_action.type,
Damjan Marion7cd468a2016-12-19 23:05:39 +01002811 violate_dscp_str);
2812
2813 vec_free (conform_dscp_str);
2814 vec_free (exceed_dscp_str);
2815 vec_free (violate_dscp_str);
2816}
2817
2818static void vl_api_policer_details_t_handler_json
2819 (vl_api_policer_details_t * mp)
2820{
2821 vat_main_t *vam = &vat_main;
2822 vat_json_node_t *node;
2823 u8 *rate_type_str, *round_type_str, *type_str;
2824 u8 *conform_action_str, *exceed_action_str, *violate_action_str;
2825
2826 rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
2827 round_type_str =
2828 format (0, "%U", format_policer_round_type, mp->round_type);
2829 type_str = format (0, "%U", format_policer_type, mp->type);
2830 conform_action_str = format (0, "%U", format_policer_action_type,
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002831 mp->conform_action.type);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002832 exceed_action_str = format (0, "%U", format_policer_action_type,
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002833 mp->exceed_action.type);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002834 violate_action_str = format (0, "%U", format_policer_action_type,
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002835 mp->violate_action.type);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002836
2837 if (VAT_JSON_ARRAY != vam->json_tree.type)
2838 {
2839 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2840 vat_json_init_array (&vam->json_tree);
2841 }
2842 node = vat_json_array_add (&vam->json_tree);
2843
2844 vat_json_init_object (node);
2845 vat_json_object_add_string_copy (node, "name", mp->name);
2846 vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
2847 vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
Marek Gradzki59ed4902017-03-21 11:51:54 +01002848 vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
2849 vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
Damjan Marion7cd468a2016-12-19 23:05:39 +01002850 vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
2851 vat_json_object_add_string_copy (node, "round_type", round_type_str);
2852 vat_json_object_add_string_copy (node, "type", type_str);
2853 vat_json_object_add_uint (node, "single_rate", mp->single_rate);
2854 vat_json_object_add_uint (node, "color_aware", mp->color_aware);
2855 vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
2856 vat_json_object_add_uint (node, "cir_tokens_per_period",
2857 ntohl (mp->cir_tokens_per_period));
2858 vat_json_object_add_uint (node, "eir_tokens_per_period",
2859 ntohl (mp->pir_tokens_per_period));
2860 vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
2861 vat_json_object_add_uint (node, "current_bucket",
2862 ntohl (mp->current_bucket));
2863 vat_json_object_add_uint (node, "extended_limit",
2864 ntohl (mp->extended_limit));
2865 vat_json_object_add_uint (node, "extended_bucket",
2866 ntohl (mp->extended_bucket));
2867 vat_json_object_add_uint (node, "last_update_time",
2868 ntohl (mp->last_update_time));
2869 vat_json_object_add_string_copy (node, "conform_action",
2870 conform_action_str);
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002871 if (mp->conform_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002872 {
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002873 u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_action.dscp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002874 vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
2875 vec_free (dscp_str);
2876 }
2877 vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002878 if (mp->exceed_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002879 {
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002880 u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_action.dscp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002881 vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
2882 vec_free (dscp_str);
2883 }
2884 vat_json_object_add_string_copy (node, "violate_action",
2885 violate_action_str);
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002886 if (mp->violate_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002887 {
Jakub Grajciarcd01fb42020-03-02 13:16:53 +01002888 u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_action.dscp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002889 vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
2890 vec_free (dscp_str);
2891 }
2892
2893 vec_free (rate_type_str);
2894 vec_free (round_type_str);
2895 vec_free (type_str);
2896 vec_free (conform_action_str);
2897 vec_free (exceed_action_str);
2898 vec_free (violate_action_str);
2899}
2900
2901static void
2902vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
2903 mp)
2904{
2905 vat_main_t *vam = &vat_main;
2906 int i, count = ntohl (mp->count);
2907
2908 if (count > 0)
2909 print (vam->ofp, "classify table ids (%d) : ", count);
2910 for (i = 0; i < count; i++)
2911 {
2912 print (vam->ofp, "%d", ntohl (mp->ids[i]));
2913 print (vam->ofp, (i < count - 1) ? "," : "");
2914 }
2915 vam->retval = ntohl (mp->retval);
2916 vam->result_ready = 1;
2917}
2918
2919static void
2920 vl_api_classify_table_ids_reply_t_handler_json
2921 (vl_api_classify_table_ids_reply_t * mp)
2922{
2923 vat_main_t *vam = &vat_main;
2924 int i, count = ntohl (mp->count);
2925
2926 if (count > 0)
2927 {
2928 vat_json_node_t node;
2929
2930 vat_json_init_object (&node);
2931 for (i = 0; i < count; i++)
2932 {
2933 vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
2934 }
2935 vat_json_print (vam->ofp, &node);
2936 vat_json_free (&node);
2937 }
2938 vam->retval = ntohl (mp->retval);
2939 vam->result_ready = 1;
2940}
2941
2942static void
2943 vl_api_classify_table_by_interface_reply_t_handler
2944 (vl_api_classify_table_by_interface_reply_t * mp)
2945{
2946 vat_main_t *vam = &vat_main;
2947 u32 table_id;
2948
2949 table_id = ntohl (mp->l2_table_id);
2950 if (table_id != ~0)
2951 print (vam->ofp, "l2 table id : %d", table_id);
2952 else
2953 print (vam->ofp, "l2 table id : No input ACL tables configured");
2954 table_id = ntohl (mp->ip4_table_id);
2955 if (table_id != ~0)
2956 print (vam->ofp, "ip4 table id : %d", table_id);
2957 else
2958 print (vam->ofp, "ip4 table id : No input ACL tables configured");
2959 table_id = ntohl (mp->ip6_table_id);
2960 if (table_id != ~0)
2961 print (vam->ofp, "ip6 table id : %d", table_id);
2962 else
2963 print (vam->ofp, "ip6 table id : No input ACL tables configured");
2964 vam->retval = ntohl (mp->retval);
2965 vam->result_ready = 1;
2966}
2967
2968static void
2969 vl_api_classify_table_by_interface_reply_t_handler_json
2970 (vl_api_classify_table_by_interface_reply_t * mp)
2971{
2972 vat_main_t *vam = &vat_main;
2973 vat_json_node_t node;
2974
2975 vat_json_init_object (&node);
2976
2977 vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
2978 vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
2979 vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
2980
2981 vat_json_print (vam->ofp, &node);
2982 vat_json_free (&node);
2983
2984 vam->retval = ntohl (mp->retval);
2985 vam->result_ready = 1;
2986}
2987
2988static void vl_api_policer_add_del_reply_t_handler
2989 (vl_api_policer_add_del_reply_t * mp)
2990{
2991 vat_main_t *vam = &vat_main;
2992 i32 retval = ntohl (mp->retval);
2993 if (vam->async_mode)
2994 {
2995 vam->async_errors += (retval < 0);
2996 }
2997 else
2998 {
2999 vam->retval = retval;
3000 vam->result_ready = 1;
3001 if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3002 /*
3003 * Note: this is just barely thread-safe, depends on
3004 * the main thread spinning waiting for an answer...
3005 */
3006 errmsg ("policer index %d", ntohl (mp->policer_index));
3007 }
3008}
3009
3010static void vl_api_policer_add_del_reply_t_handler_json
3011 (vl_api_policer_add_del_reply_t * mp)
3012{
3013 vat_main_t *vam = &vat_main;
3014 vat_json_node_t node;
3015
3016 vat_json_init_object (&node);
3017 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3018 vat_json_object_add_uint (&node, "policer_index",
3019 ntohl (mp->policer_index));
3020
3021 vat_json_print (vam->ofp, &node);
3022 vat_json_free (&node);
3023
3024 vam->retval = ntohl (mp->retval);
3025 vam->result_ready = 1;
3026}
3027
3028/* Format hex dump. */
3029u8 *
3030format_hex_bytes (u8 * s, va_list * va)
3031{
3032 u8 *bytes = va_arg (*va, u8 *);
3033 int n_bytes = va_arg (*va, int);
3034 uword i;
3035
3036 /* Print short or long form depending on byte count. */
3037 uword short_form = n_bytes <= 32;
Christophe Fontained3c008d2017-10-02 18:10:54 +02003038 u32 indent = format_get_indent (s);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003039
3040 if (n_bytes == 0)
3041 return s;
3042
3043 for (i = 0; i < n_bytes; i++)
3044 {
3045 if (!short_form && (i % 32) == 0)
3046 s = format (s, "%08x: ", i);
3047 s = format (s, "%02x", bytes[i]);
3048 if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3049 s = format (s, "\n%U", format_white_space, indent);
3050 }
3051
3052 return s;
3053}
3054
3055static void
3056vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3057 * mp)
3058{
3059 vat_main_t *vam = &vat_main;
3060 i32 retval = ntohl (mp->retval);
3061 if (retval == 0)
3062 {
3063 print (vam->ofp, "classify table info :");
3064 print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
3065 ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3066 ntohl (mp->miss_next_index));
3067 print (vam->ofp, "nbuckets: %d skip: %d match: %d",
3068 ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3069 ntohl (mp->match_n_vectors));
3070 print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
3071 ntohl (mp->mask_length));
3072 }
3073 vam->retval = retval;
3074 vam->result_ready = 1;
3075}
3076
3077static void
3078 vl_api_classify_table_info_reply_t_handler_json
3079 (vl_api_classify_table_info_reply_t * mp)
3080{
3081 vat_main_t *vam = &vat_main;
3082 vat_json_node_t node;
3083
3084 i32 retval = ntohl (mp->retval);
3085 if (retval == 0)
3086 {
3087 vat_json_init_object (&node);
3088
3089 vat_json_object_add_int (&node, "sessions",
3090 ntohl (mp->active_sessions));
3091 vat_json_object_add_int (&node, "nexttbl",
3092 ntohl (mp->next_table_index));
3093 vat_json_object_add_int (&node, "nextnode",
3094 ntohl (mp->miss_next_index));
3095 vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3096 vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3097 vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3098 u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3099 ntohl (mp->mask_length), 0);
3100 vat_json_object_add_string_copy (&node, "mask", s);
3101
3102 vat_json_print (vam->ofp, &node);
3103 vat_json_free (&node);
3104 }
3105 vam->retval = ntohl (mp->retval);
3106 vam->result_ready = 1;
3107}
3108
3109static void
3110vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3111 mp)
3112{
3113 vat_main_t *vam = &vat_main;
3114
3115 print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3116 ntohl (mp->hit_next_index), ntohl (mp->advance),
3117 ntohl (mp->opaque_index));
3118 print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
3119 ntohl (mp->match_length));
3120}
3121
3122static void
3123 vl_api_classify_session_details_t_handler_json
3124 (vl_api_classify_session_details_t * mp)
3125{
3126 vat_main_t *vam = &vat_main;
3127 vat_json_node_t *node = NULL;
3128
3129 if (VAT_JSON_ARRAY != vam->json_tree.type)
3130 {
3131 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3132 vat_json_init_array (&vam->json_tree);
3133 }
3134 node = vat_json_array_add (&vam->json_tree);
3135
3136 vat_json_init_object (node);
3137 vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3138 vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3139 vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3140 u8 *s =
3141 format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3142 0);
3143 vat_json_object_add_string_copy (node, "match", s);
3144}
3145
3146static void vl_api_pg_create_interface_reply_t_handler
3147 (vl_api_pg_create_interface_reply_t * mp)
3148{
3149 vat_main_t *vam = &vat_main;
3150
3151 vam->retval = ntohl (mp->retval);
3152 vam->result_ready = 1;
3153}
3154
3155static void vl_api_pg_create_interface_reply_t_handler_json
3156 (vl_api_pg_create_interface_reply_t * mp)
3157{
3158 vat_main_t *vam = &vat_main;
3159 vat_json_node_t node;
3160
3161 i32 retval = ntohl (mp->retval);
3162 if (retval == 0)
3163 {
3164 vat_json_init_object (&node);
3165
3166 vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3167
3168 vat_json_print (vam->ofp, &node);
3169 vat_json_free (&node);
3170 }
3171 vam->retval = ntohl (mp->retval);
3172 vam->result_ready = 1;
3173}
3174
3175static void vl_api_policer_classify_details_t_handler
3176 (vl_api_policer_classify_details_t * mp)
3177{
3178 vat_main_t *vam = &vat_main;
3179
3180 print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3181 ntohl (mp->table_index));
3182}
3183
3184static void vl_api_policer_classify_details_t_handler_json
3185 (vl_api_policer_classify_details_t * mp)
3186{
3187 vat_main_t *vam = &vat_main;
3188 vat_json_node_t *node;
3189
3190 if (VAT_JSON_ARRAY != vam->json_tree.type)
3191 {
3192 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3193 vat_json_init_array (&vam->json_tree);
3194 }
3195 node = vat_json_array_add (&vam->json_tree);
3196
3197 vat_json_init_object (node);
3198 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3199 vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3200}
3201
Damjan Marion7cd468a2016-12-19 23:05:39 +01003202static void vl_api_flow_classify_details_t_handler
3203 (vl_api_flow_classify_details_t * mp)
3204{
3205 vat_main_t *vam = &vat_main;
3206
3207 print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3208 ntohl (mp->table_index));
3209}
3210
3211static void vl_api_flow_classify_details_t_handler_json
3212 (vl_api_flow_classify_details_t * mp)
3213{
3214 vat_main_t *vam = &vat_main;
3215 vat_json_node_t *node;
3216
3217 if (VAT_JSON_ARRAY != vam->json_tree.type)
3218 {
3219 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3220 vat_json_init_array (&vam->json_tree);
3221 }
3222 node = vat_json_array_add (&vam->json_tree);
3223
3224 vat_json_init_object (node);
3225 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3226 vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3227}
3228
Damjan Marion7cd468a2016-12-19 23:05:39 +01003229/*
3230 * Generate boilerplate reply handlers, which
3231 * dig the return value out of the xxx_reply_t API message,
3232 * stick it into vam->retval, and set vam->result_ready
3233 *
3234 * Could also do this by pointing N message decode slots at
3235 * a single function, but that could break in subtle ways.
3236 */
3237
3238#define foreach_standard_reply_retval_handler \
3239_(sw_interface_set_flags_reply) \
3240_(sw_interface_add_del_address_reply) \
Stevenad8015b2017-10-29 22:10:46 -07003241_(sw_interface_set_rx_mode_reply) \
Mohsin Kazmi54f7c512018-08-23 18:28:11 +02003242_(sw_interface_set_rx_placement_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003243_(sw_interface_set_table_reply) \
3244_(sw_interface_set_mpls_enable_reply) \
3245_(sw_interface_set_vpath_reply) \
3246_(sw_interface_set_vxlan_bypass_reply) \
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +08003247_(sw_interface_set_vxlan_gpe_bypass_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003248_(sw_interface_set_l2_bridge_reply) \
Steven Luonga1876b82019-08-20 16:58:00 -07003249_(sw_interface_set_bond_weight_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003250_(bridge_domain_add_del_reply) \
3251_(sw_interface_set_l2_xconnect_reply) \
3252_(l2fib_add_del_reply) \
Eyal Barif24991c2017-04-05 05:33:21 +03003253_(l2fib_flush_int_reply) \
3254_(l2fib_flush_bd_reply) \
Neale Ranns097fa662018-05-01 05:17:55 -07003255_(ip_route_add_del_reply) \
Neale Ranns28ab9cc2017-08-14 07:18:42 -07003256_(ip_table_add_del_reply) \
Neale Ranns9db6ada2019-11-08 12:42:31 +00003257_(ip_table_replace_begin_reply) \
3258_(ip_table_flush_reply) \
3259_(ip_table_replace_end_reply) \
Neale Ranns32e1c012016-11-22 17:07:28 +00003260_(ip_mroute_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003261_(mpls_route_add_del_reply) \
Neale Ranns28ab9cc2017-08-14 07:18:42 -07003262_(mpls_table_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003263_(mpls_ip_bind_unbind_reply) \
Neale Rannsd792d9c2017-10-21 10:53:20 -07003264_(bier_route_add_del_reply) \
3265_(bier_table_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003266_(sw_interface_set_unnumbered_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003267_(set_ip_flow_hash_reply) \
3268_(sw_interface_ip6_enable_disable_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003269_(l2_patch_add_del_reply) \
John Loe166fd92018-09-13 14:08:59 -04003270_(sr_mpls_policy_add_reply) \
3271_(sr_mpls_policy_mod_reply) \
3272_(sr_mpls_policy_del_reply) \
Pablo Camarillofb380952016-12-07 18:34:18 +01003273_(sr_policy_add_reply) \
3274_(sr_policy_mod_reply) \
3275_(sr_policy_del_reply) \
3276_(sr_localsid_add_del_reply) \
3277_(sr_steering_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003278_(classify_add_del_session_reply) \
3279_(classify_set_interface_ip_table_reply) \
3280_(classify_set_interface_l2_tables_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003281_(l2_fib_clear_table_reply) \
3282_(l2_interface_efp_filter_reply) \
3283_(l2_interface_vlan_tag_rewrite_reply) \
3284_(modify_vhost_user_if_reply) \
Steven Luong27ba5002020-11-17 13:30:44 -08003285_(modify_vhost_user_if_v2_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003286_(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) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003293_(delete_loopback_reply) \
3294_(bd_ip_mac_add_del_reply) \
John Loe26c81f2019-01-07 15:16:33 -05003295_(bd_ip_mac_flush_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003296_(want_interface_events_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003297_(sw_interface_clear_stats_reply) \
Dave Barach65457162017-10-10 17:53:14 -04003298_(ioam_enable_reply) \
3299_(ioam_disable_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003300_(af_packet_delete_reply) \
3301_(policer_classify_set_interface_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003302_(set_ipfix_exporter_reply) \
3303_(set_ipfix_classify_stream_reply) \
3304_(ipfix_classify_table_add_del_reply) \
3305_(flow_classify_set_interface_reply) \
3306_(sw_interface_span_enable_disable_reply) \
3307_(pg_capture_reply) \
3308_(pg_enable_disable_reply) \
Mohsin Kazmif382b062020-08-11 15:00:44 +02003309_(pg_interface_enable_disable_coalesce_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003310_(ip_source_and_port_range_check_add_del_reply) \
3311_(ip_source_and_port_range_check_interface_add_del_reply)\
3312_(delete_subif_reply) \
3313_(l2_interface_pbb_tag_rewrite_reply) \
Pavel Kotuceke88865d2018-11-28 07:42:11 +01003314_(set_punt_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003315_(feature_enable_disable_reply) \
Mohsin Kazmi29467b52019-10-08 19:42:38 +02003316_(feature_gso_enable_disable_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003317_(sw_interface_tag_add_del_reply) \
Matthew Smithe0792fd2019-07-12 11:48:24 -05003318_(sw_interface_add_del_mac_address_reply) \
Ole Troand7231612018-06-07 10:17:57 +02003319_(hw_interface_set_mtu_reply) \
Pavel Kotucek6899a302017-06-08 08:46:10 +02003320_(p2p_ethernet_add_reply) \
Steve Shin99a0e602017-07-01 04:16:20 +00003321_(p2p_ethernet_del_reply) \
Florin Corascea194d2017-10-02 00:18:51 -07003322_(tcp_configure_src_addresses_reply) \
Florin Coras595992c2017-11-06 17:17:08 -08003323_(session_rule_add_del_reply) \
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +01003324_(ip_container_proxy_add_del_reply) \
Igor Mikhailov (imichail)582caa32018-04-26 21:33:02 -07003325_(output_acl_set_interface_reply) \
Chenmin Sund0236f72020-07-27 17:54:40 +08003326_(qos_record_enable_disable_reply) \
3327_(flow_add_reply)
Damjan Marion7cd468a2016-12-19 23:05:39 +01003328
3329#define _(n) \
3330 static void vl_api_##n##_t_handler \
3331 (vl_api_##n##_t * mp) \
3332 { \
3333 vat_main_t * vam = &vat_main; \
3334 i32 retval = ntohl(mp->retval); \
3335 if (vam->async_mode) { \
3336 vam->async_errors += (retval < 0); \
3337 } else { \
3338 vam->retval = retval; \
3339 vam->result_ready = 1; \
3340 } \
3341 }
3342foreach_standard_reply_retval_handler;
3343#undef _
3344
3345#define _(n) \
3346 static void vl_api_##n##_t_handler_json \
3347 (vl_api_##n##_t * mp) \
3348 { \
3349 vat_main_t * vam = &vat_main; \
3350 vat_json_node_t node; \
3351 vat_json_init_object(&node); \
3352 vat_json_object_add_int(&node, "retval", ntohl(mp->retval)); \
3353 vat_json_print(vam->ofp, &node); \
3354 vam->retval = ntohl(mp->retval); \
3355 vam->result_ready = 1; \
3356 }
3357foreach_standard_reply_retval_handler;
3358#undef _
3359
3360/*
3361 * Table of message reply handlers, must include boilerplate handlers
3362 * we just generated
3363 */
3364
3365#define foreach_vpe_api_reply_msg \
3366_(CREATE_LOOPBACK_REPLY, create_loopback_reply) \
Jon Loeligerc83c3b72017-02-23 13:57:35 -06003367_(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003368_(SW_INTERFACE_DETAILS, sw_interface_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003369_(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply) \
3370_(CONTROL_PING_REPLY, control_ping_reply) \
3371_(CLI_REPLY, cli_reply) \
3372_(CLI_INBAND_REPLY, cli_inband_reply) \
3373_(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY, \
3374 sw_interface_add_del_address_reply) \
Stevenad8015b2017-10-29 22:10:46 -07003375_(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply) \
Mohsin Kazmi54f7c512018-08-23 18:28:11 +02003376_(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply) \
Mohsin Kazmif0b42f42018-09-10 18:11:00 +02003377_(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003378_(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply) \
3379_(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
3380_(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply) \
3381_(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +08003382_(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003383_(SW_INTERFACE_SET_L2_XCONNECT_REPLY, \
3384 sw_interface_set_l2_xconnect_reply) \
3385_(SW_INTERFACE_SET_L2_BRIDGE_REPLY, \
3386 sw_interface_set_l2_bridge_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003387_(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply) \
3388_(BRIDGE_DOMAIN_DETAILS, bridge_domain_details) \
Eyal Barifead6702017-04-04 04:46:32 +03003389_(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003390_(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply) \
Eyal Barif24991c2017-04-05 05:33:21 +03003391_(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply) \
3392_(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003393_(L2_FLAGS_REPLY, l2_flags_reply) \
3394_(BRIDGE_FLAGS_REPLY, bridge_flags_reply) \
Damjan Marion8389fb92017-10-13 18:29:53 +02003395_(TAP_CREATE_V2_REPLY, tap_create_v2_reply) \
3396_(TAP_DELETE_V2_REPLY, tap_delete_v2_reply) \
3397_(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details) \
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01003398_(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply) \
Mohsin Kazmi518251b2020-09-01 17:17:44 +00003399_(VIRTIO_PCI_CREATE_V2_REPLY, virtio_pci_create_v2_reply) \
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01003400_(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply) \
3401_(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details) \
Steven9cd2d7a2017-12-20 12:43:01 -08003402_(BOND_CREATE_REPLY, bond_create_reply) \
Steven Luongea717862020-07-30 07:31:40 -07003403_(BOND_CREATE2_REPLY, bond_create2_reply) \
Steven9cd2d7a2017-12-20 12:43:01 -08003404_(BOND_DELETE_REPLY, bond_delete_reply) \
Steven Luong4c4223e2020-07-15 08:44:54 -07003405_(BOND_ADD_MEMBER_REPLY, bond_add_member_reply) \
3406_(BOND_DETACH_MEMBER_REPLY, bond_detach_member_reply) \
Steven Luonga1876b82019-08-20 16:58:00 -07003407_(SW_INTERFACE_SET_BOND_WEIGHT_REPLY, sw_interface_set_bond_weight_reply) \
Steven Luong4c4223e2020-07-15 08:44:54 -07003408_(SW_BOND_INTERFACE_DETAILS, sw_bond_interface_details) \
3409_(SW_MEMBER_INTERFACE_DETAILS, sw_member_interface_details) \
Neale Ranns097fa662018-05-01 05:17:55 -07003410_(IP_ROUTE_ADD_DEL_REPLY, ip_route_add_del_reply) \
Neale Ranns28ab9cc2017-08-14 07:18:42 -07003411_(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply) \
Neale Ranns9db6ada2019-11-08 12:42:31 +00003412_(IP_TABLE_REPLACE_BEGIN_REPLY, ip_table_replace_begin_reply) \
3413_(IP_TABLE_FLUSH_REPLY, ip_table_flush_reply) \
3414_(IP_TABLE_REPLACE_END_REPLY, ip_table_replace_end_reply) \
Neale Ranns32e1c012016-11-22 17:07:28 +00003415_(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply) \
Neale Ranns28ab9cc2017-08-14 07:18:42 -07003416_(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003417_(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply) \
3418_(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply) \
Neale Rannsd792d9c2017-10-21 10:53:20 -07003419_(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply) \
3420_(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003421_(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply) \
3422_(SW_INTERFACE_SET_UNNUMBERED_REPLY, \
3423 sw_interface_set_unnumbered_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003424_(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply) \
3425_(CREATE_SUBIF_REPLY, create_subif_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003426_(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply) \
3427_(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY, \
3428 sw_interface_ip6_enable_disable_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003429_(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply) \
John Loe166fd92018-09-13 14:08:59 -04003430_(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply) \
3431_(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply) \
3432_(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply) \
Pablo Camarillofb380952016-12-07 18:34:18 +01003433_(SR_POLICY_ADD_REPLY, sr_policy_add_reply) \
3434_(SR_POLICY_MOD_REPLY, sr_policy_mod_reply) \
3435_(SR_POLICY_DEL_REPLY, sr_policy_del_reply) \
3436_(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply) \
3437_(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003438_(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply) \
3439_(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply) \
3440_(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY, \
3441classify_set_interface_ip_table_reply) \
3442_(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY, \
3443 classify_set_interface_l2_tables_reply) \
3444_(GET_NODE_INDEX_REPLY, get_node_index_reply) \
3445_(ADD_NODE_NEXT_REPLY, add_node_next_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003446_(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply) \
eyal bariaf86a482018-04-17 11:20:27 +03003447_(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003448_(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003449_(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply) \
3450_(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply) \
3451_(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3452_(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details) \
3453_(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply) \
3454_(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply) \
Steven Luong27ba5002020-11-17 13:30:44 -08003455_(CREATE_VHOST_USER_IF_V2_REPLY, create_vhost_user_if_v2_reply) \
3456_(MODIFY_VHOST_USER_IF_V2_REPLY, modify_vhost_user_if_v2_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003457_(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply) \
3458_(SHOW_VERSION_REPLY, show_version_reply) \
Mohsin Kazmi5d64c782018-09-11 20:27:09 +02003459_(SHOW_THREADS_REPLY, show_threads_reply) \
Ole Troan01384fe2017-05-12 11:55:35 +02003460_(L2_FIB_TABLE_DETAILS, l2_fib_table_details) \
John Loc7b43042018-04-13 16:46:22 -04003461_(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003462_(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details) \
3463_(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply) \
John Lo8d00fff2017-08-03 00:35:36 -04003464_(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply) \
3465_(L2_MACS_EVENT, l2_macs_event) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003466_(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply) \
3467_(IP_ADDRESS_DETAILS, ip_address_details) \
3468_(IP_DETAILS, ip_details) \
3469_(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply) \
3470_(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
Neale Ranns17dcec02019-01-09 21:22:20 -08003471_(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply) \
3472_(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply) \
Matthew Smith28029532017-09-26 13:33:44 -05003473_(IPSEC_SA_DETAILS, ipsec_sa_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003474_(DELETE_LOOPBACK_REPLY, delete_loopback_reply) \
3475_(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply) \
John Loe26c81f2019-01-07 15:16:33 -05003476_(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply) \
Mohsin Kazmi5d82d2f2018-08-13 19:17:54 +02003477_(BD_IP_MAC_DETAILS, bd_ip_mac_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003478_(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003479_(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003480_(GET_NODE_GRAPH_REPLY, get_node_graph_reply) \
3481_(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply) \
3482_(IOAM_ENABLE_REPLY, ioam_enable_reply) \
3483_(IOAM_DISABLE_REPLY, ioam_disable_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003484_(AF_PACKET_CREATE_REPLY, af_packet_create_reply) \
3485_(AF_PACKET_DELETE_REPLY, af_packet_delete_reply) \
Mohsin Kazmi04e0bb22018-05-28 18:55:37 +02003486_(AF_PACKET_DETAILS, af_packet_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003487_(POLICER_ADD_DEL_REPLY, policer_add_del_reply) \
3488_(POLICER_DETAILS, policer_details) \
3489_(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3490_(POLICER_CLASSIFY_DETAILS, policer_classify_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003491_(MPLS_TUNNEL_DETAILS, mpls_tunnel_details) \
Neale Ranns097fa662018-05-01 05:17:55 -07003492_(MPLS_TABLE_DETAILS, mpls_table_details) \
3493_(MPLS_ROUTE_DETAILS, mpls_route_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003494_(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply) \
3495_(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3496_(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply) \
3497_(CLASSIFY_SESSION_DETAILS, classify_session_details) \
3498_(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply) \
3499_(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details) \
3500_(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply) \
3501_(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details) \
3502_(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
3503_(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details) \
3504_(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
3505_(FLOW_CLASSIFY_DETAILS, flow_classify_details) \
3506_(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
3507_(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details) \
3508_(GET_NEXT_INDEX_REPLY, get_next_index_reply) \
3509_(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply) \
3510_(PG_CAPTURE_REPLY, pg_capture_reply) \
3511_(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply) \
Mohsin Kazmif382b062020-08-11 15:00:44 +02003512_(PG_INTERFACE_ENABLE_DISABLE_COALESCE_REPLY, pg_interface_enable_disable_coalesce_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003513_(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY, \
3514 ip_source_and_port_range_check_add_del_reply) \
3515_(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY, \
3516 ip_source_and_port_range_check_interface_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003517_(DELETE_SUBIF_REPLY, delete_subif_reply) \
3518_(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
Pavel Kotuceke88865d2018-11-28 07:42:11 +01003519_(SET_PUNT_REPLY, set_punt_reply) \
Neale Ranns097fa662018-05-01 05:17:55 -07003520_(IP_TABLE_DETAILS, ip_table_details) \
3521_(IP_ROUTE_DETAILS, ip_route_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003522_(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply) \
Mohsin Kazmi29467b52019-10-08 19:42:38 +02003523_(FEATURE_GSO_ENABLE_DISABLE_REPLY, feature_gso_enable_disable_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003524_(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply) \
Matthew Smithe0792fd2019-07-12 11:48:24 -05003525_(SW_INTERFACE_ADD_DEL_MAC_ADDRESS_REPLY, sw_interface_add_del_mac_address_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003526_(L2_XCONNECT_DETAILS, l2_xconnect_details) \
Ole Troand7231612018-06-07 10:17:57 +02003527_(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply) \
Pavel Kotucek6899a302017-06-08 08:46:10 +02003528_(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply) \
3529_(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply) \
Steve Shin99a0e602017-07-01 04:16:20 +00003530_(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply) \
Florin Corascea194d2017-10-02 00:18:51 -07003531_(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
Dave Barach65457162017-10-10 17:53:14 -04003532_(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply) \
Florin Coras6c36f532017-11-03 18:32:34 -07003533_(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply) \
Florin Coras595992c2017-11-06 17:17:08 -08003534_(SESSION_RULES_DETAILS, session_rules_details) \
3535_(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply) \
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +01003536_(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply) \
Chenmin Sund0236f72020-07-27 17:54:40 +08003537_(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply) \
3538_(FLOW_ADD_REPLY, flow_add_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003539
Dave Baracha1a093d2017-03-02 13:13:23 -05003540#define foreach_standalone_reply_msg \
Ole Troanf49ba0e2018-11-13 14:04:50 +01003541_(SW_INTERFACE_EVENT, sw_interface_event)
Dave Baracha1a093d2017-03-02 13:13:23 -05003542
Damjan Marion7cd468a2016-12-19 23:05:39 +01003543typedef struct
3544{
3545 u8 *name;
3546 u32 value;
3547} name_sort_t;
3548
Damjan Marion7cd468a2016-12-19 23:05:39 +01003549#define STR_VTR_OP_CASE(op) \
3550 case L2_VTR_ ## op: \
3551 return "" # op;
3552
3553static const char *
3554str_vtr_op (u32 vtr_op)
3555{
3556 switch (vtr_op)
3557 {
3558 STR_VTR_OP_CASE (DISABLED);
3559 STR_VTR_OP_CASE (PUSH_1);
3560 STR_VTR_OP_CASE (PUSH_2);
3561 STR_VTR_OP_CASE (POP_1);
3562 STR_VTR_OP_CASE (POP_2);
3563 STR_VTR_OP_CASE (TRANSLATE_1_1);
3564 STR_VTR_OP_CASE (TRANSLATE_1_2);
3565 STR_VTR_OP_CASE (TRANSLATE_2_1);
3566 STR_VTR_OP_CASE (TRANSLATE_2_2);
3567 }
3568
3569 return "UNKNOWN";
3570}
3571
3572static int
3573dump_sub_interface_table (vat_main_t * vam)
3574{
3575 const sw_interface_subif_t *sub = NULL;
3576
3577 if (vam->json_output)
3578 {
3579 clib_warning
3580 ("JSON output supported only for VPE API calls and dump_stats_table");
3581 return -99;
3582 }
3583
3584 print (vam->ofp,
3585 "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
3586 "Interface", "sw_if_index",
3587 "sub id", "dot1ad", "tags", "outer id",
3588 "inner id", "exact", "default", "outer any", "inner any");
3589
3590 vec_foreach (sub, vam->sw_if_subif_table)
3591 {
3592 print (vam->ofp,
3593 "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
3594 sub->interface_name,
3595 sub->sw_if_index,
3596 sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
3597 sub->sub_number_of_tags, sub->sub_outer_vlan_id,
3598 sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
3599 sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
3600 if (sub->vtr_op != L2_VTR_DISABLED)
3601 {
3602 print (vam->ofp,
3603 " vlan-tag-rewrite - op: %-14s [ dot1q: %d "
3604 "tag1: %d tag2: %d ]",
3605 str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
3606 sub->vtr_tag1, sub->vtr_tag2);
3607 }
3608 }
3609
3610 return 0;
3611}
3612
3613static int
3614name_sort_cmp (void *a1, void *a2)
3615{
3616 name_sort_t *n1 = a1;
3617 name_sort_t *n2 = a2;
3618
3619 return strcmp ((char *) n1->name, (char *) n2->name);
3620}
3621
3622static int
3623dump_interface_table (vat_main_t * vam)
3624{
3625 hash_pair_t *p;
3626 name_sort_t *nses = 0, *ns;
3627
3628 if (vam->json_output)
3629 {
3630 clib_warning
3631 ("JSON output supported only for VPE API calls and dump_stats_table");
3632 return -99;
3633 }
3634
3635 /* *INDENT-OFF* */
3636 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3637 ({
3638 vec_add2 (nses, ns, 1);
3639 ns->name = (u8 *)(p->key);
3640 ns->value = (u32) p->value[0];
3641 }));
3642 /* *INDENT-ON* */
3643
3644 vec_sort_with_function (nses, name_sort_cmp);
3645
3646 print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
3647 vec_foreach (ns, nses)
3648 {
3649 print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
3650 }
3651 vec_free (nses);
3652 return 0;
3653}
3654
3655static int
3656dump_ip_table (vat_main_t * vam, int is_ipv6)
3657{
3658 const ip_details_t *det = NULL;
3659 const ip_address_details_t *address = NULL;
3660 u32 i = ~0;
3661
3662 print (vam->ofp, "%-12s", "sw_if_index");
3663
3664 vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
3665 {
3666 i++;
3667 if (!det->present)
3668 {
3669 continue;
3670 }
3671 print (vam->ofp, "%-12d", i);
3672 print (vam->ofp, " %-30s%-13s", "Address", "Prefix length");
3673 if (!det->addr)
3674 {
3675 continue;
3676 }
3677 vec_foreach (address, det->addr)
3678 {
3679 print (vam->ofp,
3680 " %-30U%-13d",
3681 is_ipv6 ? format_ip6_address : format_ip4_address,
3682 address->ip, address->prefix_length);
3683 }
3684 }
3685
3686 return 0;
3687}
3688
3689static int
3690dump_ipv4_table (vat_main_t * vam)
3691{
3692 if (vam->json_output)
3693 {
3694 clib_warning
3695 ("JSON output supported only for VPE API calls and dump_stats_table");
3696 return -99;
3697 }
3698
3699 return dump_ip_table (vam, 0);
3700}
3701
3702static int
3703dump_ipv6_table (vat_main_t * vam)
3704{
3705 if (vam->json_output)
3706 {
3707 clib_warning
3708 ("JSON output supported only for VPE API calls and dump_stats_table");
3709 return -99;
3710 }
3711
3712 return dump_ip_table (vam, 1);
3713}
3714
Damjan Marion7cd468a2016-12-19 23:05:39 +01003715/*
Dave Barach59b25652017-09-10 15:04:27 -04003716 * Pass CLI buffers directly in the CLI_INBAND API message,
3717 * instead of an additional shared memory area.
Damjan Marion7cd468a2016-12-19 23:05:39 +01003718 */
3719static int
3720exec_inband (vat_main_t * vam)
3721{
3722 vl_api_cli_inband_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003723 unformat_input_t *i = vam->input;
Jon Loeliger56c7b012017-02-01 12:31:41 -06003724 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003725
3726 if (vec_len (i->buffer) == 0)
3727 return -1;
3728
3729 if (vam->exec_mode == 0 && unformat (i, "mode"))
3730 {
3731 vam->exec_mode = 1;
3732 return 0;
3733 }
3734 if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
3735 {
3736 vam->exec_mode = 0;
3737 return 0;
3738 }
3739
3740 /*
3741 * In order for the CLI command to work, it
3742 * must be a vector ending in \n, not a C-string ending
3743 * in \n\0.
3744 */
Jakub Grajciar2dbee932020-02-07 11:30:26 +01003745 M2 (CLI_INBAND, mp, vec_len (vam->input->buffer));
3746 vl_api_vec_to_api_string (vam->input->buffer, &mp->cmd);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003747
Jon Loeliger7bc770c2017-01-31 14:03:33 -06003748 S (mp);
Dave Barach59b25652017-09-10 15:04:27 -04003749 W (ret);
3750 /* json responses may or may not include a useful reply... */
3751 if (vec_len (vam->cmd_reply))
Dave Barachcf5e8482017-10-17 11:48:29 -04003752 print (vam->ofp, "%v", (char *) (vam->cmd_reply));
Jon Loeliger56c7b012017-02-01 12:31:41 -06003753 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003754}
3755
Dave Barach59b25652017-09-10 15:04:27 -04003756int
3757exec (vat_main_t * vam)
3758{
3759 return exec_inband (vam);
3760}
3761
Damjan Marion7cd468a2016-12-19 23:05:39 +01003762static int
3763api_create_loopback (vat_main_t * vam)
3764{
3765 unformat_input_t *i = vam->input;
3766 vl_api_create_loopback_t *mp;
Jon Loeligerc83c3b72017-02-23 13:57:35 -06003767 vl_api_create_loopback_instance_t *mp_lbi;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003768 u8 mac_address[6];
3769 u8 mac_set = 0;
Jon Loeligerc83c3b72017-02-23 13:57:35 -06003770 u8 is_specified = 0;
3771 u32 user_instance = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06003772 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003773
Dave Barachb7b92992018-10-17 10:38:51 -04003774 clib_memset (mac_address, 0, sizeof (mac_address));
Damjan Marion7cd468a2016-12-19 23:05:39 +01003775
3776 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3777 {
3778 if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
3779 mac_set = 1;
Jon Loeligerc83c3b72017-02-23 13:57:35 -06003780 if (unformat (i, "instance %d", &user_instance))
3781 is_specified = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003782 else
3783 break;
3784 }
3785
Jon Loeligerc83c3b72017-02-23 13:57:35 -06003786 if (is_specified)
3787 {
3788 M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
3789 mp_lbi->is_specified = is_specified;
3790 if (is_specified)
3791 mp_lbi->user_instance = htonl (user_instance);
3792 if (mac_set)
3793 clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
3794 S (mp_lbi);
3795 }
3796 else
3797 {
3798 /* Construct the API message */
3799 M (CREATE_LOOPBACK, mp);
3800 if (mac_set)
3801 clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
3802 S (mp);
3803 }
Damjan Marion7cd468a2016-12-19 23:05:39 +01003804
Jon Loeliger56c7b012017-02-01 12:31:41 -06003805 W (ret);
3806 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003807}
3808
3809static int
3810api_delete_loopback (vat_main_t * vam)
3811{
3812 unformat_input_t *i = vam->input;
3813 vl_api_delete_loopback_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003814 u32 sw_if_index = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06003815 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003816
3817 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3818 {
3819 if (unformat (i, "sw_if_index %d", &sw_if_index))
3820 ;
3821 else
3822 break;
3823 }
3824
3825 if (sw_if_index == ~0)
3826 {
3827 errmsg ("missing sw_if_index");
3828 return -99;
3829 }
3830
3831 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06003832 M (DELETE_LOOPBACK, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003833 mp->sw_if_index = ntohl (sw_if_index);
3834
Jon Loeliger7bc770c2017-01-31 14:03:33 -06003835 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06003836 W (ret);
3837 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003838}
3839
3840static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01003841api_want_interface_events (vat_main_t * vam)
3842{
3843 unformat_input_t *i = vam->input;
3844 vl_api_want_interface_events_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003845 int enable = -1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06003846 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003847
3848 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3849 {
3850 if (unformat (i, "enable"))
3851 enable = 1;
3852 else if (unformat (i, "disable"))
3853 enable = 0;
3854 else
3855 break;
3856 }
3857
3858 if (enable == -1)
3859 {
3860 errmsg ("missing enable|disable");
3861 return -99;
3862 }
3863
Jon Loeliger8a2aea32017-01-31 13:19:40 -06003864 M (WANT_INTERFACE_EVENTS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003865 mp->enable_disable = enable;
3866
3867 vam->interface_event_display = enable;
3868
Jon Loeliger7bc770c2017-01-31 14:03:33 -06003869 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06003870 W (ret);
3871 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003872}
3873
3874
3875/* Note: non-static, called once to set up the initial intfc table */
3876int
3877api_sw_interface_dump (vat_main_t * vam)
3878{
3879 vl_api_sw_interface_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -06003880 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003881 hash_pair_t *p;
3882 name_sort_t *nses = 0, *ns;
3883 sw_interface_subif_t *sub = NULL;
Jon Loeliger56c7b012017-02-01 12:31:41 -06003884 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003885
3886 /* Toss the old name table */
3887 /* *INDENT-OFF* */
3888 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3889 ({
3890 vec_add2 (nses, ns, 1);
3891 ns->name = (u8 *)(p->key);
3892 ns->value = (u32) p->value[0];
3893 }));
3894 /* *INDENT-ON* */
3895
3896 hash_free (vam->sw_if_index_by_interface_name);
3897
3898 vec_foreach (ns, nses) vec_free (ns->name);
3899
3900 vec_free (nses);
3901
3902 vec_foreach (sub, vam->sw_if_subif_table)
3903 {
3904 vec_free (sub->interface_name);
3905 }
3906 vec_free (vam->sw_if_subif_table);
3907
3908 /* recreate the interface name hash table */
3909 vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
3910
Dave Barachf72212e2018-01-11 10:25:07 -05003911 /*
3912 * Ask for all interface names. Otherwise, the epic catalog of
3913 * name filters becomes ridiculously long, and vat ends up needing
3914 * to be taught about new interface types.
3915 */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06003916 M (SW_INTERFACE_DUMP, mp);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06003917 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003918
3919 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -04003920 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06003921 S (mp_ping);
3922
Jon Loeliger56c7b012017-02-01 12:31:41 -06003923 W (ret);
3924 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003925}
3926
3927static int
3928api_sw_interface_set_flags (vat_main_t * vam)
3929{
3930 unformat_input_t *i = vam->input;
3931 vl_api_sw_interface_set_flags_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003932 u32 sw_if_index;
3933 u8 sw_if_index_set = 0;
Neale Rannsa07bd702017-08-07 07:53:49 -07003934 u8 admin_up = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06003935 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003936
3937 /* Parse args required to build the message */
3938 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3939 {
3940 if (unformat (i, "admin-up"))
3941 admin_up = 1;
3942 else if (unformat (i, "admin-down"))
3943 admin_up = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003944 else
3945 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
3946 sw_if_index_set = 1;
3947 else if (unformat (i, "sw_if_index %d", &sw_if_index))
3948 sw_if_index_set = 1;
3949 else
3950 break;
3951 }
3952
3953 if (sw_if_index_set == 0)
3954 {
3955 errmsg ("missing interface name or sw_if_index");
3956 return -99;
3957 }
3958
3959 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06003960 M (SW_INTERFACE_SET_FLAGS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003961 mp->sw_if_index = ntohl (sw_if_index);
Jakub Grajciar053204a2019-03-18 13:17:53 +01003962 mp->flags = ntohl ((admin_up) ? IF_STATUS_API_FLAG_ADMIN_UP : 0);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003963
3964 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06003965 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01003966
3967 /* Wait for a reply, return the good/bad news... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06003968 W (ret);
3969 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003970}
3971
3972static int
Stevenad8015b2017-10-29 22:10:46 -07003973api_sw_interface_set_rx_mode (vat_main_t * vam)
3974{
3975 unformat_input_t *i = vam->input;
3976 vl_api_sw_interface_set_rx_mode_t *mp;
3977 u32 sw_if_index;
3978 u8 sw_if_index_set = 0;
3979 int ret;
3980 u8 queue_id_valid = 0;
3981 u32 queue_id;
Damjan Marioneabd4242020-10-07 20:59:07 +02003982 vnet_hw_if_rx_mode mode = VNET_HW_IF_RX_MODE_UNKNOWN;
Stevenad8015b2017-10-29 22:10:46 -07003983
3984 /* Parse args required to build the message */
3985 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3986 {
3987 if (unformat (i, "queue %d", &queue_id))
3988 queue_id_valid = 1;
3989 else if (unformat (i, "polling"))
Damjan Marioneabd4242020-10-07 20:59:07 +02003990 mode = VNET_HW_IF_RX_MODE_POLLING;
Stevenad8015b2017-10-29 22:10:46 -07003991 else if (unformat (i, "interrupt"))
Damjan Marioneabd4242020-10-07 20:59:07 +02003992 mode = VNET_HW_IF_RX_MODE_INTERRUPT;
Stevenad8015b2017-10-29 22:10:46 -07003993 else if (unformat (i, "adaptive"))
Damjan Marioneabd4242020-10-07 20:59:07 +02003994 mode = VNET_HW_IF_RX_MODE_ADAPTIVE;
Stevenad8015b2017-10-29 22:10:46 -07003995 else
3996 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
3997 sw_if_index_set = 1;
3998 else if (unformat (i, "sw_if_index %d", &sw_if_index))
3999 sw_if_index_set = 1;
4000 else
4001 break;
4002 }
4003
4004 if (sw_if_index_set == 0)
4005 {
4006 errmsg ("missing interface name or sw_if_index");
4007 return -99;
4008 }
Damjan Marioneabd4242020-10-07 20:59:07 +02004009 if (mode == VNET_HW_IF_RX_MODE_UNKNOWN)
Stevenad8015b2017-10-29 22:10:46 -07004010 {
4011 errmsg ("missing rx-mode");
4012 return -99;
4013 }
4014
4015 /* Construct the API message */
4016 M (SW_INTERFACE_SET_RX_MODE, mp);
4017 mp->sw_if_index = ntohl (sw_if_index);
Jakub Grajciar053204a2019-03-18 13:17:53 +01004018 mp->mode = (vl_api_rx_mode_t) mode;
Stevenad8015b2017-10-29 22:10:46 -07004019 mp->queue_id_valid = queue_id_valid;
4020 mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
4021
4022 /* send it... */
4023 S (mp);
4024
4025 /* Wait for a reply, return the good/bad news... */
4026 W (ret);
4027 return ret;
4028}
4029
4030static int
Mohsin Kazmi54f7c512018-08-23 18:28:11 +02004031api_sw_interface_set_rx_placement (vat_main_t * vam)
4032{
4033 unformat_input_t *i = vam->input;
4034 vl_api_sw_interface_set_rx_placement_t *mp;
4035 u32 sw_if_index;
4036 u8 sw_if_index_set = 0;
4037 int ret;
4038 u8 is_main = 0;
4039 u32 queue_id, thread_index;
4040
4041 /* Parse args required to build the message */
4042 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4043 {
4044 if (unformat (i, "queue %d", &queue_id))
4045 ;
4046 else if (unformat (i, "main"))
4047 is_main = 1;
4048 else if (unformat (i, "worker %d", &thread_index))
4049 ;
4050 else
4051 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4052 sw_if_index_set = 1;
4053 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4054 sw_if_index_set = 1;
4055 else
4056 break;
4057 }
4058
4059 if (sw_if_index_set == 0)
4060 {
4061 errmsg ("missing interface name or sw_if_index");
4062 return -99;
4063 }
4064
4065 if (is_main)
4066 thread_index = 0;
4067 /* Construct the API message */
4068 M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
4069 mp->sw_if_index = ntohl (sw_if_index);
4070 mp->worker_id = ntohl (thread_index);
4071 mp->queue_id = ntohl (queue_id);
4072 mp->is_main = is_main;
4073
4074 /* send it... */
4075 S (mp);
4076 /* Wait for a reply, return the good/bad news... */
4077 W (ret);
4078 return ret;
4079}
4080
Mohsin Kazmif0b42f42018-09-10 18:11:00 +02004081static void vl_api_sw_interface_rx_placement_details_t_handler
4082 (vl_api_sw_interface_rx_placement_details_t * mp)
4083{
4084 vat_main_t *vam = &vat_main;
4085 u32 worker_id = ntohl (mp->worker_id);
4086
4087 print (vam->ofp,
4088 "\n%-11d %-11s %-6d %-5d %-9s",
4089 ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
4090 worker_id, ntohl (mp->queue_id),
4091 (mp->mode ==
4092 1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
4093}
4094
4095static void vl_api_sw_interface_rx_placement_details_t_handler_json
4096 (vl_api_sw_interface_rx_placement_details_t * mp)
4097{
4098 vat_main_t *vam = &vat_main;
4099 vat_json_node_t *node = NULL;
4100
4101 if (VAT_JSON_ARRAY != vam->json_tree.type)
4102 {
4103 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4104 vat_json_init_array (&vam->json_tree);
4105 }
4106 node = vat_json_array_add (&vam->json_tree);
4107
4108 vat_json_init_object (node);
4109 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4110 vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
4111 vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
4112 vat_json_object_add_uint (node, "mode", mp->mode);
4113}
4114
4115static int
4116api_sw_interface_rx_placement_dump (vat_main_t * vam)
4117{
4118 unformat_input_t *i = vam->input;
4119 vl_api_sw_interface_rx_placement_dump_t *mp;
4120 vl_api_control_ping_t *mp_ping;
4121 int ret;
4122 u32 sw_if_index;
4123 u8 sw_if_index_set = 0;
4124
4125 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4126 {
4127 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4128 sw_if_index_set++;
4129 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4130 sw_if_index_set++;
4131 else
4132 break;
4133 }
4134
4135 print (vam->ofp,
4136 "\n%-11s %-11s %-6s %-5s %-4s",
4137 "sw_if_index", "main/worker", "thread", "queue", "mode");
4138
4139 /* Dump Interface rx placement */
4140 M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
4141
4142 if (sw_if_index_set)
4143 mp->sw_if_index = htonl (sw_if_index);
4144 else
4145 mp->sw_if_index = ~0;
4146
4147 S (mp);
4148
4149 /* Use a control ping for synchronization */
4150 MPING (CONTROL_PING, mp_ping);
4151 S (mp_ping);
4152
4153 W (ret);
4154 return ret;
4155}
4156
Mohsin Kazmi54f7c512018-08-23 18:28:11 +02004157static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01004158api_sw_interface_clear_stats (vat_main_t * vam)
4159{
4160 unformat_input_t *i = vam->input;
4161 vl_api_sw_interface_clear_stats_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004162 u32 sw_if_index;
4163 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004164 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004165
4166 /* Parse args required to build the message */
4167 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4168 {
4169 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4170 sw_if_index_set = 1;
4171 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4172 sw_if_index_set = 1;
4173 else
4174 break;
4175 }
4176
4177 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004178 M (SW_INTERFACE_CLEAR_STATS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004179
4180 if (sw_if_index_set == 1)
4181 mp->sw_if_index = ntohl (sw_if_index);
4182 else
4183 mp->sw_if_index = ~0;
4184
4185 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004186 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004187
4188 /* Wait for a reply, return the good/bad news... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06004189 W (ret);
4190 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004191}
4192
Damjan Marion7cd468a2016-12-19 23:05:39 +01004193static int
4194api_sw_interface_add_del_address (vat_main_t * vam)
4195{
4196 unformat_input_t *i = vam->input;
4197 vl_api_sw_interface_add_del_address_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004198 u32 sw_if_index;
4199 u8 sw_if_index_set = 0;
4200 u8 is_add = 1, del_all = 0;
4201 u32 address_length = 0;
4202 u8 v4_address_set = 0;
4203 u8 v6_address_set = 0;
4204 ip4_address_t v4address;
4205 ip6_address_t v6address;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004206 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004207
4208 /* Parse args required to build the message */
4209 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4210 {
4211 if (unformat (i, "del-all"))
4212 del_all = 1;
4213 else if (unformat (i, "del"))
4214 is_add = 0;
4215 else
4216 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4217 sw_if_index_set = 1;
4218 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4219 sw_if_index_set = 1;
4220 else if (unformat (i, "%U/%d",
4221 unformat_ip4_address, &v4address, &address_length))
4222 v4_address_set = 1;
4223 else if (unformat (i, "%U/%d",
4224 unformat_ip6_address, &v6address, &address_length))
4225 v6_address_set = 1;
4226 else
4227 break;
4228 }
4229
4230 if (sw_if_index_set == 0)
4231 {
4232 errmsg ("missing interface name or sw_if_index");
4233 return -99;
4234 }
4235 if (v4_address_set && v6_address_set)
4236 {
4237 errmsg ("both v4 and v6 addresses set");
4238 return -99;
4239 }
4240 if (!v4_address_set && !v6_address_set && !del_all)
4241 {
4242 errmsg ("no addresses set");
4243 return -99;
4244 }
4245
4246 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004247 M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004248
4249 mp->sw_if_index = ntohl (sw_if_index);
4250 mp->is_add = is_add;
4251 mp->del_all = del_all;
4252 if (v6_address_set)
4253 {
Jakub Grajciar053204a2019-03-18 13:17:53 +01004254 mp->prefix.address.af = ADDRESS_IP6;
4255 clib_memcpy (mp->prefix.address.un.ip6, &v6address, sizeof (v6address));
Damjan Marion7cd468a2016-12-19 23:05:39 +01004256 }
4257 else
4258 {
Jakub Grajciar053204a2019-03-18 13:17:53 +01004259 mp->prefix.address.af = ADDRESS_IP4;
4260 clib_memcpy (mp->prefix.address.un.ip4, &v4address, sizeof (v4address));
Damjan Marion7cd468a2016-12-19 23:05:39 +01004261 }
Jakub Grajciar053204a2019-03-18 13:17:53 +01004262 mp->prefix.len = address_length;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004263
4264 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004265 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004266
4267 /* Wait for a reply, return good/bad news */
Jon Loeliger56c7b012017-02-01 12:31:41 -06004268 W (ret);
4269 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004270}
4271
4272static int
4273api_sw_interface_set_mpls_enable (vat_main_t * vam)
4274{
4275 unformat_input_t *i = vam->input;
4276 vl_api_sw_interface_set_mpls_enable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004277 u32 sw_if_index;
4278 u8 sw_if_index_set = 0;
4279 u8 enable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004280 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004281
4282 /* Parse args required to build the message */
4283 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4284 {
4285 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4286 sw_if_index_set = 1;
4287 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4288 sw_if_index_set = 1;
4289 else if (unformat (i, "disable"))
4290 enable = 0;
4291 else if (unformat (i, "dis"))
4292 enable = 0;
4293 else
4294 break;
4295 }
4296
4297 if (sw_if_index_set == 0)
4298 {
4299 errmsg ("missing interface name or sw_if_index");
4300 return -99;
4301 }
4302
4303 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004304 M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004305
4306 mp->sw_if_index = ntohl (sw_if_index);
4307 mp->enable = enable;
4308
4309 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004310 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004311
4312 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06004313 W (ret);
4314 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004315}
4316
4317static int
4318api_sw_interface_set_table (vat_main_t * vam)
4319{
4320 unformat_input_t *i = vam->input;
4321 vl_api_sw_interface_set_table_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004322 u32 sw_if_index, vrf_id = 0;
4323 u8 sw_if_index_set = 0;
4324 u8 is_ipv6 = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004325 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004326
4327 /* Parse args required to build the message */
4328 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4329 {
4330 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4331 sw_if_index_set = 1;
4332 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4333 sw_if_index_set = 1;
4334 else if (unformat (i, "vrf %d", &vrf_id))
4335 ;
4336 else if (unformat (i, "ipv6"))
4337 is_ipv6 = 1;
4338 else
4339 break;
4340 }
4341
4342 if (sw_if_index_set == 0)
4343 {
4344 errmsg ("missing interface name or sw_if_index");
4345 return -99;
4346 }
4347
4348 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004349 M (SW_INTERFACE_SET_TABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004350
4351 mp->sw_if_index = ntohl (sw_if_index);
4352 mp->is_ipv6 = is_ipv6;
4353 mp->vrf_id = ntohl (vrf_id);
4354
4355 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004356 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004357
4358 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06004359 W (ret);
4360 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004361}
4362
4363static void vl_api_sw_interface_get_table_reply_t_handler
4364 (vl_api_sw_interface_get_table_reply_t * mp)
4365{
4366 vat_main_t *vam = &vat_main;
4367
4368 print (vam->ofp, "%d", ntohl (mp->vrf_id));
4369
4370 vam->retval = ntohl (mp->retval);
4371 vam->result_ready = 1;
4372
4373}
4374
4375static void vl_api_sw_interface_get_table_reply_t_handler_json
4376 (vl_api_sw_interface_get_table_reply_t * mp)
4377{
4378 vat_main_t *vam = &vat_main;
4379 vat_json_node_t node;
4380
4381 vat_json_init_object (&node);
4382 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4383 vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
4384
4385 vat_json_print (vam->ofp, &node);
4386 vat_json_free (&node);
4387
4388 vam->retval = ntohl (mp->retval);
4389 vam->result_ready = 1;
4390}
4391
4392static int
4393api_sw_interface_get_table (vat_main_t * vam)
4394{
4395 unformat_input_t *i = vam->input;
4396 vl_api_sw_interface_get_table_t *mp;
4397 u32 sw_if_index;
4398 u8 sw_if_index_set = 0;
4399 u8 is_ipv6 = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004400 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004401
4402 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4403 {
4404 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4405 sw_if_index_set = 1;
4406 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4407 sw_if_index_set = 1;
4408 else if (unformat (i, "ipv6"))
4409 is_ipv6 = 1;
4410 else
4411 break;
4412 }
4413
4414 if (sw_if_index_set == 0)
4415 {
4416 errmsg ("missing interface name or sw_if_index");
4417 return -99;
4418 }
4419
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004420 M (SW_INTERFACE_GET_TABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004421 mp->sw_if_index = htonl (sw_if_index);
4422 mp->is_ipv6 = is_ipv6;
4423
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004424 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06004425 W (ret);
4426 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004427}
4428
4429static int
4430api_sw_interface_set_vpath (vat_main_t * vam)
4431{
4432 unformat_input_t *i = vam->input;
4433 vl_api_sw_interface_set_vpath_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004434 u32 sw_if_index = 0;
4435 u8 sw_if_index_set = 0;
4436 u8 is_enable = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004437 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004438
4439 /* Parse args required to build the message */
4440 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4441 {
4442 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4443 sw_if_index_set = 1;
4444 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4445 sw_if_index_set = 1;
4446 else if (unformat (i, "enable"))
4447 is_enable = 1;
4448 else if (unformat (i, "disable"))
4449 is_enable = 0;
4450 else
4451 break;
4452 }
4453
4454 if (sw_if_index_set == 0)
4455 {
4456 errmsg ("missing interface name or sw_if_index");
4457 return -99;
4458 }
4459
4460 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004461 M (SW_INTERFACE_SET_VPATH, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004462
4463 mp->sw_if_index = ntohl (sw_if_index);
4464 mp->enable = is_enable;
4465
4466 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004467 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004468
4469 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06004470 W (ret);
4471 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004472}
4473
4474static int
4475api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
4476{
4477 unformat_input_t *i = vam->input;
4478 vl_api_sw_interface_set_vxlan_bypass_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004479 u32 sw_if_index = 0;
4480 u8 sw_if_index_set = 0;
John Lo2b81eb82017-01-30 13:12:10 -05004481 u8 is_enable = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004482 u8 is_ipv6 = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004483 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004484
4485 /* Parse args required to build the message */
4486 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4487 {
4488 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4489 sw_if_index_set = 1;
4490 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4491 sw_if_index_set = 1;
4492 else if (unformat (i, "enable"))
4493 is_enable = 1;
4494 else if (unformat (i, "disable"))
4495 is_enable = 0;
4496 else if (unformat (i, "ip4"))
4497 is_ipv6 = 0;
4498 else if (unformat (i, "ip6"))
4499 is_ipv6 = 1;
4500 else
4501 break;
4502 }
4503
4504 if (sw_if_index_set == 0)
4505 {
4506 errmsg ("missing interface name or sw_if_index");
4507 return -99;
4508 }
4509
4510 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004511 M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004512
4513 mp->sw_if_index = ntohl (sw_if_index);
4514 mp->enable = is_enable;
4515 mp->is_ipv6 = is_ipv6;
4516
4517 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004518 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004519
4520 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06004521 W (ret);
4522 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004523}
4524
Marco Varleseb598f1d2017-09-19 14:25:28 +02004525static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01004526api_sw_interface_set_l2_xconnect (vat_main_t * vam)
4527{
4528 unformat_input_t *i = vam->input;
4529 vl_api_sw_interface_set_l2_xconnect_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004530 u32 rx_sw_if_index;
4531 u8 rx_sw_if_index_set = 0;
4532 u32 tx_sw_if_index;
4533 u8 tx_sw_if_index_set = 0;
4534 u8 enable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004535 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004536
4537 /* Parse args required to build the message */
4538 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4539 {
4540 if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
4541 rx_sw_if_index_set = 1;
4542 else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
4543 tx_sw_if_index_set = 1;
4544 else if (unformat (i, "rx"))
4545 {
4546 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4547 {
4548 if (unformat (i, "%U", api_unformat_sw_if_index, vam,
4549 &rx_sw_if_index))
4550 rx_sw_if_index_set = 1;
4551 }
4552 else
4553 break;
4554 }
4555 else if (unformat (i, "tx"))
4556 {
4557 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4558 {
4559 if (unformat (i, "%U", api_unformat_sw_if_index, vam,
4560 &tx_sw_if_index))
4561 tx_sw_if_index_set = 1;
4562 }
4563 else
4564 break;
4565 }
4566 else if (unformat (i, "enable"))
4567 enable = 1;
4568 else if (unformat (i, "disable"))
4569 enable = 0;
4570 else
4571 break;
4572 }
4573
4574 if (rx_sw_if_index_set == 0)
4575 {
4576 errmsg ("missing rx interface name or rx_sw_if_index");
4577 return -99;
4578 }
4579
4580 if (enable && (tx_sw_if_index_set == 0))
4581 {
4582 errmsg ("missing tx interface name or tx_sw_if_index");
4583 return -99;
4584 }
4585
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004586 M (SW_INTERFACE_SET_L2_XCONNECT, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004587
4588 mp->rx_sw_if_index = ntohl (rx_sw_if_index);
4589 mp->tx_sw_if_index = ntohl (tx_sw_if_index);
4590 mp->enable = enable;
4591
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004592 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06004593 W (ret);
4594 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004595}
4596
4597static int
4598api_sw_interface_set_l2_bridge (vat_main_t * vam)
4599{
4600 unformat_input_t *i = vam->input;
4601 vl_api_sw_interface_set_l2_bridge_t *mp;
Neale Rannsb4743802018-09-05 09:13:57 -07004602 vl_api_l2_port_type_t port_type;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004603 u32 rx_sw_if_index;
4604 u8 rx_sw_if_index_set = 0;
4605 u32 bd_id;
4606 u8 bd_id_set = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004607 u32 shg = 0;
4608 u8 enable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004609 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004610
Neale Rannsb4743802018-09-05 09:13:57 -07004611 port_type = L2_API_PORT_TYPE_NORMAL;
4612
Damjan Marion7cd468a2016-12-19 23:05:39 +01004613 /* Parse args required to build the message */
4614 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4615 {
4616 if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
4617 rx_sw_if_index_set = 1;
4618 else if (unformat (i, "bd_id %d", &bd_id))
4619 bd_id_set = 1;
4620 else
4621 if (unformat
4622 (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
4623 rx_sw_if_index_set = 1;
4624 else if (unformat (i, "shg %d", &shg))
4625 ;
4626 else if (unformat (i, "bvi"))
Neale Rannsb4743802018-09-05 09:13:57 -07004627 port_type = L2_API_PORT_TYPE_BVI;
4628 else if (unformat (i, "uu-fwd"))
4629 port_type = L2_API_PORT_TYPE_UU_FWD;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004630 else if (unformat (i, "enable"))
4631 enable = 1;
4632 else if (unformat (i, "disable"))
4633 enable = 0;
4634 else
4635 break;
4636 }
4637
4638 if (rx_sw_if_index_set == 0)
4639 {
4640 errmsg ("missing rx interface name or sw_if_index");
4641 return -99;
4642 }
4643
4644 if (enable && (bd_id_set == 0))
4645 {
4646 errmsg ("missing bridge domain");
4647 return -99;
4648 }
4649
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004650 M (SW_INTERFACE_SET_L2_BRIDGE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004651
4652 mp->rx_sw_if_index = ntohl (rx_sw_if_index);
4653 mp->bd_id = ntohl (bd_id);
4654 mp->shg = (u8) shg;
Neale Rannsb4743802018-09-05 09:13:57 -07004655 mp->port_type = ntohl (port_type);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004656 mp->enable = enable;
4657
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004658 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06004659 W (ret);
4660 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004661}
4662
4663static int
4664api_bridge_domain_dump (vat_main_t * vam)
4665{
4666 unformat_input_t *i = vam->input;
4667 vl_api_bridge_domain_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -06004668 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004669 u32 bd_id = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004670 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004671
4672 /* Parse args required to build the message */
4673 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4674 {
4675 if (unformat (i, "bd_id %d", &bd_id))
4676 ;
4677 else
4678 break;
4679 }
4680
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004681 M (BRIDGE_DOMAIN_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004682 mp->bd_id = ntohl (bd_id);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004683 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004684
4685 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -04004686 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06004687 S (mp_ping);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004688
Jon Loeliger56c7b012017-02-01 12:31:41 -06004689 W (ret);
4690 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004691}
4692
4693static int
4694api_bridge_domain_add_del (vat_main_t * vam)
4695{
4696 unformat_input_t *i = vam->input;
4697 vl_api_bridge_domain_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004698 u32 bd_id = ~0;
4699 u8 is_add = 1;
4700 u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
Jerome Tollet50570ec2017-09-14 12:53:56 +01004701 u8 *bd_tag = NULL;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004702 u32 mac_age = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004703 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004704
4705 /* Parse args required to build the message */
4706 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4707 {
4708 if (unformat (i, "bd_id %d", &bd_id))
4709 ;
4710 else if (unformat (i, "flood %d", &flood))
4711 ;
4712 else if (unformat (i, "uu-flood %d", &uu_flood))
4713 ;
4714 else if (unformat (i, "forward %d", &forward))
4715 ;
4716 else if (unformat (i, "learn %d", &learn))
4717 ;
4718 else if (unformat (i, "arp-term %d", &arp_term))
4719 ;
4720 else if (unformat (i, "mac-age %d", &mac_age))
4721 ;
Jerome Tollet50570ec2017-09-14 12:53:56 +01004722 else if (unformat (i, "bd-tag %s", &bd_tag))
4723 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004724 else if (unformat (i, "del"))
4725 {
4726 is_add = 0;
4727 flood = uu_flood = forward = learn = 0;
4728 }
4729 else
4730 break;
4731 }
4732
4733 if (bd_id == ~0)
4734 {
4735 errmsg ("missing bridge domain");
Jerome Tollet50570ec2017-09-14 12:53:56 +01004736 ret = -99;
4737 goto done;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004738 }
4739
4740 if (mac_age > 255)
4741 {
4742 errmsg ("mac age must be less than 256 ");
Jerome Tollet50570ec2017-09-14 12:53:56 +01004743 ret = -99;
4744 goto done;
4745 }
4746
John Lo70bfcaf2017-11-14 13:19:26 -05004747 if ((bd_tag) && (vec_len (bd_tag) > 63))
Jerome Tollet50570ec2017-09-14 12:53:56 +01004748 {
4749 errmsg ("bd-tag cannot be longer than 63");
4750 ret = -99;
4751 goto done;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004752 }
4753
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004754 M (BRIDGE_DOMAIN_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004755
4756 mp->bd_id = ntohl (bd_id);
4757 mp->flood = flood;
4758 mp->uu_flood = uu_flood;
4759 mp->forward = forward;
4760 mp->learn = learn;
4761 mp->arp_term = arp_term;
4762 mp->is_add = is_add;
4763 mp->mac_age = (u8) mac_age;
Jerome Tollet50570ec2017-09-14 12:53:56 +01004764 if (bd_tag)
John Lo70bfcaf2017-11-14 13:19:26 -05004765 {
4766 clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
4767 mp->bd_tag[vec_len (bd_tag)] = 0;
4768 }
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004769 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06004770 W (ret);
Jerome Tollet50570ec2017-09-14 12:53:56 +01004771
4772done:
4773 vec_free (bd_tag);
Jon Loeliger56c7b012017-02-01 12:31:41 -06004774 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004775}
4776
4777static int
Eyal Barif24991c2017-04-05 05:33:21 +03004778api_l2fib_flush_bd (vat_main_t * vam)
4779{
4780 unformat_input_t *i = vam->input;
4781 vl_api_l2fib_flush_bd_t *mp;
4782 u32 bd_id = ~0;
4783 int ret;
4784
4785 /* Parse args required to build the message */
4786 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4787 {
4788 if (unformat (i, "bd_id %d", &bd_id));
4789 else
4790 break;
4791 }
4792
4793 if (bd_id == ~0)
4794 {
4795 errmsg ("missing bridge domain");
4796 return -99;
4797 }
4798
4799 M (L2FIB_FLUSH_BD, mp);
4800
4801 mp->bd_id = htonl (bd_id);
4802
4803 S (mp);
4804 W (ret);
4805 return ret;
4806}
4807
4808static int
4809api_l2fib_flush_int (vat_main_t * vam)
4810{
4811 unformat_input_t *i = vam->input;
4812 vl_api_l2fib_flush_int_t *mp;
4813 u32 sw_if_index = ~0;
4814 int ret;
4815
4816 /* Parse args required to build the message */
4817 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4818 {
4819 if (unformat (i, "sw_if_index %d", &sw_if_index));
4820 else
4821 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
4822 else
4823 break;
4824 }
4825
4826 if (sw_if_index == ~0)
4827 {
4828 errmsg ("missing interface name or sw_if_index");
4829 return -99;
4830 }
4831
4832 M (L2FIB_FLUSH_INT, mp);
4833
4834 mp->sw_if_index = ntohl (sw_if_index);
4835
4836 S (mp);
4837 W (ret);
4838 return ret;
4839}
4840
4841static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01004842api_l2fib_add_del (vat_main_t * vam)
4843{
4844 unformat_input_t *i = vam->input;
4845 vl_api_l2fib_add_del_t *mp;
4846 f64 timeout;
Mohsin Kazmi57938f62017-10-27 21:28:07 +02004847 u8 mac[6] = { 0 };
Damjan Marion7cd468a2016-12-19 23:05:39 +01004848 u8 mac_set = 0;
4849 u32 bd_id;
4850 u8 bd_id_set = 0;
John Lo7dbd7262018-05-31 10:25:18 -04004851 u32 sw_if_index = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004852 u8 sw_if_index_set = 0;
4853 u8 is_add = 1;
4854 u8 static_mac = 0;
4855 u8 filter_mac = 0;
4856 u8 bvi_mac = 0;
4857 int count = 1;
4858 f64 before = 0;
4859 int j;
4860
4861 /* Parse args required to build the message */
4862 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4863 {
Mohsin Kazmi57938f62017-10-27 21:28:07 +02004864 if (unformat (i, "mac %U", unformat_ethernet_address, mac))
Damjan Marion7cd468a2016-12-19 23:05:39 +01004865 mac_set = 1;
4866 else if (unformat (i, "bd_id %d", &bd_id))
4867 bd_id_set = 1;
4868 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4869 sw_if_index_set = 1;
4870 else if (unformat (i, "sw_if"))
4871 {
4872 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4873 {
4874 if (unformat
4875 (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4876 sw_if_index_set = 1;
4877 }
4878 else
4879 break;
4880 }
4881 else if (unformat (i, "static"))
4882 static_mac = 1;
4883 else if (unformat (i, "filter"))
4884 {
4885 filter_mac = 1;
4886 static_mac = 1;
4887 }
4888 else if (unformat (i, "bvi"))
4889 {
4890 bvi_mac = 1;
4891 static_mac = 1;
4892 }
4893 else if (unformat (i, "del"))
4894 is_add = 0;
4895 else if (unformat (i, "count %d", &count))
4896 ;
4897 else
4898 break;
4899 }
4900
4901 if (mac_set == 0)
4902 {
4903 errmsg ("missing mac address");
4904 return -99;
4905 }
4906
4907 if (bd_id_set == 0)
4908 {
4909 errmsg ("missing bridge domain");
4910 return -99;
4911 }
4912
4913 if (is_add && sw_if_index_set == 0 && filter_mac == 0)
4914 {
4915 errmsg ("missing interface name or sw_if_index");
4916 return -99;
4917 }
4918
4919 if (count > 1)
4920 {
4921 /* Turn on async mode */
4922 vam->async_mode = 1;
4923 vam->async_errors = 0;
4924 before = vat_time_now (vam);
4925 }
4926
4927 for (j = 0; j < count; j++)
4928 {
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004929 M (L2FIB_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004930
Mohsin Kazmi57938f62017-10-27 21:28:07 +02004931 clib_memcpy (mp->mac, mac, 6);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004932 mp->bd_id = ntohl (bd_id);
4933 mp->is_add = is_add;
John Lo7dbd7262018-05-31 10:25:18 -04004934 mp->sw_if_index = ntohl (sw_if_index);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004935
4936 if (is_add)
4937 {
Damjan Marion7cd468a2016-12-19 23:05:39 +01004938 mp->static_mac = static_mac;
4939 mp->filter_mac = filter_mac;
4940 mp->bvi_mac = bvi_mac;
4941 }
Mohsin Kazmi57938f62017-10-27 21:28:07 +02004942 increment_mac_address (mac);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004943 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004944 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004945 }
4946
4947 if (count > 1)
4948 {
Jon Loeliger2d23eca2017-02-01 13:09:58 -06004949 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004950 f64 after;
4951
4952 /* Shut off async mode */
4953 vam->async_mode = 0;
4954
Dave Barach59b25652017-09-10 15:04:27 -04004955 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06004956 S (mp_ping);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004957
4958 timeout = vat_time_now (vam) + 1.0;
4959 while (vat_time_now (vam) < timeout)
4960 if (vam->result_ready == 1)
4961 goto out;
4962 vam->retval = -99;
4963
4964 out:
4965 if (vam->retval == -99)
4966 errmsg ("timeout");
4967
4968 if (vam->async_errors > 0)
4969 {
4970 errmsg ("%d asynchronous errors", vam->async_errors);
4971 vam->retval = -98;
4972 }
4973 vam->async_errors = 0;
4974 after = vat_time_now (vam);
4975
4976 print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
4977 count, after - before, count / (after - before));
4978 }
4979 else
4980 {
Jon Loeliger56c7b012017-02-01 12:31:41 -06004981 int ret;
4982
Damjan Marion7cd468a2016-12-19 23:05:39 +01004983 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06004984 W (ret);
4985 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004986 }
4987 /* Return the good/bad news */
4988 return (vam->retval);
4989}
4990
4991static int
Eyal Barifead6702017-04-04 04:46:32 +03004992api_bridge_domain_set_mac_age (vat_main_t * vam)
4993{
4994 unformat_input_t *i = vam->input;
4995 vl_api_bridge_domain_set_mac_age_t *mp;
4996 u32 bd_id = ~0;
4997 u32 mac_age = 0;
4998 int ret;
4999
5000 /* Parse args required to build the message */
5001 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5002 {
5003 if (unformat (i, "bd_id %d", &bd_id));
5004 else if (unformat (i, "mac-age %d", &mac_age));
5005 else
5006 break;
5007 }
5008
5009 if (bd_id == ~0)
5010 {
5011 errmsg ("missing bridge domain");
5012 return -99;
5013 }
5014
5015 if (mac_age > 255)
5016 {
5017 errmsg ("mac age must be less than 256 ");
5018 return -99;
5019 }
5020
5021 M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
5022
5023 mp->bd_id = htonl (bd_id);
5024 mp->mac_age = (u8) mac_age;
5025
5026 S (mp);
5027 W (ret);
5028 return ret;
5029}
5030
5031static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01005032api_l2_flags (vat_main_t * vam)
5033{
5034 unformat_input_t *i = vam->input;
5035 vl_api_l2_flags_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005036 u32 sw_if_index;
John Lo8d00fff2017-08-03 00:35:36 -04005037 u32 flags = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005038 u8 sw_if_index_set = 0;
John Lo8d00fff2017-08-03 00:35:36 -04005039 u8 is_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005040 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005041
5042 /* Parse args required to build the message */
5043 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5044 {
5045 if (unformat (i, "sw_if_index %d", &sw_if_index))
5046 sw_if_index_set = 1;
5047 else if (unformat (i, "sw_if"))
5048 {
5049 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5050 {
5051 if (unformat
5052 (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5053 sw_if_index_set = 1;
5054 }
5055 else
5056 break;
5057 }
5058 else if (unformat (i, "learn"))
John Lo8d00fff2017-08-03 00:35:36 -04005059 flags |= L2_LEARN;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005060 else if (unformat (i, "forward"))
John Lo8d00fff2017-08-03 00:35:36 -04005061 flags |= L2_FWD;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005062 else if (unformat (i, "flood"))
John Lo8d00fff2017-08-03 00:35:36 -04005063 flags |= L2_FLOOD;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005064 else if (unformat (i, "uu-flood"))
John Lo8d00fff2017-08-03 00:35:36 -04005065 flags |= L2_UU_FLOOD;
5066 else if (unformat (i, "arp-term"))
5067 flags |= L2_ARP_TERM;
5068 else if (unformat (i, "off"))
5069 is_set = 0;
5070 else if (unformat (i, "disable"))
5071 is_set = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005072 else
5073 break;
5074 }
5075
5076 if (sw_if_index_set == 0)
5077 {
5078 errmsg ("missing interface name or sw_if_index");
5079 return -99;
5080 }
5081
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005082 M (L2_FLAGS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005083
5084 mp->sw_if_index = ntohl (sw_if_index);
John Lo8d00fff2017-08-03 00:35:36 -04005085 mp->feature_bitmap = ntohl (flags);
5086 mp->is_set = is_set;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005087
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005088 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06005089 W (ret);
5090 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005091}
5092
5093static int
5094api_bridge_flags (vat_main_t * vam)
5095{
5096 unformat_input_t *i = vam->input;
5097 vl_api_bridge_flags_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005098 u32 bd_id;
5099 u8 bd_id_set = 0;
5100 u8 is_set = 1;
Neale Rannsb4743802018-09-05 09:13:57 -07005101 bd_flags_t flags = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005102 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005103
5104 /* Parse args required to build the message */
5105 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5106 {
5107 if (unformat (i, "bd_id %d", &bd_id))
5108 bd_id_set = 1;
5109 else if (unformat (i, "learn"))
Neale Rannsb4743802018-09-05 09:13:57 -07005110 flags |= BRIDGE_API_FLAG_LEARN;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005111 else if (unformat (i, "forward"))
Neale Rannsb4743802018-09-05 09:13:57 -07005112 flags |= BRIDGE_API_FLAG_FWD;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005113 else if (unformat (i, "flood"))
Neale Rannsb4743802018-09-05 09:13:57 -07005114 flags |= BRIDGE_API_FLAG_FLOOD;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005115 else if (unformat (i, "uu-flood"))
Neale Rannsb4743802018-09-05 09:13:57 -07005116 flags |= BRIDGE_API_FLAG_UU_FLOOD;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005117 else if (unformat (i, "arp-term"))
Neale Rannsb4743802018-09-05 09:13:57 -07005118 flags |= BRIDGE_API_FLAG_ARP_TERM;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005119 else if (unformat (i, "off"))
5120 is_set = 0;
5121 else if (unformat (i, "disable"))
5122 is_set = 0;
5123 else
5124 break;
5125 }
5126
5127 if (bd_id_set == 0)
5128 {
5129 errmsg ("missing bridge domain");
5130 return -99;
5131 }
5132
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005133 M (BRIDGE_FLAGS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005134
5135 mp->bd_id = ntohl (bd_id);
Neale Rannsb4743802018-09-05 09:13:57 -07005136 mp->flags = ntohl (flags);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005137 mp->is_set = is_set;
5138
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005139 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06005140 W (ret);
5141 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005142}
5143
5144static int
5145api_bd_ip_mac_add_del (vat_main_t * vam)
5146{
Neale Ranns4d5b9172018-10-24 02:57:49 -07005147 vl_api_address_t ip = VL_API_ZERO_ADDRESS;
Ole Troan8006c6a2018-12-17 12:02:26 +01005148 vl_api_mac_address_t mac = { 0 };
Damjan Marion7cd468a2016-12-19 23:05:39 +01005149 unformat_input_t *i = vam->input;
5150 vl_api_bd_ip_mac_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005151 u32 bd_id;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005152 u8 is_add = 1;
5153 u8 bd_id_set = 0;
5154 u8 ip_set = 0;
5155 u8 mac_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005156 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005157
5158
5159 /* Parse args required to build the message */
5160 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5161 {
5162 if (unformat (i, "bd_id %d", &bd_id))
5163 {
5164 bd_id_set++;
5165 }
Neale Ranns4d5b9172018-10-24 02:57:49 -07005166 else if (unformat (i, "%U", unformat_vl_api_address, &ip))
Damjan Marion7cd468a2016-12-19 23:05:39 +01005167 {
5168 ip_set++;
5169 }
Neale Ranns4d5b9172018-10-24 02:57:49 -07005170 else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
Damjan Marion7cd468a2016-12-19 23:05:39 +01005171 {
5172 mac_set++;
5173 }
5174 else if (unformat (i, "del"))
5175 is_add = 0;
5176 else
5177 break;
5178 }
5179
5180 if (bd_id_set == 0)
5181 {
5182 errmsg ("missing bridge domain");
5183 return -99;
5184 }
5185 else if (ip_set == 0)
5186 {
5187 errmsg ("missing IP address");
5188 return -99;
5189 }
5190 else if (mac_set == 0)
5191 {
5192 errmsg ("missing MAC address");
5193 return -99;
5194 }
5195
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005196 M (BD_IP_MAC_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005197
Neale Rannsbc764c82019-06-19 07:07:13 -07005198 mp->entry.bd_id = ntohl (bd_id);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005199 mp->is_add = is_add;
Neale Ranns4d5b9172018-10-24 02:57:49 -07005200
Neale Rannsbc764c82019-06-19 07:07:13 -07005201 clib_memcpy (&mp->entry.ip, &ip, sizeof (ip));
5202 clib_memcpy (&mp->entry.mac, &mac, sizeof (mac));
Neale Ranns4d5b9172018-10-24 02:57:49 -07005203
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005204 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06005205 W (ret);
5206 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005207}
5208
John Loe26c81f2019-01-07 15:16:33 -05005209static int
5210api_bd_ip_mac_flush (vat_main_t * vam)
5211{
5212 unformat_input_t *i = vam->input;
5213 vl_api_bd_ip_mac_flush_t *mp;
5214 u32 bd_id;
5215 u8 bd_id_set = 0;
5216 int ret;
5217
5218 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5219 {
5220 if (unformat (i, "bd_id %d", &bd_id))
5221 {
5222 bd_id_set++;
5223 }
5224 else
5225 break;
5226 }
5227
5228 if (bd_id_set == 0)
5229 {
5230 errmsg ("missing bridge domain");
5231 return -99;
5232 }
5233
5234 M (BD_IP_MAC_FLUSH, mp);
5235
5236 mp->bd_id = ntohl (bd_id);
5237
5238 S (mp);
5239 W (ret);
5240 return ret;
5241}
5242
Mohsin Kazmi5d82d2f2018-08-13 19:17:54 +02005243static void vl_api_bd_ip_mac_details_t_handler
5244 (vl_api_bd_ip_mac_details_t * mp)
5245{
5246 vat_main_t *vam = &vat_main;
Mohsin Kazmi5d82d2f2018-08-13 19:17:54 +02005247
5248 print (vam->ofp,
Neale Rannsbc764c82019-06-19 07:07:13 -07005249 "\n%-5d %U %U",
5250 ntohl (mp->entry.bd_id),
5251 format_vl_api_mac_address, mp->entry.mac,
5252 format_vl_api_address, &mp->entry.ip);
Mohsin Kazmi5d82d2f2018-08-13 19:17:54 +02005253}
5254
5255static void vl_api_bd_ip_mac_details_t_handler_json
5256 (vl_api_bd_ip_mac_details_t * mp)
5257{
5258 vat_main_t *vam = &vat_main;
5259 vat_json_node_t *node = NULL;
5260
5261 if (VAT_JSON_ARRAY != vam->json_tree.type)
5262 {
5263 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5264 vat_json_init_array (&vam->json_tree);
5265 }
5266 node = vat_json_array_add (&vam->json_tree);
5267
5268 vat_json_init_object (node);
Neale Rannsbc764c82019-06-19 07:07:13 -07005269 vat_json_object_add_uint (node, "bd_id", ntohl (mp->entry.bd_id));
Mohsin Kazmi5d82d2f2018-08-13 19:17:54 +02005270 vat_json_object_add_string_copy (node, "mac_address",
Neale Rannsbc764c82019-06-19 07:07:13 -07005271 format (0, "%U", format_vl_api_mac_address,
5272 &mp->entry.mac));
Mohsin Kazmi5d82d2f2018-08-13 19:17:54 +02005273 u8 *ip = 0;
5274
Neale Rannsbc764c82019-06-19 07:07:13 -07005275 ip = format (0, "%U", format_vl_api_address, &mp->entry.ip);
Mohsin Kazmi5d82d2f2018-08-13 19:17:54 +02005276 vat_json_object_add_string_copy (node, "ip_address", ip);
5277 vec_free (ip);
5278}
5279
5280static int
5281api_bd_ip_mac_dump (vat_main_t * vam)
5282{
5283 unformat_input_t *i = vam->input;
5284 vl_api_bd_ip_mac_dump_t *mp;
5285 vl_api_control_ping_t *mp_ping;
5286 int ret;
5287 u32 bd_id;
5288 u8 bd_id_set = 0;
5289
5290 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5291 {
5292 if (unformat (i, "bd_id %d", &bd_id))
5293 {
5294 bd_id_set++;
5295 }
5296 else
5297 break;
5298 }
5299
5300 print (vam->ofp,
5301 "\n%-5s %-7s %-20s %-30s",
5302 "bd_id", "is_ipv6", "mac_address", "ip_address");
5303
5304 /* Dump Bridge Domain Ip to Mac entries */
5305 M (BD_IP_MAC_DUMP, mp);
5306
5307 if (bd_id_set)
5308 mp->bd_id = htonl (bd_id);
5309 else
5310 mp->bd_id = ~0;
5311
5312 S (mp);
5313
5314 /* Use a control ping for synchronization */
5315 MPING (CONTROL_PING, mp_ping);
5316 S (mp_ping);
5317
5318 W (ret);
5319 return ret;
5320}
5321
Damjan Marion7cd468a2016-12-19 23:05:39 +01005322static int
Damjan Marion8389fb92017-10-13 18:29:53 +02005323api_tap_create_v2 (vat_main_t * vam)
5324{
5325 unformat_input_t *i = vam->input;
5326 vl_api_tap_create_v2_t *mp;
5327 u8 mac_address[6];
5328 u8 random_mac = 1;
Damjan Marion2df39092017-12-04 20:03:37 +01005329 u32 id = ~0;
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005330 u32 num_rx_queues = 0;
Damjan Marion2df39092017-12-04 20:03:37 +01005331 u8 *host_if_name = 0;
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005332 u8 host_if_name_set = 0;
Damjan Marion2df39092017-12-04 20:03:37 +01005333 u8 *host_ns = 0;
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005334 u8 host_ns_set = 0;
Damjan Marion2df39092017-12-04 20:03:37 +01005335 u8 host_mac_addr[6];
5336 u8 host_mac_addr_set = 0;
Damjan Marion91c6ef72017-12-01 13:34:24 +01005337 u8 *host_bridge = 0;
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005338 u8 host_bridge_set = 0;
5339 u8 host_ip4_prefix_set = 0;
5340 u8 host_ip6_prefix_set = 0;
Damjan Marion91c6ef72017-12-01 13:34:24 +01005341 ip4_address_t host_ip4_addr;
Damjan Marion7866c452018-01-18 13:35:11 +01005342 ip4_address_t host_ip4_gw;
5343 u8 host_ip4_gw_set = 0;
Damjan Marion91c6ef72017-12-01 13:34:24 +01005344 u32 host_ip4_prefix_len = 0;
5345 ip6_address_t host_ip6_addr;
Damjan Marion7866c452018-01-18 13:35:11 +01005346 ip6_address_t host_ip6_gw;
5347 u8 host_ip6_gw_set = 0;
Damjan Marion91c6ef72017-12-01 13:34:24 +01005348 u32 host_ip6_prefix_len = 0;
Mohsin Kazmi97d54ed2019-06-10 11:20:15 +02005349 u32 host_mtu_size = 0;
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005350 u8 host_mtu_set = 0;
Mohsin Kazmi97d54ed2019-06-10 11:20:15 +02005351 u32 tap_flags = 0;
Damjan Marion8389fb92017-10-13 18:29:53 +02005352 int ret;
Steven9e635692018-03-01 09:36:01 -08005353 u32 rx_ring_sz = 0, tx_ring_sz = 0;
Damjan Marion8389fb92017-10-13 18:29:53 +02005354
Dave Barachb7b92992018-10-17 10:38:51 -04005355 clib_memset (mac_address, 0, sizeof (mac_address));
Damjan Marion8389fb92017-10-13 18:29:53 +02005356
5357 /* Parse args required to build the message */
5358 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5359 {
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005360 if (unformat (i, "id %u", &id))
Damjan Marion91c6ef72017-12-01 13:34:24 +01005361 ;
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005362 else
5363 if (unformat
5364 (i, "hw-addr %U", unformat_ethernet_address, mac_address))
5365 random_mac = 0;
Damjan Marion2df39092017-12-04 20:03:37 +01005366 else if (unformat (i, "host-if-name %s", &host_if_name))
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005367 host_if_name_set = 1;
5368 else if (unformat (i, "num-rx-queues %u", &num_rx_queues))
Damjan Marion91c6ef72017-12-01 13:34:24 +01005369 ;
Damjan Marion2df39092017-12-04 20:03:37 +01005370 else if (unformat (i, "host-ns %s", &host_ns))
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005371 host_ns_set = 1;
Damjan Marion2df39092017-12-04 20:03:37 +01005372 else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
5373 host_mac_addr))
5374 host_mac_addr_set = 1;
Damjan Marion91c6ef72017-12-01 13:34:24 +01005375 else if (unformat (i, "host-bridge %s", &host_bridge))
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005376 host_bridge_set = 1;
5377 else if (unformat (i, "host-ip4-addr %U/%u", unformat_ip4_address,
Damjan Marion91c6ef72017-12-01 13:34:24 +01005378 &host_ip4_addr, &host_ip4_prefix_len))
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005379 host_ip4_prefix_set = 1;
5380 else if (unformat (i, "host-ip6-addr %U/%u", unformat_ip6_address,
Damjan Marion91c6ef72017-12-01 13:34:24 +01005381 &host_ip6_addr, &host_ip6_prefix_len))
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005382 host_ip6_prefix_set = 1;
Damjan Marion7866c452018-01-18 13:35:11 +01005383 else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
5384 &host_ip4_gw))
5385 host_ip4_gw_set = 1;
5386 else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
5387 &host_ip6_gw))
5388 host_ip6_gw_set = 1;
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005389 else if (unformat (i, "rx-ring-size %u", &rx_ring_sz))
Damjan Marion8389fb92017-10-13 18:29:53 +02005390 ;
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005391 else if (unformat (i, "tx-ring-size %u", &tx_ring_sz))
Damjan Marion8389fb92017-10-13 18:29:53 +02005392 ;
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005393 else if (unformat (i, "host-mtu-size %u", &host_mtu_size))
Mohsin Kazmi97d54ed2019-06-10 11:20:15 +02005394 host_mtu_set = 1;
5395 else if (unformat (i, "no-gso"))
Mohsin Kazmid88fc0f2020-04-30 19:05:56 +02005396 tap_flags &= ~TAP_API_FLAG_GSO;
Mohsin Kazmi97d54ed2019-06-10 11:20:15 +02005397 else if (unformat (i, "gso"))
Mohsin Kazmid88fc0f2020-04-30 19:05:56 +02005398 tap_flags |= TAP_API_FLAG_GSO;
Mohsin Kazmiba0061f2019-12-18 17:08:54 +01005399 else if (unformat (i, "csum-offload"))
Mohsin Kazmid88fc0f2020-04-30 19:05:56 +02005400 tap_flags |= TAP_API_FLAG_CSUM_OFFLOAD;
Mohsin Kazmib49bc1a2020-02-14 17:51:04 +00005401 else if (unformat (i, "persist"))
Mohsin Kazmid88fc0f2020-04-30 19:05:56 +02005402 tap_flags |= TAP_API_FLAG_PERSIST;
Mohsin Kazmib49bc1a2020-02-14 17:51:04 +00005403 else if (unformat (i, "attach"))
Mohsin Kazmid88fc0f2020-04-30 19:05:56 +02005404 tap_flags |= TAP_API_FLAG_ATTACH;
5405 else if (unformat (i, "tun"))
5406 tap_flags |= TAP_API_FLAG_TUN;
5407 else if (unformat (i, "gro-coalesce"))
5408 tap_flags |= TAP_API_FLAG_GRO_COALESCE;
Mohsin Kazmi50bd1652020-08-26 11:07:48 +02005409 else if (unformat (i, "packed"))
5410 tap_flags |= TAP_API_FLAG_PACKED;
5411 else if (unformat (i, "in-order"))
5412 tap_flags |= TAP_API_FLAG_IN_ORDER;
Damjan Marion8389fb92017-10-13 18:29:53 +02005413 else
5414 break;
5415 }
5416
Damjan Marion2df39092017-12-04 20:03:37 +01005417 if (vec_len (host_if_name) > 63)
Damjan Marion8389fb92017-10-13 18:29:53 +02005418 {
5419 errmsg ("tap name too long. ");
5420 return -99;
5421 }
Damjan Marion2df39092017-12-04 20:03:37 +01005422 if (vec_len (host_ns) > 63)
Damjan Marion8389fb92017-10-13 18:29:53 +02005423 {
5424 errmsg ("host name space too long. ");
5425 return -99;
5426 }
Damjan Marion91c6ef72017-12-01 13:34:24 +01005427 if (vec_len (host_bridge) > 63)
5428 {
5429 errmsg ("host bridge name too long. ");
5430 return -99;
5431 }
5432 if (host_ip4_prefix_len > 32)
5433 {
5434 errmsg ("host ip4 prefix length not valid. ");
5435 return -99;
5436 }
5437 if (host_ip6_prefix_len > 128)
5438 {
5439 errmsg ("host ip6 prefix length not valid. ");
5440 return -99;
5441 }
Damjan Marion8389fb92017-10-13 18:29:53 +02005442 if (!is_pow2 (rx_ring_sz))
5443 {
5444 errmsg ("rx ring size must be power of 2. ");
5445 return -99;
5446 }
5447 if (rx_ring_sz > 32768)
5448 {
5449 errmsg ("rx ring size must be 32768 or lower. ");
5450 return -99;
5451 }
5452 if (!is_pow2 (tx_ring_sz))
5453 {
5454 errmsg ("tx ring size must be power of 2. ");
5455 return -99;
5456 }
5457 if (tx_ring_sz > 32768)
5458 {
5459 errmsg ("tx ring size must be 32768 or lower. ");
5460 return -99;
5461 }
Mohsin Kazmi97d54ed2019-06-10 11:20:15 +02005462 if (host_mtu_set && (host_mtu_size < 64 || host_mtu_size > 65355))
5463 {
5464 errmsg ("host MTU size must be in between 64 and 65355. ");
5465 return -99;
5466 }
Damjan Marion8389fb92017-10-13 18:29:53 +02005467
Damjan Marion8389fb92017-10-13 18:29:53 +02005468 /* Construct the API message */
5469 M (TAP_CREATE_V2, mp);
5470
Steven9e635692018-03-01 09:36:01 -08005471 mp->id = ntohl (id);
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005472 mp->use_random_mac = random_mac;
5473 mp->num_rx_queues = (u8) num_rx_queues;
Steven9e635692018-03-01 09:36:01 -08005474 mp->tx_ring_sz = ntohs (tx_ring_sz);
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005475 mp->rx_ring_sz = ntohs (rx_ring_sz);
Mohsin Kazmi97d54ed2019-06-10 11:20:15 +02005476 mp->host_mtu_set = host_mtu_set;
5477 mp->host_mtu_size = ntohl (host_mtu_size);
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005478 mp->host_mac_addr_set = host_mac_addr_set;
5479 mp->host_ip4_prefix_set = host_ip4_prefix_set;
5480 mp->host_ip6_prefix_set = host_ip6_prefix_set;
5481 mp->host_ip4_gw_set = host_ip4_gw_set;
5482 mp->host_ip6_gw_set = host_ip6_gw_set;
Mohsin Kazmi97d54ed2019-06-10 11:20:15 +02005483 mp->tap_flags = ntohl (tap_flags);
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005484 mp->host_namespace_set = host_ns_set;
5485 mp->host_if_name_set = host_if_name_set;
5486 mp->host_bridge_set = host_bridge_set;
Damjan Marion2df39092017-12-04 20:03:37 +01005487
Steven9e635692018-03-01 09:36:01 -08005488 if (random_mac == 0)
Damjan Marion2df39092017-12-04 20:03:37 +01005489 clib_memcpy (mp->mac_address, mac_address, 6);
5490 if (host_mac_addr_set)
5491 clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005492 if (host_if_name_set)
Damjan Marion2df39092017-12-04 20:03:37 +01005493 clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005494 if (host_ns_set)
Damjan Marion2df39092017-12-04 20:03:37 +01005495 clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005496 if (host_bridge_set)
Damjan Marion91c6ef72017-12-01 13:34:24 +01005497 clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +00005498 if (host_ip4_prefix_set)
5499 {
5500 clib_memcpy (mp->host_ip4_prefix.address, &host_ip4_addr, 4);
5501 mp->host_ip4_prefix.len = (u8) host_ip4_prefix_len;
5502 }
5503 if (host_ip6_prefix_set)
5504 {
5505 clib_memcpy (mp->host_ip6_prefix.address, &host_ip6_addr, 16);
5506 mp->host_ip6_prefix.len = (u8) host_ip6_prefix_len;
5507 }
Damjan Marion7866c452018-01-18 13:35:11 +01005508 if (host_ip4_gw_set)
5509 clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
5510 if (host_ip6_gw_set)
5511 clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
Damjan Marion8389fb92017-10-13 18:29:53 +02005512
Damjan Marion2df39092017-12-04 20:03:37 +01005513 vec_free (host_ns);
5514 vec_free (host_if_name);
5515 vec_free (host_bridge);
Damjan Marion8389fb92017-10-13 18:29:53 +02005516
5517 /* send it... */
5518 S (mp);
5519
5520 /* Wait for a reply... */
5521 W (ret);
5522 return ret;
5523}
5524
5525static int
5526api_tap_delete_v2 (vat_main_t * vam)
5527{
5528 unformat_input_t *i = vam->input;
5529 vl_api_tap_delete_v2_t *mp;
5530 u32 sw_if_index = ~0;
5531 u8 sw_if_index_set = 0;
5532 int ret;
5533
5534 /* Parse args required to build the message */
5535 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5536 {
5537 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5538 sw_if_index_set = 1;
5539 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5540 sw_if_index_set = 1;
5541 else
5542 break;
5543 }
5544
5545 if (sw_if_index_set == 0)
5546 {
5547 errmsg ("missing vpp interface name. ");
5548 return -99;
5549 }
5550
5551 /* Construct the API message */
5552 M (TAP_DELETE_V2, mp);
5553
5554 mp->sw_if_index = ntohl (sw_if_index);
5555
5556 /* send it... */
5557 S (mp);
5558
5559 /* Wait for a reply... */
5560 W (ret);
5561 return ret;
5562}
5563
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005564uword
jialv01082ebeb2019-09-10 00:23:55 +08005565unformat_vlib_pci_addr (unformat_input_t * input, va_list * args)
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005566{
jialv01082ebeb2019-09-10 00:23:55 +08005567 vlib_pci_addr_t *addr = va_arg (*args, vlib_pci_addr_t *);
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005568 u32 x[4];
5569
5570 if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
5571 return 0;
5572
5573 addr->domain = x[0];
5574 addr->bus = x[1];
5575 addr->slot = x[2];
5576 addr->function = x[3];
5577
5578 return 1;
5579}
5580
5581static int
Mohsin Kazmi518251b2020-09-01 17:17:44 +00005582api_virtio_pci_create_v2 (vat_main_t * vam)
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005583{
5584 unformat_input_t *i = vam->input;
Mohsin Kazmi518251b2020-09-01 17:17:44 +00005585 vl_api_virtio_pci_create_v2_t *mp;
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005586 u8 mac_address[6];
5587 u8 random_mac = 1;
5588 u32 pci_addr = 0;
5589 u64 features = (u64) ~ (0ULL);
Mohsin Kazmi518251b2020-09-01 17:17:44 +00005590 u32 virtio_flags = 0;
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005591 int ret;
5592
5593 clib_memset (mac_address, 0, sizeof (mac_address));
5594
5595 /* Parse args required to build the message */
5596 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5597 {
5598 if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
5599 {
5600 random_mac = 0;
5601 }
jialv01082ebeb2019-09-10 00:23:55 +08005602 else if (unformat (i, "pci-addr %U", unformat_vlib_pci_addr, &pci_addr))
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005603 ;
5604 else if (unformat (i, "features 0x%llx", &features))
5605 ;
Mohsin Kazmibbd6b742019-05-02 13:54:59 +02005606 else if (unformat (i, "gso-enabled"))
Mohsin Kazmi518251b2020-09-01 17:17:44 +00005607 virtio_flags |= VIRTIO_API_FLAG_GSO;
Mohsin Kazmi6d4af892020-01-03 15:11:53 +00005608 else if (unformat (i, "csum-offload-enabled"))
Mohsin Kazmi518251b2020-09-01 17:17:44 +00005609 virtio_flags |= VIRTIO_API_FLAG_CSUM_OFFLOAD;
5610 else if (unformat (i, "gro-coalesce"))
5611 virtio_flags |= VIRTIO_API_FLAG_GRO_COALESCE;
5612 else if (unformat (i, "packed"))
5613 virtio_flags |= VIRTIO_API_FLAG_PACKED;
5614 else if (unformat (i, "in-order"))
5615 virtio_flags |= VIRTIO_API_FLAG_IN_ORDER;
Mohsin Kazmie347acb2020-09-28 10:26:33 +00005616 else if (unformat (i, "buffering"))
5617 virtio_flags |= VIRTIO_API_FLAG_BUFFERING;
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005618 else
5619 break;
5620 }
5621
5622 if (pci_addr == 0)
5623 {
5624 errmsg ("pci address must be non zero. ");
5625 return -99;
5626 }
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005627
5628 /* Construct the API message */
Mohsin Kazmi518251b2020-09-01 17:17:44 +00005629 M (VIRTIO_PCI_CREATE_V2, mp);
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005630
5631 mp->use_random_mac = random_mac;
5632
Jakub Grajciar2c504f82019-09-26 10:34:41 +02005633 mp->pci_addr.domain = htons (((vlib_pci_addr_t) pci_addr).domain);
5634 mp->pci_addr.bus = ((vlib_pci_addr_t) pci_addr).bus;
5635 mp->pci_addr.slot = ((vlib_pci_addr_t) pci_addr).slot;
5636 mp->pci_addr.function = ((vlib_pci_addr_t) pci_addr).function;
5637
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005638 mp->features = clib_host_to_net_u64 (features);
Mohsin Kazmi518251b2020-09-01 17:17:44 +00005639 mp->virtio_flags = clib_host_to_net_u32 (virtio_flags);
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01005640
5641 if (random_mac == 0)
5642 clib_memcpy (mp->mac_address, mac_address, 6);
5643
5644 /* send it... */
5645 S (mp);
5646
5647 /* Wait for a reply... */
5648 W (ret);
5649 return ret;
5650}
5651
5652static int
5653api_virtio_pci_delete (vat_main_t * vam)
5654{
5655 unformat_input_t *i = vam->input;
5656 vl_api_virtio_pci_delete_t *mp;
5657 u32 sw_if_index = ~0;
5658 u8 sw_if_index_set = 0;
5659 int ret;
5660
5661 /* Parse args required to build the message */
5662 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5663 {
5664 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5665 sw_if_index_set = 1;
5666 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5667 sw_if_index_set = 1;
5668 else
5669 break;
5670 }
5671
5672 if (sw_if_index_set == 0)
5673 {
5674 errmsg ("missing vpp interface name. ");
5675 return -99;
5676 }
5677
5678 /* Construct the API message */
5679 M (VIRTIO_PCI_DELETE, mp);
5680
5681 mp->sw_if_index = htonl (sw_if_index);
5682
5683 /* send it... */
5684 S (mp);
5685
5686 /* Wait for a reply... */
5687 W (ret);
5688 return ret;
5689}
5690
Damjan Marion8389fb92017-10-13 18:29:53 +02005691static int
Steven9cd2d7a2017-12-20 12:43:01 -08005692api_bond_create (vat_main_t * vam)
5693{
5694 unformat_input_t *i = vam->input;
5695 vl_api_bond_create_t *mp;
5696 u8 mac_address[6];
5697 u8 custom_mac = 0;
5698 int ret;
5699 u8 mode;
5700 u8 lb;
5701 u8 mode_is_set = 0;
Alexander Chernavinad9d5282018-12-13 09:08:09 -05005702 u32 id = ~0;
Zhiyong Yang751e3f32019-06-26 05:49:14 -04005703 u8 numa_only = 0;
Steven9cd2d7a2017-12-20 12:43:01 -08005704
Dave Barachb7b92992018-10-17 10:38:51 -04005705 clib_memset (mac_address, 0, sizeof (mac_address));
Steven9cd2d7a2017-12-20 12:43:01 -08005706 lb = BOND_LB_L2;
5707
5708 /* Parse args required to build the message */
5709 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5710 {
5711 if (unformat (i, "mode %U", unformat_bond_mode, &mode))
5712 mode_is_set = 1;
5713 else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
5714 && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
5715 ;
5716 else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
5717 mac_address))
5718 custom_mac = 1;
Zhiyong Yang751e3f32019-06-26 05:49:14 -04005719 else if (unformat (i, "numa-only"))
5720 numa_only = 1;
Alexander Chernavinad9d5282018-12-13 09:08:09 -05005721 else if (unformat (i, "id %u", &id))
5722 ;
Steven9cd2d7a2017-12-20 12:43:01 -08005723 else
5724 break;
5725 }
5726
5727 if (mode_is_set == 0)
5728 {
5729 errmsg ("Missing bond mode. ");
5730 return -99;
5731 }
5732
5733 /* Construct the API message */
5734 M (BOND_CREATE, mp);
5735
5736 mp->use_custom_mac = custom_mac;
5737
Jakub Grajciar3d1ef872019-08-26 12:55:15 +02005738 mp->mode = htonl (mode);
5739 mp->lb = htonl (lb);
Alexander Chernavinad9d5282018-12-13 09:08:09 -05005740 mp->id = htonl (id);
Zhiyong Yang751e3f32019-06-26 05:49:14 -04005741 mp->numa_only = numa_only;
Steven9cd2d7a2017-12-20 12:43:01 -08005742
5743 if (custom_mac)
5744 clib_memcpy (mp->mac_address, mac_address, 6);
5745
5746 /* send it... */
5747 S (mp);
5748
5749 /* Wait for a reply... */
5750 W (ret);
5751 return ret;
5752}
5753
5754static int
Steven Luongea717862020-07-30 07:31:40 -07005755api_bond_create2 (vat_main_t * vam)
5756{
5757 unformat_input_t *i = vam->input;
5758 vl_api_bond_create2_t *mp;
5759 u8 mac_address[6];
5760 u8 custom_mac = 0;
5761 int ret;
5762 u8 mode;
5763 u8 lb;
5764 u8 mode_is_set = 0;
5765 u32 id = ~0;
5766 u8 numa_only = 0;
5767 u8 gso = 0;
5768
5769 clib_memset (mac_address, 0, sizeof (mac_address));
5770 lb = BOND_LB_L2;
5771
5772 /* Parse args required to build the message */
5773 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5774 {
5775 if (unformat (i, "mode %U", unformat_bond_mode, &mode))
5776 mode_is_set = 1;
5777 else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
5778 && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
5779 ;
5780 else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
5781 mac_address))
5782 custom_mac = 1;
5783 else if (unformat (i, "numa-only"))
5784 numa_only = 1;
5785 else if (unformat (i, "gso"))
5786 gso = 1;
5787 else if (unformat (i, "id %u", &id))
5788 ;
5789 else
5790 break;
5791 }
5792
5793 if (mode_is_set == 0)
5794 {
5795 errmsg ("Missing bond mode. ");
5796 return -99;
5797 }
5798
5799 /* Construct the API message */
5800 M (BOND_CREATE2, mp);
5801
5802 mp->use_custom_mac = custom_mac;
5803
5804 mp->mode = htonl (mode);
5805 mp->lb = htonl (lb);
5806 mp->id = htonl (id);
5807 mp->numa_only = numa_only;
5808 mp->enable_gso = gso;
5809
5810 if (custom_mac)
5811 clib_memcpy (mp->mac_address, mac_address, 6);
5812
5813 /* send it... */
5814 S (mp);
5815
5816 /* Wait for a reply... */
5817 W (ret);
5818 return ret;
5819}
5820
5821static int
Steven9cd2d7a2017-12-20 12:43:01 -08005822api_bond_delete (vat_main_t * vam)
5823{
5824 unformat_input_t *i = vam->input;
5825 vl_api_bond_delete_t *mp;
5826 u32 sw_if_index = ~0;
5827 u8 sw_if_index_set = 0;
5828 int ret;
5829
5830 /* Parse args required to build the message */
5831 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5832 {
5833 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5834 sw_if_index_set = 1;
5835 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5836 sw_if_index_set = 1;
5837 else
5838 break;
5839 }
5840
5841 if (sw_if_index_set == 0)
5842 {
5843 errmsg ("missing vpp interface name. ");
5844 return -99;
5845 }
5846
5847 /* Construct the API message */
5848 M (BOND_DELETE, mp);
5849
5850 mp->sw_if_index = ntohl (sw_if_index);
5851
5852 /* send it... */
5853 S (mp);
5854
5855 /* Wait for a reply... */
5856 W (ret);
5857 return ret;
5858}
5859
5860static int
Steven Luong4c4223e2020-07-15 08:44:54 -07005861api_bond_add_member (vat_main_t * vam)
Steven9cd2d7a2017-12-20 12:43:01 -08005862{
5863 unformat_input_t *i = vam->input;
Steven Luong4c4223e2020-07-15 08:44:54 -07005864 vl_api_bond_add_member_t *mp;
Steven9cd2d7a2017-12-20 12:43:01 -08005865 u32 bond_sw_if_index;
5866 int ret;
5867 u8 is_passive;
5868 u8 is_long_timeout;
5869 u32 bond_sw_if_index_is_set = 0;
5870 u32 sw_if_index;
5871 u8 sw_if_index_is_set = 0;
5872
5873 /* Parse args required to build the message */
5874 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5875 {
5876 if (unformat (i, "sw_if_index %d", &sw_if_index))
5877 sw_if_index_is_set = 1;
5878 else if (unformat (i, "bond %u", &bond_sw_if_index))
5879 bond_sw_if_index_is_set = 1;
5880 else if (unformat (i, "passive %d", &is_passive))
5881 ;
5882 else if (unformat (i, "long-timeout %d", &is_long_timeout))
5883 ;
5884 else
5885 break;
5886 }
5887
5888 if (bond_sw_if_index_is_set == 0)
5889 {
5890 errmsg ("Missing bond sw_if_index. ");
5891 return -99;
5892 }
5893 if (sw_if_index_is_set == 0)
5894 {
Steven Luong4c4223e2020-07-15 08:44:54 -07005895 errmsg ("Missing member sw_if_index. ");
Steven9cd2d7a2017-12-20 12:43:01 -08005896 return -99;
5897 }
5898
5899 /* Construct the API message */
Steven Luong4c4223e2020-07-15 08:44:54 -07005900 M (BOND_ADD_MEMBER, mp);
Steven9cd2d7a2017-12-20 12:43:01 -08005901
5902 mp->bond_sw_if_index = ntohl (bond_sw_if_index);
5903 mp->sw_if_index = ntohl (sw_if_index);
5904 mp->is_long_timeout = is_long_timeout;
5905 mp->is_passive = is_passive;
5906
5907 /* send it... */
5908 S (mp);
5909
5910 /* Wait for a reply... */
5911 W (ret);
5912 return ret;
5913}
5914
5915static int
Steven Luong4c4223e2020-07-15 08:44:54 -07005916api_bond_detach_member (vat_main_t * vam)
Steven9cd2d7a2017-12-20 12:43:01 -08005917{
5918 unformat_input_t *i = vam->input;
Steven Luong4c4223e2020-07-15 08:44:54 -07005919 vl_api_bond_detach_member_t *mp;
Steven9cd2d7a2017-12-20 12:43:01 -08005920 u32 sw_if_index = ~0;
5921 u8 sw_if_index_set = 0;
5922 int ret;
5923
5924 /* Parse args required to build the message */
5925 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5926 {
5927 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5928 sw_if_index_set = 1;
5929 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5930 sw_if_index_set = 1;
5931 else
5932 break;
5933 }
5934
5935 if (sw_if_index_set == 0)
5936 {
5937 errmsg ("missing vpp interface name. ");
5938 return -99;
5939 }
5940
5941 /* Construct the API message */
Steven Luong4c4223e2020-07-15 08:44:54 -07005942 M (BOND_DETACH_MEMBER, mp);
Steven9cd2d7a2017-12-20 12:43:01 -08005943
5944 mp->sw_if_index = ntohl (sw_if_index);
5945
5946 /* send it... */
5947 S (mp);
5948
5949 /* Wait for a reply... */
5950 W (ret);
5951 return ret;
5952}
5953
5954static int
Neale Ranns28ab9cc2017-08-14 07:18:42 -07005955api_ip_table_add_del (vat_main_t * vam)
5956{
5957 unformat_input_t *i = vam->input;
5958 vl_api_ip_table_add_del_t *mp;
5959 u32 table_id = ~0;
5960 u8 is_ipv6 = 0;
5961 u8 is_add = 1;
5962 int ret = 0;
5963
5964 /* Parse args required to build the message */
5965 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5966 {
5967 if (unformat (i, "ipv6"))
5968 is_ipv6 = 1;
5969 else if (unformat (i, "del"))
5970 is_add = 0;
5971 else if (unformat (i, "add"))
5972 is_add = 1;
5973 else if (unformat (i, "table %d", &table_id))
5974 ;
5975 else
5976 {
5977 clib_warning ("parse error '%U'", format_unformat_error, i);
5978 return -99;
5979 }
5980 }
5981
5982 if (~0 == table_id)
5983 {
5984 errmsg ("missing table-ID");
5985 return -99;
5986 }
5987
5988 /* Construct the API message */
5989 M (IP_TABLE_ADD_DEL, mp);
5990
Neale Ranns097fa662018-05-01 05:17:55 -07005991 mp->table.table_id = ntohl (table_id);
5992 mp->table.is_ip6 = is_ipv6;
Neale Ranns28ab9cc2017-08-14 07:18:42 -07005993 mp->is_add = is_add;
5994
5995 /* send it... */
5996 S (mp);
5997
5998 /* Wait for a reply... */
5999 W (ret);
6000
6001 return ret;
6002}
6003
Neale Ranns097fa662018-05-01 05:17:55 -07006004uword
6005unformat_fib_path (unformat_input_t * input, va_list * args)
6006{
6007 vat_main_t *vam = va_arg (*args, vat_main_t *);
6008 vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
6009 u32 weight, preference;
6010 mpls_label_t out_label;
6011
6012 clib_memset (path, 0, sizeof (*path));
6013 path->weight = 1;
6014 path->sw_if_index = ~0;
6015 path->rpf_id = ~0;
6016 path->n_labels = 0;
6017
6018 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
6019 {
6020 if (unformat (input, "%U %U",
6021 unformat_vl_api_ip4_address,
6022 &path->nh.address.ip4,
6023 api_unformat_sw_if_index, vam, &path->sw_if_index))
6024 {
6025 path->proto = FIB_API_PATH_NH_PROTO_IP4;
6026 }
6027 else if (unformat (input, "%U %U",
6028 unformat_vl_api_ip6_address,
6029 &path->nh.address.ip6,
6030 api_unformat_sw_if_index, vam, &path->sw_if_index))
6031 {
6032 path->proto = FIB_API_PATH_NH_PROTO_IP6;
6033 }
6034 else if (unformat (input, "weight %u", &weight))
6035 {
6036 path->weight = weight;
6037 }
6038 else if (unformat (input, "preference %u", &preference))
6039 {
6040 path->preference = preference;
6041 }
6042 else if (unformat (input, "%U next-hop-table %d",
6043 unformat_vl_api_ip4_address,
6044 &path->nh.address.ip4, &path->table_id))
6045 {
6046 path->proto = FIB_API_PATH_NH_PROTO_IP4;
6047 }
6048 else if (unformat (input, "%U next-hop-table %d",
6049 unformat_vl_api_ip6_address,
6050 &path->nh.address.ip6, &path->table_id))
6051 {
6052 path->proto = FIB_API_PATH_NH_PROTO_IP6;
6053 }
6054 else if (unformat (input, "%U",
6055 unformat_vl_api_ip4_address, &path->nh.address.ip4))
6056 {
6057 /*
6058 * the recursive next-hops are by default in the default table
6059 */
6060 path->table_id = 0;
6061 path->sw_if_index = ~0;
6062 path->proto = FIB_API_PATH_NH_PROTO_IP4;
6063 }
6064 else if (unformat (input, "%U",
6065 unformat_vl_api_ip6_address, &path->nh.address.ip6))
6066 {
6067 /*
6068 * the recursive next-hops are by default in the default table
6069 */
6070 path->table_id = 0;
6071 path->sw_if_index = ~0;
6072 path->proto = FIB_API_PATH_NH_PROTO_IP6;
6073 }
6074 else if (unformat (input, "resolve-via-host"))
6075 {
6076 path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
6077 }
6078 else if (unformat (input, "resolve-via-attached"))
6079 {
6080 path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
6081 }
6082 else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
6083 {
6084 path->type = FIB_API_PATH_TYPE_LOCAL;
6085 path->sw_if_index = ~0;
6086 path->proto = FIB_API_PATH_NH_PROTO_IP4;
6087 }
6088 else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
6089 {
6090 path->type = FIB_API_PATH_TYPE_LOCAL;
6091 path->sw_if_index = ~0;
6092 path->proto = FIB_API_PATH_NH_PROTO_IP6;
6093 }
6094 else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
6095 ;
6096 else if (unformat (input, "via-label %d", &path->nh.via_label))
6097 {
6098 path->proto = FIB_API_PATH_NH_PROTO_MPLS;
6099 path->sw_if_index = ~0;
6100 }
6101 else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
6102 {
6103 path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
6104 path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
6105 }
6106 else if (unformat (input, "local"))
6107 {
6108 path->type = FIB_API_PATH_TYPE_LOCAL;
6109 }
6110 else if (unformat (input, "out-labels"))
6111 {
6112 while (unformat (input, "%d", &out_label))
6113 {
6114 path->label_stack[path->n_labels].label = out_label;
6115 path->label_stack[path->n_labels].is_uniform = 0;
6116 path->label_stack[path->n_labels].ttl = 64;
6117 path->n_labels++;
6118 }
6119 }
6120 else if (unformat (input, "via"))
6121 {
6122 /* new path, back up and return */
6123 unformat_put_input (input);
6124 unformat_put_input (input);
6125 unformat_put_input (input);
6126 unformat_put_input (input);
6127 break;
6128 }
6129 else
6130 {
6131 return (0);
6132 }
6133 }
6134
6135 path->proto = ntohl (path->proto);
6136 path->type = ntohl (path->type);
6137 path->flags = ntohl (path->flags);
6138 path->table_id = ntohl (path->table_id);
6139 path->sw_if_index = ntohl (path->sw_if_index);
6140
6141 return (1);
6142}
6143
Neale Ranns28ab9cc2017-08-14 07:18:42 -07006144static int
Neale Ranns097fa662018-05-01 05:17:55 -07006145api_ip_route_add_del (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +01006146{
6147 unformat_input_t *i = vam->input;
Neale Ranns097fa662018-05-01 05:17:55 -07006148 vl_api_ip_route_add_del_t *mp;
6149 u32 vrf_id = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006150 u8 is_add = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006151 u8 is_multipath = 0;
Neale Ranns097fa662018-05-01 05:17:55 -07006152 u8 prefix_set = 0;
6153 u8 path_count = 0;
6154 vl_api_prefix_t pfx = { };
6155 vl_api_fib_path_t paths[8];
Damjan Marion7cd468a2016-12-19 23:05:39 +01006156 int count = 1;
6157 int j;
6158 f64 before = 0;
6159 u32 random_add_del = 0;
6160 u32 *random_vector = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006161 u32 random_seed = 0xdeaddabe;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006162
6163 /* Parse args required to build the message */
6164 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6165 {
Neale Ranns097fa662018-05-01 05:17:55 -07006166 if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
6167 prefix_set = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006168 else if (unformat (i, "del"))
6169 is_add = 0;
6170 else if (unformat (i, "add"))
6171 is_add = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006172 else if (unformat (i, "vrf %d", &vrf_id))
6173 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006174 else if (unformat (i, "count %d", &count))
6175 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006176 else if (unformat (i, "random"))
6177 random_add_del = 1;
Neale Ranns097fa662018-05-01 05:17:55 -07006178 else if (unformat (i, "multipath"))
6179 is_multipath = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006180 else if (unformat (i, "seed %d", &random_seed))
6181 ;
6182 else
Neale Ranns097fa662018-05-01 05:17:55 -07006183 if (unformat
6184 (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
6185 {
6186 path_count++;
6187 if (8 == path_count)
6188 {
6189 errmsg ("max 8 paths");
6190 return -99;
6191 }
6192 }
6193 else
Damjan Marion7cd468a2016-12-19 23:05:39 +01006194 {
6195 clib_warning ("parse error '%U'", format_unformat_error, i);
6196 return -99;
6197 }
6198 }
6199
Neale Ranns097fa662018-05-01 05:17:55 -07006200 if (!path_count)
Damjan Marion7cd468a2016-12-19 23:05:39 +01006201 {
Neale Ranns097fa662018-05-01 05:17:55 -07006202 errmsg ("specify a path; via ...");
Damjan Marion7cd468a2016-12-19 23:05:39 +01006203 return -99;
6204 }
Neale Ranns097fa662018-05-01 05:17:55 -07006205 if (prefix_set == 0)
Damjan Marion7cd468a2016-12-19 23:05:39 +01006206 {
Neale Ranns097fa662018-05-01 05:17:55 -07006207 errmsg ("missing prefix");
Damjan Marion7cd468a2016-12-19 23:05:39 +01006208 return -99;
6209 }
6210
6211 /* Generate a pile of unique, random routes */
6212 if (random_add_del)
6213 {
Neale Ranns097fa662018-05-01 05:17:55 -07006214 ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006215 u32 this_random_address;
Neale Ranns097fa662018-05-01 05:17:55 -07006216 uword *random_hash;
6217
Damjan Marion7cd468a2016-12-19 23:05:39 +01006218 random_hash = hash_create (count, sizeof (uword));
6219
Neale Ranns097fa662018-05-01 05:17:55 -07006220 hash_set (random_hash, i->as_u32, 1);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006221 for (j = 0; j <= count; j++)
6222 {
6223 do
6224 {
6225 this_random_address = random_u32 (&random_seed);
6226 this_random_address =
6227 clib_host_to_net_u32 (this_random_address);
6228 }
6229 while (hash_get (random_hash, this_random_address));
6230 vec_add1 (random_vector, this_random_address);
6231 hash_set (random_hash, this_random_address, 1);
6232 }
6233 hash_free (random_hash);
Neale Ranns097fa662018-05-01 05:17:55 -07006234 set_ip4_address (&pfx.address, random_vector[0]);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006235 }
6236
6237 if (count > 1)
6238 {
6239 /* Turn on async mode */
6240 vam->async_mode = 1;
6241 vam->async_errors = 0;
6242 before = vat_time_now (vam);
6243 }
6244
6245 for (j = 0; j < count; j++)
6246 {
6247 /* Construct the API message */
Neale Ranns097fa662018-05-01 05:17:55 -07006248 M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006249
6250 mp->is_add = is_add;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006251 mp->is_multipath = is_multipath;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006252
Neale Ranns097fa662018-05-01 05:17:55 -07006253 clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
6254 mp->route.table_id = ntohl (vrf_id);
6255 mp->route.n_paths = path_count;
6256
6257 clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
6258
6259 if (random_add_del)
6260 set_ip4_address (&pfx.address, random_vector[j + 1]);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006261 else
Neale Ranns097fa662018-05-01 05:17:55 -07006262 increment_address (&pfx.address);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006263 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006264 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006265 /* If we receive SIGTERM, stop now... */
6266 if (vam->do_exit)
6267 break;
6268 }
6269
6270 /* When testing multiple add/del ops, use a control-ping to sync */
6271 if (count > 1)
6272 {
Jon Loeliger2d23eca2017-02-01 13:09:58 -06006273 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006274 f64 after;
Jon Loeliger1f9191f2017-01-31 15:27:19 -06006275 f64 timeout;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006276
6277 /* Shut off async mode */
6278 vam->async_mode = 0;
6279
Dave Barach59b25652017-09-10 15:04:27 -04006280 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06006281 S (mp_ping);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006282
6283 timeout = vat_time_now (vam) + 1.0;
6284 while (vat_time_now (vam) < timeout)
6285 if (vam->result_ready == 1)
6286 goto out;
6287 vam->retval = -99;
6288
6289 out:
6290 if (vam->retval == -99)
6291 errmsg ("timeout");
6292
6293 if (vam->async_errors > 0)
6294 {
6295 errmsg ("%d asynchronous errors", vam->async_errors);
6296 vam->retval = -98;
6297 }
6298 vam->async_errors = 0;
6299 after = vat_time_now (vam);
6300
6301 /* slim chance, but we might have eaten SIGTERM on the first iteration */
6302 if (j > 0)
6303 count = j;
6304
6305 print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6306 count, after - before, count / (after - before));
6307 }
6308 else
6309 {
Jon Loeliger56c7b012017-02-01 12:31:41 -06006310 int ret;
6311
Damjan Marion7cd468a2016-12-19 23:05:39 +01006312 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06006313 W (ret);
6314 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006315 }
6316
6317 /* Return the good/bad news */
6318 return (vam->retval);
6319}
6320
6321static int
Neale Ranns32e1c012016-11-22 17:07:28 +00006322api_ip_mroute_add_del (vat_main_t * vam)
6323{
6324 unformat_input_t *i = vam->input;
Neale Ranns097fa662018-05-01 05:17:55 -07006325 u8 path_set = 0, prefix_set = 0, is_add = 1;
Neale Ranns32e1c012016-11-22 17:07:28 +00006326 vl_api_ip_mroute_add_del_t *mp;
Neale Ranns32e1c012016-11-22 17:07:28 +00006327 mfib_entry_flags_t eflags = 0;
Neale Ranns097fa662018-05-01 05:17:55 -07006328 vl_api_mfib_path_t path;
6329 vl_api_mprefix_t pfx = { };
6330 u32 vrf_id = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006331 int ret;
Neale Ranns32e1c012016-11-22 17:07:28 +00006332
6333 /* Parse args required to build the message */
6334 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6335 {
Neale Ranns097fa662018-05-01 05:17:55 -07006336 if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
Neale Ranns32e1c012016-11-22 17:07:28 +00006337 {
Neale Ranns097fa662018-05-01 05:17:55 -07006338 prefix_set = 1;
6339 pfx.grp_address_length = htons (pfx.grp_address_length);
Neale Ranns32e1c012016-11-22 17:07:28 +00006340 }
6341 else if (unformat (i, "del"))
6342 is_add = 0;
6343 else if (unformat (i, "add"))
6344 is_add = 1;
6345 else if (unformat (i, "vrf %d", &vrf_id))
6346 ;
Neale Ranns097fa662018-05-01 05:17:55 -07006347 else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
6348 path.itf_flags = htonl (path.itf_flags);
Neale Ranns32e1c012016-11-22 17:07:28 +00006349 else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
6350 ;
Neale Ranns097fa662018-05-01 05:17:55 -07006351 else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
6352 path_set = 1;
Neale Ranns32e1c012016-11-22 17:07:28 +00006353 else
6354 {
6355 clib_warning ("parse error '%U'", format_unformat_error, i);
6356 return -99;
6357 }
6358 }
6359
Neale Ranns097fa662018-05-01 05:17:55 -07006360 if (prefix_set == 0)
Neale Ranns32e1c012016-11-22 17:07:28 +00006361 {
6362 errmsg ("missing addresses\n");
6363 return -99;
6364 }
Neale Ranns097fa662018-05-01 05:17:55 -07006365 if (path_set == 0)
6366 {
6367 errmsg ("missing path\n");
6368 return -99;
6369 }
Neale Ranns32e1c012016-11-22 17:07:28 +00006370
6371 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006372 M (IP_MROUTE_ADD_DEL, mp);
Neale Ranns32e1c012016-11-22 17:07:28 +00006373
Neale Ranns32e1c012016-11-22 17:07:28 +00006374 mp->is_add = is_add;
Neale Ranns097fa662018-05-01 05:17:55 -07006375 mp->is_multipath = 1;
Neale Ranns32e1c012016-11-22 17:07:28 +00006376
Neale Ranns097fa662018-05-01 05:17:55 -07006377 clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
6378 mp->route.table_id = htonl (vrf_id);
6379 mp->route.n_paths = 1;
6380 mp->route.entry_flags = htonl (eflags);
Neale Ranns32e1c012016-11-22 17:07:28 +00006381
Neale Ranns097fa662018-05-01 05:17:55 -07006382 clib_memcpy (&mp->route.paths, &path, sizeof (path));
Neale Ranns32e1c012016-11-22 17:07:28 +00006383
6384 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006385 S (mp);
Neale Ranns32e1c012016-11-22 17:07:28 +00006386 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06006387 W (ret);
6388 return ret;
Neale Ranns32e1c012016-11-22 17:07:28 +00006389}
6390
6391static int
Neale Ranns28ab9cc2017-08-14 07:18:42 -07006392api_mpls_table_add_del (vat_main_t * vam)
6393{
6394 unformat_input_t *i = vam->input;
6395 vl_api_mpls_table_add_del_t *mp;
6396 u32 table_id = ~0;
6397 u8 is_add = 1;
6398 int ret = 0;
6399
6400 /* Parse args required to build the message */
6401 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6402 {
Florin Corasd0a59722017-10-15 17:41:21 +00006403 if (unformat (i, "table %d", &table_id))
6404 ;
6405 else if (unformat (i, "del"))
Neale Ranns28ab9cc2017-08-14 07:18:42 -07006406 is_add = 0;
6407 else if (unformat (i, "add"))
6408 is_add = 1;
6409 else
6410 {
6411 clib_warning ("parse error '%U'", format_unformat_error, i);
6412 return -99;
6413 }
6414 }
6415
6416 if (~0 == table_id)
6417 {
6418 errmsg ("missing table-ID");
6419 return -99;
6420 }
6421
6422 /* Construct the API message */
6423 M (MPLS_TABLE_ADD_DEL, mp);
6424
Neale Ranns097fa662018-05-01 05:17:55 -07006425 mp->mt_table.mt_table_id = ntohl (table_id);
Neale Ranns28ab9cc2017-08-14 07:18:42 -07006426 mp->mt_is_add = is_add;
6427
6428 /* send it... */
6429 S (mp);
6430
6431 /* Wait for a reply... */
6432 W (ret);
6433
6434 return ret;
6435}
6436
6437static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01006438api_mpls_route_add_del (vat_main_t * vam)
6439{
Neale Ranns097fa662018-05-01 05:17:55 -07006440 u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
6441 mpls_label_t local_label = MPLS_LABEL_INVALID;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006442 unformat_input_t *i = vam->input;
6443 vl_api_mpls_route_add_del_t *mp;
Neale Ranns097fa662018-05-01 05:17:55 -07006444 vl_api_fib_path_t paths[8];
6445 int count = 1, j;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006446 f64 before = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006447
6448 /* Parse args required to build the message */
6449 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6450 {
Neale Ranns097fa662018-05-01 05:17:55 -07006451 if (unformat (i, "%d", &local_label))
Damjan Marion7cd468a2016-12-19 23:05:39 +01006452 ;
6453 else if (unformat (i, "eos"))
6454 is_eos = 1;
6455 else if (unformat (i, "non-eos"))
6456 is_eos = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006457 else if (unformat (i, "del"))
6458 is_add = 0;
6459 else if (unformat (i, "add"))
6460 is_add = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006461 else if (unformat (i, "multipath"))
6462 is_multipath = 1;
6463 else if (unformat (i, "count %d", &count))
6464 ;
John Loe166fd92018-09-13 14:08:59 -04006465 else
6466 if (unformat
Neale Ranns097fa662018-05-01 05:17:55 -07006467 (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
John Loe166fd92018-09-13 14:08:59 -04006468 {
Neale Ranns097fa662018-05-01 05:17:55 -07006469 path_count++;
6470 if (8 == path_count)
6471 {
6472 errmsg ("max 8 paths");
6473 return -99;
6474 }
John Loe166fd92018-09-13 14:08:59 -04006475 }
Damjan Marion7cd468a2016-12-19 23:05:39 +01006476 else
6477 {
6478 clib_warning ("parse error '%U'", format_unformat_error, i);
6479 return -99;
6480 }
6481 }
6482
Neale Ranns097fa662018-05-01 05:17:55 -07006483 if (!path_count)
Damjan Marion7cd468a2016-12-19 23:05:39 +01006484 {
Neale Ranns097fa662018-05-01 05:17:55 -07006485 errmsg ("specify a path; via ...");
Damjan Marion7cd468a2016-12-19 23:05:39 +01006486 return -99;
6487 }
6488
6489 if (MPLS_LABEL_INVALID == local_label)
6490 {
6491 errmsg ("missing label");
6492 return -99;
6493 }
6494
6495 if (count > 1)
6496 {
6497 /* Turn on async mode */
6498 vam->async_mode = 1;
6499 vam->async_errors = 0;
6500 before = vat_time_now (vam);
6501 }
6502
6503 for (j = 0; j < count; j++)
6504 {
6505 /* Construct the API message */
Neale Ranns097fa662018-05-01 05:17:55 -07006506 M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006507
6508 mp->mr_is_add = is_add;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006509 mp->mr_is_multipath = is_multipath;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006510
Neale Ranns097fa662018-05-01 05:17:55 -07006511 mp->mr_route.mr_label = local_label;
6512 mp->mr_route.mr_eos = is_eos;
6513 mp->mr_route.mr_table_id = 0;
6514 mp->mr_route.mr_n_paths = path_count;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006515
Neale Ranns097fa662018-05-01 05:17:55 -07006516 clib_memcpy (&mp->mr_route.mr_paths, paths,
6517 sizeof (paths[0]) * path_count);
Neale Rannsda78f952017-05-24 09:15:43 -07006518
Damjan Marion7cd468a2016-12-19 23:05:39 +01006519 local_label++;
6520
6521 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006522 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006523 /* If we receive SIGTERM, stop now... */
6524 if (vam->do_exit)
6525 break;
6526 }
6527
6528 /* When testing multiple add/del ops, use a control-ping to sync */
6529 if (count > 1)
6530 {
Jon Loeliger2d23eca2017-02-01 13:09:58 -06006531 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006532 f64 after;
Jon Loeliger1f9191f2017-01-31 15:27:19 -06006533 f64 timeout;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006534
6535 /* Shut off async mode */
6536 vam->async_mode = 0;
6537
Dave Barach59b25652017-09-10 15:04:27 -04006538 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06006539 S (mp_ping);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006540
6541 timeout = vat_time_now (vam) + 1.0;
6542 while (vat_time_now (vam) < timeout)
6543 if (vam->result_ready == 1)
6544 goto out;
6545 vam->retval = -99;
6546
6547 out:
6548 if (vam->retval == -99)
6549 errmsg ("timeout");
6550
6551 if (vam->async_errors > 0)
6552 {
6553 errmsg ("%d asynchronous errors", vam->async_errors);
6554 vam->retval = -98;
6555 }
6556 vam->async_errors = 0;
6557 after = vat_time_now (vam);
6558
6559 /* slim chance, but we might have eaten SIGTERM on the first iteration */
6560 if (j > 0)
6561 count = j;
6562
6563 print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6564 count, after - before, count / (after - before));
6565 }
6566 else
6567 {
Jon Loeliger56c7b012017-02-01 12:31:41 -06006568 int ret;
6569
Damjan Marion7cd468a2016-12-19 23:05:39 +01006570 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06006571 W (ret);
6572 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006573 }
6574
6575 /* Return the good/bad news */
6576 return (vam->retval);
Neale Ranns097fa662018-05-01 05:17:55 -07006577 return (0);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006578}
6579
6580static int
6581api_mpls_ip_bind_unbind (vat_main_t * vam)
6582{
6583 unformat_input_t *i = vam->input;
6584 vl_api_mpls_ip_bind_unbind_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006585 u32 ip_table_id = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006586 u8 is_bind = 1;
Neale Ranns097fa662018-05-01 05:17:55 -07006587 vl_api_prefix_t pfx;
6588 u8 prefix_set = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006589 mpls_label_t local_label = MPLS_LABEL_INVALID;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006590 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006591
6592 /* Parse args required to build the message */
6593 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6594 {
Neale Ranns097fa662018-05-01 05:17:55 -07006595 if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
6596 prefix_set = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006597 else if (unformat (i, "%d", &local_label))
6598 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006599 else if (unformat (i, "table-id %d", &ip_table_id))
6600 ;
6601 else if (unformat (i, "unbind"))
6602 is_bind = 0;
6603 else if (unformat (i, "bind"))
6604 is_bind = 1;
6605 else
6606 {
6607 clib_warning ("parse error '%U'", format_unformat_error, i);
6608 return -99;
6609 }
6610 }
6611
Neale Ranns097fa662018-05-01 05:17:55 -07006612 if (!prefix_set)
Damjan Marion7cd468a2016-12-19 23:05:39 +01006613 {
Neale Ranns097fa662018-05-01 05:17:55 -07006614 errmsg ("IP prefix not set");
Damjan Marion7cd468a2016-12-19 23:05:39 +01006615 return -99;
6616 }
6617
6618 if (MPLS_LABEL_INVALID == local_label)
6619 {
6620 errmsg ("missing label");
6621 return -99;
6622 }
6623
6624 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006625 M (MPLS_IP_BIND_UNBIND, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006626
Damjan Marion7cd468a2016-12-19 23:05:39 +01006627 mp->mb_is_bind = is_bind;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006628 mp->mb_ip_table_id = ntohl (ip_table_id);
6629 mp->mb_mpls_table_id = 0;
6630 mp->mb_label = ntohl (local_label);
Neale Ranns097fa662018-05-01 05:17:55 -07006631 clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
Damjan Marion7cd468a2016-12-19 23:05:39 +01006632
6633 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006634 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006635
6636 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06006637 W (ret);
6638 return ret;
Neale Ranns097fa662018-05-01 05:17:55 -07006639 return (0);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006640}
6641
6642static int
John Loe166fd92018-09-13 14:08:59 -04006643api_sr_mpls_policy_add (vat_main_t * vam)
6644{
6645 unformat_input_t *i = vam->input;
6646 vl_api_sr_mpls_policy_add_t *mp;
6647 u32 bsid = 0;
6648 u32 weight = 1;
6649 u8 type = 0;
6650 u8 n_segments = 0;
6651 u32 sid;
6652 u32 *segments = NULL;
6653 int ret;
6654
6655 /* Parse args required to build the message */
6656 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6657 {
6658 if (unformat (i, "bsid %d", &bsid))
6659 ;
6660 else if (unformat (i, "weight %d", &weight))
6661 ;
6662 else if (unformat (i, "spray"))
6663 type = 1;
6664 else if (unformat (i, "next %d", &sid))
6665 {
6666 n_segments += 1;
6667 vec_add1 (segments, htonl (sid));
6668 }
6669 else
6670 {
6671 clib_warning ("parse error '%U'", format_unformat_error, i);
6672 return -99;
6673 }
6674 }
6675
6676 if (bsid == 0)
6677 {
6678 errmsg ("bsid not set");
6679 return -99;
6680 }
6681
6682 if (n_segments == 0)
6683 {
6684 errmsg ("no sid in segment stack");
6685 return -99;
6686 }
6687
6688 /* Construct the API message */
6689 M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
6690
6691 mp->bsid = htonl (bsid);
6692 mp->weight = htonl (weight);
Jakub Grajciar00ec4012020-01-31 10:17:29 +01006693 mp->is_spray = type;
John Loe166fd92018-09-13 14:08:59 -04006694 mp->n_segments = n_segments;
6695 memcpy (mp->segments, segments, sizeof (u32) * n_segments);
6696 vec_free (segments);
6697
6698 /* send it... */
6699 S (mp);
6700
6701 /* Wait for a reply... */
6702 W (ret);
6703 return ret;
6704}
6705
6706static int
6707api_sr_mpls_policy_del (vat_main_t * vam)
6708{
6709 unformat_input_t *i = vam->input;
6710 vl_api_sr_mpls_policy_del_t *mp;
6711 u32 bsid = 0;
6712 int ret;
6713
6714 /* Parse args required to build the message */
6715 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6716 {
6717 if (unformat (i, "bsid %d", &bsid))
6718 ;
6719 else
6720 {
6721 clib_warning ("parse error '%U'", format_unformat_error, i);
6722 return -99;
6723 }
6724 }
6725
6726 if (bsid == 0)
6727 {
6728 errmsg ("bsid not set");
6729 return -99;
6730 }
6731
6732 /* Construct the API message */
6733 M (SR_MPLS_POLICY_DEL, mp);
6734
6735 mp->bsid = htonl (bsid);
6736
6737 /* send it... */
6738 S (mp);
6739
6740 /* Wait for a reply... */
6741 W (ret);
6742 return ret;
6743}
6744
6745static int
Neale Rannsd792d9c2017-10-21 10:53:20 -07006746api_bier_table_add_del (vat_main_t * vam)
6747{
6748 unformat_input_t *i = vam->input;
6749 vl_api_bier_table_add_del_t *mp;
6750 u8 is_add = 1;
6751 u32 set = 0, sub_domain = 0, hdr_len = 3;
6752 mpls_label_t local_label = MPLS_LABEL_INVALID;
6753 int ret;
6754
6755 /* Parse args required to build the message */
6756 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6757 {
6758 if (unformat (i, "sub-domain %d", &sub_domain))
6759 ;
6760 else if (unformat (i, "set %d", &set))
6761 ;
6762 else if (unformat (i, "label %d", &local_label))
6763 ;
6764 else if (unformat (i, "hdr-len %d", &hdr_len))
6765 ;
6766 else if (unformat (i, "add"))
6767 is_add = 1;
6768 else if (unformat (i, "del"))
6769 is_add = 0;
6770 else
6771 {
6772 clib_warning ("parse error '%U'", format_unformat_error, i);
6773 return -99;
6774 }
6775 }
6776
6777 if (MPLS_LABEL_INVALID == local_label)
6778 {
6779 errmsg ("missing label\n");
6780 return -99;
6781 }
6782
6783 /* Construct the API message */
6784 M (BIER_TABLE_ADD_DEL, mp);
6785
6786 mp->bt_is_add = is_add;
6787 mp->bt_label = ntohl (local_label);
6788 mp->bt_tbl_id.bt_set = set;
6789 mp->bt_tbl_id.bt_sub_domain = sub_domain;
6790 mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
6791
6792 /* send it... */
6793 S (mp);
6794
6795 /* Wait for a reply... */
6796 W (ret);
6797
6798 return (ret);
6799}
6800
6801static int
6802api_bier_route_add_del (vat_main_t * vam)
6803{
6804 unformat_input_t *i = vam->input;
6805 vl_api_bier_route_add_del_t *mp;
6806 u8 is_add = 1;
6807 u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
6808 ip4_address_t v4_next_hop_address;
6809 ip6_address_t v6_next_hop_address;
6810 u8 next_hop_set = 0;
6811 u8 next_hop_proto_is_ip4 = 1;
6812 mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6813 int ret;
6814
6815 /* Parse args required to build the message */
6816 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6817 {
6818 if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
6819 {
6820 next_hop_proto_is_ip4 = 1;
6821 next_hop_set = 1;
6822 }
6823 else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
6824 {
6825 next_hop_proto_is_ip4 = 0;
6826 next_hop_set = 1;
6827 }
6828 if (unformat (i, "sub-domain %d", &sub_domain))
6829 ;
6830 else if (unformat (i, "set %d", &set))
6831 ;
6832 else if (unformat (i, "hdr-len %d", &hdr_len))
6833 ;
6834 else if (unformat (i, "bp %d", &bp))
6835 ;
6836 else if (unformat (i, "add"))
6837 is_add = 1;
6838 else if (unformat (i, "del"))
6839 is_add = 0;
6840 else if (unformat (i, "out-label %d", &next_hop_out_label))
6841 ;
6842 else
6843 {
6844 clib_warning ("parse error '%U'", format_unformat_error, i);
6845 return -99;
6846 }
6847 }
6848
6849 if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
6850 {
6851 errmsg ("next hop / label set\n");
6852 return -99;
6853 }
6854 if (0 == bp)
6855 {
6856 errmsg ("bit=position not set\n");
6857 return -99;
6858 }
6859
6860 /* Construct the API message */
Neale Ranns31ed7442018-02-23 05:29:09 -08006861 M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
Neale Rannsd792d9c2017-10-21 10:53:20 -07006862
6863 mp->br_is_add = is_add;
Neale Ranns097fa662018-05-01 05:17:55 -07006864 mp->br_route.br_tbl_id.bt_set = set;
6865 mp->br_route.br_tbl_id.bt_sub_domain = sub_domain;
6866 mp->br_route.br_tbl_id.bt_hdr_len_id = hdr_len;
6867 mp->br_route.br_bp = ntohs (bp);
6868 mp->br_route.br_n_paths = 1;
6869 mp->br_route.br_paths[0].n_labels = 1;
6870 mp->br_route.br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
6871 mp->br_route.br_paths[0].proto = (next_hop_proto_is_ip4 ?
6872 FIB_API_PATH_NH_PROTO_IP4 :
6873 FIB_API_PATH_NH_PROTO_IP6);
Neale Rannsd792d9c2017-10-21 10:53:20 -07006874
6875 if (next_hop_proto_is_ip4)
6876 {
Neale Ranns097fa662018-05-01 05:17:55 -07006877 clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip4,
Neale Rannsd792d9c2017-10-21 10:53:20 -07006878 &v4_next_hop_address, sizeof (v4_next_hop_address));
6879 }
6880 else
6881 {
Neale Ranns097fa662018-05-01 05:17:55 -07006882 clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip6,
Neale Rannsd792d9c2017-10-21 10:53:20 -07006883 &v6_next_hop_address, sizeof (v6_next_hop_address));
6884 }
6885
6886 /* send it... */
6887 S (mp);
6888
6889 /* Wait for a reply... */
6890 W (ret);
6891
6892 return (ret);
6893}
6894
6895static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01006896api_mpls_tunnel_add_del (vat_main_t * vam)
6897{
6898 unformat_input_t *i = vam->input;
6899 vl_api_mpls_tunnel_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006900
Neale Ranns097fa662018-05-01 05:17:55 -07006901 vl_api_fib_path_t paths[8];
Damjan Marion7cd468a2016-12-19 23:05:39 +01006902 u32 sw_if_index = ~0;
Neale Ranns097fa662018-05-01 05:17:55 -07006903 u8 path_count = 0;
6904 u8 l2_only = 0;
6905 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006906 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006907
6908 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6909 {
6910 if (unformat (i, "add"))
6911 is_add = 1;
John Lo06fda9c2018-10-03 16:32:44 -04006912 else
6913 if (unformat
6914 (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
6915 is_add = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006916 else if (unformat (i, "del sw_if_index %d", &sw_if_index))
6917 is_add = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006918 else if (unformat (i, "l2-only"))
6919 l2_only = 1;
Neale Ranns097fa662018-05-01 05:17:55 -07006920 else
6921 if (unformat
6922 (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
John Lo06fda9c2018-10-03 16:32:44 -04006923 {
Neale Ranns097fa662018-05-01 05:17:55 -07006924 path_count++;
6925 if (8 == path_count)
6926 {
6927 errmsg ("max 8 paths");
6928 return -99;
6929 }
John Lo06fda9c2018-10-03 16:32:44 -04006930 }
Damjan Marion7cd468a2016-12-19 23:05:39 +01006931 else
6932 {
6933 clib_warning ("parse error '%U'", format_unformat_error, i);
6934 return -99;
6935 }
6936 }
6937
Neale Ranns097fa662018-05-01 05:17:55 -07006938 M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006939
Damjan Marion7cd468a2016-12-19 23:05:39 +01006940 mp->mt_is_add = is_add;
Neale Ranns097fa662018-05-01 05:17:55 -07006941 mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
6942 mp->mt_tunnel.mt_l2_only = l2_only;
6943 mp->mt_tunnel.mt_is_multicast = 0;
6944 mp->mt_tunnel.mt_n_paths = path_count;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006945
Neale Ranns097fa662018-05-01 05:17:55 -07006946 clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
6947 sizeof (paths[0]) * path_count);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006948
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006949 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06006950 W (ret);
6951 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006952}
6953
6954static int
6955api_sw_interface_set_unnumbered (vat_main_t * vam)
6956{
6957 unformat_input_t *i = vam->input;
6958 vl_api_sw_interface_set_unnumbered_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006959 u32 sw_if_index;
6960 u32 unnum_sw_index = ~0;
6961 u8 is_add = 1;
6962 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006963 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006964
6965 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6966 {
6967 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6968 sw_if_index_set = 1;
6969 else if (unformat (i, "sw_if_index %d", &sw_if_index))
6970 sw_if_index_set = 1;
6971 else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
6972 ;
6973 else if (unformat (i, "del"))
6974 is_add = 0;
6975 else
6976 {
6977 clib_warning ("parse error '%U'", format_unformat_error, i);
6978 return -99;
6979 }
6980 }
6981
6982 if (sw_if_index_set == 0)
6983 {
6984 errmsg ("missing interface name or sw_if_index");
6985 return -99;
6986 }
6987
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006988 M (SW_INTERFACE_SET_UNNUMBERED, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006989
6990 mp->sw_if_index = ntohl (sw_if_index);
6991 mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
6992 mp->is_add = is_add;
6993
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006994 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06006995 W (ret);
6996 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006997}
6998
Damjan Marion7cd468a2016-12-19 23:05:39 +01006999
7000static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01007001api_create_vlan_subif (vat_main_t * vam)
7002{
7003 unformat_input_t *i = vam->input;
7004 vl_api_create_vlan_subif_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007005 u32 sw_if_index;
7006 u8 sw_if_index_set = 0;
7007 u32 vlan_id;
7008 u8 vlan_id_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007009 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007010
7011 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7012 {
7013 if (unformat (i, "sw_if_index %d", &sw_if_index))
7014 sw_if_index_set = 1;
7015 else
7016 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7017 sw_if_index_set = 1;
7018 else if (unformat (i, "vlan %d", &vlan_id))
7019 vlan_id_set = 1;
7020 else
7021 {
7022 clib_warning ("parse error '%U'", format_unformat_error, i);
7023 return -99;
7024 }
7025 }
7026
7027 if (sw_if_index_set == 0)
7028 {
7029 errmsg ("missing interface name or sw_if_index");
7030 return -99;
7031 }
7032
7033 if (vlan_id_set == 0)
7034 {
7035 errmsg ("missing vlan_id");
7036 return -99;
7037 }
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007038 M (CREATE_VLAN_SUBIF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007039
7040 mp->sw_if_index = ntohl (sw_if_index);
7041 mp->vlan_id = ntohl (vlan_id);
7042
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007043 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007044 W (ret);
7045 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007046}
7047
7048#define foreach_create_subif_bit \
7049_(no_tags) \
7050_(one_tag) \
7051_(two_tags) \
7052_(dot1ad) \
7053_(exact_match) \
7054_(default_sub) \
7055_(outer_vlan_id_any) \
7056_(inner_vlan_id_any)
7057
Jakub Grajciar053204a2019-03-18 13:17:53 +01007058#define foreach_create_subif_flag \
7059_(0, "no_tags") \
7060_(1, "one_tag") \
7061_(2, "two_tags") \
7062_(3, "dot1ad") \
7063_(4, "exact_match") \
7064_(5, "default_sub") \
7065_(6, "outer_vlan_id_any") \
7066_(7, "inner_vlan_id_any")
7067
Damjan Marion7cd468a2016-12-19 23:05:39 +01007068static int
7069api_create_subif (vat_main_t * vam)
7070{
7071 unformat_input_t *i = vam->input;
7072 vl_api_create_subif_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007073 u32 sw_if_index;
7074 u8 sw_if_index_set = 0;
7075 u32 sub_id;
7076 u8 sub_id_set = 0;
Jakub Grajciar053204a2019-03-18 13:17:53 +01007077 u32 __attribute__ ((unused)) no_tags = 0;
7078 u32 __attribute__ ((unused)) one_tag = 0;
7079 u32 __attribute__ ((unused)) two_tags = 0;
7080 u32 __attribute__ ((unused)) dot1ad = 0;
7081 u32 __attribute__ ((unused)) exact_match = 0;
7082 u32 __attribute__ ((unused)) default_sub = 0;
7083 u32 __attribute__ ((unused)) outer_vlan_id_any = 0;
7084 u32 __attribute__ ((unused)) inner_vlan_id_any = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007085 u32 tmp;
7086 u16 outer_vlan_id = 0;
7087 u16 inner_vlan_id = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007088 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007089
7090 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7091 {
7092 if (unformat (i, "sw_if_index %d", &sw_if_index))
7093 sw_if_index_set = 1;
7094 else
7095 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7096 sw_if_index_set = 1;
7097 else if (unformat (i, "sub_id %d", &sub_id))
7098 sub_id_set = 1;
7099 else if (unformat (i, "outer_vlan_id %d", &tmp))
7100 outer_vlan_id = tmp;
7101 else if (unformat (i, "inner_vlan_id %d", &tmp))
7102 inner_vlan_id = tmp;
7103
7104#define _(a) else if (unformat (i, #a)) a = 1 ;
7105 foreach_create_subif_bit
7106#undef _
7107 else
7108 {
7109 clib_warning ("parse error '%U'", format_unformat_error, i);
7110 return -99;
7111 }
7112 }
7113
7114 if (sw_if_index_set == 0)
7115 {
7116 errmsg ("missing interface name or sw_if_index");
7117 return -99;
7118 }
7119
7120 if (sub_id_set == 0)
7121 {
7122 errmsg ("missing sub_id");
7123 return -99;
7124 }
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007125 M (CREATE_SUBIF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007126
7127 mp->sw_if_index = ntohl (sw_if_index);
7128 mp->sub_id = ntohl (sub_id);
7129
Jakub Grajciar053204a2019-03-18 13:17:53 +01007130#define _(a,b) mp->sub_if_flags |= (1 << a);
7131 foreach_create_subif_flag;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007132#undef _
7133
7134 mp->outer_vlan_id = ntohs (outer_vlan_id);
7135 mp->inner_vlan_id = ntohs (inner_vlan_id);
7136
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007137 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007138 W (ret);
7139 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007140}
7141
7142static int
Neale Ranns9db6ada2019-11-08 12:42:31 +00007143api_ip_table_replace_begin (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +01007144{
7145 unformat_input_t *i = vam->input;
Neale Ranns9db6ada2019-11-08 12:42:31 +00007146 vl_api_ip_table_replace_begin_t *mp;
7147 u32 table_id = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007148 u8 is_ipv6 = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007149
Jon Loeliger56c7b012017-02-01 12:31:41 -06007150 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007151 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7152 {
Neale Ranns9db6ada2019-11-08 12:42:31 +00007153 if (unformat (i, "table %d", &table_id))
7154 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007155 else if (unformat (i, "ipv6"))
7156 is_ipv6 = 1;
7157 else
7158 {
7159 clib_warning ("parse error '%U'", format_unformat_error, i);
7160 return -99;
7161 }
7162 }
7163
Neale Ranns9db6ada2019-11-08 12:42:31 +00007164 M (IP_TABLE_REPLACE_BEGIN, mp);
7165
7166 mp->table.table_id = ntohl (table_id);
7167 mp->table.is_ip6 = is_ipv6;
7168
7169 S (mp);
7170 W (ret);
7171 return ret;
7172}
7173
7174static int
7175api_ip_table_flush (vat_main_t * vam)
7176{
7177 unformat_input_t *i = vam->input;
7178 vl_api_ip_table_flush_t *mp;
7179 u32 table_id = 0;
7180 u8 is_ipv6 = 0;
7181
7182 int ret;
7183 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
Damjan Marion7cd468a2016-12-19 23:05:39 +01007184 {
Neale Ranns9db6ada2019-11-08 12:42:31 +00007185 if (unformat (i, "table %d", &table_id))
7186 ;
7187 else if (unformat (i, "ipv6"))
7188 is_ipv6 = 1;
7189 else
7190 {
7191 clib_warning ("parse error '%U'", format_unformat_error, i);
7192 return -99;
7193 }
Damjan Marion7cd468a2016-12-19 23:05:39 +01007194 }
7195
Neale Ranns9db6ada2019-11-08 12:42:31 +00007196 M (IP_TABLE_FLUSH, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007197
Neale Ranns9db6ada2019-11-08 12:42:31 +00007198 mp->table.table_id = ntohl (table_id);
7199 mp->table.is_ip6 = is_ipv6;
7200
7201 S (mp);
7202 W (ret);
7203 return ret;
7204}
7205
7206static int
7207api_ip_table_replace_end (vat_main_t * vam)
7208{
7209 unformat_input_t *i = vam->input;
7210 vl_api_ip_table_replace_end_t *mp;
7211 u32 table_id = 0;
7212 u8 is_ipv6 = 0;
7213
7214 int ret;
7215 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7216 {
7217 if (unformat (i, "table %d", &table_id))
7218 ;
7219 else if (unformat (i, "ipv6"))
7220 is_ipv6 = 1;
7221 else
7222 {
7223 clib_warning ("parse error '%U'", format_unformat_error, i);
7224 return -99;
7225 }
7226 }
7227
7228 M (IP_TABLE_REPLACE_END, mp);
7229
7230 mp->table.table_id = ntohl (table_id);
7231 mp->table.is_ip6 = is_ipv6;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007232
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007233 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007234 W (ret);
7235 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007236}
7237
7238static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01007239api_set_ip_flow_hash (vat_main_t * vam)
7240{
7241 unformat_input_t *i = vam->input;
7242 vl_api_set_ip_flow_hash_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007243 u32 vrf_id = 0;
7244 u8 is_ipv6 = 0;
7245 u8 vrf_id_set = 0;
7246 u8 src = 0;
7247 u8 dst = 0;
7248 u8 sport = 0;
7249 u8 dport = 0;
7250 u8 proto = 0;
7251 u8 reverse = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007252 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007253
7254 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7255 {
7256 if (unformat (i, "vrf %d", &vrf_id))
7257 vrf_id_set = 1;
7258 else if (unformat (i, "ipv6"))
7259 is_ipv6 = 1;
7260 else if (unformat (i, "src"))
7261 src = 1;
7262 else if (unformat (i, "dst"))
7263 dst = 1;
7264 else if (unformat (i, "sport"))
7265 sport = 1;
7266 else if (unformat (i, "dport"))
7267 dport = 1;
7268 else if (unformat (i, "proto"))
7269 proto = 1;
7270 else if (unformat (i, "reverse"))
7271 reverse = 1;
7272
7273 else
7274 {
7275 clib_warning ("parse error '%U'", format_unformat_error, i);
7276 return -99;
7277 }
7278 }
7279
7280 if (vrf_id_set == 0)
7281 {
7282 errmsg ("missing vrf id");
7283 return -99;
7284 }
7285
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007286 M (SET_IP_FLOW_HASH, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007287 mp->src = src;
7288 mp->dst = dst;
7289 mp->sport = sport;
7290 mp->dport = dport;
7291 mp->proto = proto;
7292 mp->reverse = reverse;
7293 mp->vrf_id = ntohl (vrf_id);
7294 mp->is_ipv6 = is_ipv6;
7295
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007296 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007297 W (ret);
7298 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007299}
7300
7301static int
7302api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7303{
7304 unformat_input_t *i = vam->input;
7305 vl_api_sw_interface_ip6_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007306 u32 sw_if_index;
7307 u8 sw_if_index_set = 0;
7308 u8 enable = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007309 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007310
7311 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7312 {
7313 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7314 sw_if_index_set = 1;
7315 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7316 sw_if_index_set = 1;
7317 else if (unformat (i, "enable"))
7318 enable = 1;
7319 else if (unformat (i, "disable"))
7320 enable = 0;
7321 else
7322 {
7323 clib_warning ("parse error '%U'", format_unformat_error, i);
7324 return -99;
7325 }
7326 }
7327
7328 if (sw_if_index_set == 0)
7329 {
7330 errmsg ("missing interface name or sw_if_index");
7331 return -99;
7332 }
7333
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007334 M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007335
7336 mp->sw_if_index = ntohl (sw_if_index);
7337 mp->enable = enable;
7338
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007339 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007340 W (ret);
7341 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007342}
7343
Damjan Marion7cd468a2016-12-19 23:05:39 +01007344
7345static int
7346api_l2_patch_add_del (vat_main_t * vam)
7347{
7348 unformat_input_t *i = vam->input;
7349 vl_api_l2_patch_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007350 u32 rx_sw_if_index;
7351 u8 rx_sw_if_index_set = 0;
7352 u32 tx_sw_if_index;
7353 u8 tx_sw_if_index_set = 0;
7354 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007355 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007356
7357 /* Parse args required to build the message */
7358 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7359 {
7360 if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7361 rx_sw_if_index_set = 1;
7362 else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7363 tx_sw_if_index_set = 1;
7364 else if (unformat (i, "rx"))
7365 {
7366 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7367 {
7368 if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7369 &rx_sw_if_index))
7370 rx_sw_if_index_set = 1;
7371 }
7372 else
7373 break;
7374 }
7375 else if (unformat (i, "tx"))
7376 {
7377 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7378 {
7379 if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7380 &tx_sw_if_index))
7381 tx_sw_if_index_set = 1;
7382 }
7383 else
7384 break;
7385 }
7386 else if (unformat (i, "del"))
7387 is_add = 0;
7388 else
7389 break;
7390 }
7391
7392 if (rx_sw_if_index_set == 0)
7393 {
7394 errmsg ("missing rx interface name or rx_sw_if_index");
7395 return -99;
7396 }
7397
7398 if (tx_sw_if_index_set == 0)
7399 {
7400 errmsg ("missing tx interface name or tx_sw_if_index");
7401 return -99;
7402 }
7403
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007404 M (L2_PATCH_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007405
7406 mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7407 mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7408 mp->is_add = is_add;
7409
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007410 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007411 W (ret);
7412 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007413}
7414
Pablo Camarillofb380952016-12-07 18:34:18 +01007415u8 is_del;
7416u8 localsid_addr[16];
7417u8 end_psp;
7418u8 behavior;
7419u32 sw_if_index;
7420u32 vlan_index;
7421u32 fib_table;
7422u8 nh_addr[16];
7423
7424static int
7425api_sr_localsid_add_del (vat_main_t * vam)
7426{
7427 unformat_input_t *i = vam->input;
7428 vl_api_sr_localsid_add_del_t *mp;
7429
7430 u8 is_del;
7431 ip6_address_t localsid;
7432 u8 end_psp = 0;
7433 u8 behavior = ~0;
7434 u32 sw_if_index;
7435 u32 fib_table = ~(u32) 0;
Jakub Grajciar0938eba2020-03-04 13:08:27 +01007436 ip46_address_t nh_addr;
7437 clib_memset (&nh_addr, 0, sizeof (ip46_address_t));
Pablo Camarillofb380952016-12-07 18:34:18 +01007438
7439 bool nexthop_set = 0;
7440
7441 int ret;
7442
7443 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7444 {
7445 if (unformat (i, "del"))
7446 is_del = 1;
7447 else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
Jakub Grajciar0938eba2020-03-04 13:08:27 +01007448 else if (unformat (i, "next-hop %U", unformat_ip46_address, &nh_addr))
Pablo Camarillofb380952016-12-07 18:34:18 +01007449 nexthop_set = 1;
7450 else if (unformat (i, "behavior %u", &behavior));
7451 else if (unformat (i, "sw_if_index %u", &sw_if_index));
7452 else if (unformat (i, "fib-table %u", &fib_table));
7453 else if (unformat (i, "end.psp %u", &behavior));
7454 else
7455 break;
7456 }
7457
7458 M (SR_LOCALSID_ADD_DEL, mp);
7459
Jakub Grajciar0938eba2020-03-04 13:08:27 +01007460 clib_memcpy (mp->localsid, &localsid, sizeof (mp->localsid));
Tetsuya Murakami1b81e6e2019-11-06 11:05:51 -08007461
Pablo Camarillofb380952016-12-07 18:34:18 +01007462 if (nexthop_set)
Pablo Camarillo3337bd22018-06-19 15:49:02 +02007463 {
Jakub Grajciar0938eba2020-03-04 13:08:27 +01007464 clib_memcpy (&mp->nh_addr.un, &nh_addr, sizeof (mp->nh_addr.un));
Pablo Camarillo3337bd22018-06-19 15:49:02 +02007465 }
Pablo Camarillofb380952016-12-07 18:34:18 +01007466 mp->behavior = behavior;
7467 mp->sw_if_index = ntohl (sw_if_index);
7468 mp->fib_table = ntohl (fib_table);
7469 mp->end_psp = end_psp;
7470 mp->is_del = is_del;
7471
7472 S (mp);
7473 W (ret);
7474 return ret;
7475}
7476
Damjan Marion7cd468a2016-12-19 23:05:39 +01007477static int
7478api_ioam_enable (vat_main_t * vam)
7479{
7480 unformat_input_t *input = vam->input;
7481 vl_api_ioam_enable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007482 u32 id = 0;
7483 int has_trace_option = 0;
7484 int has_pot_option = 0;
7485 int has_seqno_option = 0;
7486 int has_analyse_option = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007487 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007488
7489 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7490 {
7491 if (unformat (input, "trace"))
7492 has_trace_option = 1;
7493 else if (unformat (input, "pot"))
7494 has_pot_option = 1;
7495 else if (unformat (input, "seqno"))
7496 has_seqno_option = 1;
7497 else if (unformat (input, "analyse"))
7498 has_analyse_option = 1;
7499 else
7500 break;
7501 }
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007502 M (IOAM_ENABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007503 mp->id = htons (id);
7504 mp->seqno = has_seqno_option;
7505 mp->analyse = has_analyse_option;
7506 mp->pot_enable = has_pot_option;
7507 mp->trace_enable = has_trace_option;
7508
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007509 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007510 W (ret);
7511 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007512}
7513
7514
7515static int
7516api_ioam_disable (vat_main_t * vam)
7517{
7518 vl_api_ioam_disable_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007519 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007520
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007521 M (IOAM_DISABLE, mp);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007522 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007523 W (ret);
7524 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007525}
7526
Damjan Marion7cd468a2016-12-19 23:05:39 +01007527#define foreach_tcp_proto_field \
7528_(src_port) \
7529_(dst_port)
7530
7531#define foreach_udp_proto_field \
7532_(src_port) \
7533_(dst_port)
7534
7535#define foreach_ip4_proto_field \
7536_(src_address) \
7537_(dst_address) \
7538_(tos) \
7539_(length) \
7540_(fragment_id) \
7541_(ttl) \
7542_(protocol) \
7543_(checksum)
7544
Dave Barach4a3f69c2017-02-22 12:44:56 -05007545typedef struct
7546{
7547 u16 src_port, dst_port;
7548} tcpudp_header_t;
7549
7550#if VPP_API_TEST_BUILTIN == 0
Damjan Marion7cd468a2016-12-19 23:05:39 +01007551uword
7552unformat_tcp_mask (unformat_input_t * input, va_list * args)
7553{
7554 u8 **maskp = va_arg (*args, u8 **);
7555 u8 *mask = 0;
7556 u8 found_something = 0;
7557 tcp_header_t *tcp;
7558
7559#define _(a) u8 a=0;
7560 foreach_tcp_proto_field;
7561#undef _
7562
7563 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7564 {
7565 if (0);
7566#define _(a) else if (unformat (input, #a)) a=1;
7567 foreach_tcp_proto_field
7568#undef _
7569 else
7570 break;
7571 }
7572
7573#define _(a) found_something += a;
7574 foreach_tcp_proto_field;
7575#undef _
7576
7577 if (found_something == 0)
7578 return 0;
7579
7580 vec_validate (mask, sizeof (*tcp) - 1);
7581
7582 tcp = (tcp_header_t *) mask;
7583
Dave Barachb7b92992018-10-17 10:38:51 -04007584#define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
Damjan Marion7cd468a2016-12-19 23:05:39 +01007585 foreach_tcp_proto_field;
7586#undef _
7587
7588 *maskp = mask;
7589 return 1;
7590}
7591
7592uword
7593unformat_udp_mask (unformat_input_t * input, va_list * args)
7594{
7595 u8 **maskp = va_arg (*args, u8 **);
7596 u8 *mask = 0;
7597 u8 found_something = 0;
7598 udp_header_t *udp;
7599
7600#define _(a) u8 a=0;
7601 foreach_udp_proto_field;
7602#undef _
7603
7604 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7605 {
7606 if (0);
7607#define _(a) else if (unformat (input, #a)) a=1;
7608 foreach_udp_proto_field
7609#undef _
7610 else
7611 break;
7612 }
7613
7614#define _(a) found_something += a;
7615 foreach_udp_proto_field;
7616#undef _
7617
7618 if (found_something == 0)
7619 return 0;
7620
7621 vec_validate (mask, sizeof (*udp) - 1);
7622
7623 udp = (udp_header_t *) mask;
7624
Dave Barachb7b92992018-10-17 10:38:51 -04007625#define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
Damjan Marion7cd468a2016-12-19 23:05:39 +01007626 foreach_udp_proto_field;
7627#undef _
7628
7629 *maskp = mask;
7630 return 1;
7631}
7632
Damjan Marion7cd468a2016-12-19 23:05:39 +01007633uword
7634unformat_l4_mask (unformat_input_t * input, va_list * args)
7635{
7636 u8 **maskp = va_arg (*args, u8 **);
7637 u16 src_port = 0, dst_port = 0;
7638 tcpudp_header_t *tcpudp;
7639
7640 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7641 {
7642 if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
7643 return 1;
7644 else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
7645 return 1;
7646 else if (unformat (input, "src_port"))
7647 src_port = 0xFFFF;
7648 else if (unformat (input, "dst_port"))
7649 dst_port = 0xFFFF;
7650 else
7651 return 0;
7652 }
7653
7654 if (!src_port && !dst_port)
7655 return 0;
7656
7657 u8 *mask = 0;
7658 vec_validate (mask, sizeof (tcpudp_header_t) - 1);
7659
7660 tcpudp = (tcpudp_header_t *) mask;
7661 tcpudp->src_port = src_port;
7662 tcpudp->dst_port = dst_port;
7663
7664 *maskp = mask;
7665
7666 return 1;
7667}
7668
7669uword
7670unformat_ip4_mask (unformat_input_t * input, va_list * args)
7671{
7672 u8 **maskp = va_arg (*args, u8 **);
7673 u8 *mask = 0;
7674 u8 found_something = 0;
7675 ip4_header_t *ip;
7676
7677#define _(a) u8 a=0;
7678 foreach_ip4_proto_field;
7679#undef _
7680 u8 version = 0;
7681 u8 hdr_length = 0;
7682
7683
7684 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7685 {
7686 if (unformat (input, "version"))
7687 version = 1;
7688 else if (unformat (input, "hdr_length"))
7689 hdr_length = 1;
7690 else if (unformat (input, "src"))
7691 src_address = 1;
7692 else if (unformat (input, "dst"))
7693 dst_address = 1;
7694 else if (unformat (input, "proto"))
7695 protocol = 1;
7696
7697#define _(a) else if (unformat (input, #a)) a=1;
7698 foreach_ip4_proto_field
7699#undef _
7700 else
7701 break;
7702 }
7703
7704#define _(a) found_something += a;
7705 foreach_ip4_proto_field;
7706#undef _
7707
7708 if (found_something == 0)
7709 return 0;
7710
7711 vec_validate (mask, sizeof (*ip) - 1);
7712
7713 ip = (ip4_header_t *) mask;
7714
Dave Barachb7b92992018-10-17 10:38:51 -04007715#define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
Damjan Marion7cd468a2016-12-19 23:05:39 +01007716 foreach_ip4_proto_field;
7717#undef _
7718
7719 ip->ip_version_and_header_length = 0;
7720
7721 if (version)
7722 ip->ip_version_and_header_length |= 0xF0;
7723
7724 if (hdr_length)
7725 ip->ip_version_and_header_length |= 0x0F;
7726
7727 *maskp = mask;
7728 return 1;
7729}
7730
7731#define foreach_ip6_proto_field \
7732_(src_address) \
7733_(dst_address) \
7734_(payload_length) \
7735_(hop_limit) \
7736_(protocol)
7737
7738uword
7739unformat_ip6_mask (unformat_input_t * input, va_list * args)
7740{
7741 u8 **maskp = va_arg (*args, u8 **);
7742 u8 *mask = 0;
7743 u8 found_something = 0;
7744 ip6_header_t *ip;
7745 u32 ip_version_traffic_class_and_flow_label;
7746
7747#define _(a) u8 a=0;
7748 foreach_ip6_proto_field;
7749#undef _
7750 u8 version = 0;
7751 u8 traffic_class = 0;
7752 u8 flow_label = 0;
7753
7754 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7755 {
7756 if (unformat (input, "version"))
7757 version = 1;
7758 else if (unformat (input, "traffic-class"))
7759 traffic_class = 1;
7760 else if (unformat (input, "flow-label"))
7761 flow_label = 1;
7762 else if (unformat (input, "src"))
7763 src_address = 1;
7764 else if (unformat (input, "dst"))
7765 dst_address = 1;
7766 else if (unformat (input, "proto"))
7767 protocol = 1;
7768
7769#define _(a) else if (unformat (input, #a)) a=1;
7770 foreach_ip6_proto_field
7771#undef _
7772 else
7773 break;
7774 }
7775
7776#define _(a) found_something += a;
7777 foreach_ip6_proto_field;
7778#undef _
7779
7780 if (found_something == 0)
7781 return 0;
7782
7783 vec_validate (mask, sizeof (*ip) - 1);
7784
7785 ip = (ip6_header_t *) mask;
7786
Dave Barachb7b92992018-10-17 10:38:51 -04007787#define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
Damjan Marion7cd468a2016-12-19 23:05:39 +01007788 foreach_ip6_proto_field;
7789#undef _
7790
7791 ip_version_traffic_class_and_flow_label = 0;
7792
7793 if (version)
7794 ip_version_traffic_class_and_flow_label |= 0xF0000000;
7795
7796 if (traffic_class)
7797 ip_version_traffic_class_and_flow_label |= 0x0FF00000;
7798
7799 if (flow_label)
7800 ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
7801
7802 ip->ip_version_traffic_class_and_flow_label =
7803 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
7804
7805 *maskp = mask;
7806 return 1;
7807}
7808
7809uword
7810unformat_l3_mask (unformat_input_t * input, va_list * args)
7811{
7812 u8 **maskp = va_arg (*args, u8 **);
7813
7814 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7815 {
7816 if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
7817 return 1;
7818 else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
7819 return 1;
7820 else
7821 break;
7822 }
7823 return 0;
7824}
7825
7826uword
7827unformat_l2_mask (unformat_input_t * input, va_list * args)
7828{
7829 u8 **maskp = va_arg (*args, u8 **);
7830 u8 *mask = 0;
7831 u8 src = 0;
7832 u8 dst = 0;
7833 u8 proto = 0;
7834 u8 tag1 = 0;
7835 u8 tag2 = 0;
7836 u8 ignore_tag1 = 0;
7837 u8 ignore_tag2 = 0;
7838 u8 cos1 = 0;
7839 u8 cos2 = 0;
7840 u8 dot1q = 0;
7841 u8 dot1ad = 0;
7842 int len = 14;
7843
7844 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7845 {
7846 if (unformat (input, "src"))
7847 src = 1;
7848 else if (unformat (input, "dst"))
7849 dst = 1;
7850 else if (unformat (input, "proto"))
7851 proto = 1;
7852 else if (unformat (input, "tag1"))
7853 tag1 = 1;
7854 else if (unformat (input, "tag2"))
7855 tag2 = 1;
7856 else if (unformat (input, "ignore-tag1"))
7857 ignore_tag1 = 1;
7858 else if (unformat (input, "ignore-tag2"))
7859 ignore_tag2 = 1;
7860 else if (unformat (input, "cos1"))
7861 cos1 = 1;
7862 else if (unformat (input, "cos2"))
7863 cos2 = 1;
7864 else if (unformat (input, "dot1q"))
7865 dot1q = 1;
7866 else if (unformat (input, "dot1ad"))
7867 dot1ad = 1;
7868 else
7869 break;
7870 }
7871 if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
7872 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
7873 return 0;
7874
7875 if (tag1 || ignore_tag1 || cos1 || dot1q)
7876 len = 18;
7877 if (tag2 || ignore_tag2 || cos2 || dot1ad)
7878 len = 22;
7879
7880 vec_validate (mask, len - 1);
7881
7882 if (dst)
Dave Barachb7b92992018-10-17 10:38:51 -04007883 clib_memset (mask, 0xff, 6);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007884
7885 if (src)
Dave Barachb7b92992018-10-17 10:38:51 -04007886 clib_memset (mask + 6, 0xff, 6);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007887
7888 if (tag2 || dot1ad)
7889 {
7890 /* inner vlan tag */
7891 if (tag2)
7892 {
7893 mask[19] = 0xff;
7894 mask[18] = 0x0f;
7895 }
7896 if (cos2)
7897 mask[18] |= 0xe0;
7898 if (proto)
7899 mask[21] = mask[20] = 0xff;
7900 if (tag1)
7901 {
7902 mask[15] = 0xff;
7903 mask[14] = 0x0f;
7904 }
7905 if (cos1)
7906 mask[14] |= 0xe0;
7907 *maskp = mask;
7908 return 1;
7909 }
7910 if (tag1 | dot1q)
7911 {
7912 if (tag1)
7913 {
7914 mask[15] = 0xff;
7915 mask[14] = 0x0f;
7916 }
7917 if (cos1)
7918 mask[14] |= 0xe0;
7919 if (proto)
7920 mask[16] = mask[17] = 0xff;
7921
7922 *maskp = mask;
7923 return 1;
7924 }
7925 if (cos2)
7926 mask[18] |= 0xe0;
7927 if (cos1)
7928 mask[14] |= 0xe0;
7929 if (proto)
7930 mask[12] = mask[13] = 0xff;
7931
7932 *maskp = mask;
7933 return 1;
7934}
7935
7936uword
7937unformat_classify_mask (unformat_input_t * input, va_list * args)
7938{
7939 u8 **maskp = va_arg (*args, u8 **);
7940 u32 *skipp = va_arg (*args, u32 *);
7941 u32 *matchp = va_arg (*args, u32 *);
7942 u32 match;
7943 u8 *mask = 0;
7944 u8 *l2 = 0;
7945 u8 *l3 = 0;
7946 u8 *l4 = 0;
7947 int i;
7948
7949 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7950 {
7951 if (unformat (input, "hex %U", unformat_hex_string, &mask))
7952 ;
7953 else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
7954 ;
7955 else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
7956 ;
7957 else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
7958 ;
7959 else
7960 break;
7961 }
7962
7963 if (l4 && !l3)
7964 {
7965 vec_free (mask);
7966 vec_free (l2);
7967 vec_free (l4);
7968 return 0;
7969 }
7970
7971 if (mask || l2 || l3 || l4)
7972 {
7973 if (l2 || l3 || l4)
7974 {
7975 /* "With a free Ethernet header in every package" */
7976 if (l2 == 0)
7977 vec_validate (l2, 13);
7978 mask = l2;
7979 if (vec_len (l3))
7980 {
7981 vec_append (mask, l3);
7982 vec_free (l3);
7983 }
7984 if (vec_len (l4))
7985 {
7986 vec_append (mask, l4);
7987 vec_free (l4);
7988 }
7989 }
7990
7991 /* Scan forward looking for the first significant mask octet */
7992 for (i = 0; i < vec_len (mask); i++)
7993 if (mask[i])
7994 break;
7995
7996 /* compute (skip, match) params */
7997 *skipp = i / sizeof (u32x4);
7998 vec_delete (mask, *skipp * sizeof (u32x4), 0);
7999
8000 /* Pad mask to an even multiple of the vector size */
8001 while (vec_len (mask) % sizeof (u32x4))
8002 vec_add1 (mask, 0);
8003
8004 match = vec_len (mask) / sizeof (u32x4);
8005
8006 for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
8007 {
8008 u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
8009 if (*tmp || *(tmp + 1))
8010 break;
8011 match--;
8012 }
8013 if (match == 0)
8014 clib_warning ("BUG: match 0");
8015
8016 _vec_len (mask) = match * sizeof (u32x4);
8017
8018 *matchp = match;
8019 *maskp = mask;
8020
8021 return 1;
8022 }
8023
8024 return 0;
8025}
Dave Barach4a3f69c2017-02-22 12:44:56 -05008026#endif /* VPP_API_TEST_BUILTIN */
Damjan Marion7cd468a2016-12-19 23:05:39 +01008027
8028#define foreach_l2_next \
8029_(drop, DROP) \
8030_(ethernet, ETHERNET_INPUT) \
8031_(ip4, IP4_INPUT) \
8032_(ip6, IP6_INPUT)
8033
8034uword
8035unformat_l2_next_index (unformat_input_t * input, va_list * args)
8036{
8037 u32 *miss_next_indexp = va_arg (*args, u32 *);
8038 u32 next_index = 0;
8039 u32 tmp;
8040
8041#define _(n,N) \
8042 if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
8043 foreach_l2_next;
8044#undef _
8045
8046 if (unformat (input, "%d", &tmp))
8047 {
8048 next_index = tmp;
8049 goto out;
8050 }
8051
8052 return 0;
8053
8054out:
8055 *miss_next_indexp = next_index;
8056 return 1;
8057}
8058
8059#define foreach_ip_next \
8060_(drop, DROP) \
8061_(local, LOCAL) \
8062_(rewrite, REWRITE)
8063
8064uword
Dave Barach4a3f69c2017-02-22 12:44:56 -05008065api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
Damjan Marion7cd468a2016-12-19 23:05:39 +01008066{
8067 u32 *miss_next_indexp = va_arg (*args, u32 *);
8068 u32 next_index = 0;
8069 u32 tmp;
8070
8071#define _(n,N) \
8072 if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
8073 foreach_ip_next;
8074#undef _
8075
8076 if (unformat (input, "%d", &tmp))
8077 {
8078 next_index = tmp;
8079 goto out;
8080 }
8081
8082 return 0;
8083
8084out:
8085 *miss_next_indexp = next_index;
8086 return 1;
8087}
8088
8089#define foreach_acl_next \
8090_(deny, DENY)
8091
8092uword
Dave Barach4a3f69c2017-02-22 12:44:56 -05008093api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
Damjan Marion7cd468a2016-12-19 23:05:39 +01008094{
8095 u32 *miss_next_indexp = va_arg (*args, u32 *);
8096 u32 next_index = 0;
8097 u32 tmp;
8098
8099#define _(n,N) \
8100 if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
8101 foreach_acl_next;
8102#undef _
8103
8104 if (unformat (input, "permit"))
8105 {
8106 next_index = ~0;
8107 goto out;
8108 }
8109 else if (unformat (input, "%d", &tmp))
8110 {
8111 next_index = tmp;
8112 goto out;
8113 }
8114
8115 return 0;
8116
8117out:
8118 *miss_next_indexp = next_index;
8119 return 1;
8120}
8121
8122uword
8123unformat_policer_precolor (unformat_input_t * input, va_list * args)
8124{
8125 u32 *r = va_arg (*args, u32 *);
8126
8127 if (unformat (input, "conform-color"))
8128 *r = POLICE_CONFORM;
8129 else if (unformat (input, "exceed-color"))
8130 *r = POLICE_EXCEED;
8131 else
8132 return 0;
8133
8134 return 1;
8135}
8136
8137static int
8138api_classify_add_del_table (vat_main_t * vam)
8139{
8140 unformat_input_t *i = vam->input;
8141 vl_api_classify_add_del_table_t *mp;
8142
8143 u32 nbuckets = 2;
8144 u32 skip = ~0;
8145 u32 match = ~0;
8146 int is_add = 1;
8147 int del_chain = 0;
8148 u32 table_index = ~0;
8149 u32 next_table_index = ~0;
8150 u32 miss_next_index = ~0;
8151 u32 memory_size = 32 << 20;
8152 u8 *mask = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008153 u32 current_data_flag = 0;
8154 int current_data_offset = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008155 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008156
8157 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8158 {
8159 if (unformat (i, "del"))
8160 is_add = 0;
8161 else if (unformat (i, "del-chain"))
8162 {
8163 is_add = 0;
8164 del_chain = 1;
8165 }
8166 else if (unformat (i, "buckets %d", &nbuckets))
8167 ;
8168 else if (unformat (i, "memory_size %d", &memory_size))
8169 ;
8170 else if (unformat (i, "skip %d", &skip))
8171 ;
8172 else if (unformat (i, "match %d", &match))
8173 ;
8174 else if (unformat (i, "table %d", &table_index))
8175 ;
8176 else if (unformat (i, "mask %U", unformat_classify_mask,
8177 &mask, &skip, &match))
8178 ;
8179 else if (unformat (i, "next-table %d", &next_table_index))
8180 ;
Dave Barach4a3f69c2017-02-22 12:44:56 -05008181 else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
Damjan Marion7cd468a2016-12-19 23:05:39 +01008182 &miss_next_index))
8183 ;
8184 else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
8185 &miss_next_index))
8186 ;
Dave Barach4a3f69c2017-02-22 12:44:56 -05008187 else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
Damjan Marion7cd468a2016-12-19 23:05:39 +01008188 &miss_next_index))
8189 ;
8190 else if (unformat (i, "current-data-flag %d", &current_data_flag))
8191 ;
8192 else if (unformat (i, "current-data-offset %d", &current_data_offset))
8193 ;
8194 else
8195 break;
8196 }
8197
8198 if (is_add && mask == 0)
8199 {
8200 errmsg ("Mask required");
8201 return -99;
8202 }
8203
8204 if (is_add && skip == ~0)
8205 {
8206 errmsg ("skip count required");
8207 return -99;
8208 }
8209
8210 if (is_add && match == ~0)
8211 {
8212 errmsg ("match count required");
8213 return -99;
8214 }
8215
8216 if (!is_add && table_index == ~0)
8217 {
8218 errmsg ("table index required for delete");
8219 return -99;
8220 }
8221
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008222 M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
Damjan Marion7cd468a2016-12-19 23:05:39 +01008223
8224 mp->is_add = is_add;
8225 mp->del_chain = del_chain;
8226 mp->table_index = ntohl (table_index);
8227 mp->nbuckets = ntohl (nbuckets);
8228 mp->memory_size = ntohl (memory_size);
8229 mp->skip_n_vectors = ntohl (skip);
8230 mp->match_n_vectors = ntohl (match);
8231 mp->next_table_index = ntohl (next_table_index);
8232 mp->miss_next_index = ntohl (miss_next_index);
8233 mp->current_data_flag = ntohl (current_data_flag);
8234 mp->current_data_offset = ntohl (current_data_offset);
Juraj Sloboda75282452018-06-12 14:20:49 +02008235 mp->mask_len = ntohl (vec_len (mask));
Damjan Marion7cd468a2016-12-19 23:05:39 +01008236 clib_memcpy (mp->mask, mask, vec_len (mask));
8237
8238 vec_free (mask);
8239
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008240 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008241 W (ret);
8242 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008243}
8244
Dave Barach4a3f69c2017-02-22 12:44:56 -05008245#if VPP_API_TEST_BUILTIN == 0
Damjan Marion7cd468a2016-12-19 23:05:39 +01008246uword
8247unformat_l4_match (unformat_input_t * input, va_list * args)
8248{
8249 u8 **matchp = va_arg (*args, u8 **);
8250
8251 u8 *proto_header = 0;
8252 int src_port = 0;
8253 int dst_port = 0;
8254
8255 tcpudp_header_t h;
8256
8257 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8258 {
8259 if (unformat (input, "src_port %d", &src_port))
8260 ;
8261 else if (unformat (input, "dst_port %d", &dst_port))
8262 ;
8263 else
8264 return 0;
8265 }
8266
8267 h.src_port = clib_host_to_net_u16 (src_port);
8268 h.dst_port = clib_host_to_net_u16 (dst_port);
8269 vec_validate (proto_header, sizeof (h) - 1);
8270 memcpy (proto_header, &h, sizeof (h));
8271
8272 *matchp = proto_header;
8273
8274 return 1;
8275}
8276
8277uword
8278unformat_ip4_match (unformat_input_t * input, va_list * args)
8279{
8280 u8 **matchp = va_arg (*args, u8 **);
8281 u8 *match = 0;
8282 ip4_header_t *ip;
8283 int version = 0;
8284 u32 version_val;
8285 int hdr_length = 0;
8286 u32 hdr_length_val;
8287 int src = 0, dst = 0;
8288 ip4_address_t src_val, dst_val;
8289 int proto = 0;
8290 u32 proto_val;
8291 int tos = 0;
8292 u32 tos_val;
8293 int length = 0;
8294 u32 length_val;
8295 int fragment_id = 0;
8296 u32 fragment_id_val;
8297 int ttl = 0;
8298 int ttl_val;
8299 int checksum = 0;
8300 u32 checksum_val;
8301
8302 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8303 {
8304 if (unformat (input, "version %d", &version_val))
8305 version = 1;
8306 else if (unformat (input, "hdr_length %d", &hdr_length_val))
8307 hdr_length = 1;
8308 else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
8309 src = 1;
8310 else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
8311 dst = 1;
8312 else if (unformat (input, "proto %d", &proto_val))
8313 proto = 1;
8314 else if (unformat (input, "tos %d", &tos_val))
8315 tos = 1;
8316 else if (unformat (input, "length %d", &length_val))
8317 length = 1;
8318 else if (unformat (input, "fragment_id %d", &fragment_id_val))
8319 fragment_id = 1;
8320 else if (unformat (input, "ttl %d", &ttl_val))
8321 ttl = 1;
8322 else if (unformat (input, "checksum %d", &checksum_val))
8323 checksum = 1;
8324 else
8325 break;
8326 }
8327
8328 if (version + hdr_length + src + dst + proto + tos + length + fragment_id
8329 + ttl + checksum == 0)
8330 return 0;
8331
8332 /*
8333 * Aligned because we use the real comparison functions
8334 */
8335 vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8336
8337 ip = (ip4_header_t *) match;
8338
8339 /* These are realistically matched in practice */
8340 if (src)
8341 ip->src_address.as_u32 = src_val.as_u32;
8342
8343 if (dst)
8344 ip->dst_address.as_u32 = dst_val.as_u32;
8345
8346 if (proto)
8347 ip->protocol = proto_val;
8348
8349
8350 /* These are not, but they're included for completeness */
8351 if (version)
8352 ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
8353
8354 if (hdr_length)
8355 ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
8356
8357 if (tos)
8358 ip->tos = tos_val;
8359
8360 if (length)
8361 ip->length = clib_host_to_net_u16 (length_val);
8362
8363 if (ttl)
8364 ip->ttl = ttl_val;
8365
8366 if (checksum)
8367 ip->checksum = clib_host_to_net_u16 (checksum_val);
8368
8369 *matchp = match;
8370 return 1;
8371}
8372
8373uword
8374unformat_ip6_match (unformat_input_t * input, va_list * args)
8375{
8376 u8 **matchp = va_arg (*args, u8 **);
8377 u8 *match = 0;
8378 ip6_header_t *ip;
8379 int version = 0;
8380 u32 version_val;
8381 u8 traffic_class = 0;
8382 u32 traffic_class_val = 0;
8383 u8 flow_label = 0;
8384 u8 flow_label_val;
8385 int src = 0, dst = 0;
8386 ip6_address_t src_val, dst_val;
8387 int proto = 0;
8388 u32 proto_val;
8389 int payload_length = 0;
8390 u32 payload_length_val;
8391 int hop_limit = 0;
8392 int hop_limit_val;
8393 u32 ip_version_traffic_class_and_flow_label;
8394
8395 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8396 {
8397 if (unformat (input, "version %d", &version_val))
8398 version = 1;
8399 else if (unformat (input, "traffic_class %d", &traffic_class_val))
8400 traffic_class = 1;
8401 else if (unformat (input, "flow_label %d", &flow_label_val))
8402 flow_label = 1;
8403 else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
8404 src = 1;
8405 else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
8406 dst = 1;
8407 else if (unformat (input, "proto %d", &proto_val))
8408 proto = 1;
8409 else if (unformat (input, "payload_length %d", &payload_length_val))
8410 payload_length = 1;
8411 else if (unformat (input, "hop_limit %d", &hop_limit_val))
8412 hop_limit = 1;
8413 else
8414 break;
8415 }
8416
8417 if (version + traffic_class + flow_label + src + dst + proto +
8418 payload_length + hop_limit == 0)
8419 return 0;
8420
8421 /*
8422 * Aligned because we use the real comparison functions
8423 */
8424 vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8425
8426 ip = (ip6_header_t *) match;
8427
8428 if (src)
8429 clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
8430
8431 if (dst)
8432 clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
8433
8434 if (proto)
8435 ip->protocol = proto_val;
8436
8437 ip_version_traffic_class_and_flow_label = 0;
8438
8439 if (version)
8440 ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
8441
8442 if (traffic_class)
8443 ip_version_traffic_class_and_flow_label |=
8444 (traffic_class_val & 0xFF) << 20;
8445
8446 if (flow_label)
8447 ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
8448
8449 ip->ip_version_traffic_class_and_flow_label =
8450 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8451
8452 if (payload_length)
8453 ip->payload_length = clib_host_to_net_u16 (payload_length_val);
8454
8455 if (hop_limit)
8456 ip->hop_limit = hop_limit_val;
8457
8458 *matchp = match;
8459 return 1;
8460}
8461
8462uword
8463unformat_l3_match (unformat_input_t * input, va_list * args)
8464{
8465 u8 **matchp = va_arg (*args, u8 **);
8466
8467 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8468 {
8469 if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
8470 return 1;
8471 else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
8472 return 1;
8473 else
8474 break;
8475 }
8476 return 0;
8477}
8478
8479uword
8480unformat_vlan_tag (unformat_input_t * input, va_list * args)
8481{
8482 u8 *tagp = va_arg (*args, u8 *);
8483 u32 tag;
8484
8485 if (unformat (input, "%d", &tag))
8486 {
8487 tagp[0] = (tag >> 8) & 0x0F;
8488 tagp[1] = tag & 0xFF;
8489 return 1;
8490 }
8491
8492 return 0;
8493}
8494
8495uword
8496unformat_l2_match (unformat_input_t * input, va_list * args)
8497{
8498 u8 **matchp = va_arg (*args, u8 **);
8499 u8 *match = 0;
8500 u8 src = 0;
8501 u8 src_val[6];
8502 u8 dst = 0;
8503 u8 dst_val[6];
8504 u8 proto = 0;
8505 u16 proto_val;
8506 u8 tag1 = 0;
8507 u8 tag1_val[2];
8508 u8 tag2 = 0;
8509 u8 tag2_val[2];
8510 int len = 14;
8511 u8 ignore_tag1 = 0;
8512 u8 ignore_tag2 = 0;
8513 u8 cos1 = 0;
8514 u8 cos2 = 0;
8515 u32 cos1_val = 0;
8516 u32 cos2_val = 0;
8517
8518 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8519 {
8520 if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
8521 src = 1;
8522 else
8523 if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
8524 dst = 1;
8525 else if (unformat (input, "proto %U",
8526 unformat_ethernet_type_host_byte_order, &proto_val))
8527 proto = 1;
8528 else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
8529 tag1 = 1;
8530 else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
8531 tag2 = 1;
8532 else if (unformat (input, "ignore-tag1"))
8533 ignore_tag1 = 1;
8534 else if (unformat (input, "ignore-tag2"))
8535 ignore_tag2 = 1;
8536 else if (unformat (input, "cos1 %d", &cos1_val))
8537 cos1 = 1;
8538 else if (unformat (input, "cos2 %d", &cos2_val))
8539 cos2 = 1;
8540 else
8541 break;
8542 }
8543 if ((src + dst + proto + tag1 + tag2 +
8544 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8545 return 0;
8546
8547 if (tag1 || ignore_tag1 || cos1)
8548 len = 18;
8549 if (tag2 || ignore_tag2 || cos2)
8550 len = 22;
8551
8552 vec_validate_aligned (match, len - 1, sizeof (u32x4));
8553
8554 if (dst)
8555 clib_memcpy (match, dst_val, 6);
8556
8557 if (src)
8558 clib_memcpy (match + 6, src_val, 6);
8559
8560 if (tag2)
8561 {
8562 /* inner vlan tag */
8563 match[19] = tag2_val[1];
8564 match[18] = tag2_val[0];
8565 if (cos2)
8566 match[18] |= (cos2_val & 0x7) << 5;
8567 if (proto)
8568 {
8569 match[21] = proto_val & 0xff;
8570 match[20] = proto_val >> 8;
8571 }
8572 if (tag1)
8573 {
8574 match[15] = tag1_val[1];
8575 match[14] = tag1_val[0];
8576 }
8577 if (cos1)
8578 match[14] |= (cos1_val & 0x7) << 5;
8579 *matchp = match;
8580 return 1;
8581 }
8582 if (tag1)
8583 {
8584 match[15] = tag1_val[1];
8585 match[14] = tag1_val[0];
8586 if (proto)
8587 {
8588 match[17] = proto_val & 0xff;
8589 match[16] = proto_val >> 8;
8590 }
8591 if (cos1)
8592 match[14] |= (cos1_val & 0x7) << 5;
8593
8594 *matchp = match;
8595 return 1;
8596 }
8597 if (cos2)
8598 match[18] |= (cos2_val & 0x7) << 5;
8599 if (cos1)
8600 match[14] |= (cos1_val & 0x7) << 5;
8601 if (proto)
8602 {
8603 match[13] = proto_val & 0xff;
8604 match[12] = proto_val >> 8;
8605 }
8606
8607 *matchp = match;
8608 return 1;
8609}
Igor Mikhailov (imichail)582caa32018-04-26 21:33:02 -07008610
8611uword
8612unformat_qos_source (unformat_input_t * input, va_list * args)
8613{
8614 int *qs = va_arg (*args, int *);
8615
8616 if (unformat (input, "ip"))
8617 *qs = QOS_SOURCE_IP;
8618 else if (unformat (input, "mpls"))
8619 *qs = QOS_SOURCE_MPLS;
8620 else if (unformat (input, "ext"))
8621 *qs = QOS_SOURCE_EXT;
8622 else if (unformat (input, "vlan"))
8623 *qs = QOS_SOURCE_VLAN;
8624 else
8625 return 0;
8626
8627 return 1;
8628}
Dave Barach4a3f69c2017-02-22 12:44:56 -05008629#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +01008630
8631uword
Dave Barach4a3f69c2017-02-22 12:44:56 -05008632api_unformat_classify_match (unformat_input_t * input, va_list * args)
Damjan Marion7cd468a2016-12-19 23:05:39 +01008633{
8634 u8 **matchp = va_arg (*args, u8 **);
8635 u32 skip_n_vectors = va_arg (*args, u32);
8636 u32 match_n_vectors = va_arg (*args, u32);
8637
8638 u8 *match = 0;
8639 u8 *l2 = 0;
8640 u8 *l3 = 0;
8641 u8 *l4 = 0;
8642
8643 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8644 {
8645 if (unformat (input, "hex %U", unformat_hex_string, &match))
8646 ;
8647 else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
8648 ;
8649 else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
8650 ;
8651 else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
8652 ;
8653 else
8654 break;
8655 }
8656
8657 if (l4 && !l3)
8658 {
8659 vec_free (match);
8660 vec_free (l2);
8661 vec_free (l4);
8662 return 0;
8663 }
8664
8665 if (match || l2 || l3 || l4)
8666 {
8667 if (l2 || l3 || l4)
8668 {
8669 /* "Win a free Ethernet header in every packet" */
8670 if (l2 == 0)
8671 vec_validate_aligned (l2, 13, sizeof (u32x4));
8672 match = l2;
8673 if (vec_len (l3))
8674 {
8675 vec_append_aligned (match, l3, sizeof (u32x4));
8676 vec_free (l3);
8677 }
8678 if (vec_len (l4))
8679 {
8680 vec_append_aligned (match, l4, sizeof (u32x4));
8681 vec_free (l4);
8682 }
8683 }
8684
8685 /* Make sure the vector is big enough even if key is all 0's */
8686 vec_validate_aligned
8687 (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
8688 sizeof (u32x4));
8689
8690 /* Set size, include skipped vectors */
8691 _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
8692
8693 *matchp = match;
8694
8695 return 1;
8696 }
8697
8698 return 0;
8699}
8700
8701static int
8702api_classify_add_del_session (vat_main_t * vam)
8703{
8704 unformat_input_t *i = vam->input;
8705 vl_api_classify_add_del_session_t *mp;
8706 int is_add = 1;
8707 u32 table_index = ~0;
8708 u32 hit_next_index = ~0;
8709 u32 opaque_index = ~0;
8710 u8 *match = 0;
8711 i32 advance = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008712 u32 skip_n_vectors = 0;
8713 u32 match_n_vectors = 0;
8714 u32 action = 0;
8715 u32 metadata = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008716 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008717
8718 /*
8719 * Warning: you have to supply skip_n and match_n
8720 * because the API client cant simply look at the classify
8721 * table object.
8722 */
8723
8724 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8725 {
8726 if (unformat (i, "del"))
8727 is_add = 0;
Dave Barach4a3f69c2017-02-22 12:44:56 -05008728 else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
Damjan Marion7cd468a2016-12-19 23:05:39 +01008729 &hit_next_index))
8730 ;
8731 else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
8732 &hit_next_index))
8733 ;
Dave Barach4a3f69c2017-02-22 12:44:56 -05008734 else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
Damjan Marion7cd468a2016-12-19 23:05:39 +01008735 &hit_next_index))
8736 ;
8737 else if (unformat (i, "policer-hit-next %d", &hit_next_index))
8738 ;
8739 else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
8740 ;
8741 else if (unformat (i, "opaque-index %d", &opaque_index))
8742 ;
8743 else if (unformat (i, "skip_n %d", &skip_n_vectors))
8744 ;
8745 else if (unformat (i, "match_n %d", &match_n_vectors))
8746 ;
Dave Barach4a3f69c2017-02-22 12:44:56 -05008747 else if (unformat (i, "match %U", api_unformat_classify_match,
Damjan Marion7cd468a2016-12-19 23:05:39 +01008748 &match, skip_n_vectors, match_n_vectors))
8749 ;
8750 else if (unformat (i, "advance %d", &advance))
8751 ;
8752 else if (unformat (i, "table-index %d", &table_index))
8753 ;
8754 else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
8755 action = 1;
8756 else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
8757 action = 2;
8758 else if (unformat (i, "action %d", &action))
8759 ;
8760 else if (unformat (i, "metadata %d", &metadata))
8761 ;
8762 else
8763 break;
8764 }
8765
8766 if (table_index == ~0)
8767 {
8768 errmsg ("Table index required");
8769 return -99;
8770 }
8771
8772 if (is_add && match == 0)
8773 {
8774 errmsg ("Match value required");
8775 return -99;
8776 }
8777
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008778 M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
Damjan Marion7cd468a2016-12-19 23:05:39 +01008779
8780 mp->is_add = is_add;
8781 mp->table_index = ntohl (table_index);
8782 mp->hit_next_index = ntohl (hit_next_index);
8783 mp->opaque_index = ntohl (opaque_index);
8784 mp->advance = ntohl (advance);
8785 mp->action = action;
8786 mp->metadata = ntohl (metadata);
Juraj Sloboda75282452018-06-12 14:20:49 +02008787 mp->match_len = ntohl (vec_len (match));
Damjan Marion7cd468a2016-12-19 23:05:39 +01008788 clib_memcpy (mp->match, match, vec_len (match));
8789 vec_free (match);
8790
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008791 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008792 W (ret);
8793 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008794}
8795
8796static int
8797api_classify_set_interface_ip_table (vat_main_t * vam)
8798{
8799 unformat_input_t *i = vam->input;
8800 vl_api_classify_set_interface_ip_table_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008801 u32 sw_if_index;
8802 int sw_if_index_set;
8803 u32 table_index = ~0;
8804 u8 is_ipv6 = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008805 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008806
8807 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8808 {
8809 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8810 sw_if_index_set = 1;
8811 else if (unformat (i, "sw_if_index %d", &sw_if_index))
8812 sw_if_index_set = 1;
8813 else if (unformat (i, "table %d", &table_index))
8814 ;
8815 else
8816 {
8817 clib_warning ("parse error '%U'", format_unformat_error, i);
8818 return -99;
8819 }
8820 }
8821
8822 if (sw_if_index_set == 0)
8823 {
8824 errmsg ("missing interface name or sw_if_index");
8825 return -99;
8826 }
8827
8828
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008829 M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008830
8831 mp->sw_if_index = ntohl (sw_if_index);
8832 mp->table_index = ntohl (table_index);
8833 mp->is_ipv6 = is_ipv6;
8834
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008835 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008836 W (ret);
8837 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008838}
8839
8840static int
8841api_classify_set_interface_l2_tables (vat_main_t * vam)
8842{
8843 unformat_input_t *i = vam->input;
8844 vl_api_classify_set_interface_l2_tables_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008845 u32 sw_if_index;
8846 int sw_if_index_set;
8847 u32 ip4_table_index = ~0;
8848 u32 ip6_table_index = ~0;
8849 u32 other_table_index = ~0;
8850 u32 is_input = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008851 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008852
8853 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8854 {
8855 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8856 sw_if_index_set = 1;
8857 else if (unformat (i, "sw_if_index %d", &sw_if_index))
8858 sw_if_index_set = 1;
8859 else if (unformat (i, "ip4-table %d", &ip4_table_index))
8860 ;
8861 else if (unformat (i, "ip6-table %d", &ip6_table_index))
8862 ;
8863 else if (unformat (i, "other-table %d", &other_table_index))
8864 ;
8865 else if (unformat (i, "is-input %d", &is_input))
8866 ;
8867 else
8868 {
8869 clib_warning ("parse error '%U'", format_unformat_error, i);
8870 return -99;
8871 }
8872 }
8873
8874 if (sw_if_index_set == 0)
8875 {
8876 errmsg ("missing interface name or sw_if_index");
8877 return -99;
8878 }
8879
8880
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008881 M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008882
8883 mp->sw_if_index = ntohl (sw_if_index);
8884 mp->ip4_table_index = ntohl (ip4_table_index);
8885 mp->ip6_table_index = ntohl (ip6_table_index);
8886 mp->other_table_index = ntohl (other_table_index);
8887 mp->is_input = (u8) is_input;
8888
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008889 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008890 W (ret);
8891 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008892}
8893
8894static int
8895api_set_ipfix_exporter (vat_main_t * vam)
8896{
8897 unformat_input_t *i = vam->input;
8898 vl_api_set_ipfix_exporter_t *mp;
8899 ip4_address_t collector_address;
8900 u8 collector_address_set = 0;
8901 u32 collector_port = ~0;
8902 ip4_address_t src_address;
8903 u8 src_address_set = 0;
8904 u32 vrf_id = ~0;
8905 u32 path_mtu = ~0;
8906 u32 template_interval = ~0;
8907 u8 udp_checksum = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008908 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008909
8910 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8911 {
8912 if (unformat (i, "collector_address %U", unformat_ip4_address,
8913 &collector_address))
8914 collector_address_set = 1;
8915 else if (unformat (i, "collector_port %d", &collector_port))
8916 ;
8917 else if (unformat (i, "src_address %U", unformat_ip4_address,
8918 &src_address))
8919 src_address_set = 1;
8920 else if (unformat (i, "vrf_id %d", &vrf_id))
8921 ;
8922 else if (unformat (i, "path_mtu %d", &path_mtu))
8923 ;
8924 else if (unformat (i, "template_interval %d", &template_interval))
8925 ;
8926 else if (unformat (i, "udp_checksum"))
8927 udp_checksum = 1;
8928 else
8929 break;
8930 }
8931
8932 if (collector_address_set == 0)
8933 {
8934 errmsg ("collector_address required");
8935 return -99;
8936 }
8937
8938 if (src_address_set == 0)
8939 {
8940 errmsg ("src_address required");
8941 return -99;
8942 }
8943
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008944 M (SET_IPFIX_EXPORTER, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008945
Jakub Grajciar2f71a882019-10-10 14:21:22 +02008946 memcpy (mp->collector_address.un.ip4, collector_address.data,
Damjan Marion7cd468a2016-12-19 23:05:39 +01008947 sizeof (collector_address.data));
8948 mp->collector_port = htons ((u16) collector_port);
Jakub Grajciar2f71a882019-10-10 14:21:22 +02008949 memcpy (mp->src_address.un.ip4, src_address.data,
8950 sizeof (src_address.data));
Damjan Marion7cd468a2016-12-19 23:05:39 +01008951 mp->vrf_id = htonl (vrf_id);
8952 mp->path_mtu = htonl (path_mtu);
8953 mp->template_interval = htonl (template_interval);
8954 mp->udp_checksum = udp_checksum;
8955
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008956 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008957 W (ret);
8958 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008959}
8960
8961static int
8962api_set_ipfix_classify_stream (vat_main_t * vam)
8963{
8964 unformat_input_t *i = vam->input;
8965 vl_api_set_ipfix_classify_stream_t *mp;
8966 u32 domain_id = 0;
8967 u32 src_port = UDP_DST_PORT_ipfix;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008968 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008969
8970 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8971 {
8972 if (unformat (i, "domain %d", &domain_id))
8973 ;
8974 else if (unformat (i, "src_port %d", &src_port))
8975 ;
8976 else
8977 {
8978 errmsg ("unknown input `%U'", format_unformat_error, i);
8979 return -99;
8980 }
8981 }
8982
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008983 M (SET_IPFIX_CLASSIFY_STREAM, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008984
8985 mp->domain_id = htonl (domain_id);
8986 mp->src_port = htons ((u16) src_port);
8987
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008988 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008989 W (ret);
8990 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008991}
8992
8993static int
8994api_ipfix_classify_table_add_del (vat_main_t * vam)
8995{
8996 unformat_input_t *i = vam->input;
8997 vl_api_ipfix_classify_table_add_del_t *mp;
8998 int is_add = -1;
8999 u32 classify_table_index = ~0;
9000 u8 ip_version = 0;
9001 u8 transport_protocol = 255;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009002 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009003
9004 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9005 {
9006 if (unformat (i, "add"))
9007 is_add = 1;
9008 else if (unformat (i, "del"))
9009 is_add = 0;
9010 else if (unformat (i, "table %d", &classify_table_index))
9011 ;
9012 else if (unformat (i, "ip4"))
9013 ip_version = 4;
9014 else if (unformat (i, "ip6"))
9015 ip_version = 6;
9016 else if (unformat (i, "tcp"))
9017 transport_protocol = 6;
9018 else if (unformat (i, "udp"))
9019 transport_protocol = 17;
9020 else
9021 {
9022 errmsg ("unknown input `%U'", format_unformat_error, i);
9023 return -99;
9024 }
9025 }
9026
9027 if (is_add == -1)
9028 {
9029 errmsg ("expecting: add|del");
9030 return -99;
9031 }
9032 if (classify_table_index == ~0)
9033 {
9034 errmsg ("classifier table not specified");
9035 return -99;
9036 }
9037 if (ip_version == 0)
9038 {
9039 errmsg ("IP version not specified");
9040 return -99;
9041 }
9042
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009043 M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009044
9045 mp->is_add = is_add;
9046 mp->table_id = htonl (classify_table_index);
9047 mp->ip_version = ip_version;
9048 mp->transport_protocol = transport_protocol;
9049
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009050 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06009051 W (ret);
9052 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009053}
9054
9055static int
9056api_get_node_index (vat_main_t * vam)
9057{
9058 unformat_input_t *i = vam->input;
9059 vl_api_get_node_index_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009060 u8 *name = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009061 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009062
9063 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9064 {
9065 if (unformat (i, "node %s", &name))
9066 ;
9067 else
9068 break;
9069 }
9070 if (name == 0)
9071 {
9072 errmsg ("node name required");
9073 return -99;
9074 }
9075 if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9076 {
9077 errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9078 return -99;
9079 }
9080
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009081 M (GET_NODE_INDEX, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009082 clib_memcpy (mp->node_name, name, vec_len (name));
9083 vec_free (name);
9084
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009085 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06009086 W (ret);
9087 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009088}
9089
9090static int
9091api_get_next_index (vat_main_t * vam)
9092{
9093 unformat_input_t *i = vam->input;
9094 vl_api_get_next_index_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009095 u8 *node_name = 0, *next_node_name = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009096 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009097
9098 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9099 {
9100 if (unformat (i, "node-name %s", &node_name))
9101 ;
9102 else if (unformat (i, "next-node-name %s", &next_node_name))
9103 break;
9104 }
9105
9106 if (node_name == 0)
9107 {
9108 errmsg ("node name required");
9109 return -99;
9110 }
9111 if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
9112 {
9113 errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9114 return -99;
9115 }
9116
9117 if (next_node_name == 0)
9118 {
9119 errmsg ("next node name required");
9120 return -99;
9121 }
9122 if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
9123 {
9124 errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
9125 return -99;
9126 }
9127
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009128 M (GET_NEXT_INDEX, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009129 clib_memcpy (mp->node_name, node_name, vec_len (node_name));
9130 clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
9131 vec_free (node_name);
9132 vec_free (next_node_name);
9133
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009134 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06009135 W (ret);
9136 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009137}
9138
9139static int
9140api_add_node_next (vat_main_t * vam)
9141{
9142 unformat_input_t *i = vam->input;
9143 vl_api_add_node_next_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009144 u8 *name = 0;
9145 u8 *next = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009146 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009147
9148 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9149 {
9150 if (unformat (i, "node %s", &name))
9151 ;
9152 else if (unformat (i, "next %s", &next))
9153 ;
9154 else
9155 break;
9156 }
9157 if (name == 0)
9158 {
9159 errmsg ("node name required");
9160 return -99;
9161 }
9162 if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9163 {
9164 errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9165 return -99;
9166 }
9167 if (next == 0)
9168 {
9169 errmsg ("next node required");
9170 return -99;
9171 }
9172 if (vec_len (next) >= ARRAY_LEN (mp->next_name))
9173 {
9174 errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
9175 return -99;
9176 }
9177
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009178 M (ADD_NODE_NEXT, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009179 clib_memcpy (mp->node_name, name, vec_len (name));
9180 clib_memcpy (mp->next_name, next, vec_len (next));
9181 vec_free (name);
9182 vec_free (next);
9183
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009184 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06009185 W (ret);
9186 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009187}
9188
Damjan Marion8389fb92017-10-13 18:29:53 +02009189static void vl_api_sw_interface_tap_v2_details_t_handler
9190 (vl_api_sw_interface_tap_v2_details_t * mp)
9191{
9192 vat_main_t *vam = &vat_main;
9193
Jakub Grajciar5de4fb72019-09-03 10:40:01 +02009194 u8 *ip4 =
9195 format (0, "%U/%d", format_ip4_address, mp->host_ip4_prefix.address,
9196 mp->host_ip4_prefix.len);
9197 u8 *ip6 =
9198 format (0, "%U/%d", format_ip6_address, mp->host_ip6_prefix.address,
9199 mp->host_ip6_prefix.len);
Milan Lenco73e7f422017-12-14 10:04:25 +01009200
9201 print (vam->ofp,
Andrew Yourtchenko754f24b2019-01-07 20:56:46 +01009202 "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
Milan Lenco73e7f422017-12-14 10:04:25 +01009203 mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
9204 ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
9205 format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
Andrew Yourtchenko754f24b2019-01-07 20:56:46 +01009206 mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
Milan Lenco73e7f422017-12-14 10:04:25 +01009207
9208 vec_free (ip4);
9209 vec_free (ip6);
Damjan Marion8389fb92017-10-13 18:29:53 +02009210}
9211
9212static void vl_api_sw_interface_tap_v2_details_t_handler_json
9213 (vl_api_sw_interface_tap_v2_details_t * mp)
9214{
9215 vat_main_t *vam = &vat_main;
9216 vat_json_node_t *node = NULL;
9217
9218 if (VAT_JSON_ARRAY != vam->json_tree.type)
9219 {
9220 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9221 vat_json_init_array (&vam->json_tree);
9222 }
9223 node = vat_json_array_add (&vam->json_tree);
9224
9225 vat_json_init_object (node);
Milan Lenco73e7f422017-12-14 10:04:25 +01009226 vat_json_object_add_uint (node, "id", ntohl (mp->id));
Damjan Marion8389fb92017-10-13 18:29:53 +02009227 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
Andrew Yourtchenko754f24b2019-01-07 20:56:46 +01009228 vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
Damjan Marion8389fb92017-10-13 18:29:53 +02009229 vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
Milan Lenco73e7f422017-12-14 10:04:25 +01009230 vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
9231 vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
9232 vat_json_object_add_string_copy (node, "host_mac_addr",
9233 format (0, "%U", format_ethernet_address,
9234 &mp->host_mac_addr));
9235 vat_json_object_add_string_copy (node, "host_namespace",
9236 mp->host_namespace);
9237 vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
9238 vat_json_object_add_string_copy (node, "host_ip4_addr",
9239 format (0, "%U/%d", format_ip4_address,
Jakub Grajciar5de4fb72019-09-03 10:40:01 +02009240 mp->host_ip4_prefix.address,
9241 mp->host_ip4_prefix.len));
9242 vat_json_object_add_string_copy (node, "host_ip6_prefix",
Milan Lenco73e7f422017-12-14 10:04:25 +01009243 format (0, "%U/%d", format_ip6_address,
Jakub Grajciar5de4fb72019-09-03 10:40:01 +02009244 mp->host_ip6_prefix.address,
9245 mp->host_ip6_prefix.len));
Milan Lenco73e7f422017-12-14 10:04:25 +01009246
Damjan Marion8389fb92017-10-13 18:29:53 +02009247}
9248
9249static int
9250api_sw_interface_tap_v2_dump (vat_main_t * vam)
9251{
9252 vl_api_sw_interface_tap_v2_dump_t *mp;
9253 vl_api_control_ping_t *mp_ping;
9254 int ret;
9255
Milan Lenco73e7f422017-12-14 10:04:25 +01009256 print (vam->ofp,
9257 "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
9258 "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
9259 "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
9260 "host_ip6_addr");
9261
Damjan Marion8389fb92017-10-13 18:29:53 +02009262 /* Get list of tap interfaces */
9263 M (SW_INTERFACE_TAP_V2_DUMP, mp);
9264 S (mp);
9265
9266 /* Use a control ping for synchronization */
9267 MPING (CONTROL_PING, mp_ping);
9268 S (mp_ping);
9269
9270 W (ret);
9271 return ret;
9272}
9273
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01009274static void vl_api_sw_interface_virtio_pci_details_t_handler
9275 (vl_api_sw_interface_virtio_pci_details_t * mp)
9276{
9277 vat_main_t *vam = &vat_main;
9278
9279 typedef union
9280 {
9281 struct
9282 {
9283 u16 domain;
9284 u8 bus;
9285 u8 slot:5;
9286 u8 function:3;
9287 };
9288 u32 as_u32;
9289 } pci_addr_t;
9290 pci_addr_t addr;
Jakub Grajciar2c504f82019-09-26 10:34:41 +02009291
9292 addr.domain = ntohs (mp->pci_addr.domain);
9293 addr.bus = mp->pci_addr.bus;
9294 addr.slot = mp->pci_addr.slot;
9295 addr.function = mp->pci_addr.function;
9296
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01009297 u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
9298 addr.slot, addr.function);
9299
9300 print (vam->ofp,
9301 "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
9302 pci_addr, ntohl (mp->sw_if_index),
9303 ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
9304 format_ethernet_address, mp->mac_addr,
9305 clib_net_to_host_u64 (mp->features));
9306 vec_free (pci_addr);
9307}
9308
9309static void vl_api_sw_interface_virtio_pci_details_t_handler_json
9310 (vl_api_sw_interface_virtio_pci_details_t * mp)
9311{
9312 vat_main_t *vam = &vat_main;
9313 vat_json_node_t *node = NULL;
Jakub Grajciar2c504f82019-09-26 10:34:41 +02009314 vlib_pci_addr_t pci_addr;
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01009315
9316 if (VAT_JSON_ARRAY != vam->json_tree.type)
9317 {
9318 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9319 vat_json_init_array (&vam->json_tree);
9320 }
9321 node = vat_json_array_add (&vam->json_tree);
9322
Jakub Grajciar2c504f82019-09-26 10:34:41 +02009323 pci_addr.domain = ntohs (mp->pci_addr.domain);
9324 pci_addr.bus = mp->pci_addr.bus;
9325 pci_addr.slot = mp->pci_addr.slot;
9326 pci_addr.function = mp->pci_addr.function;
9327
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01009328 vat_json_init_object (node);
Jakub Grajciar2c504f82019-09-26 10:34:41 +02009329 vat_json_object_add_uint (node, "pci-addr", pci_addr.as_u32);
Mohsin Kazmi03ae24b2019-01-18 11:50:00 +01009330 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9331 vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
9332 vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
9333 vat_json_object_add_uint (node, "features",
9334 clib_net_to_host_u64 (mp->features));
9335 vat_json_object_add_string_copy (node, "mac_addr",
9336 format (0, "%U", format_ethernet_address,
9337 &mp->mac_addr));
9338}
9339
9340static int
9341api_sw_interface_virtio_pci_dump (vat_main_t * vam)
9342{
9343 vl_api_sw_interface_virtio_pci_dump_t *mp;
9344 vl_api_control_ping_t *mp_ping;
9345 int ret;
9346
9347 print (vam->ofp,
9348 "\n%-12s %-12s %-12s %-12s %-17s %-08s",
9349 "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
9350 "mac_addr", "features");
9351
9352 /* Get list of tap interfaces */
9353 M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
9354 S (mp);
9355
9356 /* Use a control ping for synchronization */
9357 MPING (CONTROL_PING, mp_ping);
9358 S (mp_ping);
9359
9360 W (ret);
9361 return ret;
9362}
9363
eyal bariaf86a482018-04-17 11:20:27 +03009364static int
9365api_vxlan_offload_rx (vat_main_t * vam)
9366{
9367 unformat_input_t *line_input = vam->input;
9368 vl_api_vxlan_offload_rx_t *mp;
9369 u32 hw_if_index = ~0, rx_if_index = ~0;
9370 u8 is_add = 1;
9371 int ret;
9372
9373 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9374 {
9375 if (unformat (line_input, "del"))
9376 is_add = 0;
9377 else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
9378 &hw_if_index))
9379 ;
9380 else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
9381 ;
9382 else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
9383 &rx_if_index))
9384 ;
9385 else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
9386 ;
9387 else
9388 {
9389 errmsg ("parse error '%U'", format_unformat_error, line_input);
9390 return -99;
9391 }
9392 }
9393
9394 if (hw_if_index == ~0)
9395 {
9396 errmsg ("no hw interface");
9397 return -99;
9398 }
9399
9400 if (rx_if_index == ~0)
9401 {
9402 errmsg ("no rx tunnel");
9403 return -99;
9404 }
9405
9406 M (VXLAN_OFFLOAD_RX, mp);
9407
9408 mp->hw_if_index = ntohl (hw_if_index);
9409 mp->sw_if_index = ntohl (rx_if_index);
9410 mp->enable = is_add;
9411
9412 S (mp);
9413 W (ret);
9414 return ret;
9415}
9416
Damjan Marion7cd468a2016-12-19 23:05:39 +01009417static uword unformat_vxlan_decap_next
9418 (unformat_input_t * input, va_list * args)
9419{
9420 u32 *result = va_arg (*args, u32 *);
9421 u32 tmp;
9422
9423 if (unformat (input, "l2"))
9424 *result = VXLAN_INPUT_NEXT_L2_INPUT;
9425 else if (unformat (input, "%d", &tmp))
9426 *result = tmp;
9427 else
9428 return 0;
9429 return 1;
9430}
9431
9432static int
9433api_vxlan_add_del_tunnel (vat_main_t * vam)
9434{
9435 unformat_input_t *line_input = vam->input;
9436 vl_api_vxlan_add_del_tunnel_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009437 ip46_address_t src, dst;
9438 u8 is_add = 1;
9439 u8 ipv4_set = 0, ipv6_set = 0;
9440 u8 src_set = 0;
9441 u8 dst_set = 0;
9442 u8 grp_set = 0;
Jon Loeliger3d460bd2018-02-01 16:36:12 -06009443 u32 instance = ~0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009444 u32 mcast_sw_if_index = ~0;
9445 u32 encap_vrf_id = 0;
9446 u32 decap_next_index = ~0;
9447 u32 vni = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009448 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009449
9450 /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
Dave Barachb7b92992018-10-17 10:38:51 -04009451 clib_memset (&src, 0, sizeof src);
9452 clib_memset (&dst, 0, sizeof dst);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009453
9454 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9455 {
9456 if (unformat (line_input, "del"))
9457 is_add = 0;
Jon Loeliger3d460bd2018-02-01 16:36:12 -06009458 else if (unformat (line_input, "instance %d", &instance))
9459 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009460 else
9461 if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
9462 {
9463 ipv4_set = 1;
9464 src_set = 1;
9465 }
9466 else
9467 if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
9468 {
9469 ipv4_set = 1;
9470 dst_set = 1;
9471 }
9472 else
9473 if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
9474 {
9475 ipv6_set = 1;
9476 src_set = 1;
9477 }
9478 else
9479 if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
9480 {
9481 ipv6_set = 1;
9482 dst_set = 1;
9483 }
9484 else if (unformat (line_input, "group %U %U",
9485 unformat_ip4_address, &dst.ip4,
9486 api_unformat_sw_if_index, vam, &mcast_sw_if_index))
9487 {
9488 grp_set = dst_set = 1;
9489 ipv4_set = 1;
9490 }
9491 else if (unformat (line_input, "group %U",
9492 unformat_ip4_address, &dst.ip4))
9493 {
9494 grp_set = dst_set = 1;
9495 ipv4_set = 1;
9496 }
9497 else if (unformat (line_input, "group %U %U",
9498 unformat_ip6_address, &dst.ip6,
9499 api_unformat_sw_if_index, vam, &mcast_sw_if_index))
9500 {
9501 grp_set = dst_set = 1;
9502 ipv6_set = 1;
9503 }
9504 else if (unformat (line_input, "group %U",
9505 unformat_ip6_address, &dst.ip6))
9506 {
9507 grp_set = dst_set = 1;
9508 ipv6_set = 1;
9509 }
9510 else
9511 if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
9512 ;
9513 else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
9514 ;
9515 else if (unformat (line_input, "decap-next %U",
9516 unformat_vxlan_decap_next, &decap_next_index))
9517 ;
9518 else if (unformat (line_input, "vni %d", &vni))
9519 ;
9520 else
9521 {
9522 errmsg ("parse error '%U'", format_unformat_error, line_input);
9523 return -99;
9524 }
9525 }
9526
9527 if (src_set == 0)
9528 {
9529 errmsg ("tunnel src address not specified");
9530 return -99;
9531 }
9532 if (dst_set == 0)
9533 {
9534 errmsg ("tunnel dst address not specified");
9535 return -99;
9536 }
9537
9538 if (grp_set && !ip46_address_is_multicast (&dst))
9539 {
9540 errmsg ("tunnel group address not multicast");
9541 return -99;
9542 }
9543 if (grp_set && mcast_sw_if_index == ~0)
9544 {
9545 errmsg ("tunnel nonexistent multicast device");
9546 return -99;
9547 }
9548 if (grp_set == 0 && ip46_address_is_multicast (&dst))
9549 {
9550 errmsg ("tunnel dst address must be unicast");
9551 return -99;
9552 }
9553
9554
9555 if (ipv4_set && ipv6_set)
9556 {
9557 errmsg ("both IPv4 and IPv6 addresses specified");
9558 return -99;
9559 }
9560
9561 if ((vni == 0) || (vni >> 24))
9562 {
9563 errmsg ("vni not specified or out of range");
9564 return -99;
9565 }
9566
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009567 M (VXLAN_ADD_DEL_TUNNEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009568
9569 if (ipv6_set)
9570 {
Jakub Grajciar7c0eb562020-03-02 13:55:31 +01009571 clib_memcpy (mp->src_address.un.ip6, &src.ip6, sizeof (src.ip6));
9572 clib_memcpy (mp->dst_address.un.ip6, &dst.ip6, sizeof (dst.ip6));
Damjan Marion7cd468a2016-12-19 23:05:39 +01009573 }
9574 else
9575 {
Jakub Grajciar7c0eb562020-03-02 13:55:31 +01009576 clib_memcpy (mp->src_address.un.ip4, &src.ip4, sizeof (src.ip4));
9577 clib_memcpy (mp->dst_address.un.ip4, &dst.ip4, sizeof (dst.ip4));
Damjan Marion7cd468a2016-12-19 23:05:39 +01009578 }
Jakub Grajciar7c0eb562020-03-02 13:55:31 +01009579 mp->src_address.af = ipv6_set;
9580 mp->dst_address.af = ipv6_set;
Jon Loeliger3d460bd2018-02-01 16:36:12 -06009581
9582 mp->instance = htonl (instance);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009583 mp->encap_vrf_id = ntohl (encap_vrf_id);
9584 mp->decap_next_index = ntohl (decap_next_index);
9585 mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
9586 mp->vni = ntohl (vni);
9587 mp->is_add = is_add;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009588
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009589 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06009590 W (ret);
9591 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009592}
9593
9594static void vl_api_vxlan_tunnel_details_t_handler
9595 (vl_api_vxlan_tunnel_details_t * mp)
9596{
9597 vat_main_t *vam = &vat_main;
Jakub Grajciar7c0eb562020-03-02 13:55:31 +01009598 ip46_address_t src =
9599 to_ip46 (mp->dst_address.af, (u8 *) & mp->dst_address.un);
9600 ip46_address_t dst =
9601 to_ip46 (mp->dst_address.af, (u8 *) & mp->src_address.un);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009602
Jon Loeliger3d460bd2018-02-01 16:36:12 -06009603 print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
Damjan Marion7cd468a2016-12-19 23:05:39 +01009604 ntohl (mp->sw_if_index),
Jon Loeliger3d460bd2018-02-01 16:36:12 -06009605 ntohl (mp->instance),
Damjan Marion7cd468a2016-12-19 23:05:39 +01009606 format_ip46_address, &src, IP46_TYPE_ANY,
9607 format_ip46_address, &dst, IP46_TYPE_ANY,
9608 ntohl (mp->encap_vrf_id),
9609 ntohl (mp->decap_next_index), ntohl (mp->vni),
9610 ntohl (mp->mcast_sw_if_index));
9611}
9612
9613static void vl_api_vxlan_tunnel_details_t_handler_json
9614 (vl_api_vxlan_tunnel_details_t * mp)
9615{
9616 vat_main_t *vam = &vat_main;
9617 vat_json_node_t *node = NULL;
9618
9619 if (VAT_JSON_ARRAY != vam->json_tree.type)
9620 {
9621 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9622 vat_json_init_array (&vam->json_tree);
9623 }
9624 node = vat_json_array_add (&vam->json_tree);
9625
9626 vat_json_init_object (node);
9627 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
Jon Loeliger3d460bd2018-02-01 16:36:12 -06009628
9629 vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
9630
Jakub Grajciar7c0eb562020-03-02 13:55:31 +01009631 if (mp->src_address.af)
Damjan Marion7cd468a2016-12-19 23:05:39 +01009632 {
9633 struct in6_addr ip6;
9634
Jakub Grajciar7c0eb562020-03-02 13:55:31 +01009635 clib_memcpy (&ip6, mp->src_address.un.ip6, sizeof (ip6));
Damjan Marion7cd468a2016-12-19 23:05:39 +01009636 vat_json_object_add_ip6 (node, "src_address", ip6);
Jakub Grajciar7c0eb562020-03-02 13:55:31 +01009637 clib_memcpy (&ip6, mp->dst_address.un.ip6, sizeof (ip6));
Damjan Marion7cd468a2016-12-19 23:05:39 +01009638 vat_json_object_add_ip6 (node, "dst_address", ip6);
9639 }
9640 else
9641 {
9642 struct in_addr ip4;
9643
Jakub Grajciar7c0eb562020-03-02 13:55:31 +01009644 clib_memcpy (&ip4, mp->src_address.un.ip4, sizeof (ip4));
Damjan Marion7cd468a2016-12-19 23:05:39 +01009645 vat_json_object_add_ip4 (node, "src_address", ip4);
Jakub Grajciar7c0eb562020-03-02 13:55:31 +01009646 clib_memcpy (&ip4, mp->dst_address.un.ip4, sizeof (ip4));
Damjan Marion7cd468a2016-12-19 23:05:39 +01009647 vat_json_object_add_ip4 (node, "dst_address", ip4);
9648 }
9649 vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
9650 vat_json_object_add_uint (node, "decap_next_index",
9651 ntohl (mp->decap_next_index));
9652 vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
Damjan Marion7cd468a2016-12-19 23:05:39 +01009653 vat_json_object_add_uint (node, "mcast_sw_if_index",
9654 ntohl (mp->mcast_sw_if_index));
9655}
9656
9657static int
9658api_vxlan_tunnel_dump (vat_main_t * vam)
9659{
9660 unformat_input_t *i = vam->input;
9661 vl_api_vxlan_tunnel_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -06009662 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009663 u32 sw_if_index;
9664 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009665 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009666
9667 /* Parse args required to build the message */
9668 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9669 {
9670 if (unformat (i, "sw_if_index %d", &sw_if_index))
9671 sw_if_index_set = 1;
9672 else
9673 break;
9674 }
9675
9676 if (sw_if_index_set == 0)
9677 {
9678 sw_if_index = ~0;
9679 }
9680
9681 if (!vam->json_output)
9682 {
Jon Loeliger3d460bd2018-02-01 16:36:12 -06009683 print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
9684 "sw_if_index", "instance", "src_address", "dst_address",
Damjan Marion7cd468a2016-12-19 23:05:39 +01009685 "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
9686 }
9687
9688 /* Get list of vxlan-tunnel interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009689 M (VXLAN_TUNNEL_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009690
9691 mp->sw_if_index = htonl (sw_if_index);
9692
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009693 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009694
9695 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -04009696 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -06009697 S (mp_ping);
9698
Jon Loeliger56c7b012017-02-01 12:31:41 -06009699 W (ret);
9700 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009701}
9702
9703static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01009704api_l2_fib_clear_table (vat_main_t * vam)
9705{
9706// unformat_input_t * i = vam->input;
9707 vl_api_l2_fib_clear_table_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009708 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009709
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009710 M (L2_FIB_CLEAR_TABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009711
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009712 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06009713 W (ret);
9714 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009715}
9716
9717static int
9718api_l2_interface_efp_filter (vat_main_t * vam)
9719{
9720 unformat_input_t *i = vam->input;
9721 vl_api_l2_interface_efp_filter_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009722 u32 sw_if_index;
9723 u8 enable = 1;
9724 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009725 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009726
9727 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9728 {
9729 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9730 sw_if_index_set = 1;
9731 else if (unformat (i, "sw_if_index %d", &sw_if_index))
9732 sw_if_index_set = 1;
9733 else if (unformat (i, "enable"))
9734 enable = 1;
9735 else if (unformat (i, "disable"))
9736 enable = 0;
9737 else
9738 {
9739 clib_warning ("parse error '%U'", format_unformat_error, i);
9740 return -99;
9741 }
9742 }
9743
9744 if (sw_if_index_set == 0)
9745 {
9746 errmsg ("missing sw_if_index");
9747 return -99;
9748 }
9749
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009750 M (L2_INTERFACE_EFP_FILTER, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009751
9752 mp->sw_if_index = ntohl (sw_if_index);
9753 mp->enable_disable = enable;
9754
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009755 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06009756 W (ret);
9757 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009758}
9759
9760#define foreach_vtr_op \
9761_("disable", L2_VTR_DISABLED) \
9762_("push-1", L2_VTR_PUSH_1) \
9763_("push-2", L2_VTR_PUSH_2) \
9764_("pop-1", L2_VTR_POP_1) \
9765_("pop-2", L2_VTR_POP_2) \
9766_("translate-1-1", L2_VTR_TRANSLATE_1_1) \
9767_("translate-1-2", L2_VTR_TRANSLATE_1_2) \
9768_("translate-2-1", L2_VTR_TRANSLATE_2_1) \
9769_("translate-2-2", L2_VTR_TRANSLATE_2_2)
9770
9771static int
9772api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
9773{
9774 unformat_input_t *i = vam->input;
9775 vl_api_l2_interface_vlan_tag_rewrite_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009776 u32 sw_if_index;
9777 u8 sw_if_index_set = 0;
9778 u8 vtr_op_set = 0;
9779 u32 vtr_op = 0;
9780 u32 push_dot1q = 1;
9781 u32 tag1 = ~0;
9782 u32 tag2 = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009783 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009784
9785 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9786 {
9787 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9788 sw_if_index_set = 1;
9789 else if (unformat (i, "sw_if_index %d", &sw_if_index))
9790 sw_if_index_set = 1;
9791 else if (unformat (i, "vtr_op %d", &vtr_op))
9792 vtr_op_set = 1;
9793#define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
9794 foreach_vtr_op
9795#undef _
9796 else if (unformat (i, "push_dot1q %d", &push_dot1q))
9797 ;
9798 else if (unformat (i, "tag1 %d", &tag1))
9799 ;
9800 else if (unformat (i, "tag2 %d", &tag2))
9801 ;
9802 else
9803 {
9804 clib_warning ("parse error '%U'", format_unformat_error, i);
9805 return -99;
9806 }
9807 }
9808
9809 if ((sw_if_index_set == 0) || (vtr_op_set == 0))
9810 {
9811 errmsg ("missing vtr operation or sw_if_index");
9812 return -99;
9813 }
9814
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009815 M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
9816 mp->sw_if_index = ntohl (sw_if_index);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009817 mp->vtr_op = ntohl (vtr_op);
9818 mp->push_dot1q = ntohl (push_dot1q);
9819 mp->tag1 = ntohl (tag1);
9820 mp->tag2 = ntohl (tag2);
9821
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009822 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06009823 W (ret);
9824 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009825}
9826
9827static int
9828api_create_vhost_user_if (vat_main_t * vam)
9829{
9830 unformat_input_t *i = vam->input;
9831 vl_api_create_vhost_user_if_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009832 u8 *file_name;
9833 u8 is_server = 0;
9834 u8 file_name_set = 0;
9835 u32 custom_dev_instance = ~0;
9836 u8 hwaddr[6];
9837 u8 use_custom_mac = 0;
Mohsin Kazmiee2e58f2018-08-21 16:07:03 +02009838 u8 disable_mrg_rxbuf = 0;
9839 u8 disable_indirect_desc = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009840 u8 *tag = 0;
Steven Luong4208a4c2019-05-06 08:51:56 -07009841 u8 enable_gso = 0;
Steven Luongbc0d9ff2020-03-23 09:34:59 -07009842 u8 enable_packed = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009843 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009844
9845 /* Shut up coverity */
Dave Barachb7b92992018-10-17 10:38:51 -04009846 clib_memset (hwaddr, 0, sizeof (hwaddr));
Damjan Marion7cd468a2016-12-19 23:05:39 +01009847
9848 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9849 {
9850 if (unformat (i, "socket %s", &file_name))
9851 {
9852 file_name_set = 1;
9853 }
9854 else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
9855 ;
9856 else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
9857 use_custom_mac = 1;
9858 else if (unformat (i, "server"))
9859 is_server = 1;
Mohsin Kazmiee2e58f2018-08-21 16:07:03 +02009860 else if (unformat (i, "disable_mrg_rxbuf"))
9861 disable_mrg_rxbuf = 1;
9862 else if (unformat (i, "disable_indirect_desc"))
9863 disable_indirect_desc = 1;
Steven Luong4208a4c2019-05-06 08:51:56 -07009864 else if (unformat (i, "gso"))
9865 enable_gso = 1;
Steven Luongbc0d9ff2020-03-23 09:34:59 -07009866 else if (unformat (i, "packed"))
9867 enable_packed = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009868 else if (unformat (i, "tag %s", &tag))
9869 ;
9870 else
9871 break;
9872 }
9873
9874 if (file_name_set == 0)
9875 {
9876 errmsg ("missing socket file name");
9877 return -99;
9878 }
9879
9880 if (vec_len (file_name) > 255)
9881 {
9882 errmsg ("socket file name too long");
9883 return -99;
9884 }
9885 vec_add1 (file_name, 0);
9886
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009887 M (CREATE_VHOST_USER_IF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009888
9889 mp->is_server = is_server;
Mohsin Kazmiee2e58f2018-08-21 16:07:03 +02009890 mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
9891 mp->disable_indirect_desc = disable_indirect_desc;
Steven Luong4208a4c2019-05-06 08:51:56 -07009892 mp->enable_gso = enable_gso;
Steven Luongbc0d9ff2020-03-23 09:34:59 -07009893 mp->enable_packed = enable_packed;
Steven Luong27ba5002020-11-17 13:30:44 -08009894 mp->custom_dev_instance = ntohl (custom_dev_instance);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009895 clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
9896 vec_free (file_name);
9897 if (custom_dev_instance != ~0)
Steven Luong27ba5002020-11-17 13:30:44 -08009898 mp->renumber = 1;
Mohsin Kazmiee2e58f2018-08-21 16:07:03 +02009899
Damjan Marion7cd468a2016-12-19 23:05:39 +01009900 mp->use_custom_mac = use_custom_mac;
9901 clib_memcpy (mp->mac_address, hwaddr, 6);
9902 if (tag)
9903 strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
9904 vec_free (tag);
9905
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009906 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06009907 W (ret);
9908 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009909}
9910
9911static int
9912api_modify_vhost_user_if (vat_main_t * vam)
9913{
9914 unformat_input_t *i = vam->input;
9915 vl_api_modify_vhost_user_if_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009916 u8 *file_name;
9917 u8 is_server = 0;
9918 u8 file_name_set = 0;
9919 u32 custom_dev_instance = ~0;
9920 u8 sw_if_index_set = 0;
9921 u32 sw_if_index = (u32) ~ 0;
Steven Luong4208a4c2019-05-06 08:51:56 -07009922 u8 enable_gso = 0;
Steven Luongbc0d9ff2020-03-23 09:34:59 -07009923 u8 enable_packed = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009924 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009925
9926 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9927 {
9928 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9929 sw_if_index_set = 1;
9930 else if (unformat (i, "sw_if_index %d", &sw_if_index))
9931 sw_if_index_set = 1;
9932 else if (unformat (i, "socket %s", &file_name))
9933 {
9934 file_name_set = 1;
9935 }
9936 else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
9937 ;
9938 else if (unformat (i, "server"))
9939 is_server = 1;
Steven Luong4208a4c2019-05-06 08:51:56 -07009940 else if (unformat (i, "gso"))
9941 enable_gso = 1;
Steven Luongbc0d9ff2020-03-23 09:34:59 -07009942 else if (unformat (i, "packed"))
9943 enable_packed = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009944 else
9945 break;
9946 }
9947
9948 if (sw_if_index_set == 0)
9949 {
9950 errmsg ("missing sw_if_index or interface name");
9951 return -99;
9952 }
9953
9954 if (file_name_set == 0)
9955 {
9956 errmsg ("missing socket file name");
9957 return -99;
9958 }
9959
9960 if (vec_len (file_name) > 255)
9961 {
9962 errmsg ("socket file name too long");
9963 return -99;
9964 }
9965 vec_add1 (file_name, 0);
9966
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009967 M (MODIFY_VHOST_USER_IF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009968
9969 mp->sw_if_index = ntohl (sw_if_index);
9970 mp->is_server = is_server;
Steven Luong4208a4c2019-05-06 08:51:56 -07009971 mp->enable_gso = enable_gso;
Steven Luongbc0d9ff2020-03-23 09:34:59 -07009972 mp->enable_packed = enable_packed;
Steven Luong27ba5002020-11-17 13:30:44 -08009973 mp->custom_dev_instance = ntohl (custom_dev_instance);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009974 clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
9975 vec_free (file_name);
9976 if (custom_dev_instance != ~0)
Steven Luong27ba5002020-11-17 13:30:44 -08009977 mp->renumber = 1;
9978
9979 S (mp);
9980 W (ret);
9981 return ret;
9982}
9983
9984static int
9985api_create_vhost_user_if_v2 (vat_main_t * vam)
9986{
9987 unformat_input_t *i = vam->input;
9988 vl_api_create_vhost_user_if_v2_t *mp;
9989 u8 *file_name;
9990 u8 is_server = 0;
9991 u8 file_name_set = 0;
9992 u32 custom_dev_instance = ~0;
9993 u8 hwaddr[6];
9994 u8 use_custom_mac = 0;
9995 u8 disable_mrg_rxbuf = 0;
9996 u8 disable_indirect_desc = 0;
9997 u8 *tag = 0;
9998 u8 enable_gso = 0;
9999 u8 enable_packed = 0;
10000 u8 enable_event_idx = 0;
10001 int ret;
10002
10003 /* Shut up coverity */
10004 clib_memset (hwaddr, 0, sizeof (hwaddr));
10005
10006 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
Damjan Marion7cd468a2016-12-19 23:05:39 +010010007 {
Steven Luong27ba5002020-11-17 13:30:44 -080010008 if (unformat (i, "socket %s", &file_name))
10009 {
10010 file_name_set = 1;
10011 }
10012 else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10013 ;
10014 else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
10015 use_custom_mac = 1;
10016 else if (unformat (i, "server"))
10017 is_server = 1;
10018 else if (unformat (i, "disable_mrg_rxbuf"))
10019 disable_mrg_rxbuf = 1;
10020 else if (unformat (i, "disable_indirect_desc"))
10021 disable_indirect_desc = 1;
10022 else if (unformat (i, "gso"))
10023 enable_gso = 1;
10024 else if (unformat (i, "packed"))
10025 enable_packed = 1;
10026 else if (unformat (i, "event-idx"))
10027 enable_event_idx = 1;
10028 else if (unformat (i, "tag %s", &tag))
10029 ;
10030 else
10031 break;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010032 }
10033
Steven Luong27ba5002020-11-17 13:30:44 -080010034 if (file_name_set == 0)
10035 {
10036 errmsg ("missing socket file name");
10037 return -99;
10038 }
10039
10040 if (vec_len (file_name) > 255)
10041 {
10042 errmsg ("socket file name too long");
10043 return -99;
10044 }
10045 vec_add1 (file_name, 0);
10046
10047 M (CREATE_VHOST_USER_IF_V2, mp);
10048
10049 mp->is_server = is_server;
10050 mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
10051 mp->disable_indirect_desc = disable_indirect_desc;
10052 mp->enable_gso = enable_gso;
10053 mp->enable_packed = enable_packed;
10054 mp->enable_event_idx = enable_event_idx;
10055 mp->custom_dev_instance = ntohl (custom_dev_instance);
10056 clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10057 vec_free (file_name);
10058 if (custom_dev_instance != ~0)
10059 mp->renumber = 1;
10060
10061 mp->use_custom_mac = use_custom_mac;
10062 clib_memcpy (mp->mac_address, hwaddr, 6);
10063 if (tag)
10064 strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
10065 vec_free (tag);
10066
10067 S (mp);
10068 W (ret);
10069 return ret;
10070}
10071
10072static int
10073api_modify_vhost_user_if_v2 (vat_main_t * vam)
10074{
10075 unformat_input_t *i = vam->input;
10076 vl_api_modify_vhost_user_if_v2_t *mp;
10077 u8 *file_name;
10078 u8 is_server = 0;
10079 u8 file_name_set = 0;
10080 u32 custom_dev_instance = ~0;
10081 u8 sw_if_index_set = 0;
10082 u32 sw_if_index = (u32) ~ 0;
10083 u8 enable_gso = 0;
10084 u8 enable_packed = 0;
10085 u8 enable_event_idx = 0;
10086 int ret;
10087
10088 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10089 {
10090 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10091 sw_if_index_set = 1;
10092 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10093 sw_if_index_set = 1;
10094 else if (unformat (i, "socket %s", &file_name))
10095 {
10096 file_name_set = 1;
10097 }
10098 else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10099 ;
10100 else if (unformat (i, "server"))
10101 is_server = 1;
10102 else if (unformat (i, "gso"))
10103 enable_gso = 1;
10104 else if (unformat (i, "packed"))
10105 enable_packed = 1;
10106 else if (unformat (i, "event-idx"))
10107 enable_event_idx = 1;
10108 else
10109 break;
10110 }
10111
10112 if (sw_if_index_set == 0)
10113 {
10114 errmsg ("missing sw_if_index or interface name");
10115 return -99;
10116 }
10117
10118 if (file_name_set == 0)
10119 {
10120 errmsg ("missing socket file name");
10121 return -99;
10122 }
10123
10124 if (vec_len (file_name) > 255)
10125 {
10126 errmsg ("socket file name too long");
10127 return -99;
10128 }
10129 vec_add1 (file_name, 0);
10130
10131 M (MODIFY_VHOST_USER_IF_V2, mp);
10132
10133 mp->sw_if_index = ntohl (sw_if_index);
10134 mp->is_server = is_server;
10135 mp->enable_gso = enable_gso;
10136 mp->enable_packed = enable_packed;
10137 mp->enable_event_idx = enable_event_idx;
10138 mp->custom_dev_instance = ntohl (custom_dev_instance);
10139 clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10140 vec_free (file_name);
10141 if (custom_dev_instance != ~0)
10142 mp->renumber = 1;
10143
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010144 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010145 W (ret);
10146 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010147}
10148
10149static int
10150api_delete_vhost_user_if (vat_main_t * vam)
10151{
10152 unformat_input_t *i = vam->input;
10153 vl_api_delete_vhost_user_if_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010154 u32 sw_if_index = ~0;
10155 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010156 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010157
10158 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10159 {
10160 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10161 sw_if_index_set = 1;
10162 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10163 sw_if_index_set = 1;
10164 else
10165 break;
10166 }
10167
10168 if (sw_if_index_set == 0)
10169 {
10170 errmsg ("missing sw_if_index or interface name");
10171 return -99;
10172 }
10173
10174
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010175 M (DELETE_VHOST_USER_IF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010176
10177 mp->sw_if_index = ntohl (sw_if_index);
10178
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010179 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010180 W (ret);
10181 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010182}
10183
10184static void vl_api_sw_interface_vhost_user_details_t_handler
10185 (vl_api_sw_interface_vhost_user_details_t * mp)
10186{
10187 vat_main_t *vam = &vat_main;
Jakub Grajciar5d4c99f2019-09-26 10:21:59 +020010188 u64 features;
10189
10190 features =
10191 clib_net_to_host_u32 (mp->features_first_32) | ((u64)
10192 clib_net_to_host_u32
10193 (mp->features_last_32) <<
10194 32);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010195
Steven Luong150bf5a2020-11-17 15:56:10 -080010196 print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %16llx %6d %7d %s",
10197 (char *) mp->interface_name, ntohl (mp->sw_if_index),
10198 ntohl (mp->virtio_net_hdr_sz), features, mp->is_server,
Stevenf3b53642017-05-01 14:03:02 -070010199 ntohl (mp->num_regions), (char *) mp->sock_filename);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010200 print (vam->ofp, " Status: '%s'", strerror (ntohl (mp->sock_errno)));
10201}
10202
10203static void vl_api_sw_interface_vhost_user_details_t_handler_json
10204 (vl_api_sw_interface_vhost_user_details_t * mp)
10205{
10206 vat_main_t *vam = &vat_main;
10207 vat_json_node_t *node = NULL;
10208
10209 if (VAT_JSON_ARRAY != vam->json_tree.type)
10210 {
10211 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10212 vat_json_init_array (&vam->json_tree);
10213 }
10214 node = vat_json_array_add (&vam->json_tree);
10215
10216 vat_json_init_object (node);
10217 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10218 vat_json_object_add_string_copy (node, "interface_name",
10219 mp->interface_name);
10220 vat_json_object_add_uint (node, "virtio_net_hdr_sz",
10221 ntohl (mp->virtio_net_hdr_sz));
Jakub Grajciar5d4c99f2019-09-26 10:21:59 +020010222 vat_json_object_add_uint (node, "features_first_32",
10223 clib_net_to_host_u32 (mp->features_first_32));
10224 vat_json_object_add_uint (node, "features_last_32",
10225 clib_net_to_host_u32 (mp->features_last_32));
Damjan Marion7cd468a2016-12-19 23:05:39 +010010226 vat_json_object_add_uint (node, "is_server", mp->is_server);
10227 vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
10228 vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
10229 vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
10230}
10231
10232static int
10233api_sw_interface_vhost_user_dump (vat_main_t * vam)
10234{
Steven Luonga0e8d962020-05-18 17:12:56 -070010235 unformat_input_t *i = vam->input;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010236 vl_api_sw_interface_vhost_user_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010237 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010238 int ret;
Steven Luonga0e8d962020-05-18 17:12:56 -070010239 u32 sw_if_index = ~0;
10240
10241 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10242 {
10243 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10244 ;
10245 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10246 ;
10247 else
10248 break;
10249 }
10250
Steven Luong150bf5a2020-11-17 15:56:10 -080010251 print (vam->ofp, "Interface name idx hdr_sz features "
10252 "server regions filename");
Damjan Marion7cd468a2016-12-19 23:05:39 +010010253
10254 /* Get list of vhost-user interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010255 M (SW_INTERFACE_VHOST_USER_DUMP, mp);
Steven Luonga0e8d962020-05-18 17:12:56 -070010256 mp->sw_if_index = ntohl (sw_if_index);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010257 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010258
10259 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040010260 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010261 S (mp_ping);
10262
Jon Loeliger56c7b012017-02-01 12:31:41 -060010263 W (ret);
10264 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010265}
10266
10267static int
10268api_show_version (vat_main_t * vam)
10269{
10270 vl_api_show_version_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010271 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010272
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010273 M (SHOW_VERSION, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010274
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010275 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010276 W (ret);
10277 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010278}
10279
10280
10281static int
10282api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
10283{
10284 unformat_input_t *line_input = vam->input;
10285 vl_api_vxlan_gpe_add_del_tunnel_t *mp;
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010286 ip46_address_t local, remote;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010287 u8 is_add = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010288 u8 local_set = 0;
10289 u8 remote_set = 0;
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010290 u8 grp_set = 0;
10291 u32 mcast_sw_if_index = ~0;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010292 u32 encap_vrf_id = 0;
10293 u32 decap_vrf_id = 0;
10294 u8 protocol = ~0;
10295 u32 vni;
10296 u8 vni_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010297 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010298
10299 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10300 {
10301 if (unformat (line_input, "del"))
10302 is_add = 0;
10303 else if (unformat (line_input, "local %U",
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010304 unformat_ip46_address, &local))
Damjan Marion7cd468a2016-12-19 23:05:39 +010010305 {
10306 local_set = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010307 }
10308 else if (unformat (line_input, "remote %U",
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010309 unformat_ip46_address, &remote))
Damjan Marion7cd468a2016-12-19 23:05:39 +010010310 {
10311 remote_set = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010312 }
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010313 else if (unformat (line_input, "group %U %U",
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010314 unformat_ip46_address, &remote,
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010315 api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10316 {
10317 grp_set = remote_set = 1;
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010318 }
10319 else if (unformat (line_input, "group %U",
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010320 unformat_ip46_address, &remote))
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010321 {
10322 grp_set = remote_set = 1;
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010323 }
10324 else
10325 if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10326 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010327 else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10328 ;
10329 else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
10330 ;
10331 else if (unformat (line_input, "vni %d", &vni))
10332 vni_set = 1;
10333 else if (unformat (line_input, "next-ip4"))
10334 protocol = 1;
10335 else if (unformat (line_input, "next-ip6"))
10336 protocol = 2;
10337 else if (unformat (line_input, "next-ethernet"))
10338 protocol = 3;
10339 else if (unformat (line_input, "next-nsh"))
10340 protocol = 4;
10341 else
10342 {
10343 errmsg ("parse error '%U'", format_unformat_error, line_input);
10344 return -99;
10345 }
10346 }
10347
10348 if (local_set == 0)
10349 {
10350 errmsg ("tunnel local address not specified");
10351 return -99;
10352 }
10353 if (remote_set == 0)
10354 {
10355 errmsg ("tunnel remote address not specified");
10356 return -99;
10357 }
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010358 if (grp_set && mcast_sw_if_index == ~0)
10359 {
10360 errmsg ("tunnel nonexistent multicast device");
10361 return -99;
10362 }
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010363 if (ip46_address_is_ip4 (&local) != ip46_address_is_ip4 (&remote))
Damjan Marion7cd468a2016-12-19 23:05:39 +010010364 {
10365 errmsg ("both IPv4 and IPv6 addresses specified");
10366 return -99;
10367 }
10368
10369 if (vni_set == 0)
10370 {
10371 errmsg ("vni not specified");
10372 return -99;
10373 }
10374
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010375 M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010376
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010377 ip_address_encode (&local,
10378 ip46_address_is_ip4 (&local) ? IP46_TYPE_IP4 :
10379 IP46_TYPE_IP6, &mp->local);
10380 ip_address_encode (&remote,
10381 ip46_address_is_ip4 (&remote) ? IP46_TYPE_IP4 :
10382 IP46_TYPE_IP6, &mp->remote);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010383
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010384 mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010385 mp->encap_vrf_id = ntohl (encap_vrf_id);
10386 mp->decap_vrf_id = ntohl (decap_vrf_id);
10387 mp->protocol = protocol;
10388 mp->vni = ntohl (vni);
10389 mp->is_add = is_add;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010390
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010391 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010392 W (ret);
10393 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010394}
10395
10396static void vl_api_vxlan_gpe_tunnel_details_t_handler
10397 (vl_api_vxlan_gpe_tunnel_details_t * mp)
10398{
10399 vat_main_t *vam = &vat_main;
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010400 ip46_address_t local, remote;
10401
10402 ip_address_decode (&mp->local, &local);
10403 ip_address_decode (&mp->remote, &remote);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010404
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010405 print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
Damjan Marion7cd468a2016-12-19 23:05:39 +010010406 ntohl (mp->sw_if_index),
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010407 format_ip46_address, &local, IP46_TYPE_ANY,
10408 format_ip46_address, &remote, IP46_TYPE_ANY,
10409 ntohl (mp->vni), mp->protocol,
10410 ntohl (mp->mcast_sw_if_index),
Damjan Marion7cd468a2016-12-19 23:05:39 +010010411 ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
10412}
10413
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010414
Damjan Marion7cd468a2016-12-19 23:05:39 +010010415static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
10416 (vl_api_vxlan_gpe_tunnel_details_t * mp)
10417{
10418 vat_main_t *vam = &vat_main;
10419 vat_json_node_t *node = NULL;
10420 struct in_addr ip4;
10421 struct in6_addr ip6;
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010422 ip46_address_t local, remote;
10423
10424 ip_address_decode (&mp->local, &local);
10425 ip_address_decode (&mp->remote, &remote);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010426
10427 if (VAT_JSON_ARRAY != vam->json_tree.type)
10428 {
10429 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10430 vat_json_init_array (&vam->json_tree);
10431 }
10432 node = vat_json_array_add (&vam->json_tree);
10433
10434 vat_json_init_object (node);
10435 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010436 if (ip46_address_is_ip4 (&local))
Damjan Marion7cd468a2016-12-19 23:05:39 +010010437 {
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010438 clib_memcpy (&ip4, &local.ip4, sizeof (ip4));
10439 vat_json_object_add_ip4 (node, "local", ip4);
10440 clib_memcpy (&ip4, &remote.ip4, sizeof (ip4));
10441 vat_json_object_add_ip4 (node, "remote", ip4);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010442 }
10443 else
10444 {
Jakub Grajciar1c2002a2020-01-31 10:45:30 +010010445 clib_memcpy (&ip6, &local.ip6, sizeof (ip6));
10446 vat_json_object_add_ip6 (node, "local", ip6);
10447 clib_memcpy (&ip6, &remote.ip6, sizeof (ip6));
10448 vat_json_object_add_ip6 (node, "remote", ip6);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010449 }
10450 vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10451 vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010452 vat_json_object_add_uint (node, "mcast_sw_if_index",
10453 ntohl (mp->mcast_sw_if_index));
Damjan Marion7cd468a2016-12-19 23:05:39 +010010454 vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10455 vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
10456 vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10457}
10458
10459static int
10460api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
10461{
10462 unformat_input_t *i = vam->input;
10463 vl_api_vxlan_gpe_tunnel_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010464 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010465 u32 sw_if_index;
10466 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010467 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010468
10469 /* Parse args required to build the message */
10470 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10471 {
10472 if (unformat (i, "sw_if_index %d", &sw_if_index))
10473 sw_if_index_set = 1;
10474 else
10475 break;
10476 }
10477
10478 if (sw_if_index_set == 0)
10479 {
10480 sw_if_index = ~0;
10481 }
10482
10483 if (!vam->json_output)
10484 {
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010485 print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
Damjan Marion7cd468a2016-12-19 23:05:39 +010010486 "sw_if_index", "local", "remote", "vni",
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080010487 "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
Damjan Marion7cd468a2016-12-19 23:05:39 +010010488 }
10489
10490 /* Get list of vxlan-tunnel interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010491 M (VXLAN_GPE_TUNNEL_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010492
10493 mp->sw_if_index = htonl (sw_if_index);
10494
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010495 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010496
10497 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040010498 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010499 S (mp_ping);
10500
Jon Loeliger56c7b012017-02-01 12:31:41 -060010501 W (ret);
10502 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010503}
10504
Ole Troan01384fe2017-05-12 11:55:35 +020010505static void vl_api_l2_fib_table_details_t_handler
10506 (vl_api_l2_fib_table_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010010507{
10508 vat_main_t *vam = &vat_main;
10509
10510 print (vam->ofp, "%3" PRIu32 " %U %3" PRIu32
10511 " %d %d %d",
Mohsin Kazmi57938f62017-10-27 21:28:07 +020010512 ntohl (mp->bd_id), format_ethernet_address, mp->mac,
Damjan Marion7cd468a2016-12-19 23:05:39 +010010513 ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
10514 mp->bvi_mac);
10515}
10516
Ole Troan01384fe2017-05-12 11:55:35 +020010517static void vl_api_l2_fib_table_details_t_handler_json
10518 (vl_api_l2_fib_table_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010010519{
10520 vat_main_t *vam = &vat_main;
10521 vat_json_node_t *node = NULL;
10522
10523 if (VAT_JSON_ARRAY != vam->json_tree.type)
10524 {
10525 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10526 vat_json_init_array (&vam->json_tree);
10527 }
10528 node = vat_json_array_add (&vam->json_tree);
10529
10530 vat_json_init_object (node);
10531 vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
Mohsin Kazmi57938f62017-10-27 21:28:07 +020010532 vat_json_object_add_bytes (node, "mac", mp->mac, 6);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010533 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10534 vat_json_object_add_uint (node, "static_mac", mp->static_mac);
10535 vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
10536 vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
10537}
10538
10539static int
10540api_l2_fib_table_dump (vat_main_t * vam)
10541{
10542 unformat_input_t *i = vam->input;
10543 vl_api_l2_fib_table_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010544 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010545 u32 bd_id;
10546 u8 bd_id_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010547 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010548
10549 /* Parse args required to build the message */
10550 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10551 {
10552 if (unformat (i, "bd_id %d", &bd_id))
10553 bd_id_set = 1;
10554 else
10555 break;
10556 }
10557
10558 if (bd_id_set == 0)
10559 {
10560 errmsg ("missing bridge domain");
10561 return -99;
10562 }
10563
10564 print (vam->ofp, "BD-ID Mac Address sw-ndx Static Filter BVI");
10565
10566 /* Get list of l2 fib entries */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010567 M (L2_FIB_TABLE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010568
10569 mp->bd_id = ntohl (bd_id);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010570 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010571
10572 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040010573 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010574 S (mp_ping);
10575
Jon Loeliger56c7b012017-02-01 12:31:41 -060010576 W (ret);
10577 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010578}
10579
10580
10581static int
10582api_interface_name_renumber (vat_main_t * vam)
10583{
10584 unformat_input_t *line_input = vam->input;
10585 vl_api_interface_name_renumber_t *mp;
10586 u32 sw_if_index = ~0;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010587 u32 new_show_dev_instance = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010588 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010589
10590 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10591 {
10592 if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
10593 &sw_if_index))
10594 ;
10595 else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
10596 ;
10597 else if (unformat (line_input, "new_show_dev_instance %d",
10598 &new_show_dev_instance))
10599 ;
10600 else
10601 break;
10602 }
10603
10604 if (sw_if_index == ~0)
10605 {
10606 errmsg ("missing interface name or sw_if_index");
10607 return -99;
10608 }
10609
10610 if (new_show_dev_instance == ~0)
10611 {
10612 errmsg ("missing new_show_dev_instance");
10613 return -99;
10614 }
10615
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010616 M (INTERFACE_NAME_RENUMBER, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010617
10618 mp->sw_if_index = ntohl (sw_if_index);
10619 mp->new_show_dev_instance = ntohl (new_show_dev_instance);
10620
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010621 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010622 W (ret);
10623 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010624}
10625
10626static int
John Lo8d00fff2017-08-03 00:35:36 -040010627api_want_l2_macs_events (vat_main_t * vam)
10628{
10629 unformat_input_t *line_input = vam->input;
10630 vl_api_want_l2_macs_events_t *mp;
10631 u8 enable_disable = 1;
10632 u32 scan_delay = 0;
10633 u32 max_macs_in_event = 0;
10634 u32 learn_limit = 0;
10635 int ret;
10636
10637 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10638 {
10639 if (unformat (line_input, "learn-limit %d", &learn_limit))
10640 ;
10641 else if (unformat (line_input, "scan-delay %d", &scan_delay))
10642 ;
10643 else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
10644 ;
10645 else if (unformat (line_input, "disable"))
10646 enable_disable = 0;
10647 else
10648 break;
10649 }
10650
10651 M (WANT_L2_MACS_EVENTS, mp);
10652 mp->enable_disable = enable_disable;
10653 mp->pid = htonl (getpid ());
10654 mp->learn_limit = htonl (learn_limit);
10655 mp->scan_delay = (u8) scan_delay;
10656 mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
10657 S (mp);
10658 W (ret);
10659 return ret;
10660}
10661
10662static int
Damjan Marion7cd468a2016-12-19 23:05:39 +010010663api_input_acl_set_interface (vat_main_t * vam)
10664{
10665 unformat_input_t *i = vam->input;
10666 vl_api_input_acl_set_interface_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010667 u32 sw_if_index;
10668 int sw_if_index_set;
10669 u32 ip4_table_index = ~0;
10670 u32 ip6_table_index = ~0;
10671 u32 l2_table_index = ~0;
10672 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010673 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010674
10675 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10676 {
10677 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10678 sw_if_index_set = 1;
10679 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10680 sw_if_index_set = 1;
10681 else if (unformat (i, "del"))
10682 is_add = 0;
10683 else if (unformat (i, "ip4-table %d", &ip4_table_index))
10684 ;
10685 else if (unformat (i, "ip6-table %d", &ip6_table_index))
10686 ;
10687 else if (unformat (i, "l2-table %d", &l2_table_index))
10688 ;
10689 else
10690 {
10691 clib_warning ("parse error '%U'", format_unformat_error, i);
10692 return -99;
10693 }
10694 }
10695
10696 if (sw_if_index_set == 0)
10697 {
10698 errmsg ("missing interface name or sw_if_index");
10699 return -99;
10700 }
10701
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010702 M (INPUT_ACL_SET_INTERFACE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010703
10704 mp->sw_if_index = ntohl (sw_if_index);
10705 mp->ip4_table_index = ntohl (ip4_table_index);
10706 mp->ip6_table_index = ntohl (ip6_table_index);
10707 mp->l2_table_index = ntohl (l2_table_index);
10708 mp->is_add = is_add;
10709
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010710 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010711 W (ret);
10712 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010713}
10714
10715static int
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +010010716api_output_acl_set_interface (vat_main_t * vam)
10717{
10718 unformat_input_t *i = vam->input;
10719 vl_api_output_acl_set_interface_t *mp;
10720 u32 sw_if_index;
10721 int sw_if_index_set;
10722 u32 ip4_table_index = ~0;
10723 u32 ip6_table_index = ~0;
10724 u32 l2_table_index = ~0;
10725 u8 is_add = 1;
10726 int ret;
10727
10728 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10729 {
10730 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10731 sw_if_index_set = 1;
10732 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10733 sw_if_index_set = 1;
10734 else if (unformat (i, "del"))
10735 is_add = 0;
10736 else if (unformat (i, "ip4-table %d", &ip4_table_index))
10737 ;
10738 else if (unformat (i, "ip6-table %d", &ip6_table_index))
10739 ;
10740 else if (unformat (i, "l2-table %d", &l2_table_index))
10741 ;
10742 else
10743 {
10744 clib_warning ("parse error '%U'", format_unformat_error, i);
10745 return -99;
10746 }
10747 }
10748
10749 if (sw_if_index_set == 0)
10750 {
10751 errmsg ("missing interface name or sw_if_index");
10752 return -99;
10753 }
10754
10755 M (OUTPUT_ACL_SET_INTERFACE, mp);
10756
10757 mp->sw_if_index = ntohl (sw_if_index);
10758 mp->ip4_table_index = ntohl (ip4_table_index);
10759 mp->ip6_table_index = ntohl (ip6_table_index);
10760 mp->l2_table_index = ntohl (l2_table_index);
10761 mp->is_add = is_add;
10762
10763 S (mp);
10764 W (ret);
10765 return ret;
10766}
10767
10768static int
Damjan Marion7cd468a2016-12-19 23:05:39 +010010769api_ip_address_dump (vat_main_t * vam)
10770{
10771 unformat_input_t *i = vam->input;
10772 vl_api_ip_address_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010773 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010774 u32 sw_if_index = ~0;
10775 u8 sw_if_index_set = 0;
10776 u8 ipv4_set = 0;
10777 u8 ipv6_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010778 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010779
10780 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10781 {
10782 if (unformat (i, "sw_if_index %d", &sw_if_index))
10783 sw_if_index_set = 1;
10784 else
10785 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10786 sw_if_index_set = 1;
10787 else if (unformat (i, "ipv4"))
10788 ipv4_set = 1;
10789 else if (unformat (i, "ipv6"))
10790 ipv6_set = 1;
10791 else
10792 break;
10793 }
10794
10795 if (ipv4_set && ipv6_set)
10796 {
10797 errmsg ("ipv4 and ipv6 flags cannot be both set");
10798 return -99;
10799 }
10800
10801 if ((!ipv4_set) && (!ipv6_set))
10802 {
10803 errmsg ("no ipv4 nor ipv6 flag set");
10804 return -99;
10805 }
10806
10807 if (sw_if_index_set == 0)
10808 {
10809 errmsg ("missing interface name or sw_if_index");
10810 return -99;
10811 }
10812
10813 vam->current_sw_if_index = sw_if_index;
10814 vam->is_ipv6 = ipv6_set;
10815
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010816 M (IP_ADDRESS_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010817 mp->sw_if_index = ntohl (sw_if_index);
10818 mp->is_ipv6 = ipv6_set;
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010819 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010820
10821 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040010822 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010823 S (mp_ping);
10824
Jon Loeliger56c7b012017-02-01 12:31:41 -060010825 W (ret);
10826 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010827}
10828
10829static int
10830api_ip_dump (vat_main_t * vam)
10831{
10832 vl_api_ip_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010833 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010834 unformat_input_t *in = vam->input;
10835 int ipv4_set = 0;
10836 int ipv6_set = 0;
10837 int is_ipv6;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010838 int i;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010839 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010840
10841 while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
10842 {
10843 if (unformat (in, "ipv4"))
10844 ipv4_set = 1;
10845 else if (unformat (in, "ipv6"))
10846 ipv6_set = 1;
10847 else
10848 break;
10849 }
10850
10851 if (ipv4_set && ipv6_set)
10852 {
10853 errmsg ("ipv4 and ipv6 flags cannot be both set");
10854 return -99;
10855 }
10856
10857 if ((!ipv4_set) && (!ipv6_set))
10858 {
10859 errmsg ("no ipv4 nor ipv6 flag set");
10860 return -99;
10861 }
10862
10863 is_ipv6 = ipv6_set;
10864 vam->is_ipv6 = is_ipv6;
10865
10866 /* free old data */
10867 for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
10868 {
10869 vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
10870 }
10871 vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
10872
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010873 M (IP_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010874 mp->is_ipv6 = ipv6_set;
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010875 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010876
10877 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040010878 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010879 S (mp_ping);
10880
Jon Loeliger56c7b012017-02-01 12:31:41 -060010881 W (ret);
10882 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010883}
10884
10885static int
10886api_ipsec_spd_add_del (vat_main_t * vam)
10887{
10888 unformat_input_t *i = vam->input;
10889 vl_api_ipsec_spd_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010890 u32 spd_id = ~0;
10891 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010892 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010893
10894 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10895 {
10896 if (unformat (i, "spd_id %d", &spd_id))
10897 ;
10898 else if (unformat (i, "del"))
10899 is_add = 0;
10900 else
10901 {
10902 clib_warning ("parse error '%U'", format_unformat_error, i);
10903 return -99;
10904 }
10905 }
10906 if (spd_id == ~0)
10907 {
10908 errmsg ("spd_id must be set");
10909 return -99;
10910 }
10911
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010912 M (IPSEC_SPD_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010913
10914 mp->spd_id = ntohl (spd_id);
10915 mp->is_add = is_add;
10916
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010917 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010918 W (ret);
10919 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010920}
10921
10922static int
10923api_ipsec_interface_add_del_spd (vat_main_t * vam)
10924{
10925 unformat_input_t *i = vam->input;
10926 vl_api_ipsec_interface_add_del_spd_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010927 u32 sw_if_index;
10928 u8 sw_if_index_set = 0;
10929 u32 spd_id = (u32) ~ 0;
10930 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010931 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010932
10933 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10934 {
10935 if (unformat (i, "del"))
10936 is_add = 0;
10937 else if (unformat (i, "spd_id %d", &spd_id))
10938 ;
10939 else
10940 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10941 sw_if_index_set = 1;
10942 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10943 sw_if_index_set = 1;
10944 else
10945 {
10946 clib_warning ("parse error '%U'", format_unformat_error, i);
10947 return -99;
10948 }
10949
10950 }
10951
10952 if (spd_id == (u32) ~ 0)
10953 {
10954 errmsg ("spd_id must be set");
10955 return -99;
10956 }
10957
10958 if (sw_if_index_set == 0)
10959 {
10960 errmsg ("missing interface name or sw_if_index");
10961 return -99;
10962 }
10963
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010964 M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010965
10966 mp->spd_id = ntohl (spd_id);
10967 mp->sw_if_index = ntohl (sw_if_index);
10968 mp->is_add = is_add;
10969
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010970 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010971 W (ret);
10972 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010973}
10974
10975static int
Neale Ranns17dcec02019-01-09 21:22:20 -080010976api_ipsec_spd_entry_add_del (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010010977{
10978 unformat_input_t *i = vam->input;
Neale Ranns17dcec02019-01-09 21:22:20 -080010979 vl_api_ipsec_spd_entry_add_del_t *mp;
Benoît Ganne49ee6842019-04-30 11:50:46 +020010980 u8 is_add = 1, is_outbound = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010981 u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
10982 i32 priority = 0;
10983 u32 rport_start = 0, rport_stop = (u32) ~ 0;
10984 u32 lport_start = 0, lport_stop = (u32) ~ 0;
Neale Ranns17dcec02019-01-09 21:22:20 -080010985 vl_api_address_t laddr_start = { }, laddr_stop =
10986 {
10987 }, raddr_start =
10988 {
10989 }, raddr_stop =
10990 {
10991 };
Jon Loeliger56c7b012017-02-01 12:31:41 -060010992 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010993
Damjan Marion7cd468a2016-12-19 23:05:39 +010010994 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10995 {
10996 if (unformat (i, "del"))
10997 is_add = 0;
10998 if (unformat (i, "outbound"))
10999 is_outbound = 1;
11000 if (unformat (i, "inbound"))
11001 is_outbound = 0;
11002 else if (unformat (i, "spd_id %d", &spd_id))
11003 ;
11004 else if (unformat (i, "sa_id %d", &sa_id))
11005 ;
11006 else if (unformat (i, "priority %d", &priority))
11007 ;
11008 else if (unformat (i, "protocol %d", &protocol))
11009 ;
11010 else if (unformat (i, "lport_start %d", &lport_start))
11011 ;
11012 else if (unformat (i, "lport_stop %d", &lport_stop))
11013 ;
11014 else if (unformat (i, "rport_start %d", &rport_start))
11015 ;
11016 else if (unformat (i, "rport_stop %d", &rport_stop))
11017 ;
Neale Ranns17dcec02019-01-09 21:22:20 -080011018 else if (unformat (i, "laddr_start %U",
11019 unformat_vl_api_address, &laddr_start))
Benoît Ganne49ee6842019-04-30 11:50:46 +020011020 ;
Neale Ranns17dcec02019-01-09 21:22:20 -080011021 else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
11022 &laddr_stop))
Benoît Ganne49ee6842019-04-30 11:50:46 +020011023 ;
Neale Ranns17dcec02019-01-09 21:22:20 -080011024 else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
11025 &raddr_start))
Benoît Ganne49ee6842019-04-30 11:50:46 +020011026 ;
Neale Ranns17dcec02019-01-09 21:22:20 -080011027 else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
11028 &raddr_stop))
Benoît Ganne49ee6842019-04-30 11:50:46 +020011029 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011030 else
11031 if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
11032 {
11033 if (policy == IPSEC_POLICY_ACTION_RESOLVE)
11034 {
11035 clib_warning ("unsupported action: 'resolve'");
11036 return -99;
11037 }
11038 }
11039 else
11040 {
11041 clib_warning ("parse error '%U'", format_unformat_error, i);
11042 return -99;
11043 }
11044
11045 }
11046
Neale Ranns17dcec02019-01-09 21:22:20 -080011047 M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011048
Damjan Marion7cd468a2016-12-19 23:05:39 +010011049 mp->is_add = is_add;
Neale Ranns17dcec02019-01-09 21:22:20 -080011050
11051 mp->entry.spd_id = ntohl (spd_id);
11052 mp->entry.priority = ntohl (priority);
11053 mp->entry.is_outbound = is_outbound;
11054
11055 clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
11056 sizeof (vl_api_address_t));
11057 clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
11058 sizeof (vl_api_address_t));
11059 clib_memcpy (&mp->entry.local_address_start, &laddr_start,
11060 sizeof (vl_api_address_t));
11061 clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
11062 sizeof (vl_api_address_t));
11063
11064 mp->entry.protocol = (u8) protocol;
11065 mp->entry.local_port_start = ntohs ((u16) lport_start);
11066 mp->entry.local_port_stop = ntohs ((u16) lport_stop);
11067 mp->entry.remote_port_start = ntohs ((u16) rport_start);
11068 mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
11069 mp->entry.policy = (u8) policy;
11070 mp->entry.sa_id = ntohl (sa_id);
Neale Ranns17dcec02019-01-09 21:22:20 -080011071
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011072 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011073 W (ret);
11074 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011075}
11076
11077static int
Neale Ranns17dcec02019-01-09 21:22:20 -080011078api_ipsec_sad_entry_add_del (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010011079{
11080 unformat_input_t *i = vam->input;
Neale Ranns17dcec02019-01-09 21:22:20 -080011081 vl_api_ipsec_sad_entry_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011082 u32 sad_id = 0, spi = 0;
11083 u8 *ck = 0, *ik = 0;
11084 u8 is_add = 1;
11085
Neale Ranns17dcec02019-01-09 21:22:20 -080011086 vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
11087 vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
11088 vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
11089 vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
11090 vl_api_address_t tun_src, tun_dst;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011091 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011092
11093 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11094 {
11095 if (unformat (i, "del"))
11096 is_add = 0;
11097 else if (unformat (i, "sad_id %d", &sad_id))
11098 ;
11099 else if (unformat (i, "spi %d", &spi))
11100 ;
11101 else if (unformat (i, "esp"))
Neale Ranns17dcec02019-01-09 21:22:20 -080011102 protocol = IPSEC_API_PROTO_ESP;
11103 else
11104 if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
Damjan Marion7cd468a2016-12-19 23:05:39 +010011105 {
Neale Ranns17dcec02019-01-09 21:22:20 -080011106 flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
11107 if (ADDRESS_IP6 == tun_src.af)
11108 flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011109 }
11110 else
Neale Ranns17dcec02019-01-09 21:22:20 -080011111 if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
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 }
Neale Ranns17dcec02019-01-09 21:22:20 -080011117 else
11118 if (unformat (i, "crypto_alg %U",
11119 unformat_ipsec_api_crypto_alg, &crypto_alg))
11120 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011121 else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11122 ;
Neale Ranns17dcec02019-01-09 21:22:20 -080011123 else if (unformat (i, "integ_alg %U",
11124 unformat_ipsec_api_integ_alg, &integ_alg))
11125 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011126 else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11127 ;
11128 else
11129 {
11130 clib_warning ("parse error '%U'", format_unformat_error, i);
11131 return -99;
11132 }
11133
11134 }
11135
Neale Ranns17dcec02019-01-09 21:22:20 -080011136 M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011137
Damjan Marion7cd468a2016-12-19 23:05:39 +010011138 mp->is_add = is_add;
Neale Ranns17dcec02019-01-09 21:22:20 -080011139 mp->entry.sad_id = ntohl (sad_id);
11140 mp->entry.protocol = protocol;
11141 mp->entry.spi = ntohl (spi);
11142 mp->entry.flags = flags;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011143
Neale Ranns17dcec02019-01-09 21:22:20 -080011144 mp->entry.crypto_algorithm = crypto_alg;
11145 mp->entry.integrity_algorithm = integ_alg;
11146 mp->entry.crypto_key.length = vec_len (ck);
11147 mp->entry.integrity_key.length = vec_len (ik);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011148
Neale Ranns17dcec02019-01-09 21:22:20 -080011149 if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
11150 mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
11151
11152 if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
11153 mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011154
11155 if (ck)
Neale Ranns17dcec02019-01-09 21:22:20 -080011156 clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011157 if (ik)
Neale Ranns17dcec02019-01-09 21:22:20 -080011158 clib_memcpy (mp->entry.integrity_key.data, ik,
11159 mp->entry.integrity_key.length);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011160
Neale Ranns17dcec02019-01-09 21:22:20 -080011161 if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
Damjan Marion7cd468a2016-12-19 23:05:39 +010011162 {
Neale Ranns17dcec02019-01-09 21:22:20 -080011163 clib_memcpy (&mp->entry.tunnel_src, &tun_src,
11164 sizeof (mp->entry.tunnel_src));
11165 clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
11166 sizeof (mp->entry.tunnel_dst));
Damjan Marion7cd468a2016-12-19 23:05:39 +010011167 }
11168
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011169 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011170 W (ret);
11171 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011172}
11173
Matthew Smith28029532017-09-26 13:33:44 -050011174static void
11175vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
11176{
11177 vat_main_t *vam = &vat_main;
11178
11179 print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
Neale Ranns8d7c5022019-02-06 01:41:05 -080011180 "crypto_key %U integ_alg %u integ_key %U flags %x "
Matthew Smith28029532017-09-26 13:33:44 -050011181 "tunnel_src_addr %U tunnel_dst_addr %U "
11182 "salt %u seq_outbound %lu last_seq_inbound %lu "
Matthew Smith48d32b42020-04-02 07:45:49 -050011183 "replay_window %lu stat_index %u\n",
Neale Ranns8d7c5022019-02-06 01:41:05 -080011184 ntohl (mp->entry.sad_id),
11185 ntohl (mp->sw_if_index),
11186 ntohl (mp->entry.spi),
11187 ntohl (mp->entry.protocol),
11188 ntohl (mp->entry.crypto_algorithm),
11189 format_hex_bytes, mp->entry.crypto_key.data,
11190 mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
11191 format_hex_bytes, mp->entry.integrity_key.data,
11192 mp->entry.integrity_key.length, ntohl (mp->entry.flags),
11193 format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
11194 &mp->entry.tunnel_dst, ntohl (mp->salt),
Matthew Smith28029532017-09-26 13:33:44 -050011195 clib_net_to_host_u64 (mp->seq_outbound),
11196 clib_net_to_host_u64 (mp->last_seq_inbound),
Matthew Smith48d32b42020-04-02 07:45:49 -050011197 clib_net_to_host_u64 (mp->replay_window), ntohl (mp->stat_index));
Matthew Smith28029532017-09-26 13:33:44 -050011198}
11199
11200#define vl_api_ipsec_sa_details_t_endian vl_noop_handler
11201#define vl_api_ipsec_sa_details_t_print vl_noop_handler
11202
11203static void vl_api_ipsec_sa_details_t_handler_json
11204 (vl_api_ipsec_sa_details_t * mp)
11205{
11206 vat_main_t *vam = &vat_main;
11207 vat_json_node_t *node = NULL;
Neale Ranns8d7c5022019-02-06 01:41:05 -080011208 vl_api_ipsec_sad_flags_t flags;
Matthew Smith28029532017-09-26 13:33:44 -050011209
11210 if (VAT_JSON_ARRAY != vam->json_tree.type)
11211 {
11212 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11213 vat_json_init_array (&vam->json_tree);
11214 }
11215 node = vat_json_array_add (&vam->json_tree);
11216
11217 vat_json_init_object (node);
Neale Ranns8d7c5022019-02-06 01:41:05 -080011218 vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
Matthew Smith28029532017-09-26 13:33:44 -050011219 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
Neale Ranns8d7c5022019-02-06 01:41:05 -080011220 vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
11221 vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
11222 vat_json_object_add_uint (node, "crypto_alg",
11223 ntohl (mp->entry.crypto_algorithm));
11224 vat_json_object_add_uint (node, "integ_alg",
11225 ntohl (mp->entry.integrity_algorithm));
11226 flags = ntohl (mp->entry.flags);
11227 vat_json_object_add_uint (node, "use_esn",
Damjan Marion1e3aa5e2019-03-28 10:58:59 +010011228 ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
Neale Ranns8d7c5022019-02-06 01:41:05 -080011229 vat_json_object_add_uint (node, "use_anti_replay",
11230 ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
11231 vat_json_object_add_uint (node, "is_tunnel",
11232 ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
11233 vat_json_object_add_uint (node, "is_tunnel_ip6",
11234 ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
11235 vat_json_object_add_uint (node, "udp_encap",
11236 ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
11237 vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
11238 mp->entry.crypto_key.length);
11239 vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
11240 mp->entry.integrity_key.length);
Neale Ranns5a8844b2019-04-16 07:15:35 +000011241 vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
11242 vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
Matthew Smith28029532017-09-26 13:33:44 -050011243 vat_json_object_add_uint (node, "replay_window",
11244 clib_net_to_host_u64 (mp->replay_window));
Matthew Smith48d32b42020-04-02 07:45:49 -050011245 vat_json_object_add_uint (node, "stat_index", ntohl (mp->stat_index));
Matthew Smith28029532017-09-26 13:33:44 -050011246}
11247
11248static int
11249api_ipsec_sa_dump (vat_main_t * vam)
11250{
11251 unformat_input_t *i = vam->input;
11252 vl_api_ipsec_sa_dump_t *mp;
11253 vl_api_control_ping_t *mp_ping;
11254 u32 sa_id = ~0;
11255 int ret;
11256
11257 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11258 {
11259 if (unformat (i, "sa_id %d", &sa_id))
11260 ;
11261 else
11262 {
11263 clib_warning ("parse error '%U'", format_unformat_error, i);
11264 return -99;
11265 }
11266 }
11267
11268 M (IPSEC_SA_DUMP, mp);
11269
11270 mp->sa_id = ntohl (sa_id);
11271
11272 S (mp);
11273
11274 /* Use a control ping for synchronization */
11275 M (CONTROL_PING, mp_ping);
11276 S (mp_ping);
11277
11278 W (ret);
11279 return ret;
11280}
11281
Matthew Smithb0972cb2017-05-02 16:20:41 -050011282static int
Damjan Marion7cd468a2016-12-19 23:05:39 +010011283api_get_first_msg_id (vat_main_t * vam)
11284{
11285 vl_api_get_first_msg_id_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011286 unformat_input_t *i = vam->input;
11287 u8 *name;
11288 u8 name_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011289 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011290
11291 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11292 {
11293 if (unformat (i, "client %s", &name))
11294 name_set = 1;
11295 else
11296 break;
11297 }
11298
11299 if (name_set == 0)
11300 {
11301 errmsg ("missing client name");
11302 return -99;
11303 }
11304 vec_add1 (name, 0);
11305
11306 if (vec_len (name) > 63)
11307 {
11308 errmsg ("client name too long");
11309 return -99;
11310 }
11311
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011312 M (GET_FIRST_MSG_ID, mp);
Ole Troan7adaa222019-08-27 15:05:27 +020011313 clib_memcpy (mp->name, name, vec_len (name));
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011314 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011315 W (ret);
11316 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011317}
11318
11319static int
Damjan Marion7cd468a2016-12-19 23:05:39 +010011320api_get_node_graph (vat_main_t * vam)
11321{
11322 vl_api_get_node_graph_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011323 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011324
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011325 M (GET_NODE_GRAPH, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011326
11327 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011328 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011329 /* Wait for the reply */
Jon Loeliger56c7b012017-02-01 12:31:41 -060011330 W (ret);
11331 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011332}
11333
Damjan Marion7cd468a2016-12-19 23:05:39 +010011334static int
11335api_af_packet_create (vat_main_t * vam)
11336{
11337 unformat_input_t *i = vam->input;
11338 vl_api_af_packet_create_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011339 u8 *host_if_name = 0;
11340 u8 hw_addr[6];
11341 u8 random_hw_addr = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011342 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011343
Dave Barachb7b92992018-10-17 10:38:51 -040011344 clib_memset (hw_addr, 0, sizeof (hw_addr));
Damjan Marion7cd468a2016-12-19 23:05:39 +010011345
11346 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11347 {
11348 if (unformat (i, "name %s", &host_if_name))
11349 vec_add1 (host_if_name, 0);
11350 else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
11351 random_hw_addr = 0;
11352 else
11353 break;
11354 }
11355
11356 if (!vec_len (host_if_name))
11357 {
11358 errmsg ("host-interface name must be specified");
11359 return -99;
11360 }
11361
11362 if (vec_len (host_if_name) > 64)
11363 {
11364 errmsg ("host-interface name too long");
11365 return -99;
11366 }
11367
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011368 M (AF_PACKET_CREATE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011369
11370 clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
11371 clib_memcpy (mp->hw_addr, hw_addr, 6);
11372 mp->use_random_hw_addr = random_hw_addr;
11373 vec_free (host_if_name);
11374
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011375 S (mp);
Dave Baracha1a093d2017-03-02 13:13:23 -050011376
11377 /* *INDENT-OFF* */
11378 W2 (ret,
11379 ({
11380 if (ret == 0)
11381 fprintf (vam->ofp ? vam->ofp : stderr,
11382 " new sw_if_index = %d\n", vam->sw_if_index);
11383 }));
11384 /* *INDENT-ON* */
Jon Loeliger56c7b012017-02-01 12:31:41 -060011385 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011386}
11387
11388static int
11389api_af_packet_delete (vat_main_t * vam)
11390{
11391 unformat_input_t *i = vam->input;
11392 vl_api_af_packet_delete_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011393 u8 *host_if_name = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011394 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011395
11396 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11397 {
11398 if (unformat (i, "name %s", &host_if_name))
11399 vec_add1 (host_if_name, 0);
11400 else
11401 break;
11402 }
11403
11404 if (!vec_len (host_if_name))
11405 {
11406 errmsg ("host-interface name must be specified");
11407 return -99;
11408 }
11409
11410 if (vec_len (host_if_name) > 64)
11411 {
11412 errmsg ("host-interface name too long");
11413 return -99;
11414 }
11415
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011416 M (AF_PACKET_DELETE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011417
11418 clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
11419 vec_free (host_if_name);
11420
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011421 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011422 W (ret);
11423 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011424}
11425
Mohsin Kazmi04e0bb22018-05-28 18:55:37 +020011426static void vl_api_af_packet_details_t_handler
11427 (vl_api_af_packet_details_t * mp)
11428{
11429 vat_main_t *vam = &vat_main;
11430
11431 print (vam->ofp, "%-16s %d",
11432 mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
11433}
11434
11435static void vl_api_af_packet_details_t_handler_json
11436 (vl_api_af_packet_details_t * mp)
11437{
11438 vat_main_t *vam = &vat_main;
11439 vat_json_node_t *node = NULL;
11440
11441 if (VAT_JSON_ARRAY != vam->json_tree.type)
11442 {
11443 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11444 vat_json_init_array (&vam->json_tree);
11445 }
11446 node = vat_json_array_add (&vam->json_tree);
11447
11448 vat_json_init_object (node);
11449 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11450 vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
11451}
11452
11453static int
11454api_af_packet_dump (vat_main_t * vam)
11455{
11456 vl_api_af_packet_dump_t *mp;
11457 vl_api_control_ping_t *mp_ping;
11458 int ret;
11459
11460 print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
11461 /* Get list of tap interfaces */
11462 M (AF_PACKET_DUMP, mp);
11463 S (mp);
11464
11465 /* Use a control ping for synchronization */
11466 MPING (CONTROL_PING, mp_ping);
11467 S (mp_ping);
11468
11469 W (ret);
11470 return ret;
11471}
11472
Damjan Marion7cd468a2016-12-19 23:05:39 +010011473static int
11474api_policer_add_del (vat_main_t * vam)
11475{
11476 unformat_input_t *i = vam->input;
11477 vl_api_policer_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011478 u8 is_add = 1;
11479 u8 *name = 0;
11480 u32 cir = 0;
11481 u32 eir = 0;
11482 u64 cb = 0;
11483 u64 eb = 0;
11484 u8 rate_type = 0;
11485 u8 round_type = 0;
11486 u8 type = 0;
11487 u8 color_aware = 0;
Brian Russellc5299ff2021-02-09 10:16:58 +000011488 qos_pol_action_params_st conform_action, exceed_action, violate_action;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011489 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011490
Brian Russellc5299ff2021-02-09 10:16:58 +000011491 conform_action.action_type = QOS_ACTION_TRANSMIT;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011492 conform_action.dscp = 0;
Brian Russellc5299ff2021-02-09 10:16:58 +000011493 exceed_action.action_type = QOS_ACTION_MARK_AND_TRANSMIT;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011494 exceed_action.dscp = 0;
Brian Russellc5299ff2021-02-09 10:16:58 +000011495 violate_action.action_type = QOS_ACTION_DROP;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011496 violate_action.dscp = 0;
11497
11498 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11499 {
11500 if (unformat (i, "del"))
11501 is_add = 0;
11502 else if (unformat (i, "name %s", &name))
11503 vec_add1 (name, 0);
11504 else if (unformat (i, "cir %u", &cir))
11505 ;
11506 else if (unformat (i, "eir %u", &eir))
11507 ;
11508 else if (unformat (i, "cb %u", &cb))
11509 ;
11510 else if (unformat (i, "eb %u", &eb))
11511 ;
11512 else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
11513 &rate_type))
11514 ;
11515 else if (unformat (i, "round_type %U", unformat_policer_round_type,
11516 &round_type))
11517 ;
11518 else if (unformat (i, "type %U", unformat_policer_type, &type))
11519 ;
11520 else if (unformat (i, "conform_action %U", unformat_policer_action_type,
11521 &conform_action))
11522 ;
11523 else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
11524 &exceed_action))
11525 ;
11526 else if (unformat (i, "violate_action %U", unformat_policer_action_type,
11527 &violate_action))
11528 ;
11529 else if (unformat (i, "color-aware"))
11530 color_aware = 1;
11531 else
11532 break;
11533 }
11534
11535 if (!vec_len (name))
11536 {
11537 errmsg ("policer name must be specified");
11538 return -99;
11539 }
11540
11541 if (vec_len (name) > 64)
11542 {
11543 errmsg ("policer name too long");
11544 return -99;
11545 }
11546
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011547 M (POLICER_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011548
11549 clib_memcpy (mp->name, name, vec_len (name));
11550 vec_free (name);
11551 mp->is_add = is_add;
Neale Rannsd91c1db2017-07-31 02:30:50 -070011552 mp->cir = ntohl (cir);
11553 mp->eir = ntohl (eir);
11554 mp->cb = clib_net_to_host_u64 (cb);
11555 mp->eb = clib_net_to_host_u64 (eb);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011556 mp->rate_type = rate_type;
11557 mp->round_type = round_type;
11558 mp->type = type;
Brian Russellb2aae752021-02-09 11:36:31 +000011559 mp->conform_action.type =
11560 (vl_api_sse2_qos_action_type_t) conform_action.action_type;
Jakub Grajciarcd01fb42020-03-02 13:16:53 +010011561 mp->conform_action.dscp = conform_action.dscp;
Brian Russellb2aae752021-02-09 11:36:31 +000011562 mp->exceed_action.type =
11563 (vl_api_sse2_qos_action_type_t) exceed_action.action_type;
Jakub Grajciarcd01fb42020-03-02 13:16:53 +010011564 mp->exceed_action.dscp = exceed_action.dscp;
Brian Russellb2aae752021-02-09 11:36:31 +000011565 mp->violate_action.type =
11566 (vl_api_sse2_qos_action_type_t) violate_action.action_type;
Jakub Grajciarcd01fb42020-03-02 13:16:53 +010011567 mp->violate_action.dscp = violate_action.dscp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011568 mp->color_aware = color_aware;
11569
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011570 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011571 W (ret);
11572 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011573}
11574
11575static int
11576api_policer_dump (vat_main_t * vam)
11577{
11578 unformat_input_t *i = vam->input;
11579 vl_api_policer_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011580 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011581 u8 *match_name = 0;
11582 u8 match_name_valid = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011583 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011584
11585 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11586 {
11587 if (unformat (i, "name %s", &match_name))
11588 {
11589 vec_add1 (match_name, 0);
11590 match_name_valid = 1;
11591 }
11592 else
11593 break;
11594 }
11595
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011596 M (POLICER_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011597 mp->match_name_valid = match_name_valid;
11598 clib_memcpy (mp->match_name, match_name, vec_len (match_name));
11599 vec_free (match_name);
11600 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011601 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011602
11603 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040011604 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011605 S (mp_ping);
11606
Damjan Marion7cd468a2016-12-19 23:05:39 +010011607 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060011608 W (ret);
11609 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011610}
11611
11612static int
11613api_policer_classify_set_interface (vat_main_t * vam)
11614{
11615 unformat_input_t *i = vam->input;
11616 vl_api_policer_classify_set_interface_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011617 u32 sw_if_index;
11618 int sw_if_index_set;
11619 u32 ip4_table_index = ~0;
11620 u32 ip6_table_index = ~0;
11621 u32 l2_table_index = ~0;
11622 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011623 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011624
11625 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11626 {
11627 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11628 sw_if_index_set = 1;
11629 else if (unformat (i, "sw_if_index %d", &sw_if_index))
11630 sw_if_index_set = 1;
11631 else if (unformat (i, "del"))
11632 is_add = 0;
11633 else if (unformat (i, "ip4-table %d", &ip4_table_index))
11634 ;
11635 else if (unformat (i, "ip6-table %d", &ip6_table_index))
11636 ;
11637 else if (unformat (i, "l2-table %d", &l2_table_index))
11638 ;
11639 else
11640 {
11641 clib_warning ("parse error '%U'", format_unformat_error, i);
11642 return -99;
11643 }
11644 }
11645
11646 if (sw_if_index_set == 0)
11647 {
11648 errmsg ("missing interface name or sw_if_index");
11649 return -99;
11650 }
11651
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011652 M (POLICER_CLASSIFY_SET_INTERFACE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011653
11654 mp->sw_if_index = ntohl (sw_if_index);
11655 mp->ip4_table_index = ntohl (ip4_table_index);
11656 mp->ip6_table_index = ntohl (ip6_table_index);
11657 mp->l2_table_index = ntohl (l2_table_index);
11658 mp->is_add = is_add;
11659
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011660 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011661 W (ret);
11662 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011663}
11664
11665static int
11666api_policer_classify_dump (vat_main_t * vam)
11667{
11668 unformat_input_t *i = vam->input;
11669 vl_api_policer_classify_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011670 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011671 u8 type = POLICER_CLASSIFY_N_TABLES;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011672 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011673
11674 if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
11675 ;
11676 else
11677 {
11678 errmsg ("classify table type must be specified");
11679 return -99;
11680 }
11681
11682 if (!vam->json_output)
11683 {
11684 print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
11685 }
11686
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011687 M (POLICER_CLASSIFY_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011688 mp->type = type;
11689 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011690 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011691
11692 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040011693 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011694 S (mp_ping);
11695
Damjan Marion7cd468a2016-12-19 23:05:39 +010011696 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060011697 W (ret);
11698 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011699}
11700
Neale Ranns097fa662018-05-01 05:17:55 -070011701static u8 *
11702format_fib_api_path_nh_proto (u8 * s, va_list * args)
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011703{
Neale Ranns097fa662018-05-01 05:17:55 -070011704 vl_api_fib_path_nh_proto_t proto =
11705 va_arg (*args, vl_api_fib_path_nh_proto_t);
11706
11707 switch (proto)
11708 {
11709 case FIB_API_PATH_NH_PROTO_IP4:
11710 s = format (s, "ip4");
11711 break;
11712 case FIB_API_PATH_NH_PROTO_IP6:
11713 s = format (s, "ip6");
11714 break;
11715 case FIB_API_PATH_NH_PROTO_MPLS:
11716 s = format (s, "mpls");
11717 break;
11718 case FIB_API_PATH_NH_PROTO_BIER:
11719 s = format (s, "bier");
11720 break;
11721 case FIB_API_PATH_NH_PROTO_ETHERNET:
11722 s = format (s, "ethernet");
11723 break;
11724 }
11725
11726 return (s);
11727}
11728
11729static u8 *
11730format_vl_api_ip_address_union (u8 * s, va_list * args)
11731{
Jakub Grajciar7dd63e52020-03-19 08:03:55 +010011732 vl_api_address_family_t af = va_arg (*args, int);
Neale Ranns097fa662018-05-01 05:17:55 -070011733 const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
11734
11735 switch (af)
11736 {
11737 case ADDRESS_IP4:
11738 s = format (s, "%U", format_ip4_address, u->ip4);
11739 break;
11740 case ADDRESS_IP6:
11741 s = format (s, "%U", format_ip6_address, u->ip6);
11742 break;
11743 }
11744 return (s);
11745}
11746
11747static u8 *
11748format_vl_api_fib_path_type (u8 * s, va_list * args)
11749{
11750 vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
11751
11752 switch (t)
11753 {
11754 case FIB_API_PATH_TYPE_NORMAL:
11755 s = format (s, "normal");
11756 break;
11757 case FIB_API_PATH_TYPE_LOCAL:
11758 s = format (s, "local");
11759 break;
11760 case FIB_API_PATH_TYPE_DROP:
11761 s = format (s, "drop");
11762 break;
11763 case FIB_API_PATH_TYPE_UDP_ENCAP:
11764 s = format (s, "udp-encap");
11765 break;
11766 case FIB_API_PATH_TYPE_BIER_IMP:
11767 s = format (s, "bier-imp");
11768 break;
11769 case FIB_API_PATH_TYPE_ICMP_UNREACH:
11770 s = format (s, "unreach");
11771 break;
11772 case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
11773 s = format (s, "prohibit");
11774 break;
11775 case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
11776 s = format (s, "src-lookup");
11777 break;
11778 case FIB_API_PATH_TYPE_DVR:
11779 s = format (s, "dvr");
11780 break;
11781 case FIB_API_PATH_TYPE_INTERFACE_RX:
11782 s = format (s, "interface-rx");
11783 break;
11784 case FIB_API_PATH_TYPE_CLASSIFY:
11785 s = format (s, "classify");
11786 break;
11787 }
11788
11789 return (s);
11790}
11791
11792static void
11793vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
11794{
11795 print (vam->ofp,
11796 " weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
11797 ntohl (fp->weight), ntohl (fp->sw_if_index),
11798 format_vl_api_fib_path_type, fp->type,
11799 format_fib_api_path_nh_proto, fp->proto,
11800 format_vl_api_ip_address_union, &fp->nh.address);
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011801}
11802
11803static void
11804vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
Neale Ranns31ed7442018-02-23 05:29:09 -080011805 vl_api_fib_path_t * fp)
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011806{
11807 struct in_addr ip4;
11808 struct in6_addr ip6;
11809
11810 vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
11811 vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
Neale Ranns097fa662018-05-01 05:17:55 -070011812 vat_json_object_add_uint (node, "type", fp->type);
11813 vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
11814 if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011815 {
Neale Ranns097fa662018-05-01 05:17:55 -070011816 clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011817 vat_json_object_add_ip4 (node, "next_hop", ip4);
11818 }
Dave Barachc35f3e82020-04-02 10:44:09 -040011819 else if (fp->proto == FIB_API_PATH_NH_PROTO_IP6)
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011820 {
Neale Ranns097fa662018-05-01 05:17:55 -070011821 clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011822 vat_json_object_add_ip6 (node, "next_hop", ip6);
11823 }
11824}
11825
11826static void
11827vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010011828{
11829 vat_main_t *vam = &vat_main;
Neale Ranns097fa662018-05-01 05:17:55 -070011830 int count = ntohl (mp->mt_tunnel.mt_n_paths);
Neale Ranns31ed7442018-02-23 05:29:09 -080011831 vl_api_fib_path_t *fp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011832 i32 i;
11833
Neale Ranns097fa662018-05-01 05:17:55 -070011834 print (vam->ofp, "sw_if_index %d via:",
11835 ntohl (mp->mt_tunnel.mt_sw_if_index));
11836 fp = mp->mt_tunnel.mt_paths;
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011837 for (i = 0; i < count; i++)
Damjan Marion7cd468a2016-12-19 23:05:39 +010011838 {
Neale Ranns097fa662018-05-01 05:17:55 -070011839 vl_api_fib_path_print (vam, fp);
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011840 fp++;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011841 }
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011842
Damjan Marion7cd468a2016-12-19 23:05:39 +010011843 print (vam->ofp, "");
11844}
11845
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011846#define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
11847#define vl_api_mpls_tunnel_details_t_print vl_noop_handler
11848
11849static void
11850vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010011851{
11852 vat_main_t *vam = &vat_main;
11853 vat_json_node_t *node = NULL;
Neale Ranns097fa662018-05-01 05:17:55 -070011854 int count = ntohl (mp->mt_tunnel.mt_n_paths);
Neale Ranns31ed7442018-02-23 05:29:09 -080011855 vl_api_fib_path_t *fp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011856 i32 i;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011857
11858 if (VAT_JSON_ARRAY != vam->json_tree.type)
11859 {
11860 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11861 vat_json_init_array (&vam->json_tree);
11862 }
11863 node = vat_json_array_add (&vam->json_tree);
11864
11865 vat_json_init_object (node);
Neale Ranns097fa662018-05-01 05:17:55 -070011866 vat_json_object_add_uint (node, "sw_if_index",
11867 ntohl (mp->mt_tunnel.mt_sw_if_index));
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011868
Neale Ranns097fa662018-05-01 05:17:55 -070011869 vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011870
Neale Ranns097fa662018-05-01 05:17:55 -070011871 fp = mp->mt_tunnel.mt_paths;
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011872 for (i = 0; i < count; i++)
Damjan Marion7cd468a2016-12-19 23:05:39 +010011873 {
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011874 vl_api_mpls_fib_path_json_print (node, fp);
11875 fp++;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011876 }
11877}
11878
11879static int
11880api_mpls_tunnel_dump (vat_main_t * vam)
11881{
11882 vl_api_mpls_tunnel_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011883 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011884 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011885
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011886 M (MPLS_TUNNEL_DUMP, mp);
Neale Ranns097fa662018-05-01 05:17:55 -070011887
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011888 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011889
11890 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040011891 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011892 S (mp_ping);
11893
Jon Loeliger56c7b012017-02-01 12:31:41 -060011894 W (ret);
11895 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011896}
11897
Neale Ranns097fa662018-05-01 05:17:55 -070011898#define vl_api_mpls_table_details_t_endian vl_noop_handler
11899#define vl_api_mpls_table_details_t_print vl_noop_handler
Damjan Marion7cd468a2016-12-19 23:05:39 +010011900
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011901
Damjan Marion7cd468a2016-12-19 23:05:39 +010011902static void
Neale Ranns097fa662018-05-01 05:17:55 -070011903vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010011904{
11905 vat_main_t *vam = &vat_main;
Neale Ranns097fa662018-05-01 05:17:55 -070011906
11907 print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
11908}
11909
11910static void vl_api_mpls_table_details_t_handler_json
11911 (vl_api_mpls_table_details_t * mp)
11912{
11913 vat_main_t *vam = &vat_main;
11914 vat_json_node_t *node = NULL;
11915
11916 if (VAT_JSON_ARRAY != vam->json_tree.type)
11917 {
11918 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11919 vat_json_init_array (&vam->json_tree);
11920 }
11921 node = vat_json_array_add (&vam->json_tree);
11922
11923 vat_json_init_object (node);
11924 vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
11925}
11926
11927static int
11928api_mpls_table_dump (vat_main_t * vam)
11929{
11930 vl_api_mpls_table_dump_t *mp;
11931 vl_api_control_ping_t *mp_ping;
11932 int ret;
11933
11934 M (MPLS_TABLE_DUMP, mp);
11935 S (mp);
11936
11937 /* Use a control ping for synchronization */
11938 MPING (CONTROL_PING, mp_ping);
11939 S (mp_ping);
11940
11941 W (ret);
11942 return ret;
11943}
11944
11945#define vl_api_mpls_route_details_t_endian vl_noop_handler
11946#define vl_api_mpls_route_details_t_print vl_noop_handler
11947
11948static void
11949vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
11950{
11951 vat_main_t *vam = &vat_main;
Dave Barach4bda2d92019-07-03 15:21:50 -040011952 int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
Neale Ranns31ed7442018-02-23 05:29:09 -080011953 vl_api_fib_path_t *fp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011954 int i;
11955
11956 print (vam->ofp,
11957 "table-id %d, label %u, ess_bit %u",
Neale Ranns097fa662018-05-01 05:17:55 -070011958 ntohl (mp->mr_route.mr_table_id),
11959 ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
11960 fp = mp->mr_route.mr_paths;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011961 for (i = 0; i < count; i++)
11962 {
Neale Ranns097fa662018-05-01 05:17:55 -070011963 vl_api_fib_path_print (vam, fp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011964 fp++;
11965 }
11966}
11967
Neale Ranns097fa662018-05-01 05:17:55 -070011968static void vl_api_mpls_route_details_t_handler_json
11969 (vl_api_mpls_route_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010011970{
11971 vat_main_t *vam = &vat_main;
Dave Barach4bda2d92019-07-03 15:21:50 -040011972 int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011973 vat_json_node_t *node = NULL;
Neale Ranns31ed7442018-02-23 05:29:09 -080011974 vl_api_fib_path_t *fp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011975 int i;
11976
11977 if (VAT_JSON_ARRAY != vam->json_tree.type)
11978 {
11979 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11980 vat_json_init_array (&vam->json_tree);
11981 }
11982 node = vat_json_array_add (&vam->json_tree);
11983
11984 vat_json_init_object (node);
Neale Ranns097fa662018-05-01 05:17:55 -070011985 vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
11986 vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
11987 vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
Damjan Marion7cd468a2016-12-19 23:05:39 +010011988 vat_json_object_add_uint (node, "path_count", count);
Neale Ranns097fa662018-05-01 05:17:55 -070011989 fp = mp->mr_route.mr_paths;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011990 for (i = 0; i < count; i++)
11991 {
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011992 vl_api_mpls_fib_path_json_print (node, fp);
11993 fp++;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011994 }
11995}
11996
11997static int
Neale Ranns097fa662018-05-01 05:17:55 -070011998api_mpls_route_dump (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010011999{
Neale Ranns097fa662018-05-01 05:17:55 -070012000 unformat_input_t *input = vam->input;
12001 vl_api_mpls_route_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012002 vl_api_control_ping_t *mp_ping;
Neale Ranns097fa662018-05-01 05:17:55 -070012003 u32 table_id;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012004 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012005
Neale Ranns097fa662018-05-01 05:17:55 -070012006 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12007 {
12008 if (unformat (input, "table_id %d", &table_id))
12009 ;
12010 else
12011 break;
12012 }
12013 if (table_id == ~0)
12014 {
12015 errmsg ("missing table id");
12016 return -99;
12017 }
12018
12019 M (MPLS_ROUTE_DUMP, mp);
12020
12021 mp->table.mt_table_id = ntohl (table_id);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012022 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012023
12024 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040012025 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012026 S (mp_ping);
12027
Jon Loeliger56c7b012017-02-01 12:31:41 -060012028 W (ret);
12029 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012030}
12031
Neale Ranns097fa662018-05-01 05:17:55 -070012032#define vl_api_ip_table_details_t_endian vl_noop_handler
12033#define vl_api_ip_table_details_t_print vl_noop_handler
Damjan Marion7cd468a2016-12-19 23:05:39 +010012034
12035static void
Neale Ranns097fa662018-05-01 05:17:55 -070012036vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012037{
12038 vat_main_t *vam = &vat_main;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012039
12040 print (vam->ofp,
Neale Ranns097fa662018-05-01 05:17:55 -070012041 "%s; table-id %d, prefix %U/%d",
12042 mp->table.name, ntohl (mp->table.table_id));
Damjan Marion7cd468a2016-12-19 23:05:39 +010012043}
12044
Neale Ranns097fa662018-05-01 05:17:55 -070012045
12046static void vl_api_ip_table_details_t_handler_json
12047 (vl_api_ip_table_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012048{
12049 vat_main_t *vam = &vat_main;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012050 vat_json_node_t *node = NULL;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012051
12052 if (VAT_JSON_ARRAY != vam->json_tree.type)
12053 {
12054 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12055 vat_json_init_array (&vam->json_tree);
12056 }
12057 node = vat_json_array_add (&vam->json_tree);
12058
12059 vat_json_init_object (node);
Neale Ranns097fa662018-05-01 05:17:55 -070012060 vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
Damjan Marion7cd468a2016-12-19 23:05:39 +010012061}
12062
12063static int
Neale Ranns097fa662018-05-01 05:17:55 -070012064api_ip_table_dump (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012065{
Neale Ranns097fa662018-05-01 05:17:55 -070012066 vl_api_ip_table_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012067 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012068 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012069
Neale Ranns097fa662018-05-01 05:17:55 -070012070 M (IP_TABLE_DUMP, mp);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012071 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012072
12073 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040012074 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012075 S (mp_ping);
12076
Jon Loeliger56c7b012017-02-01 12:31:41 -060012077 W (ret);
12078 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012079}
12080
Neale Ranns5a8123b2017-01-26 01:18:23 -080012081static int
Neale Ranns097fa662018-05-01 05:17:55 -070012082api_ip_mtable_dump (vat_main_t * vam)
Neale Ranns5a8123b2017-01-26 01:18:23 -080012083{
Neale Ranns097fa662018-05-01 05:17:55 -070012084 vl_api_ip_mtable_dump_t *mp;
Neale Ranns5a8123b2017-01-26 01:18:23 -080012085 vl_api_control_ping_t *mp_ping;
12086 int ret;
12087
Neale Ranns097fa662018-05-01 05:17:55 -070012088 M (IP_MTABLE_DUMP, mp);
12089 S (mp);
12090
12091 /* Use a control ping for synchronization */
12092 MPING (CONTROL_PING, mp_ping);
12093 S (mp_ping);
12094
12095 W (ret);
12096 return ret;
12097}
12098
12099static int
12100api_ip_mroute_dump (vat_main_t * vam)
12101{
12102 unformat_input_t *input = vam->input;
12103 vl_api_control_ping_t *mp_ping;
12104 vl_api_ip_mroute_dump_t *mp;
12105 int ret, is_ip6;
12106 u32 table_id;
12107
12108 is_ip6 = 0;
12109 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12110 {
12111 if (unformat (input, "table_id %d", &table_id))
12112 ;
12113 else if (unformat (input, "ip6"))
12114 is_ip6 = 1;
12115 else if (unformat (input, "ip4"))
12116 is_ip6 = 0;
12117 else
12118 break;
12119 }
12120 if (table_id == ~0)
12121 {
12122 errmsg ("missing table id");
12123 return -99;
12124 }
12125
12126 M (IP_MROUTE_DUMP, mp);
12127 mp->table.table_id = table_id;
12128 mp->table.is_ip6 = is_ip6;
Neale Ranns5a8123b2017-01-26 01:18:23 -080012129 S (mp);
12130
12131 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040012132 MPING (CONTROL_PING, mp_ping);
Neale Ranns5a8123b2017-01-26 01:18:23 -080012133 S (mp_ping);
12134
12135 W (ret);
12136 return ret;
12137}
12138
Neale Ranns097fa662018-05-01 05:17:55 -070012139#define vl_api_ip_route_details_t_endian vl_noop_handler
12140#define vl_api_ip_route_details_t_print vl_noop_handler
Damjan Marion7cd468a2016-12-19 23:05:39 +010012141
12142static void
Neale Ranns097fa662018-05-01 05:17:55 -070012143vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012144{
12145 vat_main_t *vam = &vat_main;
Neale Ranns097fa662018-05-01 05:17:55 -070012146 u8 count = mp->route.n_paths;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012147 vl_api_fib_path_t *fp;
12148 int i;
12149
12150 print (vam->ofp,
Neale Ranns097fa662018-05-01 05:17:55 -070012151 "table-id %d, prefix %U/%d",
12152 ntohl (mp->route.table_id),
Paul Vinciguerraab055082019-06-06 14:07:55 -040012153 format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012154 for (i = 0; i < count; i++)
12155 {
Neale Ranns097fa662018-05-01 05:17:55 -070012156 fp = &mp->route.paths[i];
12157
12158 vl_api_fib_path_print (vam, fp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012159 fp++;
12160 }
12161}
12162
Neale Ranns097fa662018-05-01 05:17:55 -070012163static void vl_api_ip_route_details_t_handler_json
12164 (vl_api_ip_route_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012165{
12166 vat_main_t *vam = &vat_main;
Neale Ranns097fa662018-05-01 05:17:55 -070012167 u8 count = mp->route.n_paths;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012168 vat_json_node_t *node = NULL;
12169 struct in_addr ip4;
12170 struct in6_addr ip6;
12171 vl_api_fib_path_t *fp;
12172 int i;
12173
12174 if (VAT_JSON_ARRAY != vam->json_tree.type)
12175 {
12176 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12177 vat_json_init_array (&vam->json_tree);
12178 }
12179 node = vat_json_array_add (&vam->json_tree);
12180
12181 vat_json_init_object (node);
Neale Ranns097fa662018-05-01 05:17:55 -070012182 vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
12183 if (ADDRESS_IP6 == mp->route.prefix.address.af)
12184 {
12185 clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
12186 vat_json_object_add_ip6 (node, "prefix", ip6);
12187 }
12188 else
12189 {
12190 clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
12191 vat_json_object_add_ip4 (node, "prefix", ip4);
12192 }
Paul Vinciguerraab055082019-06-06 14:07:55 -040012193 vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012194 vat_json_object_add_uint (node, "path_count", count);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012195 for (i = 0; i < count; i++)
12196 {
Neale Ranns097fa662018-05-01 05:17:55 -070012197 fp = &mp->route.paths[i];
12198 vl_api_mpls_fib_path_json_print (node, fp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012199 }
12200}
12201
12202static int
Neale Ranns097fa662018-05-01 05:17:55 -070012203api_ip_route_dump (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010012204{
Neale Ranns097fa662018-05-01 05:17:55 -070012205 unformat_input_t *input = vam->input;
12206 vl_api_ip_route_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012207 vl_api_control_ping_t *mp_ping;
Neale Ranns097fa662018-05-01 05:17:55 -070012208 u32 table_id;
12209 u8 is_ip6;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012210 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012211
Neale Ranns097fa662018-05-01 05:17:55 -070012212 is_ip6 = 0;
12213 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12214 {
12215 if (unformat (input, "table_id %d", &table_id))
12216 ;
12217 else if (unformat (input, "ip6"))
12218 is_ip6 = 1;
12219 else if (unformat (input, "ip4"))
12220 is_ip6 = 0;
12221 else
12222 break;
12223 }
12224 if (table_id == ~0)
12225 {
12226 errmsg ("missing table id");
12227 return -99;
12228 }
Damjan Marion7cd468a2016-12-19 23:05:39 +010012229
Neale Ranns097fa662018-05-01 05:17:55 -070012230 M (IP_ROUTE_DUMP, mp);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012231
Neale Ranns097fa662018-05-01 05:17:55 -070012232 mp->table.table_id = table_id;
12233 mp->table.is_ip6 = is_ip6;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012234
Neale Ranns5a8123b2017-01-26 01:18:23 -080012235 S (mp);
12236
12237 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040012238 MPING (CONTROL_PING, mp_ping);
Neale Ranns5a8123b2017-01-26 01:18:23 -080012239 S (mp_ping);
12240
12241 W (ret);
12242 return ret;
12243}
12244
Damjan Marion7cd468a2016-12-19 23:05:39 +010012245int
12246api_classify_table_ids (vat_main_t * vam)
12247{
12248 vl_api_classify_table_ids_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012249 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012250
12251 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012252 M (CLASSIFY_TABLE_IDS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012253 mp->context = 0;
12254
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012255 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012256 W (ret);
12257 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012258}
12259
12260int
12261api_classify_table_by_interface (vat_main_t * vam)
12262{
12263 unformat_input_t *input = vam->input;
12264 vl_api_classify_table_by_interface_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012265
12266 u32 sw_if_index = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012267 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012268 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12269 {
12270 if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12271 ;
12272 else if (unformat (input, "sw_if_index %d", &sw_if_index))
12273 ;
12274 else
12275 break;
12276 }
12277 if (sw_if_index == ~0)
12278 {
12279 errmsg ("missing interface name or sw_if_index");
12280 return -99;
12281 }
12282
12283 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012284 M (CLASSIFY_TABLE_BY_INTERFACE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012285 mp->context = 0;
12286 mp->sw_if_index = ntohl (sw_if_index);
12287
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012288 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012289 W (ret);
12290 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012291}
12292
12293int
12294api_classify_table_info (vat_main_t * vam)
12295{
12296 unformat_input_t *input = vam->input;
12297 vl_api_classify_table_info_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012298
12299 u32 table_id = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012300 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012301 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12302 {
12303 if (unformat (input, "table_id %d", &table_id))
12304 ;
12305 else
12306 break;
12307 }
12308 if (table_id == ~0)
12309 {
12310 errmsg ("missing table id");
12311 return -99;
12312 }
12313
12314 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012315 M (CLASSIFY_TABLE_INFO, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012316 mp->context = 0;
12317 mp->table_id = ntohl (table_id);
12318
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012319 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012320 W (ret);
12321 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012322}
12323
12324int
12325api_classify_session_dump (vat_main_t * vam)
12326{
12327 unformat_input_t *input = vam->input;
12328 vl_api_classify_session_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012329 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012330
12331 u32 table_id = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012332 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012333 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12334 {
12335 if (unformat (input, "table_id %d", &table_id))
12336 ;
12337 else
12338 break;
12339 }
12340 if (table_id == ~0)
12341 {
12342 errmsg ("missing table id");
12343 return -99;
12344 }
12345
12346 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012347 M (CLASSIFY_SESSION_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012348 mp->context = 0;
12349 mp->table_id = ntohl (table_id);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012350 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012351
12352 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040012353 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012354 S (mp_ping);
12355
Jon Loeliger56c7b012017-02-01 12:31:41 -060012356 W (ret);
12357 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012358}
12359
12360static void
12361vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
12362{
12363 vat_main_t *vam = &vat_main;
12364
12365 print (vam->ofp, "collector_address %U, collector_port %d, "
12366 "src_address %U, vrf_id %d, path_mtu %u, "
12367 "template_interval %u, udp_checksum %d",
12368 format_ip4_address, mp->collector_address,
12369 ntohs (mp->collector_port),
12370 format_ip4_address, mp->src_address,
12371 ntohl (mp->vrf_id), ntohl (mp->path_mtu),
12372 ntohl (mp->template_interval), mp->udp_checksum);
12373
12374 vam->retval = 0;
12375 vam->result_ready = 1;
12376}
12377
12378static void
12379 vl_api_ipfix_exporter_details_t_handler_json
12380 (vl_api_ipfix_exporter_details_t * mp)
12381{
12382 vat_main_t *vam = &vat_main;
12383 vat_json_node_t node;
12384 struct in_addr collector_address;
12385 struct in_addr src_address;
12386
12387 vat_json_init_object (&node);
12388 clib_memcpy (&collector_address, &mp->collector_address,
12389 sizeof (collector_address));
12390 vat_json_object_add_ip4 (&node, "collector_address", collector_address);
12391 vat_json_object_add_uint (&node, "collector_port",
12392 ntohs (mp->collector_port));
12393 clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
12394 vat_json_object_add_ip4 (&node, "src_address", src_address);
12395 vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
12396 vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
12397 vat_json_object_add_uint (&node, "template_interval",
12398 ntohl (mp->template_interval));
12399 vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
12400
12401 vat_json_print (vam->ofp, &node);
12402 vat_json_free (&node);
12403 vam->retval = 0;
12404 vam->result_ready = 1;
12405}
12406
12407int
12408api_ipfix_exporter_dump (vat_main_t * vam)
12409{
12410 vl_api_ipfix_exporter_dump_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012411 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012412
12413 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012414 M (IPFIX_EXPORTER_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012415 mp->context = 0;
12416
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012417 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012418 W (ret);
12419 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012420}
12421
12422static int
12423api_ipfix_classify_stream_dump (vat_main_t * vam)
12424{
12425 vl_api_ipfix_classify_stream_dump_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012426 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012427
12428 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012429 M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012430 mp->context = 0;
12431
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012432 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012433 W (ret);
12434 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012435 /* NOTREACHED */
12436 return 0;
12437}
12438
12439static void
12440 vl_api_ipfix_classify_stream_details_t_handler
12441 (vl_api_ipfix_classify_stream_details_t * mp)
12442{
12443 vat_main_t *vam = &vat_main;
12444 print (vam->ofp, "domain_id %d, src_port %d",
12445 ntohl (mp->domain_id), ntohs (mp->src_port));
12446 vam->retval = 0;
12447 vam->result_ready = 1;
12448}
12449
12450static void
12451 vl_api_ipfix_classify_stream_details_t_handler_json
12452 (vl_api_ipfix_classify_stream_details_t * mp)
12453{
12454 vat_main_t *vam = &vat_main;
12455 vat_json_node_t node;
12456
12457 vat_json_init_object (&node);
12458 vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
12459 vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
12460
12461 vat_json_print (vam->ofp, &node);
12462 vat_json_free (&node);
12463 vam->retval = 0;
12464 vam->result_ready = 1;
12465}
12466
12467static int
12468api_ipfix_classify_table_dump (vat_main_t * vam)
12469{
12470 vl_api_ipfix_classify_table_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012471 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012472 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012473
12474 if (!vam->json_output)
12475 {
12476 print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
12477 "transport_protocol");
12478 }
12479
12480 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012481 M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012482
12483 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012484 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012485
12486 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040012487 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012488 S (mp_ping);
12489
Jon Loeliger56c7b012017-02-01 12:31:41 -060012490 W (ret);
12491 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012492}
12493
12494static void
12495 vl_api_ipfix_classify_table_details_t_handler
12496 (vl_api_ipfix_classify_table_details_t * mp)
12497{
12498 vat_main_t *vam = &vat_main;
12499 print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
12500 mp->transport_protocol);
12501}
12502
12503static void
12504 vl_api_ipfix_classify_table_details_t_handler_json
12505 (vl_api_ipfix_classify_table_details_t * mp)
12506{
12507 vat_json_node_t *node = NULL;
12508 vat_main_t *vam = &vat_main;
12509
12510 if (VAT_JSON_ARRAY != vam->json_tree.type)
12511 {
12512 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12513 vat_json_init_array (&vam->json_tree);
12514 }
12515
12516 node = vat_json_array_add (&vam->json_tree);
12517 vat_json_init_object (node);
12518
12519 vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
12520 vat_json_object_add_uint (node, "ip_version", mp->ip_version);
12521 vat_json_object_add_uint (node, "transport_protocol",
12522 mp->transport_protocol);
12523}
12524
12525static int
12526api_sw_interface_span_enable_disable (vat_main_t * vam)
12527{
12528 unformat_input_t *i = vam->input;
12529 vl_api_sw_interface_span_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012530 u32 src_sw_if_index = ~0;
12531 u32 dst_sw_if_index = ~0;
12532 u8 state = 3;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012533 int ret;
Eyal Bari001fd402017-07-16 09:34:53 +030012534 u8 is_l2 = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012535
12536 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12537 {
12538 if (unformat
12539 (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
12540 ;
12541 else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
12542 ;
12543 else
12544 if (unformat
12545 (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
12546 ;
12547 else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
12548 ;
12549 else if (unformat (i, "disable"))
12550 state = 0;
12551 else if (unformat (i, "rx"))
12552 state = 1;
12553 else if (unformat (i, "tx"))
12554 state = 2;
12555 else if (unformat (i, "both"))
12556 state = 3;
Eyal Bari001fd402017-07-16 09:34:53 +030012557 else if (unformat (i, "l2"))
12558 is_l2 = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012559 else
12560 break;
12561 }
12562
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012563 M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012564
12565 mp->sw_if_index_from = htonl (src_sw_if_index);
12566 mp->sw_if_index_to = htonl (dst_sw_if_index);
12567 mp->state = state;
Eyal Bari001fd402017-07-16 09:34:53 +030012568 mp->is_l2 = is_l2;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012569
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012570 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012571 W (ret);
12572 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012573}
12574
12575static void
12576vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
12577 * mp)
12578{
12579 vat_main_t *vam = &vat_main;
12580 u8 *sw_if_from_name = 0;
12581 u8 *sw_if_to_name = 0;
12582 u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
12583 u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
12584 char *states[] = { "none", "rx", "tx", "both" };
12585 hash_pair_t *p;
12586
12587 /* *INDENT-OFF* */
12588 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
12589 ({
12590 if ((u32) p->value[0] == sw_if_index_from)
12591 {
12592 sw_if_from_name = (u8 *)(p->key);
12593 if (sw_if_to_name)
12594 break;
12595 }
12596 if ((u32) p->value[0] == sw_if_index_to)
12597 {
12598 sw_if_to_name = (u8 *)(p->key);
12599 if (sw_if_from_name)
12600 break;
12601 }
12602 }));
12603 /* *INDENT-ON* */
Jon Loeliger179ab362018-03-12 14:50:08 -050012604 print (vam->ofp, "%20s => %20s (%s) %s",
12605 sw_if_from_name, sw_if_to_name, states[mp->state],
12606 mp->is_l2 ? "l2" : "device");
Damjan Marion7cd468a2016-12-19 23:05:39 +010012607}
12608
12609static void
12610 vl_api_sw_interface_span_details_t_handler_json
12611 (vl_api_sw_interface_span_details_t * mp)
12612{
12613 vat_main_t *vam = &vat_main;
12614 vat_json_node_t *node = NULL;
12615 u8 *sw_if_from_name = 0;
12616 u8 *sw_if_to_name = 0;
12617 u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
12618 u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
12619 hash_pair_t *p;
12620
12621 /* *INDENT-OFF* */
12622 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
12623 ({
12624 if ((u32) p->value[0] == sw_if_index_from)
12625 {
12626 sw_if_from_name = (u8 *)(p->key);
12627 if (sw_if_to_name)
12628 break;
12629 }
12630 if ((u32) p->value[0] == sw_if_index_to)
12631 {
12632 sw_if_to_name = (u8 *)(p->key);
12633 if (sw_if_from_name)
12634 break;
12635 }
12636 }));
12637 /* *INDENT-ON* */
12638
12639 if (VAT_JSON_ARRAY != vam->json_tree.type)
12640 {
12641 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12642 vat_json_init_array (&vam->json_tree);
12643 }
12644 node = vat_json_array_add (&vam->json_tree);
12645
12646 vat_json_init_object (node);
12647 vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
12648 vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
12649 vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
Neale Ranns05b2bf22017-01-30 06:44:58 -080012650 if (0 != sw_if_to_name)
12651 {
12652 vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
12653 }
Damjan Marion7cd468a2016-12-19 23:05:39 +010012654 vat_json_object_add_uint (node, "state", mp->state);
Jon Loeliger179ab362018-03-12 14:50:08 -050012655 vat_json_object_add_uint (node, "is-l2", mp->is_l2);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012656}
12657
12658static int
12659api_sw_interface_span_dump (vat_main_t * vam)
12660{
Eyal Bari5b311202017-07-31 13:12:30 +030012661 unformat_input_t *input = vam->input;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012662 vl_api_sw_interface_span_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012663 vl_api_control_ping_t *mp_ping;
Eyal Bari5b311202017-07-31 13:12:30 +030012664 u8 is_l2 = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012665 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012666
Eyal Bari5b311202017-07-31 13:12:30 +030012667 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12668 {
12669 if (unformat (input, "l2"))
12670 is_l2 = 1;
12671 else
12672 break;
12673 }
12674
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012675 M (SW_INTERFACE_SPAN_DUMP, mp);
Eyal Bari5b311202017-07-31 13:12:30 +030012676 mp->is_l2 = is_l2;
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012677 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012678
12679 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040012680 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012681 S (mp_ping);
12682
Jon Loeliger56c7b012017-02-01 12:31:41 -060012683 W (ret);
12684 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012685}
12686
12687int
12688api_pg_create_interface (vat_main_t * vam)
12689{
12690 unformat_input_t *input = vam->input;
12691 vl_api_pg_create_interface_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012692
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +020012693 u32 if_id = ~0, gso_size = 0;
12694 u8 gso_enabled = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012695 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012696 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12697 {
12698 if (unformat (input, "if_id %d", &if_id))
12699 ;
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +020012700 else if (unformat (input, "gso-enabled"))
12701 {
12702 gso_enabled = 1;
12703 if (unformat (input, "gso-size %u", &gso_size))
12704 ;
12705 else
12706 {
12707 errmsg ("missing gso-size");
12708 return -99;
12709 }
12710 }
Damjan Marion7cd468a2016-12-19 23:05:39 +010012711 else
12712 break;
12713 }
12714 if (if_id == ~0)
12715 {
12716 errmsg ("missing pg interface index");
12717 return -99;
12718 }
12719
12720 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012721 M (PG_CREATE_INTERFACE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012722 mp->context = 0;
12723 mp->interface_id = ntohl (if_id);
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +020012724 mp->gso_enabled = gso_enabled;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012725
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012726 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012727 W (ret);
12728 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012729}
12730
12731int
12732api_pg_capture (vat_main_t * vam)
12733{
12734 unformat_input_t *input = vam->input;
12735 vl_api_pg_capture_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012736
12737 u32 if_id = ~0;
12738 u8 enable = 1;
12739 u32 count = 1;
12740 u8 pcap_file_set = 0;
12741 u8 *pcap_file = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012742 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012743 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12744 {
12745 if (unformat (input, "if_id %d", &if_id))
12746 ;
12747 else if (unformat (input, "pcap %s", &pcap_file))
12748 pcap_file_set = 1;
12749 else if (unformat (input, "count %d", &count))
12750 ;
12751 else if (unformat (input, "disable"))
12752 enable = 0;
12753 else
12754 break;
12755 }
12756 if (if_id == ~0)
12757 {
12758 errmsg ("missing pg interface index");
12759 return -99;
12760 }
12761 if (pcap_file_set > 0)
12762 {
12763 if (vec_len (pcap_file) > 255)
12764 {
12765 errmsg ("pcap file name is too long");
12766 return -99;
12767 }
12768 }
12769
Damjan Marion7cd468a2016-12-19 23:05:39 +010012770 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012771 M (PG_CAPTURE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012772 mp->context = 0;
12773 mp->interface_id = ntohl (if_id);
12774 mp->is_enabled = enable;
12775 mp->count = ntohl (count);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012776 if (pcap_file_set != 0)
12777 {
Jakub Grajciardb863292020-01-30 14:14:15 +010012778 vl_api_vec_to_api_string (pcap_file, &mp->pcap_file_name);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012779 }
12780 vec_free (pcap_file);
12781
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012782 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012783 W (ret);
12784 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012785}
12786
12787int
12788api_pg_enable_disable (vat_main_t * vam)
12789{
12790 unformat_input_t *input = vam->input;
12791 vl_api_pg_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012792
12793 u8 enable = 1;
12794 u8 stream_name_set = 0;
12795 u8 *stream_name = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012796 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012797 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12798 {
12799 if (unformat (input, "stream %s", &stream_name))
12800 stream_name_set = 1;
12801 else if (unformat (input, "disable"))
12802 enable = 0;
12803 else
12804 break;
12805 }
12806
12807 if (stream_name_set > 0)
12808 {
12809 if (vec_len (stream_name) > 255)
12810 {
12811 errmsg ("stream name too long");
12812 return -99;
12813 }
12814 }
12815
Damjan Marion7cd468a2016-12-19 23:05:39 +010012816 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012817 M (PG_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012818 mp->context = 0;
12819 mp->is_enabled = enable;
12820 if (stream_name_set != 0)
12821 {
Jakub Grajciardb863292020-01-30 14:14:15 +010012822 vl_api_vec_to_api_string (stream_name, &mp->stream_name);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012823 }
12824 vec_free (stream_name);
12825
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012826 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012827 W (ret);
12828 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012829}
12830
12831int
Mohsin Kazmif382b062020-08-11 15:00:44 +020012832api_pg_interface_enable_disable_coalesce (vat_main_t * vam)
12833{
12834 unformat_input_t *input = vam->input;
12835 vl_api_pg_interface_enable_disable_coalesce_t *mp;
12836
12837 u32 sw_if_index = ~0;
12838 u8 enable = 1;
12839 int ret;
12840 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12841 {
12842 if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12843 ;
12844 else if (unformat (input, "sw_if_index %d", &sw_if_index))
12845 ;
12846 else if (unformat (input, "disable"))
12847 enable = 0;
12848 else
12849 break;
12850 }
12851
12852 if (sw_if_index == ~0)
12853 {
12854 errmsg ("Interface required but not specified");
12855 return -99;
12856 }
12857
12858 /* Construct the API message */
12859 M (PG_INTERFACE_ENABLE_DISABLE_COALESCE, mp);
12860 mp->context = 0;
12861 mp->coalesce_enabled = enable;
12862 mp->sw_if_index = htonl (sw_if_index);
12863
12864 S (mp);
12865 W (ret);
12866 return ret;
12867}
12868
12869int
Damjan Marion7cd468a2016-12-19 23:05:39 +010012870api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
12871{
12872 unformat_input_t *input = vam->input;
12873 vl_api_ip_source_and_port_range_check_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012874
12875 u16 *low_ports = 0;
12876 u16 *high_ports = 0;
12877 u16 this_low;
12878 u16 this_hi;
Neale Ranns37029302018-08-10 05:30:06 -070012879 vl_api_prefix_t prefix;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012880 u32 tmp, tmp2;
12881 u8 prefix_set = 0;
12882 u32 vrf_id = ~0;
12883 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012884 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012885
12886 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12887 {
Neale Ranns37029302018-08-10 05:30:06 -070012888 if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
12889 prefix_set = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012890 else if (unformat (input, "vrf %d", &vrf_id))
12891 ;
12892 else if (unformat (input, "del"))
12893 is_add = 0;
12894 else if (unformat (input, "port %d", &tmp))
12895 {
12896 if (tmp == 0 || tmp > 65535)
12897 {
12898 errmsg ("port %d out of range", tmp);
12899 return -99;
12900 }
12901 this_low = tmp;
12902 this_hi = this_low + 1;
12903 vec_add1 (low_ports, this_low);
12904 vec_add1 (high_ports, this_hi);
12905 }
12906 else if (unformat (input, "range %d - %d", &tmp, &tmp2))
12907 {
12908 if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
12909 {
12910 errmsg ("incorrect range parameters");
12911 return -99;
12912 }
12913 this_low = tmp;
12914 /* Note: in debug CLI +1 is added to high before
12915 passing to real fn that does "the work"
12916 (ip_source_and_port_range_check_add_del).
12917 This fn is a wrapper around the binary API fn a
12918 control plane will call, which expects this increment
12919 to have occurred. Hence letting the binary API control
12920 plane fn do the increment for consistency between VAT
12921 and other control planes.
12922 */
12923 this_hi = tmp2;
12924 vec_add1 (low_ports, this_low);
12925 vec_add1 (high_ports, this_hi);
12926 }
12927 else
12928 break;
12929 }
12930
12931 if (prefix_set == 0)
12932 {
12933 errmsg ("<address>/<mask> not specified");
12934 return -99;
12935 }
12936
12937 if (vrf_id == ~0)
12938 {
12939 errmsg ("VRF ID required, not specified");
12940 return -99;
12941 }
12942
12943 if (vrf_id == 0)
12944 {
12945 errmsg
12946 ("VRF ID should not be default. Should be distinct VRF for this purpose.");
12947 return -99;
12948 }
12949
12950 if (vec_len (low_ports) == 0)
12951 {
12952 errmsg ("At least one port or port range required");
12953 return -99;
12954 }
12955
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012956 M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012957
12958 mp->is_add = is_add;
12959
Neale Ranns37029302018-08-10 05:30:06 -070012960 clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
Damjan Marion7cd468a2016-12-19 23:05:39 +010012961
Damjan Marion7cd468a2016-12-19 23:05:39 +010012962 mp->number_of_ranges = vec_len (low_ports);
12963
12964 clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
12965 vec_free (low_ports);
12966
12967 clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
12968 vec_free (high_ports);
12969
12970 mp->vrf_id = ntohl (vrf_id);
12971
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012972 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012973 W (ret);
12974 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012975}
12976
12977int
12978api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
12979{
12980 unformat_input_t *input = vam->input;
12981 vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012982 u32 sw_if_index = ~0;
12983 int vrf_set = 0;
12984 u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
12985 u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
12986 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012987 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012988
12989 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12990 {
12991 if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12992 ;
12993 else if (unformat (input, "sw_if_index %d", &sw_if_index))
12994 ;
12995 else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
12996 vrf_set = 1;
12997 else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
12998 vrf_set = 1;
12999 else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
13000 vrf_set = 1;
13001 else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
13002 vrf_set = 1;
13003 else if (unformat (input, "del"))
13004 is_add = 0;
13005 else
13006 break;
13007 }
13008
13009 if (sw_if_index == ~0)
13010 {
13011 errmsg ("Interface required but not specified");
13012 return -99;
13013 }
13014
13015 if (vrf_set == 0)
13016 {
13017 errmsg ("VRF ID required but not specified");
13018 return -99;
13019 }
13020
13021 if (tcp_out_vrf_id == 0
13022 || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
13023 {
13024 errmsg
13025 ("VRF ID should not be default. Should be distinct VRF for this purpose.");
13026 return -99;
13027 }
13028
13029 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013030 M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013031
13032 mp->sw_if_index = ntohl (sw_if_index);
13033 mp->is_add = is_add;
13034 mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
13035 mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
13036 mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
13037 mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
13038
13039 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013040 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013041
13042 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060013043 W (ret);
13044 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013045}
13046
13047static int
Pavel Kotuceke88865d2018-11-28 07:42:11 +010013048api_set_punt (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010013049{
13050 unformat_input_t *i = vam->input;
Neale Ranns50f0ac02019-05-15 02:13:37 -070013051 vl_api_address_family_t af;
Pavel Kotuceke88865d2018-11-28 07:42:11 +010013052 vl_api_set_punt_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013053 u32 protocol = ~0;
13054 u32 port = ~0;
13055 int is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013056 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013057
13058 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13059 {
Neale Ranns50f0ac02019-05-15 02:13:37 -070013060 if (unformat (i, "%U", unformat_vl_api_address_family, &af))
Damjan Marion7cd468a2016-12-19 23:05:39 +010013061 ;
13062 else if (unformat (i, "protocol %d", &protocol))
13063 ;
13064 else if (unformat (i, "port %d", &port))
13065 ;
13066 else if (unformat (i, "del"))
13067 is_add = 0;
13068 else
13069 {
13070 clib_warning ("parse error '%U'", format_unformat_error, i);
13071 return -99;
13072 }
13073 }
13074
Pavel Kotuceke88865d2018-11-28 07:42:11 +010013075 M (SET_PUNT, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013076
13077 mp->is_add = (u8) is_add;
Neale Ranns50f0ac02019-05-15 02:13:37 -070013078 mp->punt.type = PUNT_API_TYPE_L4;
13079 mp->punt.punt.l4.af = af;
13080 mp->punt.punt.l4.protocol = (u8) protocol;
13081 mp->punt.punt.l4.port = htons ((u16) port);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013082
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013083 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013084 W (ret);
13085 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013086}
13087
Damjan Marion7cd468a2016-12-19 23:05:39 +010013088static int
13089api_delete_subif (vat_main_t * vam)
13090{
13091 unformat_input_t *i = vam->input;
13092 vl_api_delete_subif_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013093 u32 sw_if_index = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013094 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013095
13096 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13097 {
13098 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13099 ;
13100 if (unformat (i, "sw_if_index %d", &sw_if_index))
13101 ;
13102 else
13103 break;
13104 }
13105
13106 if (sw_if_index == ~0)
13107 {
13108 errmsg ("missing sw_if_index");
13109 return -99;
13110 }
13111
13112 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013113 M (DELETE_SUBIF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013114 mp->sw_if_index = ntohl (sw_if_index);
13115
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013116 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013117 W (ret);
13118 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013119}
13120
13121#define foreach_pbb_vtr_op \
13122_("disable", L2_VTR_DISABLED) \
13123_("pop", L2_VTR_POP_2) \
13124_("push", L2_VTR_PUSH_2)
13125
13126static int
13127api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
13128{
13129 unformat_input_t *i = vam->input;
13130 vl_api_l2_interface_pbb_tag_rewrite_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013131 u32 sw_if_index = ~0, vtr_op = ~0;
13132 u16 outer_tag = ~0;
13133 u8 dmac[6], smac[6];
13134 u8 dmac_set = 0, smac_set = 0;
13135 u16 vlanid = 0;
13136 u32 sid = ~0;
13137 u32 tmp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013138 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013139
13140 /* Shut up coverity */
Dave Barachb7b92992018-10-17 10:38:51 -040013141 clib_memset (dmac, 0, sizeof (dmac));
13142 clib_memset (smac, 0, sizeof (smac));
Damjan Marion7cd468a2016-12-19 23:05:39 +010013143
13144 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13145 {
13146 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13147 ;
13148 else if (unformat (i, "sw_if_index %d", &sw_if_index))
13149 ;
13150 else if (unformat (i, "vtr_op %d", &vtr_op))
13151 ;
13152#define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
13153 foreach_pbb_vtr_op
13154#undef _
13155 else if (unformat (i, "translate_pbb_stag"))
13156 {
13157 if (unformat (i, "%d", &tmp))
13158 {
13159 vtr_op = L2_VTR_TRANSLATE_2_1;
13160 outer_tag = tmp;
13161 }
13162 else
13163 {
13164 errmsg
13165 ("translate_pbb_stag operation requires outer tag definition");
13166 return -99;
13167 }
13168 }
13169 else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
13170 dmac_set++;
13171 else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
13172 smac_set++;
13173 else if (unformat (i, "sid %d", &sid))
13174 ;
13175 else if (unformat (i, "vlanid %d", &tmp))
13176 vlanid = tmp;
13177 else
13178 {
13179 clib_warning ("parse error '%U'", format_unformat_error, i);
13180 return -99;
13181 }
13182 }
13183
13184 if ((sw_if_index == ~0) || (vtr_op == ~0))
13185 {
13186 errmsg ("missing sw_if_index or vtr operation");
13187 return -99;
13188 }
13189 if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
13190 && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
13191 {
13192 errmsg
13193 ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
13194 return -99;
13195 }
13196
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013197 M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013198 mp->sw_if_index = ntohl (sw_if_index);
13199 mp->vtr_op = ntohl (vtr_op);
13200 mp->outer_tag = ntohs (outer_tag);
13201 clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
13202 clib_memcpy (mp->b_smac, smac, sizeof (smac));
13203 mp->b_vlanid = ntohs (vlanid);
13204 mp->i_sid = ntohl (sid);
13205
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013206 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013207 W (ret);
13208 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013209}
13210
13211static int
13212api_flow_classify_set_interface (vat_main_t * vam)
13213{
13214 unformat_input_t *i = vam->input;
13215 vl_api_flow_classify_set_interface_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013216 u32 sw_if_index;
13217 int sw_if_index_set;
13218 u32 ip4_table_index = ~0;
13219 u32 ip6_table_index = ~0;
13220 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013221 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013222
13223 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13224 {
13225 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13226 sw_if_index_set = 1;
13227 else if (unformat (i, "sw_if_index %d", &sw_if_index))
13228 sw_if_index_set = 1;
13229 else if (unformat (i, "del"))
13230 is_add = 0;
13231 else if (unformat (i, "ip4-table %d", &ip4_table_index))
13232 ;
13233 else if (unformat (i, "ip6-table %d", &ip6_table_index))
13234 ;
13235 else
13236 {
13237 clib_warning ("parse error '%U'", format_unformat_error, i);
13238 return -99;
13239 }
13240 }
13241
13242 if (sw_if_index_set == 0)
13243 {
13244 errmsg ("missing interface name or sw_if_index");
13245 return -99;
13246 }
13247
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013248 M (FLOW_CLASSIFY_SET_INTERFACE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013249
13250 mp->sw_if_index = ntohl (sw_if_index);
13251 mp->ip4_table_index = ntohl (ip4_table_index);
13252 mp->ip6_table_index = ntohl (ip6_table_index);
13253 mp->is_add = is_add;
13254
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013255 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013256 W (ret);
13257 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013258}
13259
13260static int
13261api_flow_classify_dump (vat_main_t * vam)
13262{
13263 unformat_input_t *i = vam->input;
13264 vl_api_flow_classify_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060013265 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013266 u8 type = FLOW_CLASSIFY_N_TABLES;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013267 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013268
13269 if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
13270 ;
13271 else
13272 {
13273 errmsg ("classify table type must be specified");
13274 return -99;
13275 }
13276
13277 if (!vam->json_output)
13278 {
13279 print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
13280 }
13281
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013282 M (FLOW_CLASSIFY_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013283 mp->type = type;
13284 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013285 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013286
13287 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040013288 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060013289 S (mp_ping);
13290
Damjan Marion7cd468a2016-12-19 23:05:39 +010013291 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060013292 W (ret);
13293 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013294}
13295
13296static int
13297api_feature_enable_disable (vat_main_t * vam)
13298{
13299 unformat_input_t *i = vam->input;
13300 vl_api_feature_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013301 u8 *arc_name = 0;
13302 u8 *feature_name = 0;
13303 u32 sw_if_index = ~0;
13304 u8 enable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013305 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013306
13307 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13308 {
13309 if (unformat (i, "arc_name %s", &arc_name))
13310 ;
13311 else if (unformat (i, "feature_name %s", &feature_name))
13312 ;
13313 else
13314 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13315 ;
13316 else if (unformat (i, "sw_if_index %d", &sw_if_index))
13317 ;
13318 else if (unformat (i, "disable"))
13319 enable = 0;
13320 else
13321 break;
13322 }
13323
13324 if (arc_name == 0)
13325 {
13326 errmsg ("missing arc name");
13327 return -99;
13328 }
13329 if (vec_len (arc_name) > 63)
13330 {
13331 errmsg ("arc name too long");
13332 }
13333
13334 if (feature_name == 0)
13335 {
13336 errmsg ("missing feature name");
13337 return -99;
13338 }
13339 if (vec_len (feature_name) > 63)
13340 {
13341 errmsg ("feature name too long");
13342 }
13343
13344 if (sw_if_index == ~0)
13345 {
13346 errmsg ("missing interface name or sw_if_index");
13347 return -99;
13348 }
13349
13350 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013351 M (FEATURE_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013352 mp->sw_if_index = ntohl (sw_if_index);
13353 mp->enable = enable;
13354 clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
13355 clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
13356 vec_free (arc_name);
13357 vec_free (feature_name);
13358
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013359 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013360 W (ret);
13361 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013362}
13363
13364static int
Mohsin Kazmi29467b52019-10-08 19:42:38 +020013365api_feature_gso_enable_disable (vat_main_t * vam)
13366{
13367 unformat_input_t *i = vam->input;
13368 vl_api_feature_gso_enable_disable_t *mp;
13369 u32 sw_if_index = ~0;
13370 u8 enable = 1;
13371 int ret;
13372
13373 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13374 {
13375 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13376 ;
13377 else if (unformat (i, "sw_if_index %d", &sw_if_index))
13378 ;
13379 else if (unformat (i, "enable"))
13380 enable = 1;
13381 else if (unformat (i, "disable"))
13382 enable = 0;
13383 else
13384 break;
13385 }
13386
13387 if (sw_if_index == ~0)
13388 {
13389 errmsg ("missing interface name or sw_if_index");
13390 return -99;
13391 }
13392
13393 /* Construct the API message */
13394 M (FEATURE_GSO_ENABLE_DISABLE, mp);
13395 mp->sw_if_index = ntohl (sw_if_index);
13396 mp->enable_disable = enable;
13397
13398 S (mp);
13399 W (ret);
13400 return ret;
13401}
13402
13403static int
Damjan Marion7cd468a2016-12-19 23:05:39 +010013404api_sw_interface_tag_add_del (vat_main_t * vam)
13405{
13406 unformat_input_t *i = vam->input;
13407 vl_api_sw_interface_tag_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013408 u32 sw_if_index = ~0;
13409 u8 *tag = 0;
13410 u8 enable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013411 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013412
13413 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13414 {
13415 if (unformat (i, "tag %s", &tag))
13416 ;
13417 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13418 ;
13419 else if (unformat (i, "sw_if_index %d", &sw_if_index))
13420 ;
13421 else if (unformat (i, "del"))
13422 enable = 0;
13423 else
13424 break;
13425 }
13426
13427 if (sw_if_index == ~0)
13428 {
13429 errmsg ("missing interface name or sw_if_index");
13430 return -99;
13431 }
13432
13433 if (enable && (tag == 0))
13434 {
13435 errmsg ("no tag specified");
13436 return -99;
13437 }
13438
13439 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013440 M (SW_INTERFACE_TAG_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013441 mp->sw_if_index = ntohl (sw_if_index);
13442 mp->is_add = enable;
13443 if (enable)
Ole Troane5ff5a32019-08-23 22:55:18 +020013444 strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013445 vec_free (tag);
13446
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013447 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013448 W (ret);
13449 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013450}
13451
Matthew Smithe0792fd2019-07-12 11:48:24 -050013452static int
13453api_sw_interface_add_del_mac_address (vat_main_t * vam)
13454{
13455 unformat_input_t *i = vam->input;
13456 vl_api_mac_address_t mac = { 0 };
13457 vl_api_sw_interface_add_del_mac_address_t *mp;
13458 u32 sw_if_index = ~0;
13459 u8 is_add = 1;
13460 u8 mac_set = 0;
13461 int ret;
13462
13463 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13464 {
13465 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13466 ;
13467 else if (unformat (i, "sw_if_index %d", &sw_if_index))
13468 ;
13469 else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
13470 mac_set++;
13471 else if (unformat (i, "del"))
13472 is_add = 0;
13473 else
13474 break;
13475 }
13476
13477 if (sw_if_index == ~0)
13478 {
13479 errmsg ("missing interface name or sw_if_index");
13480 return -99;
13481 }
13482
13483 if (!mac_set)
13484 {
13485 errmsg ("missing MAC address");
13486 return -99;
13487 }
13488
13489 /* Construct the API message */
13490 M (SW_INTERFACE_ADD_DEL_MAC_ADDRESS, mp);
13491 mp->sw_if_index = ntohl (sw_if_index);
13492 mp->is_add = is_add;
13493 clib_memcpy (&mp->addr, &mac, sizeof (mac));
13494
13495 S (mp);
13496 W (ret);
13497 return ret;
13498}
13499
Damjan Marion7cd468a2016-12-19 23:05:39 +010013500static void vl_api_l2_xconnect_details_t_handler
13501 (vl_api_l2_xconnect_details_t * mp)
13502{
13503 vat_main_t *vam = &vat_main;
13504
13505 print (vam->ofp, "%15d%15d",
13506 ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
13507}
13508
13509static void vl_api_l2_xconnect_details_t_handler_json
13510 (vl_api_l2_xconnect_details_t * mp)
13511{
13512 vat_main_t *vam = &vat_main;
13513 vat_json_node_t *node = NULL;
13514
13515 if (VAT_JSON_ARRAY != vam->json_tree.type)
13516 {
13517 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13518 vat_json_init_array (&vam->json_tree);
13519 }
13520 node = vat_json_array_add (&vam->json_tree);
13521
13522 vat_json_init_object (node);
13523 vat_json_object_add_uint (node, "rx_sw_if_index",
13524 ntohl (mp->rx_sw_if_index));
13525 vat_json_object_add_uint (node, "tx_sw_if_index",
13526 ntohl (mp->tx_sw_if_index));
13527}
13528
13529static int
13530api_l2_xconnect_dump (vat_main_t * vam)
13531{
13532 vl_api_l2_xconnect_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060013533 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013534 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013535
13536 if (!vam->json_output)
13537 {
13538 print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
13539 }
13540
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013541 M (L2_XCONNECT_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013542
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013543 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013544
13545 /* Use a control ping for synchronization */
Dave Barach59b25652017-09-10 15:04:27 -040013546 MPING (CONTROL_PING, mp_ping);
Jon Loeliger2d23eca2017-02-01 13:09:58 -060013547 S (mp_ping);
13548
Jon Loeliger56c7b012017-02-01 12:31:41 -060013549 W (ret);
13550 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013551}
13552
13553static int
Ole Troand7231612018-06-07 10:17:57 +020013554api_hw_interface_set_mtu (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010013555{
13556 unformat_input_t *i = vam->input;
Ole Troand7231612018-06-07 10:17:57 +020013557 vl_api_hw_interface_set_mtu_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013558 u32 sw_if_index = ~0;
13559 u32 mtu = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013560 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013561
13562 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13563 {
13564 if (unformat (i, "mtu %d", &mtu))
13565 ;
13566 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13567 ;
13568 else if (unformat (i, "sw_if_index %d", &sw_if_index))
13569 ;
13570 else
13571 break;
13572 }
13573
13574 if (sw_if_index == ~0)
13575 {
13576 errmsg ("missing interface name or sw_if_index");
13577 return -99;
13578 }
13579
13580 if (mtu == 0)
13581 {
13582 errmsg ("no mtu specified");
13583 return -99;
13584 }
13585
13586 /* Construct the API message */
Ole Troand7231612018-06-07 10:17:57 +020013587 M (HW_INTERFACE_SET_MTU, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013588 mp->sw_if_index = ntohl (sw_if_index);
13589 mp->mtu = ntohs ((u16) mtu);
13590
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013591 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013592 W (ret);
13593 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013594}
13595
Pavel Kotucek6899a302017-06-08 08:46:10 +020013596static int
13597api_p2p_ethernet_add (vat_main_t * vam)
13598{
13599 unformat_input_t *i = vam->input;
13600 vl_api_p2p_ethernet_add_t *mp;
13601 u32 parent_if_index = ~0;
Pavel Kotucek15ac81c2017-06-20 14:00:26 +020013602 u32 sub_id = ~0;
Pavel Kotucek6899a302017-06-08 08:46:10 +020013603 u8 remote_mac[6];
13604 u8 mac_set = 0;
13605 int ret;
13606
Dave Barachb7b92992018-10-17 10:38:51 -040013607 clib_memset (remote_mac, 0, sizeof (remote_mac));
Pavel Kotucek6899a302017-06-08 08:46:10 +020013608 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13609 {
13610 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
13611 ;
13612 else if (unformat (i, "sw_if_index %d", &parent_if_index))
13613 ;
13614 else
13615 if (unformat
13616 (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
13617 mac_set++;
Pavel Kotucek15ac81c2017-06-20 14:00:26 +020013618 else if (unformat (i, "sub_id %d", &sub_id))
13619 ;
Pavel Kotucek6899a302017-06-08 08:46:10 +020013620 else
13621 {
13622 clib_warning ("parse error '%U'", format_unformat_error, i);
13623 return -99;
13624 }
13625 }
13626
13627 if (parent_if_index == ~0)
13628 {
13629 errmsg ("missing interface name or sw_if_index");
13630 return -99;
13631 }
13632 if (mac_set == 0)
13633 {
13634 errmsg ("missing remote mac address");
13635 return -99;
13636 }
Pavel Kotucek15ac81c2017-06-20 14:00:26 +020013637 if (sub_id == ~0)
13638 {
13639 errmsg ("missing sub-interface id");
13640 return -99;
13641 }
Pavel Kotucek6899a302017-06-08 08:46:10 +020013642
13643 M (P2P_ETHERNET_ADD, mp);
13644 mp->parent_if_index = ntohl (parent_if_index);
Pavel Kotucek15ac81c2017-06-20 14:00:26 +020013645 mp->subif_id = ntohl (sub_id);
Pavel Kotucek6899a302017-06-08 08:46:10 +020013646 clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
13647
13648 S (mp);
13649 W (ret);
13650 return ret;
13651}
13652
13653static int
13654api_p2p_ethernet_del (vat_main_t * vam)
13655{
13656 unformat_input_t *i = vam->input;
13657 vl_api_p2p_ethernet_del_t *mp;
13658 u32 parent_if_index = ~0;
13659 u8 remote_mac[6];
13660 u8 mac_set = 0;
13661 int ret;
13662
Dave Barachb7b92992018-10-17 10:38:51 -040013663 clib_memset (remote_mac, 0, sizeof (remote_mac));
Pavel Kotucek6899a302017-06-08 08:46:10 +020013664 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13665 {
13666 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
13667 ;
13668 else if (unformat (i, "sw_if_index %d", &parent_if_index))
13669 ;
13670 else
13671 if (unformat
13672 (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
13673 mac_set++;
13674 else
13675 {
13676 clib_warning ("parse error '%U'", format_unformat_error, i);
13677 return -99;
13678 }
13679 }
13680
13681 if (parent_if_index == ~0)
13682 {
13683 errmsg ("missing interface name or sw_if_index");
13684 return -99;
13685 }
13686 if (mac_set == 0)
13687 {
13688 errmsg ("missing remote mac address");
13689 return -99;
13690 }
13691
13692 M (P2P_ETHERNET_DEL, mp);
13693 mp->parent_if_index = ntohl (parent_if_index);
13694 clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
13695
13696 S (mp);
13697 W (ret);
13698 return ret;
13699}
Damjan Marion7cd468a2016-12-19 23:05:39 +010013700
13701static int
Dave Barach3bbcfab2017-08-15 19:03:44 -040013702api_tcp_configure_src_addresses (vat_main_t * vam)
13703{
13704 vl_api_tcp_configure_src_addresses_t *mp;
13705 unformat_input_t *i = vam->input;
Neale Rannscbe25aa2019-09-30 10:53:31 +000013706 vl_api_address_t first, last;
Dave Barach3bbcfab2017-08-15 19:03:44 -040013707 u8 range_set = 0;
13708 u32 vrf_id = 0;
13709 int ret;
13710
13711 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13712 {
13713 if (unformat (i, "%U - %U",
Neale Rannscbe25aa2019-09-30 10:53:31 +000013714 unformat_vl_api_address, &first,
13715 unformat_vl_api_address, &last))
Dave Barach3bbcfab2017-08-15 19:03:44 -040013716 {
13717 if (range_set)
13718 {
13719 errmsg ("one range per message (range already set)");
13720 return -99;
13721 }
13722 range_set = 1;
13723 }
Dave Barach3bbcfab2017-08-15 19:03:44 -040013724 else if (unformat (i, "vrf %d", &vrf_id))
13725 ;
13726 else
13727 break;
13728 }
13729
13730 if (range_set == 0)
13731 {
13732 errmsg ("address range not set");
13733 return -99;
13734 }
13735
13736 M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
Neale Rannscbe25aa2019-09-30 10:53:31 +000013737
Dave Barach3bbcfab2017-08-15 19:03:44 -040013738 mp->vrf_id = ntohl (vrf_id);
Neale Rannscbe25aa2019-09-30 10:53:31 +000013739 clib_memcpy (&mp->first_address, &first, sizeof (first));
13740 clib_memcpy (&mp->last_address, &last, sizeof (last));
13741
Dave Barach3bbcfab2017-08-15 19:03:44 -040013742 S (mp);
13743 W (ret);
13744 return ret;
13745}
13746
Florin Coras6e8c6672017-11-10 09:03:54 -080013747static void vl_api_app_namespace_add_del_reply_t_handler
13748 (vl_api_app_namespace_add_del_reply_t * mp)
13749{
13750 vat_main_t *vam = &vat_main;
13751 i32 retval = ntohl (mp->retval);
13752 if (vam->async_mode)
13753 {
13754 vam->async_errors += (retval < 0);
13755 }
13756 else
13757 {
13758 vam->retval = retval;
13759 if (retval == 0)
13760 errmsg ("app ns index %d\n", ntohl (mp->appns_index));
13761 vam->result_ready = 1;
13762 }
13763}
13764
13765static void vl_api_app_namespace_add_del_reply_t_handler_json
13766 (vl_api_app_namespace_add_del_reply_t * mp)
13767{
13768 vat_main_t *vam = &vat_main;
13769 vat_json_node_t node;
13770
13771 vat_json_init_object (&node);
13772 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
13773 vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
13774
13775 vat_json_print (vam->ofp, &node);
13776 vat_json_free (&node);
13777
13778 vam->retval = ntohl (mp->retval);
13779 vam->result_ready = 1;
13780}
13781
Dave Barach3bbcfab2017-08-15 19:03:44 -040013782static int
Florin Corascea194d2017-10-02 00:18:51 -070013783api_app_namespace_add_del (vat_main_t * vam)
13784{
13785 vl_api_app_namespace_add_del_t *mp;
13786 unformat_input_t *i = vam->input;
13787 u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
13788 u32 sw_if_index, ip4_fib_id, ip6_fib_id;
13789 u64 secret;
13790 int ret;
13791
13792 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13793 {
13794 if (unformat (i, "id %_%v%_", &ns_id))
13795 ;
13796 else if (unformat (i, "secret %lu", &secret))
13797 secret_set = 1;
13798 else if (unformat (i, "sw_if_index %d", &sw_if_index))
13799 sw_if_index_set = 1;
13800 else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
13801 ;
13802 else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
13803 ;
13804 else
13805 break;
13806 }
13807 if (!ns_id || !secret_set || !sw_if_index_set)
13808 {
13809 errmsg ("namespace id, secret and sw_if_index must be set");
13810 return -99;
13811 }
13812 if (vec_len (ns_id) > 64)
13813 {
13814 errmsg ("namespace id too long");
13815 return -99;
13816 }
13817 M (APP_NAMESPACE_ADD_DEL, mp);
13818
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010013819 vl_api_vec_to_api_string (ns_id, &mp->namespace_id);
Florin Coras9a9adb22017-10-26 08:16:59 -070013820 mp->secret = clib_host_to_net_u64 (secret);
Florin Corascea194d2017-10-02 00:18:51 -070013821 mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
13822 mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
13823 mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
13824 vec_free (ns_id);
13825 S (mp);
13826 W (ret);
13827 return ret;
13828}
13829
13830static int
Florin Coras90a63982017-12-19 04:50:01 -080013831api_sock_init_shm (vat_main_t * vam)
13832{
13833#if VPP_API_TEST_BUILTIN == 0
13834 unformat_input_t *i = vam->input;
13835 vl_api_shm_elem_config_t *config = 0;
13836 u64 size = 64 << 20;
13837 int rv;
13838
13839 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13840 {
13841 if (unformat (i, "size %U", unformat_memory_size, &size))
13842 ;
13843 else
13844 break;
13845 }
13846
Dave Barach78958722018-05-10 16:44:27 -040013847 /*
13848 * Canned custom ring allocator config.
13849 * Should probably parse all of this
13850 */
13851 vec_validate (config, 6);
Florin Coras90a63982017-12-19 04:50:01 -080013852 config[0].type = VL_API_VLIB_RING;
Florin Coras90a63982017-12-19 04:50:01 -080013853 config[0].size = 256;
Dave Barach78958722018-05-10 16:44:27 -040013854 config[0].count = 32;
13855
13856 config[1].type = VL_API_VLIB_RING;
Florin Coras90a63982017-12-19 04:50:01 -080013857 config[1].size = 1024;
Dave Barach78958722018-05-10 16:44:27 -040013858 config[1].count = 16;
13859
13860 config[2].type = VL_API_VLIB_RING;
Florin Coras90a63982017-12-19 04:50:01 -080013861 config[2].size = 4096;
Dave Barach78958722018-05-10 16:44:27 -040013862 config[2].count = 2;
13863
13864 config[3].type = VL_API_CLIENT_RING;
13865 config[3].size = 256;
13866 config[3].count = 32;
13867
13868 config[4].type = VL_API_CLIENT_RING;
13869 config[4].size = 1024;
13870 config[4].count = 16;
13871
13872 config[5].type = VL_API_CLIENT_RING;
13873 config[5].size = 4096;
13874 config[5].count = 2;
13875
13876 config[6].type = VL_API_QUEUE;
13877 config[6].count = 128;
13878 config[6].size = sizeof (uword);
13879
Tomasz Kulasek97dcf5b2019-01-31 18:26:32 +010013880 rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
Florin Coras90a63982017-12-19 04:50:01 -080013881 if (!rv)
13882 vam->client_index_invalid = 1;
13883 return rv;
13884#else
13885 return -99;
13886#endif
13887}
13888
Florin Coras6c36f532017-11-03 18:32:34 -070013889static void
13890vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
13891{
13892 vat_main_t *vam = &vat_main;
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010013893 fib_prefix_t lcl, rmt;
Florin Coras6c36f532017-11-03 18:32:34 -070013894
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010013895 ip_prefix_decode (&mp->lcl, &lcl);
13896 ip_prefix_decode (&mp->rmt, &rmt);
13897
13898 if (lcl.fp_proto == FIB_PROTOCOL_IP4)
Florin Coras6c36f532017-11-03 18:32:34 -070013899 {
Florin Corasc97a7392017-11-05 23:07:07 -080013900 print (vam->ofp,
13901 "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
Steven85dbac02017-11-07 16:29:53 -080013902 clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010013903 mp->scope, format_ip4_address, &lcl.fp_addr.ip4, lcl.fp_len,
Steven85dbac02017-11-07 16:29:53 -080013904 clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010013905 &rmt.fp_addr.ip4, rmt.fp_len,
13906 clib_net_to_host_u16 (mp->rmt_port),
Steven85dbac02017-11-07 16:29:53 -080013907 clib_net_to_host_u32 (mp->action_index), mp->tag);
Florin Coras6c36f532017-11-03 18:32:34 -070013908 }
13909 else
13910 {
Florin Corasc97a7392017-11-05 23:07:07 -080013911 print (vam->ofp,
13912 "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
Steven85dbac02017-11-07 16:29:53 -080013913 clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010013914 mp->scope, format_ip6_address, &lcl.fp_addr.ip6, lcl.fp_len,
Steven85dbac02017-11-07 16:29:53 -080013915 clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010013916 &rmt.fp_addr.ip6, rmt.fp_len,
13917 clib_net_to_host_u16 (mp->rmt_port),
Steven85dbac02017-11-07 16:29:53 -080013918 clib_net_to_host_u32 (mp->action_index), mp->tag);
Florin Coras6c36f532017-11-03 18:32:34 -070013919 }
13920}
13921
13922static void
13923vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
13924 mp)
13925{
13926 vat_main_t *vam = &vat_main;
13927 vat_json_node_t *node = NULL;
13928 struct in6_addr ip6;
13929 struct in_addr ip4;
13930
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010013931 fib_prefix_t lcl, rmt;
13932
13933 ip_prefix_decode (&mp->lcl, &lcl);
13934 ip_prefix_decode (&mp->rmt, &rmt);
13935
Florin Coras6c36f532017-11-03 18:32:34 -070013936 if (VAT_JSON_ARRAY != vam->json_tree.type)
13937 {
13938 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13939 vat_json_init_array (&vam->json_tree);
13940 }
13941 node = vat_json_array_add (&vam->json_tree);
13942 vat_json_init_object (node);
13943
Florin Coras6c36f532017-11-03 18:32:34 -070013944 vat_json_object_add_uint (node, "appns_index",
13945 clib_net_to_host_u32 (mp->appns_index));
13946 vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
13947 vat_json_object_add_uint (node, "scope", mp->scope);
13948 vat_json_object_add_uint (node, "action_index",
13949 clib_net_to_host_u32 (mp->action_index));
13950 vat_json_object_add_uint (node, "lcl_port",
13951 clib_net_to_host_u16 (mp->lcl_port));
13952 vat_json_object_add_uint (node, "rmt_port",
13953 clib_net_to_host_u16 (mp->rmt_port));
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010013954 vat_json_object_add_uint (node, "lcl_plen", lcl.fp_len);
13955 vat_json_object_add_uint (node, "rmt_plen", rmt.fp_len);
Florin Corasc97a7392017-11-05 23:07:07 -080013956 vat_json_object_add_string_copy (node, "tag", mp->tag);
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010013957 if (lcl.fp_proto == FIB_PROTOCOL_IP4)
Florin Coras6c36f532017-11-03 18:32:34 -070013958 {
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010013959 clib_memcpy (&ip4, &lcl.fp_addr.ip4, sizeof (ip4));
Florin Coras6c36f532017-11-03 18:32:34 -070013960 vat_json_object_add_ip4 (node, "lcl_ip", ip4);
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010013961 clib_memcpy (&ip4, &rmt.fp_addr.ip4, sizeof (ip4));
Florin Coras6c36f532017-11-03 18:32:34 -070013962 vat_json_object_add_ip4 (node, "rmt_ip", ip4);
13963 }
13964 else
13965 {
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010013966 clib_memcpy (&ip6, &lcl.fp_addr.ip6, sizeof (ip6));
Florin Coras6c36f532017-11-03 18:32:34 -070013967 vat_json_object_add_ip6 (node, "lcl_ip", ip6);
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010013968 clib_memcpy (&ip6, &rmt.fp_addr.ip6, sizeof (ip6));
Florin Coras6c36f532017-11-03 18:32:34 -070013969 vat_json_object_add_ip6 (node, "rmt_ip", ip6);
13970 }
13971}
13972
Florin Coras1c710452017-10-17 00:03:13 -070013973static int
13974api_session_rule_add_del (vat_main_t * vam)
13975{
13976 vl_api_session_rule_add_del_t *mp;
13977 unformat_input_t *i = vam->input;
13978 u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
13979 u32 appns_index = 0, scope = 0;
13980 ip4_address_t lcl_ip4, rmt_ip4;
13981 ip6_address_t lcl_ip6, rmt_ip6;
13982 u8 is_ip4 = 1, conn_set = 0;
Florin Corasc97a7392017-11-05 23:07:07 -080013983 u8 is_add = 1, *tag = 0;
Florin Coras1c710452017-10-17 00:03:13 -070013984 int ret;
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010013985 fib_prefix_t lcl, rmt;
Florin Coras1c710452017-10-17 00:03:13 -070013986
13987 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13988 {
13989 if (unformat (i, "del"))
13990 is_add = 0;
13991 else if (unformat (i, "add"))
13992 ;
13993 else if (unformat (i, "proto tcp"))
13994 proto = 0;
13995 else if (unformat (i, "proto udp"))
13996 proto = 1;
13997 else if (unformat (i, "appns %d", &appns_index))
13998 ;
13999 else if (unformat (i, "scope %d", &scope))
14000 ;
Florin Corasc97a7392017-11-05 23:07:07 -080014001 else if (unformat (i, "tag %_%v%_", &tag))
14002 ;
Florin Coras1c710452017-10-17 00:03:13 -070014003 else
14004 if (unformat
14005 (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
14006 &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
14007 &rmt_port))
14008 {
14009 is_ip4 = 1;
14010 conn_set = 1;
14011 }
14012 else
14013 if (unformat
14014 (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
14015 &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
14016 &rmt_port))
14017 {
14018 is_ip4 = 0;
14019 conn_set = 1;
14020 }
14021 else if (unformat (i, "action %d", &action))
14022 ;
14023 else
14024 break;
14025 }
14026 if (proto == ~0 || !conn_set || action == ~0)
14027 {
14028 errmsg ("transport proto, connection and action must be set");
14029 return -99;
14030 }
14031
14032 if (scope > 3)
14033 {
14034 errmsg ("scope should be 0-3");
14035 return -99;
14036 }
14037
14038 M (SESSION_RULE_ADD_DEL, mp);
14039
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014040 clib_memset (&lcl, 0, sizeof (lcl));
14041 clib_memset (&rmt, 0, sizeof (rmt));
14042 if (is_ip4)
14043 {
14044 ip_set (&lcl.fp_addr, &lcl_ip4, 1);
14045 ip_set (&rmt.fp_addr, &rmt_ip4, 1);
14046 lcl.fp_len = lcl_plen;
14047 rmt.fp_len = rmt_plen;
14048 }
14049 else
14050 {
14051 ip_set (&lcl.fp_addr, &lcl_ip6, 0);
14052 ip_set (&rmt.fp_addr, &rmt_ip6, 0);
14053 lcl.fp_len = lcl_plen;
14054 rmt.fp_len = rmt_plen;
14055 }
14056
14057
14058 ip_prefix_encode (&lcl, &mp->lcl);
14059 ip_prefix_encode (&rmt, &mp->rmt);
Florin Corasc97a7392017-11-05 23:07:07 -080014060 mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
14061 mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
Jakub Grajciarb4e5e502020-01-31 09:35:29 +010014062 mp->transport_proto =
14063 proto ? TRANSPORT_PROTO_API_UDP : TRANSPORT_PROTO_API_TCP;
Florin Coras1c710452017-10-17 00:03:13 -070014064 mp->action_index = clib_host_to_net_u32 (action);
14065 mp->appns_index = clib_host_to_net_u32 (appns_index);
14066 mp->scope = scope;
14067 mp->is_add = is_add;
Florin Corasc97a7392017-11-05 23:07:07 -080014068 if (tag)
14069 {
14070 clib_memcpy (mp->tag, tag, vec_len (tag));
14071 vec_free (tag);
14072 }
Florin Coras1c710452017-10-17 00:03:13 -070014073
14074 S (mp);
14075 W (ret);
14076 return ret;
14077}
Dave Barach65457162017-10-10 17:53:14 -040014078
14079static int
Florin Coras6c36f532017-11-03 18:32:34 -070014080api_session_rules_dump (vat_main_t * vam)
14081{
14082 vl_api_session_rules_dump_t *mp;
14083 vl_api_control_ping_t *mp_ping;
14084 int ret;
14085
14086 if (!vam->json_output)
14087 {
14088 print (vam->ofp, "%=20s", "Session Rules");
14089 }
14090
14091 M (SESSION_RULES_DUMP, mp);
14092 /* send it... */
14093 S (mp);
14094
14095 /* Use a control ping for synchronization */
14096 MPING (CONTROL_PING, mp_ping);
14097 S (mp_ping);
14098
14099 /* Wait for a reply... */
14100 W (ret);
14101 return ret;
14102}
14103
14104static int
Florin Coras595992c2017-11-06 17:17:08 -080014105api_ip_container_proxy_add_del (vat_main_t * vam)
14106{
14107 vl_api_ip_container_proxy_add_del_t *mp;
14108 unformat_input_t *i = vam->input;
Neale Ranns37029302018-08-10 05:30:06 -070014109 u32 sw_if_index = ~0;
14110 vl_api_prefix_t pfx = { };
Florin Coras595992c2017-11-06 17:17:08 -080014111 u8 is_add = 1;
14112 int ret;
14113
14114 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14115 {
14116 if (unformat (i, "del"))
14117 is_add = 0;
14118 else if (unformat (i, "add"))
14119 ;
Neale Ranns37029302018-08-10 05:30:06 -070014120 if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
14121 ;
Florin Coras595992c2017-11-06 17:17:08 -080014122 else if (unformat (i, "sw_if_index %u", &sw_if_index))
14123 ;
14124 else
14125 break;
14126 }
Paul Vinciguerraab055082019-06-06 14:07:55 -040014127 if (sw_if_index == ~0 || pfx.len == 0)
Florin Coras595992c2017-11-06 17:17:08 -080014128 {
14129 errmsg ("address and sw_if_index must be set");
14130 return -99;
14131 }
14132
14133 M (IP_CONTAINER_PROXY_ADD_DEL, mp);
14134
Florin Coras595992c2017-11-06 17:17:08 -080014135 mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
Florin Coras595992c2017-11-06 17:17:08 -080014136 mp->is_add = is_add;
Neale Ranns37029302018-08-10 05:30:06 -070014137 clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
Florin Coras595992c2017-11-06 17:17:08 -080014138
14139 S (mp);
14140 W (ret);
14141 return ret;
14142}
14143
14144static int
Igor Mikhailov (imichail)582caa32018-04-26 21:33:02 -070014145api_qos_record_enable_disable (vat_main_t * vam)
14146{
14147 unformat_input_t *i = vam->input;
14148 vl_api_qos_record_enable_disable_t *mp;
14149 u32 sw_if_index, qs = 0xff;
14150 u8 sw_if_index_set = 0;
14151 u8 enable = 1;
14152 int ret;
14153
14154 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14155 {
14156 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14157 sw_if_index_set = 1;
14158 else if (unformat (i, "sw_if_index %d", &sw_if_index))
14159 sw_if_index_set = 1;
14160 else if (unformat (i, "%U", unformat_qos_source, &qs))
14161 ;
14162 else if (unformat (i, "disable"))
14163 enable = 0;
14164 else
14165 {
14166 clib_warning ("parse error '%U'", format_unformat_error, i);
14167 return -99;
14168 }
14169 }
14170
14171 if (sw_if_index_set == 0)
14172 {
14173 errmsg ("missing interface name or sw_if_index");
14174 return -99;
14175 }
14176 if (qs == 0xff)
14177 {
14178 errmsg ("input location must be specified");
14179 return -99;
14180 }
14181
14182 M (QOS_RECORD_ENABLE_DISABLE, mp);
14183
Neale Ranns5281a902019-07-23 08:16:19 -070014184 mp->record.sw_if_index = ntohl (sw_if_index);
14185 mp->record.input_source = qs;
Igor Mikhailov (imichail)582caa32018-04-26 21:33:02 -070014186 mp->enable = enable;
14187
14188 S (mp);
14189 W (ret);
14190 return ret;
14191}
14192
Dave Barach048a4e52018-06-01 18:52:25 -040014193
Igor Mikhailov (imichail)582caa32018-04-26 21:33:02 -070014194static int
Damjan Marion7cd468a2016-12-19 23:05:39 +010014195q_or_quit (vat_main_t * vam)
14196{
Dave Barachdef19da2017-02-22 17:29:20 -050014197#if VPP_API_TEST_BUILTIN == 0
Damjan Marion7cd468a2016-12-19 23:05:39 +010014198 longjmp (vam->jump_buf, 1);
Dave Barachdef19da2017-02-22 17:29:20 -050014199#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +010014200 return 0; /* not so much */
14201}
14202
14203static int
14204q (vat_main_t * vam)
14205{
14206 return q_or_quit (vam);
14207}
14208
14209static int
14210quit (vat_main_t * vam)
14211{
14212 return q_or_quit (vam);
14213}
14214
14215static int
14216comment (vat_main_t * vam)
14217{
14218 return 0;
14219}
14220
14221static int
Dave Barachb09f4d02019-07-15 16:00:03 -040014222elog_save (vat_main_t * vam)
14223{
14224#if VPP_API_TEST_BUILTIN == 0
14225 elog_main_t *em = &vam->elog_main;
14226 unformat_input_t *i = vam->input;
14227 char *file, *chroot_file;
14228 clib_error_t *error;
14229
14230 if (!unformat (i, "%s", &file))
14231 {
14232 errmsg ("expected file name, got `%U'", format_unformat_error, i);
14233 return 0;
14234 }
14235
14236 /* It's fairly hard to get "../oopsie" through unformat; just in case */
14237 if (strstr (file, "..") || index (file, '/'))
14238 {
14239 errmsg ("illegal characters in filename '%s'", file);
14240 return 0;
14241 }
14242
14243 chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
14244
14245 vec_free (file);
14246
14247 errmsg ("Saving %wd of %wd events to %s",
14248 elog_n_events_in_buffer (em),
14249 elog_buffer_capacity (em), chroot_file);
14250
14251 error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
14252 vec_free (chroot_file);
14253
14254 if (error)
14255 clib_error_report (error);
14256#else
14257 errmsg ("Use the vpp event loger...");
14258#endif
14259
14260 return 0;
14261}
14262
14263static int
14264elog_setup (vat_main_t * vam)
14265{
14266#if VPP_API_TEST_BUILTIN == 0
14267 elog_main_t *em = &vam->elog_main;
14268 unformat_input_t *i = vam->input;
14269 u32 nevents = 128 << 10;
14270
14271 (void) unformat (i, "nevents %d", &nevents);
14272
14273 elog_init (em, nevents);
14274 vl_api_set_elog_main (em);
14275 vl_api_set_elog_trace_api_messages (1);
14276 errmsg ("Event logger initialized with %u events", nevents);
14277#else
14278 errmsg ("Use the vpp event loger...");
14279#endif
14280 return 0;
14281}
14282
14283static int
14284elog_enable (vat_main_t * vam)
14285{
14286#if VPP_API_TEST_BUILTIN == 0
14287 elog_main_t *em = &vam->elog_main;
14288
14289 elog_enable_disable (em, 1 /* enable */ );
14290 vl_api_set_elog_trace_api_messages (1);
14291 errmsg ("Event logger enabled...");
14292#else
14293 errmsg ("Use the vpp event loger...");
14294#endif
14295 return 0;
14296}
14297
14298static int
14299elog_disable (vat_main_t * vam)
14300{
14301#if VPP_API_TEST_BUILTIN == 0
14302 elog_main_t *em = &vam->elog_main;
14303
14304 elog_enable_disable (em, 0 /* enable */ );
14305 vl_api_set_elog_trace_api_messages (1);
14306 errmsg ("Event logger disabled...");
14307#else
14308 errmsg ("Use the vpp event loger...");
14309#endif
14310 return 0;
14311}
14312
14313static int
Dave Barach048a4e52018-06-01 18:52:25 -040014314statseg (vat_main_t * vam)
14315{
14316 ssvm_private_t *ssvmp = &vam->stat_segment;
14317 ssvm_shared_header_t *shared_header = ssvmp->sh;
14318 vlib_counter_t **counters;
14319 u64 thread0_index1_packets;
14320 u64 thread0_index1_bytes;
14321 f64 vector_rate, input_rate;
14322 uword *p;
14323
14324 uword *counter_vector_by_name;
14325 if (vam->stat_segment_lockp == 0)
14326 {
14327 errmsg ("Stat segment not mapped...");
14328 return -99;
14329 }
14330
14331 /* look up "/if/rx for sw_if_index 1 as a test */
14332
14333 clib_spinlock_lock (vam->stat_segment_lockp);
14334
14335 counter_vector_by_name = (uword *) shared_header->opaque[1];
14336
14337 p = hash_get_mem (counter_vector_by_name, "/if/rx");
14338 if (p == 0)
14339 {
14340 clib_spinlock_unlock (vam->stat_segment_lockp);
14341 errmsg ("/if/tx not found?");
14342 return -99;
14343 }
14344
14345 /* Fish per-thread vector of combined counters from shared memory */
14346 counters = (vlib_counter_t **) p[0];
14347
14348 if (vec_len (counters[0]) < 2)
14349 {
14350 clib_spinlock_unlock (vam->stat_segment_lockp);
14351 errmsg ("/if/tx vector length %d", vec_len (counters[0]));
14352 return -99;
14353 }
14354
14355 /* Read thread 0 sw_if_index 1 counter */
14356 thread0_index1_packets = counters[0][1].packets;
14357 thread0_index1_bytes = counters[0][1].bytes;
14358
14359 p = hash_get_mem (counter_vector_by_name, "vector_rate");
14360 if (p == 0)
14361 {
14362 clib_spinlock_unlock (vam->stat_segment_lockp);
14363 errmsg ("vector_rate not found?");
14364 return -99;
14365 }
14366
14367 vector_rate = *(f64 *) (p[0]);
14368 p = hash_get_mem (counter_vector_by_name, "input_rate");
14369 if (p == 0)
14370 {
14371 clib_spinlock_unlock (vam->stat_segment_lockp);
14372 errmsg ("input_rate not found?");
14373 return -99;
14374 }
14375 input_rate = *(f64 *) (p[0]);
14376
14377 clib_spinlock_unlock (vam->stat_segment_lockp);
14378
14379 print (vam->ofp, "vector_rate %.2f input_rate %.2f",
14380 vector_rate, input_rate);
14381 print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
14382 thread0_index1_packets, thread0_index1_bytes);
14383
14384 return 0;
14385}
14386
14387static int
Damjan Marion7cd468a2016-12-19 23:05:39 +010014388cmd_cmp (void *a1, void *a2)
14389{
14390 u8 **c1 = a1;
14391 u8 **c2 = a2;
14392
14393 return strcmp ((char *) (c1[0]), (char *) (c2[0]));
14394}
14395
14396static int
14397help (vat_main_t * vam)
14398{
14399 u8 **cmds = 0;
14400 u8 *name = 0;
14401 hash_pair_t *p;
14402 unformat_input_t *i = vam->input;
14403 int j;
14404
14405 if (unformat (i, "%s", &name))
14406 {
14407 uword *hs;
14408
14409 vec_add1 (name, 0);
14410
14411 hs = hash_get_mem (vam->help_by_name, name);
14412 if (hs)
14413 print (vam->ofp, "usage: %s %s", name, hs[0]);
14414 else
14415 print (vam->ofp, "No such msg / command '%s'", name);
14416 vec_free (name);
14417 return 0;
14418 }
14419
14420 print (vam->ofp, "Help is available for the following:");
14421
14422 /* *INDENT-OFF* */
14423 hash_foreach_pair (p, vam->function_by_name,
14424 ({
14425 vec_add1 (cmds, (u8 *)(p->key));
14426 }));
14427 /* *INDENT-ON* */
14428
14429 vec_sort_with_function (cmds, cmd_cmp);
14430
14431 for (j = 0; j < vec_len (cmds); j++)
14432 print (vam->ofp, "%s", cmds[j]);
14433
14434 vec_free (cmds);
14435 return 0;
14436}
14437
14438static int
14439set (vat_main_t * vam)
14440{
14441 u8 *name = 0, *value = 0;
14442 unformat_input_t *i = vam->input;
14443
14444 if (unformat (i, "%s", &name))
14445 {
14446 /* The input buffer is a vector, not a string. */
14447 value = vec_dup (i->buffer);
14448 vec_delete (value, i->index, 0);
14449 /* Almost certainly has a trailing newline */
14450 if (value[vec_len (value) - 1] == '\n')
14451 value[vec_len (value) - 1] = 0;
14452 /* Make sure it's a proper string, one way or the other */
14453 vec_add1 (value, 0);
14454 (void) clib_macro_set_value (&vam->macro_main,
14455 (char *) name, (char *) value);
14456 }
14457 else
14458 errmsg ("usage: set <name> <value>");
14459
14460 vec_free (name);
14461 vec_free (value);
14462 return 0;
14463}
14464
14465static int
14466unset (vat_main_t * vam)
14467{
14468 u8 *name = 0;
14469
14470 if (unformat (vam->input, "%s", &name))
14471 if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
14472 errmsg ("unset: %s wasn't set", name);
14473 vec_free (name);
14474 return 0;
14475}
14476
14477typedef struct
14478{
14479 u8 *name;
14480 u8 *value;
14481} macro_sort_t;
14482
14483
14484static int
14485macro_sort_cmp (void *a1, void *a2)
14486{
14487 macro_sort_t *s1 = a1;
14488 macro_sort_t *s2 = a2;
14489
14490 return strcmp ((char *) (s1->name), (char *) (s2->name));
14491}
14492
14493static int
14494dump_macro_table (vat_main_t * vam)
14495{
14496 macro_sort_t *sort_me = 0, *sm;
14497 int i;
14498 hash_pair_t *p;
14499
14500 /* *INDENT-OFF* */
14501 hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
14502 ({
14503 vec_add2 (sort_me, sm, 1);
14504 sm->name = (u8 *)(p->key);
14505 sm->value = (u8 *) (p->value[0]);
14506 }));
14507 /* *INDENT-ON* */
14508
14509 vec_sort_with_function (sort_me, macro_sort_cmp);
14510
14511 if (vec_len (sort_me))
14512 print (vam->ofp, "%-15s%s", "Name", "Value");
14513 else
14514 print (vam->ofp, "The macro table is empty...");
14515
14516 for (i = 0; i < vec_len (sort_me); i++)
14517 print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
14518 return 0;
14519}
14520
14521static int
14522dump_node_table (vat_main_t * vam)
14523{
14524 int i, j;
14525 vlib_node_t *node, *next_node;
14526
14527 if (vec_len (vam->graph_nodes) == 0)
14528 {
14529 print (vam->ofp, "Node table empty, issue get_node_graph...");
14530 return 0;
14531 }
14532
Dave Barach1ddbc012018-06-13 09:26:05 -040014533 for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
Damjan Marion7cd468a2016-12-19 23:05:39 +010014534 {
Dave Barach1ddbc012018-06-13 09:26:05 -040014535 node = vam->graph_nodes[0][i];
Damjan Marion7cd468a2016-12-19 23:05:39 +010014536 print (vam->ofp, "[%d] %s", i, node->name);
14537 for (j = 0; j < vec_len (node->next_nodes); j++)
14538 {
14539 if (node->next_nodes[j] != ~0)
14540 {
Dave Barach1ddbc012018-06-13 09:26:05 -040014541 next_node = vam->graph_nodes[0][node->next_nodes[j]];
Damjan Marion7cd468a2016-12-19 23:05:39 +010014542 print (vam->ofp, " [%d] %s", j, next_node->name);
14543 }
14544 }
14545 }
14546 return 0;
14547}
14548
14549static int
14550value_sort_cmp (void *a1, void *a2)
14551{
14552 name_sort_t *n1 = a1;
14553 name_sort_t *n2 = a2;
14554
14555 if (n1->value < n2->value)
14556 return -1;
14557 if (n1->value > n2->value)
14558 return 1;
14559 return 0;
14560}
14561
14562
14563static int
14564dump_msg_api_table (vat_main_t * vam)
14565{
Dave Barach39d69112019-11-27 11:42:13 -050014566 api_main_t *am = vlibapi_get_main ();
Damjan Marion7cd468a2016-12-19 23:05:39 +010014567 name_sort_t *nses = 0, *ns;
14568 hash_pair_t *hp;
14569 int i;
14570
14571 /* *INDENT-OFF* */
14572 hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
14573 ({
14574 vec_add2 (nses, ns, 1);
14575 ns->name = (u8 *)(hp->key);
14576 ns->value = (u32) hp->value[0];
14577 }));
14578 /* *INDENT-ON* */
14579
14580 vec_sort_with_function (nses, value_sort_cmp);
14581
14582 for (i = 0; i < vec_len (nses); i++)
14583 print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
14584 vec_free (nses);
14585 return 0;
14586}
14587
14588static int
14589get_msg_id (vat_main_t * vam)
14590{
14591 u8 *name_and_crc;
14592 u32 message_index;
14593
14594 if (unformat (vam->input, "%s", &name_and_crc))
14595 {
Florin Corase86a8ed2018-01-05 03:20:25 -080014596 message_index = vl_msg_api_get_msg_index (name_and_crc);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014597 if (message_index == ~0)
14598 {
14599 print (vam->ofp, " '%s' not found", name_and_crc);
14600 return 0;
14601 }
14602 print (vam->ofp, " '%s' has message index %d",
14603 name_and_crc, message_index);
14604 return 0;
14605 }
14606 errmsg ("name_and_crc required...");
14607 return 0;
14608}
14609
14610static int
14611search_node_table (vat_main_t * vam)
14612{
14613 unformat_input_t *line_input = vam->input;
14614 u8 *node_to_find;
14615 int j;
14616 vlib_node_t *node, *next_node;
14617 uword *p;
14618
14619 if (vam->graph_node_index_by_name == 0)
14620 {
14621 print (vam->ofp, "Node table empty, issue get_node_graph...");
14622 return 0;
14623 }
14624
14625 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14626 {
14627 if (unformat (line_input, "%s", &node_to_find))
14628 {
14629 vec_add1 (node_to_find, 0);
14630 p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
14631 if (p == 0)
14632 {
14633 print (vam->ofp, "%s not found...", node_to_find);
14634 goto out;
14635 }
Dave Barach1ddbc012018-06-13 09:26:05 -040014636 node = vam->graph_nodes[0][p[0]];
Damjan Marion7cd468a2016-12-19 23:05:39 +010014637 print (vam->ofp, "[%d] %s", p[0], node->name);
14638 for (j = 0; j < vec_len (node->next_nodes); j++)
14639 {
14640 if (node->next_nodes[j] != ~0)
14641 {
Dave Barach1ddbc012018-06-13 09:26:05 -040014642 next_node = vam->graph_nodes[0][node->next_nodes[j]];
Damjan Marion7cd468a2016-12-19 23:05:39 +010014643 print (vam->ofp, " [%d] %s", j, next_node->name);
14644 }
14645 }
14646 }
14647
14648 else
14649 {
14650 clib_warning ("parse error '%U'", format_unformat_error,
14651 line_input);
14652 return -99;
14653 }
14654
14655 out:
14656 vec_free (node_to_find);
14657
14658 }
14659
14660 return 0;
14661}
14662
14663
14664static int
14665script (vat_main_t * vam)
14666{
14667#if (VPP_API_TEST_BUILTIN==0)
14668 u8 *s = 0;
14669 char *save_current_file;
14670 unformat_input_t save_input;
14671 jmp_buf save_jump_buf;
14672 u32 save_line_number;
14673
14674 FILE *new_fp, *save_ifp;
14675
14676 if (unformat (vam->input, "%s", &s))
14677 {
14678 new_fp = fopen ((char *) s, "r");
14679 if (new_fp == 0)
14680 {
14681 errmsg ("Couldn't open script file %s", s);
14682 vec_free (s);
14683 return -99;
14684 }
14685 }
14686 else
14687 {
14688 errmsg ("Missing script name");
14689 return -99;
14690 }
14691
14692 clib_memcpy (&save_input, &vam->input, sizeof (save_input));
14693 clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
14694 save_ifp = vam->ifp;
14695 save_line_number = vam->input_line_number;
14696 save_current_file = (char *) vam->current_file;
14697
14698 vam->input_line_number = 0;
14699 vam->ifp = new_fp;
14700 vam->current_file = s;
14701 do_one_file (vam);
14702
Sirshak Dasb0861822018-05-29 21:13:21 -050014703 clib_memcpy (&vam->input, &save_input, sizeof (save_input));
Damjan Marion7cd468a2016-12-19 23:05:39 +010014704 clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
14705 vam->ifp = save_ifp;
14706 vam->input_line_number = save_line_number;
14707 vam->current_file = (u8 *) save_current_file;
14708 vec_free (s);
14709
14710 return 0;
14711#else
14712 clib_warning ("use the exec command...");
14713 return -99;
14714#endif
14715}
14716
14717static int
14718echo (vat_main_t * vam)
14719{
14720 print (vam->ofp, "%v", vam->input->buffer);
14721 return 0;
14722}
14723
14724/* List of API message constructors, CLI names map to api_xxx */
14725#define foreach_vpe_api_msg \
Jon Loeligerc83c3b72017-02-23 13:57:35 -060014726_(create_loopback,"[mac <mac-addr>] [instance <instance>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014727_(sw_interface_dump,"") \
14728_(sw_interface_set_flags, \
14729 "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
14730_(sw_interface_add_del_address, \
14731 "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
Stevenad8015b2017-10-29 22:10:46 -070014732_(sw_interface_set_rx_mode, \
14733 "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
Mohsin Kazmi54f7c512018-08-23 18:28:11 +020014734_(sw_interface_set_rx_placement, \
14735 "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]") \
Mohsin Kazmif0b42f42018-09-10 18:11:00 +020014736_(sw_interface_rx_placement_dump, \
14737 "[<intfc> | sw_if_index <id>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014738_(sw_interface_set_table, \
14739 "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]") \
14740_(sw_interface_set_mpls_enable, \
14741 "<intfc> | sw_if_index [disable | dis]") \
14742_(sw_interface_set_vpath, \
14743 "<intfc> | sw_if_index <id> enable | disable") \
14744_(sw_interface_set_vxlan_bypass, \
John Lo2b81eb82017-01-30 13:12:10 -050014745 "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014746_(sw_interface_set_l2_xconnect, \
14747 "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
14748 "enable | disable") \
14749_(sw_interface_set_l2_bridge, \
Eyal Barif24991c2017-04-05 05:33:21 +030014750 "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n" \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014751 "[shg <split-horizon-group>] [bvi]\n" \
14752 "enable | disable") \
Eyal Barif24991c2017-04-05 05:33:21 +030014753_(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014754_(bridge_domain_add_del, \
John Lo70bfcaf2017-11-14 13:19:26 -050014755 "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 +010014756_(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n") \
14757_(l2fib_add_del, \
14758 "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 +030014759_(l2fib_flush_bd, "bd_id <bridge-domain-id>") \
14760_(l2fib_flush_int, "<intfc> | sw_if_index <id>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014761_(l2_flags, \
John Lo8d00fff2017-08-03 00:35:36 -040014762 "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014763_(bridge_flags, \
14764 "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
Damjan Marion8389fb92017-10-13 18:29:53 +020014765_(tap_create_v2, \
Mohsin Kazmi50bd1652020-08-26 11:07:48 +020014766 "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 +020014767_(tap_delete_v2, \
14768 "<vpp-if-name> | sw_if_index <id>") \
14769_(sw_interface_tap_v2_dump, "") \
Mohsin Kazmi518251b2020-09-01 17:17:44 +000014770_(virtio_pci_create_v2, \
Mohsin Kazmie347acb2020-09-28 10:26:33 +000014771 "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 +010014772_(virtio_pci_delete, \
14773 "<vpp-if-name> | sw_if_index <id>") \
14774_(sw_interface_virtio_pci_dump, "") \
Steven9cd2d7a2017-12-20 12:43:01 -080014775_(bond_create, \
14776 "[hw-addr <mac-addr>] {round-robin | active-backup | " \
Alexander Chernavinad9d5282018-12-13 09:08:09 -050014777 "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} " \
Steven Luonga1876b82019-08-20 16:58:00 -070014778 "[id <if-id>]") \
Steven Luongea717862020-07-30 07:31:40 -070014779_(bond_create2, \
14780 "[hw-addr <mac-addr>] {mode round-robin | active-backup | " \
14781 "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} " \
14782 "[id <if-id>] [gso]") \
Steven9cd2d7a2017-12-20 12:43:01 -080014783_(bond_delete, \
14784 "<vpp-if-name> | sw_if_index <id>") \
Steven Luong4c4223e2020-07-15 08:44:54 -070014785_(bond_add_member, \
Steven Luonga1876b82019-08-20 16:58:00 -070014786 "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]") \
Steven Luong4c4223e2020-07-15 08:44:54 -070014787_(bond_detach_member, \
Steven9cd2d7a2017-12-20 12:43:01 -080014788 "sw_if_index <n>") \
Steven Luonga1876b82019-08-20 16:58:00 -070014789 _(sw_interface_set_bond_weight, "<intfc> | sw_if_index <nn> weight <value>") \
Steven Luong4c4223e2020-07-15 08:44:54 -070014790 _(sw_bond_interface_dump, "<intfc> | sw_if_index <nn>") \
14791 _(sw_member_interface_dump, \
Steven9cd2d7a2017-12-20 12:43:01 -080014792 "<vpp-if-name> | sw_if_index <id>") \
Neale Ranns28ab9cc2017-08-14 07:18:42 -070014793_(ip_table_add_del, \
John Loe166fd92018-09-13 14:08:59 -040014794 "table <n> [ipv6] [add | del]\n") \
Neale Ranns097fa662018-05-01 05:17:55 -070014795_(ip_route_add_del, \
John Lo22030432018-09-20 16:07:00 -040014796 "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
14797 "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
John Lo06fda9c2018-10-03 16:32:44 -040014798 "[weight <n>] [drop] [local] [classify <n>] [out-label <n>]\n" \
14799 "[multipath] [count <n>] [del]") \
Neale Ranns32e1c012016-11-22 17:07:28 +000014800_(ip_mroute_add_del, \
14801 "<src> <grp>/<mask> [table-id <n>]\n" \
14802 "[<intfc> | sw_if_index <id>] [local] [del]") \
Neale Ranns28ab9cc2017-08-14 07:18:42 -070014803_(mpls_table_add_del, \
John Loe166fd92018-09-13 14:08:59 -040014804 "table <n> [add | del]\n") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014805_(mpls_route_add_del, \
John Loe166fd92018-09-13 14:08:59 -040014806 "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n" \
14807 "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n" \
14808 "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n" \
14809 "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n" \
John Lo06fda9c2018-10-03 16:32:44 -040014810 "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n" \
14811 "[count <n>] [del]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014812_(mpls_ip_bind_unbind, \
14813 "<label> <addr/len>") \
14814_(mpls_tunnel_add_del, \
John Lo06fda9c2018-10-03 16:32:44 -040014815 "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
14816 "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n" \
14817 "[l2-only] [out-label <n>]") \
John Loe166fd92018-09-13 14:08:59 -040014818_(sr_mpls_policy_add, \
14819 "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]") \
14820_(sr_mpls_policy_del, \
14821 "bsid <id>") \
Neale Rannsd792d9c2017-10-21 10:53:20 -070014822_(bier_table_add_del, \
14823 "<label> <sub-domain> <set> <bsl> [del]") \
14824_(bier_route_add_del, \
14825 "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
14826 "[<intfc> | sw_if_index <id>]" \
14827 "[weight <n>] [del] [multipath]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014828_(sw_interface_set_unnumbered, \
14829 "<intfc> | sw_if_index <id> unnum_if_index <id> [del]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014830_(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>") \
14831_(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n" \
14832 "[outer_vlan_id <n>][inner_vlan_id <n>]\n" \
14833 "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n" \
14834 "[outer_vlan_id_any][inner_vlan_id_any]") \
Neale Ranns9db6ada2019-11-08 12:42:31 +000014835_(ip_table_replace_begin, "table <n> [ipv6]") \
14836_(ip_table_flush, "table <n> [ipv6]") \
14837_(ip_table_replace_end, "table <n> [ipv6]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014838_(set_ip_flow_hash, \
14839 "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]") \
14840_(sw_interface_ip6_enable_disable, \
14841 "<intfc> | sw_if_index <id> enable | disable") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014842_(l2_patch_add_del, \
14843 "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
14844 "enable | disable") \
Pablo Camarillofb380952016-12-07 18:34:18 +010014845_(sr_localsid_add_del, \
14846 "(del) address <addr> next_hop <addr> behavior <beh>\n" \
14847 "fib-table <num> (end.psp) sw_if_index <num>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014848_(classify_add_del_table, \
14849 "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n" \
14850 " [del] [del-chain] mask <mask-value>\n" \
14851 " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n" \
14852 " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]") \
14853_(classify_add_del_session, \
14854 "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n" \
14855 " table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n" \
14856 " [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n" \
14857 " [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]") \
14858_(classify_set_interface_ip_table, \
14859 "<intfc> | sw_if_index <nn> table <nn>") \
14860_(classify_set_interface_l2_tables, \
14861 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
14862 " [other-table <nn>]") \
14863_(get_node_index, "node <node-name") \
14864_(add_node_next, "node <node-name> next <next-node-name>") \
eyal bariaf86a482018-04-17 11:20:27 +030014865_(vxlan_offload_rx, \
14866 "hw { <interface name> | hw_if_index <nn>} " \
14867 "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014868_(vxlan_add_del_tunnel, \
14869 "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n" \
Jon Loeliger3d460bd2018-02-01 16:36:12 -060014870 "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n" \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014871 "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]") \
14872_(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014873_(l2_fib_clear_table, "") \
14874_(l2_interface_efp_filter, "sw_if_index <nn> enable | disable") \
14875_(l2_interface_vlan_tag_rewrite, \
14876 "<intfc> | sw_if_index <nn> \n" \
14877 "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n" \
14878 "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>") \
14879_(create_vhost_user_if, \
14880 "socket <filename> [server] [renumber <dev_instance>] " \
Steven Luong4208a4c2019-05-06 08:51:56 -070014881 "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] " \
Steven Luongbc0d9ff2020-03-23 09:34:59 -070014882 "[mac <mac_address>] [packed]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014883_(modify_vhost_user_if, \
14884 "<intfc> | sw_if_index <nn> socket <filename>\n" \
Steven Luongbc0d9ff2020-03-23 09:34:59 -070014885 "[server] [renumber <dev_instance>] [gso] [packed]") \
Steven Luong27ba5002020-11-17 13:30:44 -080014886_(create_vhost_user_if_v2, \
14887 "socket <filename> [server] [renumber <dev_instance>] " \
14888 "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] " \
14889 "[mac <mac_address>] [packed] [event-idx]") \
14890_(modify_vhost_user_if_v2, \
14891 "<intfc> | sw_if_index <nn> socket <filename>\n" \
14892 "[server] [renumber <dev_instance>] [gso] [packed] [event-idx]")\
Damjan Marion7cd468a2016-12-19 23:05:39 +010014893_(delete_vhost_user_if, "<intfc> | sw_if_index <nn>") \
Steven Luonga0e8d962020-05-18 17:12:56 -070014894_(sw_interface_vhost_user_dump, "<intfc> | sw_if_index <nn>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014895_(show_version, "") \
Mohsin Kazmi5d64c782018-09-11 20:27:09 +020014896_(show_threads, "") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014897_(vxlan_gpe_add_del_tunnel, \
Hongjun Ni04ffd0ad2017-06-23 00:18:40 +080014898 "local <addr> remote <addr> | group <mcast-ip-addr>\n" \
14899 "{ <intfc> | mcast_sw_if_index <nn> } }\n" \
14900 "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n" \
14901 "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014902_(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]") \
14903_(l2_fib_table_dump, "bd_id <bridge-domain-id>") \
14904_(interface_name_renumber, \
14905 "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>") \
14906_(input_acl_set_interface, \
14907 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
14908 " [l2-table <nn>] [del]") \
John Lo8d00fff2017-08-03 00:35:36 -040014909_(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014910_(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)") \
14911_(ip_dump, "ipv4 | ipv6") \
14912_(ipsec_spd_add_del, "spd_id <n> [del]") \
14913_(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n" \
14914 " spid_id <n> ") \
Neale Ranns17dcec02019-01-09 21:22:20 -080014915_(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n" \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014916 " crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n" \
14917 " integ_alg <alg> integ_key <hex>") \
Neale Ranns17dcec02019-01-09 21:22:20 -080014918_(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n" \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014919 " (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n" \
14920 " laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
14921 " [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
Matthew Smith28029532017-09-26 13:33:44 -050014922_(ipsec_sa_dump, "[sa_id <n>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014923_(delete_loopback,"sw_if_index <nn>") \
14924_(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
John Loe26c81f2019-01-07 15:16:33 -050014925_(bd_ip_mac_flush, "bd_id <bridge-domain-id>") \
14926_(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014927_(want_interface_events, "enable|disable") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014928_(get_first_msg_id, "client <name>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014929_(get_node_graph, " ") \
14930_(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>") \
14931_(ioam_enable, "[trace] [pow] [ppc <encap|decap>]") \
14932_(ioam_disable, "") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014933_(af_packet_create, "name <host interface name> [hw_addr <mac>]") \
14934_(af_packet_delete, "name <host interface name>") \
Mohsin Kazmi04e0bb22018-05-28 18:55:37 +020014935_(af_packet_dump, "") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014936_(policer_add_del, "name <policer name> <params> [del]") \
14937_(policer_dump, "[name <policer name>]") \
14938_(policer_classify_set_interface, \
14939 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
14940 " [l2-table <nn>] [del]") \
14941_(policer_classify_dump, "type [ip4|ip6|l2]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014942_(mpls_tunnel_dump, "tunnel_index <tunnel-id>") \
Neale Ranns097fa662018-05-01 05:17:55 -070014943_(mpls_table_dump, "") \
14944_(mpls_route_dump, "table-id <ID>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014945_(classify_table_ids, "") \
14946_(classify_table_by_interface, "sw_if_index <sw_if_index>") \
14947_(classify_table_info, "table_id <nn>") \
14948_(classify_session_dump, "table_id <nn>") \
14949_(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] " \
14950 "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] " \
14951 "[template_interval <nn>] [udp_checksum]") \
14952_(ipfix_exporter_dump, "") \
14953_(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
14954_(ipfix_classify_stream_dump, "") \
14955_(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
14956_(ipfix_classify_table_dump, "") \
Eyal Bari001fd402017-07-16 09:34:53 +030014957_(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 +030014958_(sw_interface_span_dump, "[l2]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014959_(get_next_index, "node-name <node-name> next-node-name <node-name>") \
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +020014960_(pg_create_interface, "if_id <nn> [gso-enabled gso-size <size>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014961_(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]") \
14962_(pg_enable_disable, "[stream <id>] disable") \
Mohsin Kazmif382b062020-08-11 15:00:44 +020014963_(pg_interface_enable_disable_coalesce, "<intf> | sw_if_index <nn> enable | disable") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014964_(ip_source_and_port_range_check_add_del, \
14965 "<ip-addr>/<mask> range <nn>-<nn> vrf <id>") \
14966_(ip_source_and_port_range_check_interface_add_del, \
14967 "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]" \
14968 "[udp-in-vrf <id>] [udp-out-vrf <id>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014969_(delete_subif,"<intfc> | sw_if_index <nn>") \
14970_(l2_interface_pbb_tag_rewrite, \
14971 "<intfc> | sw_if_index <nn> \n" \
14972 "[disable | push | pop | translate_pbb_stag <outer_tag>] \n" \
14973 "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]") \
Pavel Kotuceke88865d2018-11-28 07:42:11 +010014974_(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014975_(flow_classify_set_interface, \
14976 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
14977_(flow_classify_dump, "type [ip4|ip6]") \
Neale Ranns097fa662018-05-01 05:17:55 -070014978_(ip_table_dump, "") \
14979_(ip_route_dump, "table-id [ip4|ip6]") \
14980_(ip_mtable_dump, "") \
14981_(ip_mroute_dump, "table-id [ip4|ip6]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014982_(feature_enable_disable, "arc_name <arc_name> " \
14983 "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]") \
Mohsin Kazmi29467b52019-10-08 19:42:38 +020014984_(feature_gso_enable_disable, "<intfc> | sw_if_index <nn> " \
14985 "[enable | disable] ") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014986_(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>" \
14987"[disable]") \
Matthew Smithe0792fd2019-07-12 11:48:24 -050014988_(sw_interface_add_del_mac_address, "<intfc> | sw_if_index <nn> " \
14989 "mac <mac-address> [del]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010014990_(l2_xconnect_dump, "") \
Ole Troand7231612018-06-07 10:17:57 +020014991_(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>") \
Pavel Kotucek6899a302017-06-08 08:46:10 +020014992_(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]") \
Pavel Kotucek15ac81c2017-06-20 14:00:26 +020014993_(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
Steve Shin99a0e602017-07-01 04:16:20 +000014994_(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
Dave Barach59b25652017-09-10 15:04:27 -040014995_(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]") \
Florin Coras90a63982017-12-19 04:50:01 -080014996_(sock_init_shm, "size <nnn>") \
Florin Corascea194d2017-10-02 00:18:51 -070014997_(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
Florin Coras1c710452017-10-17 00:03:13 -070014998_(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> " \
14999 "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>") \
Florin Coras6c36f532017-11-03 18:32:34 -070015000_(session_rules_dump, "") \
Florin Coras595992c2017-11-06 17:17:08 -080015001_(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>") \
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +010015002_(output_acl_set_interface, \
15003 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
15004 " [l2-table <nn>] [del]") \
Ole Troane906aac2018-06-14 14:42:14 +020015005_(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
Damjan Marion7cd468a2016-12-19 23:05:39 +010015006
15007/* List of command functions, CLI names map directly to functions */
15008#define foreach_cli_function \
15009_(comment, "usage: comment <ignore-rest-of-line>") \
15010_(dump_interface_table, "usage: dump_interface_table") \
15011_(dump_sub_interface_table, "usage: dump_sub_interface_table") \
15012_(dump_ipv4_table, "usage: dump_ipv4_table") \
15013_(dump_ipv6_table, "usage: dump_ipv6_table") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015014_(dump_macro_table, "usage: dump_macro_table ") \
15015_(dump_node_table, "usage: dump_node_table") \
15016_(dump_msg_api_table, "usage: dump_msg_api_table") \
Dave Barachb09f4d02019-07-15 16:00:03 -040015017_(elog_setup, "usage: elog_setup [nevents, default 128K]") \
15018_(elog_disable, "usage: elog_disable") \
15019_(elog_enable, "usage: elog_enable") \
15020_(elog_save, "usage: elog_save <filename>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015021_(get_msg_id, "usage: get_msg_id name_and_crc") \
15022_(echo, "usage: echo <message>") \
15023_(exec, "usage: exec <vpe-debug-CLI-command>") \
15024_(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>") \
15025_(help, "usage: help") \
15026_(q, "usage: quit") \
15027_(quit, "usage: quit") \
15028_(search_node_table, "usage: search_node_table <name>...") \
15029_(set, "usage: set <variable-name> <value>") \
15030_(script, "usage: script <file-name>") \
Neale Ranns097fa662018-05-01 05:17:55 -070015031_(statseg, "usage: statseg") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010015032_(unset, "usage: unset <variable-name>")
Dave Barach048a4e52018-06-01 18:52:25 -040015033
Damjan Marion7cd468a2016-12-19 23:05:39 +010015034#define _(N,n) \
15035 static void vl_api_##n##_t_handler_uni \
15036 (vl_api_##n##_t * mp) \
15037 { \
15038 vat_main_t * vam = &vat_main; \
15039 if (vam->json_output) { \
15040 vl_api_##n##_t_handler_json(mp); \
15041 } else { \
15042 vl_api_##n##_t_handler(mp); \
15043 } \
15044 }
15045foreach_vpe_api_reply_msg;
Dave Baracha1a093d2017-03-02 13:13:23 -050015046#if VPP_API_TEST_BUILTIN == 0
15047foreach_standalone_reply_msg;
15048#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +010015049#undef _
15050
15051void
15052vat_api_hookup (vat_main_t * vam)
15053{
15054#define _(N,n) \
15055 vl_msg_api_set_handlers(VL_API_##N, #n, \
15056 vl_api_##n##_t_handler_uni, \
15057 vl_noop_handler, \
15058 vl_api_##n##_t_endian, \
15059 vl_api_##n##_t_print, \
15060 sizeof(vl_api_##n##_t), 1);
15061 foreach_vpe_api_reply_msg;
Dave Baracha1a093d2017-03-02 13:13:23 -050015062#if VPP_API_TEST_BUILTIN == 0
15063 foreach_standalone_reply_msg;
15064#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +010015065#undef _
15066
15067#if (VPP_API_TEST_BUILTIN==0)
15068 vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015069
15070 vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
15071
15072 vam->function_by_name = hash_create_string (0, sizeof (uword));
15073
15074 vam->help_by_name = hash_create_string (0, sizeof (uword));
Dave Barach45e4f362017-03-07 12:52:31 -050015075#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +010015076
15077 /* API messages we can send */
15078#define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
15079 foreach_vpe_api_msg;
15080#undef _
15081
15082 /* Help strings */
15083#define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
15084 foreach_vpe_api_msg;
15085#undef _
Damjan Marion7cd468a2016-12-19 23:05:39 +010015086
15087 /* CLI functions */
15088#define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
15089 foreach_cli_function;
15090#undef _
15091
15092 /* Help strings */
15093#define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
15094 foreach_cli_function;
15095#undef _
15096}
15097
Dave Baracha1a093d2017-03-02 13:13:23 -050015098#if VPP_API_TEST_BUILTIN
15099static clib_error_t *
15100vat_api_hookup_shim (vlib_main_t * vm)
15101{
15102 vat_api_hookup (&vat_main);
15103 return 0;
15104}
15105
15106VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
15107#endif
15108
Damjan Marion7cd468a2016-12-19 23:05:39 +010015109/*
15110 * fd.io coding-style-patch-verification: ON
15111 *
15112 * Local Variables:
15113 * eval: (c-set-style "gnu")
15114 * End:
15115 */