blob: f3e6f64c57e3aefc12cb13aa3d5b56cb31c2cad0 [file] [log] [blame]
Damjan Marion7cd468a2016-12-19 23:05:39 +01001/*
2 *------------------------------------------------------------------
3 * api_format.c
4 *
5 * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6 * 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>
21#include <vlibapi/api.h>
22#include <vlibmemory/api.h>
23#include <vlibsocket/api.h>
24#include <vnet/ip/ip.h>
Damjan Marion7cd468a2016-12-19 23:05:39 +010025#include <vnet/l2/l2_input.h>
26#include <vnet/l2tp/l2tp.h>
27#include <vnet/vxlan/vxlan.h>
28#include <vnet/gre/gre.h>
29#include <vnet/vxlan-gpe/vxlan_gpe.h>
30#include <vnet/lisp-gpe/lisp_gpe.h>
31
32#include <vpp/api/vpe_msg_enum.h>
33#include <vnet/l2/l2_classify.h>
34#include <vnet/l2/l2_vtr.h>
35#include <vnet/classify/input_acl.h>
36#include <vnet/classify/policer_classify.h>
37#include <vnet/classify/flow_classify.h>
38#include <vnet/mpls/mpls.h>
39#include <vnet/ipsec/ipsec.h>
40#include <vnet/ipsec/ikev2.h>
41#include <inttypes.h>
42#include <vnet/map/map.h>
43#include <vnet/cop/cop.h>
44#include <vnet/ip/ip6_hop_by_hop.h>
45#include <vnet/ip/ip_source_and_port_range_check.h>
46#include <vnet/policer/xlate.h>
47#include <vnet/span/span.h>
48#include <vnet/policer/policer.h>
49#include <vnet/policer/police.h>
Neale Ranns32e1c012016-11-22 17:07:28 +000050#include <vnet/mfib/mfib_types.h>
Damjan Marion7cd468a2016-12-19 23:05:39 +010051
52#include "vat/json_format.h"
53
54#include <inttypes.h>
55#include <sys/stat.h>
56
57#define vl_typedefs /* define message structures */
58#include <vpp/api/vpe_all_api_h.h>
59#undef vl_typedefs
60
61/* declare message handlers for each api */
62
63#define vl_endianfun /* define message structures */
64#include <vpp/api/vpe_all_api_h.h>
65#undef vl_endianfun
66
67/* instantiate all the print functions we know about */
68#define vl_print(handle, ...)
69#define vl_printfun
70#include <vpp/api/vpe_all_api_h.h>
71#undef vl_printfun
72
Dave Barach2d6b2d62017-01-25 16:32:08 -050073#define __plugin_msg_base 0
Dave Barachfe6bdfd2017-01-20 19:50:09 -050074#include <vlibapi/vat_helper_macros.h>
75
76f64
77vat_time_now (vat_main_t * vam)
78{
79#if VPP_API_TEST_BUILTIN
80 return vlib_time_now (vam->vlib_main);
81#else
82 return clib_time_now (&vam->clib_time);
83#endif
84}
85
86void
87errmsg (char *fmt, ...)
88{
89 vat_main_t *vam = &vat_main;
90 va_list va;
91 u8 *s;
92
93 va_start (va, fmt);
94 s = va_format (0, fmt, &va);
95 va_end (va);
96
97 vec_add1 (s, 0);
98
99#if VPP_API_TEST_BUILTIN
100 vlib_cli_output (vam->vlib_main, (char *) s);
101#else
102 {
103 if (vam->ifp != stdin)
104 fformat (vam->ofp, "%s(%d): \n", vam->current_file,
105 vam->input_line_number);
106 fformat (vam->ofp, (char *) s);
107 fflush (vam->ofp);
108 }
109#endif
110
111 vec_free (s);
112}
113
Dave Barach4a3f69c2017-02-22 12:44:56 -0500114#if VPP_API_TEST_BUILTIN == 0
Damjan Marion7cd468a2016-12-19 23:05:39 +0100115static uword
116api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
117{
118 vat_main_t *vam = va_arg (*args, vat_main_t *);
119 u32 *result = va_arg (*args, u32 *);
120 u8 *if_name;
121 uword *p;
122
123 if (!unformat (input, "%s", &if_name))
124 return 0;
125
126 p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
127 if (p == 0)
128 return 0;
129 *result = p[0];
130 return 1;
131}
132
Damjan Marion7cd468a2016-12-19 23:05:39 +0100133/* Parse an IP4 address %d.%d.%d.%d. */
134uword
135unformat_ip4_address (unformat_input_t * input, va_list * args)
136{
137 u8 *result = va_arg (*args, u8 *);
138 unsigned a[4];
139
140 if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
141 return 0;
142
143 if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
144 return 0;
145
146 result[0] = a[0];
147 result[1] = a[1];
148 result[2] = a[2];
149 result[3] = a[3];
150
151 return 1;
152}
153
154uword
155unformat_ethernet_address (unformat_input_t * input, va_list * args)
156{
157 u8 *result = va_arg (*args, u8 *);
158 u32 i, a[6];
159
160 if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
161 &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
162 return 0;
163
164 /* Check range. */
165 for (i = 0; i < 6; i++)
166 if (a[i] >= (1 << 8))
167 return 0;
168
169 for (i = 0; i < 6; i++)
170 result[i] = a[i];
171
172 return 1;
173}
174
175/* Returns ethernet type as an int in host byte order. */
176uword
177unformat_ethernet_type_host_byte_order (unformat_input_t * input,
178 va_list * args)
179{
180 u16 *result = va_arg (*args, u16 *);
181 int type;
182
183 /* Numeric type. */
184 if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
185 {
186 if (type >= (1 << 16))
187 return 0;
188 *result = type;
189 return 1;
190 }
191 return 0;
192}
193
194/* Parse an IP6 address. */
195uword
196unformat_ip6_address (unformat_input_t * input, va_list * args)
197{
198 ip6_address_t *result = va_arg (*args, ip6_address_t *);
199 u16 hex_quads[8];
200 uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
201 uword c, n_colon, double_colon_index;
202
203 n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
204 double_colon_index = ARRAY_LEN (hex_quads);
205 while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
206 {
207 hex_digit = 16;
208 if (c >= '0' && c <= '9')
209 hex_digit = c - '0';
210 else if (c >= 'a' && c <= 'f')
211 hex_digit = c + 10 - 'a';
212 else if (c >= 'A' && c <= 'F')
213 hex_digit = c + 10 - 'A';
214 else if (c == ':' && n_colon < 2)
215 n_colon++;
216 else
217 {
218 unformat_put_input (input);
219 break;
220 }
221
222 /* Too many hex quads. */
223 if (n_hex_quads >= ARRAY_LEN (hex_quads))
224 return 0;
225
226 if (hex_digit < 16)
227 {
228 hex_quad = (hex_quad << 4) | hex_digit;
229
230 /* Hex quad must fit in 16 bits. */
231 if (n_hex_digits >= 4)
232 return 0;
233
234 n_colon = 0;
235 n_hex_digits++;
236 }
237
238 /* Save position of :: */
239 if (n_colon == 2)
240 {
241 /* More than one :: ? */
242 if (double_colon_index < ARRAY_LEN (hex_quads))
243 return 0;
244 double_colon_index = n_hex_quads;
245 }
246
247 if (n_colon > 0 && n_hex_digits > 0)
248 {
249 hex_quads[n_hex_quads++] = hex_quad;
250 hex_quad = 0;
251 n_hex_digits = 0;
252 }
253 }
254
255 if (n_hex_digits > 0)
256 hex_quads[n_hex_quads++] = hex_quad;
257
258 {
259 word i;
260
261 /* Expand :: to appropriate number of zero hex quads. */
262 if (double_colon_index < ARRAY_LEN (hex_quads))
263 {
264 word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
265
266 for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
267 hex_quads[n_zero + i] = hex_quads[i];
268
269 for (i = 0; i < n_zero; i++)
270 hex_quads[double_colon_index + i] = 0;
271
272 n_hex_quads = ARRAY_LEN (hex_quads);
273 }
274
275 /* Too few hex quads given. */
276 if (n_hex_quads < ARRAY_LEN (hex_quads))
277 return 0;
278
279 for (i = 0; i < ARRAY_LEN (hex_quads); i++)
280 result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
281
282 return 1;
283 }
284}
285
286uword
287unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
288{
289 u32 *r = va_arg (*args, u32 *);
290
291 if (0);
292#define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
293 foreach_ipsec_policy_action
294#undef _
295 else
296 return 0;
297 return 1;
298}
299
300uword
301unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
302{
303 u32 *r = va_arg (*args, u32 *);
304
305 if (0);
306#define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
307 foreach_ipsec_crypto_alg
308#undef _
309 else
310 return 0;
311 return 1;
312}
313
314u8 *
315format_ipsec_crypto_alg (u8 * s, va_list * args)
316{
317 u32 i = va_arg (*args, u32);
318 u8 *t = 0;
319
320 switch (i)
321 {
322#define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
323 foreach_ipsec_crypto_alg
324#undef _
325 default:
326 return format (s, "unknown");
327 }
328 return format (s, "%s", t);
329}
330
331uword
332unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
333{
334 u32 *r = va_arg (*args, u32 *);
335
336 if (0);
337#define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
338 foreach_ipsec_integ_alg
339#undef _
340 else
341 return 0;
342 return 1;
343}
344
345u8 *
346format_ipsec_integ_alg (u8 * s, va_list * args)
347{
348 u32 i = va_arg (*args, u32);
349 u8 *t = 0;
350
351 switch (i)
352 {
353#define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
354 foreach_ipsec_integ_alg
355#undef _
356 default:
357 return format (s, "unknown");
358 }
359 return format (s, "%s", t);
360}
361
362uword
363unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
364{
365 u32 *r = va_arg (*args, u32 *);
366
367 if (0);
368#define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
369 foreach_ikev2_auth_method
370#undef _
371 else
372 return 0;
373 return 1;
374}
375
376uword
377unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
378{
379 u32 *r = va_arg (*args, u32 *);
380
381 if (0);
382#define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
383 foreach_ikev2_id_type
384#undef _
385 else
386 return 0;
387 return 1;
388}
Dave Barach4a3f69c2017-02-22 12:44:56 -0500389#else /* VPP_API_TEST_BUILTIN == 1 */
390static uword
391api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
392{
393 vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
394 vnet_main_t *vnm = vnet_get_main ();
395 u32 *result = va_arg (*args, u32 *);
396 u32 sw_if_index;
397
398 if (!unformat (input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
399 return 0;
400
401 *result = sw_if_index;
402 return 1;
403}
Damjan Marion7cd468a2016-12-19 23:05:39 +0100404#endif /* VPP_API_TEST_BUILTIN */
405
406static uword
407unformat_policer_rate_type (unformat_input_t * input, va_list * args)
408{
409 u8 *r = va_arg (*args, u8 *);
410
411 if (unformat (input, "kbps"))
412 *r = SSE2_QOS_RATE_KBPS;
413 else if (unformat (input, "pps"))
414 *r = SSE2_QOS_RATE_PPS;
415 else
416 return 0;
417 return 1;
418}
419
420static uword
421unformat_policer_round_type (unformat_input_t * input, va_list * args)
422{
423 u8 *r = va_arg (*args, u8 *);
424
425 if (unformat (input, "closest"))
426 *r = SSE2_QOS_ROUND_TO_CLOSEST;
427 else if (unformat (input, "up"))
428 *r = SSE2_QOS_ROUND_TO_UP;
429 else if (unformat (input, "down"))
430 *r = SSE2_QOS_ROUND_TO_DOWN;
431 else
432 return 0;
433 return 1;
434}
435
436static uword
437unformat_policer_type (unformat_input_t * input, va_list * args)
438{
439 u8 *r = va_arg (*args, u8 *);
440
441 if (unformat (input, "1r2c"))
442 *r = SSE2_QOS_POLICER_TYPE_1R2C;
443 else if (unformat (input, "1r3c"))
444 *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
445 else if (unformat (input, "2r3c-2698"))
446 *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
447 else if (unformat (input, "2r3c-4115"))
448 *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
449 else if (unformat (input, "2r3c-mef5cf1"))
450 *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
451 else
452 return 0;
453 return 1;
454}
455
456static uword
457unformat_dscp (unformat_input_t * input, va_list * va)
458{
459 u8 *r = va_arg (*va, u8 *);
460
461 if (0);
462#define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
463 foreach_vnet_dscp
464#undef _
465 else
466 return 0;
467 return 1;
468}
469
470static uword
471unformat_policer_action_type (unformat_input_t * input, va_list * va)
472{
473 sse2_qos_pol_action_params_st *a
474 = va_arg (*va, sse2_qos_pol_action_params_st *);
475
476 if (unformat (input, "drop"))
477 a->action_type = SSE2_QOS_ACTION_DROP;
478 else if (unformat (input, "transmit"))
479 a->action_type = SSE2_QOS_ACTION_TRANSMIT;
480 else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
481 a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
482 else
483 return 0;
484 return 1;
485}
486
487static uword
488unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
489{
490 u32 *r = va_arg (*va, u32 *);
491 u32 tid;
492
493 if (unformat (input, "ip4"))
494 tid = POLICER_CLASSIFY_TABLE_IP4;
495 else if (unformat (input, "ip6"))
496 tid = POLICER_CLASSIFY_TABLE_IP6;
497 else if (unformat (input, "l2"))
498 tid = POLICER_CLASSIFY_TABLE_L2;
499 else
500 return 0;
501
502 *r = tid;
503 return 1;
504}
505
506static uword
507unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
508{
509 u32 *r = va_arg (*va, u32 *);
510 u32 tid;
511
512 if (unformat (input, "ip4"))
513 tid = FLOW_CLASSIFY_TABLE_IP4;
514 else if (unformat (input, "ip6"))
515 tid = FLOW_CLASSIFY_TABLE_IP6;
516 else
517 return 0;
518
519 *r = tid;
520 return 1;
521}
522
Neale Ranns32e1c012016-11-22 17:07:28 +0000523static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
524static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
525static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
526static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
527
Dave Barach4a3f69c2017-02-22 12:44:56 -0500528#if (VPP_API_TEST_BUILTIN==0)
Neale Ranns32e1c012016-11-22 17:07:28 +0000529uword
530unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
531{
532 mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
533 mfib_itf_attribute_t attr;
534
535 old = *iflags;
536 FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
537 {
538 if (unformat (input, mfib_itf_flag_long_names[attr]))
539 *iflags |= (1 << attr);
540 }
541 FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
542 {
543 if (unformat (input, mfib_itf_flag_names[attr]))
544 *iflags |= (1 << attr);
545 }
546
547 return (old == *iflags ? 0 : 1);
548}
549
550uword
551unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
552{
553 mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
554 mfib_entry_attribute_t attr;
555
556 old = *eflags;
557 FOR_EACH_MFIB_ATTRIBUTE (attr)
558 {
559 if (unformat (input, mfib_flag_long_names[attr]))
560 *eflags |= (1 << attr);
561 }
562 FOR_EACH_MFIB_ATTRIBUTE (attr)
563 {
564 if (unformat (input, mfib_flag_names[attr]))
565 *eflags |= (1 << attr);
566 }
567
568 return (old == *eflags ? 0 : 1);
569}
570
Damjan Marion7cd468a2016-12-19 23:05:39 +0100571u8 *
572format_ip4_address (u8 * s, va_list * args)
573{
574 u8 *a = va_arg (*args, u8 *);
575 return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
576}
577
578u8 *
579format_ip6_address (u8 * s, va_list * args)
580{
581 ip6_address_t *a = va_arg (*args, ip6_address_t *);
582 u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
583
584 i_max_n_zero = ARRAY_LEN (a->as_u16);
585 max_n_zeros = 0;
586 i_first_zero = i_max_n_zero;
587 n_zeros = 0;
588 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
589 {
590 u32 is_zero = a->as_u16[i] == 0;
591 if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
592 {
593 i_first_zero = i;
594 n_zeros = 0;
595 }
596 n_zeros += is_zero;
597 if ((!is_zero && n_zeros > max_n_zeros)
598 || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
599 {
600 i_max_n_zero = i_first_zero;
601 max_n_zeros = n_zeros;
602 i_first_zero = ARRAY_LEN (a->as_u16);
603 n_zeros = 0;
604 }
605 }
606
607 last_double_colon = 0;
608 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
609 {
610 if (i == i_max_n_zero && max_n_zeros > 1)
611 {
612 s = format (s, "::");
613 i += max_n_zeros - 1;
614 last_double_colon = 1;
615 }
616 else
617 {
618 s = format (s, "%s%x",
619 (last_double_colon || i == 0) ? "" : ":",
620 clib_net_to_host_u16 (a->as_u16[i]));
621 last_double_colon = 0;
622 }
623 }
624
625 return s;
626}
627
628/* Format an IP46 address. */
629u8 *
630format_ip46_address (u8 * s, va_list * args)
631{
632 ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
633 ip46_type_t type = va_arg (*args, ip46_type_t);
634 int is_ip4 = 1;
635
636 switch (type)
637 {
638 case IP46_TYPE_ANY:
639 is_ip4 = ip46_address_is_ip4 (ip46);
640 break;
641 case IP46_TYPE_IP4:
642 is_ip4 = 1;
643 break;
644 case IP46_TYPE_IP6:
645 is_ip4 = 0;
646 break;
647 }
648
649 return is_ip4 ?
650 format (s, "%U", format_ip4_address, &ip46->ip4) :
651 format (s, "%U", format_ip6_address, &ip46->ip6);
652}
653
654u8 *
655format_ethernet_address (u8 * s, va_list * args)
656{
657 u8 *a = va_arg (*args, u8 *);
658
659 return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
660 a[0], a[1], a[2], a[3], a[4], a[5]);
661}
662#endif
663
664static void
665increment_v4_address (ip4_address_t * a)
666{
667 u32 v;
668
669 v = ntohl (a->as_u32) + 1;
670 a->as_u32 = ntohl (v);
671}
672
673static void
674increment_v6_address (ip6_address_t * a)
675{
676 u64 v0, v1;
677
678 v0 = clib_net_to_host_u64 (a->as_u64[0]);
679 v1 = clib_net_to_host_u64 (a->as_u64[1]);
680
681 v1 += 1;
682 if (v1 == 0)
683 v0 += 1;
684 a->as_u64[0] = clib_net_to_host_u64 (v0);
685 a->as_u64[1] = clib_net_to_host_u64 (v1);
686}
687
688static void
689increment_mac_address (u64 * mac)
690{
691 u64 tmp = *mac;
692
693 tmp = clib_net_to_host_u64 (tmp);
694 tmp += 1 << 16; /* skip unused (least significant) octets */
695 tmp = clib_host_to_net_u64 (tmp);
696 *mac = tmp;
697}
698
699static void vl_api_create_loopback_reply_t_handler
700 (vl_api_create_loopback_reply_t * mp)
701{
702 vat_main_t *vam = &vat_main;
703 i32 retval = ntohl (mp->retval);
704
705 vam->retval = retval;
706 vam->regenerate_interface_table = 1;
707 vam->sw_if_index = ntohl (mp->sw_if_index);
708 vam->result_ready = 1;
709}
710
711static void vl_api_create_loopback_reply_t_handler_json
712 (vl_api_create_loopback_reply_t * mp)
713{
714 vat_main_t *vam = &vat_main;
715 vat_json_node_t node;
716
717 vat_json_init_object (&node);
718 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
719 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
720
721 vat_json_print (vam->ofp, &node);
722 vat_json_free (&node);
723 vam->retval = ntohl (mp->retval);
724 vam->result_ready = 1;
725}
726
Jon Loeligerc83c3b72017-02-23 13:57:35 -0600727static void vl_api_create_loopback_instance_reply_t_handler
728 (vl_api_create_loopback_instance_reply_t * mp)
729{
730 vat_main_t *vam = &vat_main;
731 i32 retval = ntohl (mp->retval);
732
733 vam->retval = retval;
734 vam->regenerate_interface_table = 1;
735 vam->sw_if_index = ntohl (mp->sw_if_index);
736 vam->result_ready = 1;
737}
738
739static void vl_api_create_loopback_instance_reply_t_handler_json
740 (vl_api_create_loopback_instance_reply_t * mp)
741{
742 vat_main_t *vam = &vat_main;
743 vat_json_node_t node;
744
745 vat_json_init_object (&node);
746 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
747 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
748
749 vat_json_print (vam->ofp, &node);
750 vat_json_free (&node);
751 vam->retval = ntohl (mp->retval);
752 vam->result_ready = 1;
753}
754
Damjan Marion7cd468a2016-12-19 23:05:39 +0100755static void vl_api_af_packet_create_reply_t_handler
756 (vl_api_af_packet_create_reply_t * mp)
757{
758 vat_main_t *vam = &vat_main;
759 i32 retval = ntohl (mp->retval);
760
761 vam->retval = retval;
762 vam->regenerate_interface_table = 1;
763 vam->sw_if_index = ntohl (mp->sw_if_index);
764 vam->result_ready = 1;
765}
766
767static void vl_api_af_packet_create_reply_t_handler_json
768 (vl_api_af_packet_create_reply_t * mp)
769{
770 vat_main_t *vam = &vat_main;
771 vat_json_node_t node;
772
773 vat_json_init_object (&node);
774 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
775 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
776
777 vat_json_print (vam->ofp, &node);
778 vat_json_free (&node);
779
780 vam->retval = ntohl (mp->retval);
781 vam->result_ready = 1;
782}
783
784static void vl_api_create_vlan_subif_reply_t_handler
785 (vl_api_create_vlan_subif_reply_t * mp)
786{
787 vat_main_t *vam = &vat_main;
788 i32 retval = ntohl (mp->retval);
789
790 vam->retval = retval;
791 vam->regenerate_interface_table = 1;
792 vam->sw_if_index = ntohl (mp->sw_if_index);
793 vam->result_ready = 1;
794}
795
796static void vl_api_create_vlan_subif_reply_t_handler_json
797 (vl_api_create_vlan_subif_reply_t * mp)
798{
799 vat_main_t *vam = &vat_main;
800 vat_json_node_t node;
801
802 vat_json_init_object (&node);
803 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
804 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
805
806 vat_json_print (vam->ofp, &node);
807 vat_json_free (&node);
808
809 vam->retval = ntohl (mp->retval);
810 vam->result_ready = 1;
811}
812
813static void vl_api_create_subif_reply_t_handler
814 (vl_api_create_subif_reply_t * mp)
815{
816 vat_main_t *vam = &vat_main;
817 i32 retval = ntohl (mp->retval);
818
819 vam->retval = retval;
820 vam->regenerate_interface_table = 1;
821 vam->sw_if_index = ntohl (mp->sw_if_index);
822 vam->result_ready = 1;
823}
824
825static void vl_api_create_subif_reply_t_handler_json
826 (vl_api_create_subif_reply_t * mp)
827{
828 vat_main_t *vam = &vat_main;
829 vat_json_node_t node;
830
831 vat_json_init_object (&node);
832 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
833 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
834
835 vat_json_print (vam->ofp, &node);
836 vat_json_free (&node);
837
838 vam->retval = ntohl (mp->retval);
839 vam->result_ready = 1;
840}
841
842static void vl_api_interface_name_renumber_reply_t_handler
843 (vl_api_interface_name_renumber_reply_t * mp)
844{
845 vat_main_t *vam = &vat_main;
846 i32 retval = ntohl (mp->retval);
847
848 vam->retval = retval;
849 vam->regenerate_interface_table = 1;
850 vam->result_ready = 1;
851}
852
853static void vl_api_interface_name_renumber_reply_t_handler_json
854 (vl_api_interface_name_renumber_reply_t * mp)
855{
856 vat_main_t *vam = &vat_main;
857 vat_json_node_t node;
858
859 vat_json_init_object (&node);
860 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
861
862 vat_json_print (vam->ofp, &node);
863 vat_json_free (&node);
864
865 vam->retval = ntohl (mp->retval);
866 vam->result_ready = 1;
867}
868
869/*
870 * Special-case: build the interface table, maintain
871 * the next loopback sw_if_index vbl.
872 */
873static void vl_api_sw_interface_details_t_handler
874 (vl_api_sw_interface_details_t * mp)
875{
876 vat_main_t *vam = &vat_main;
877 u8 *s = format (0, "%s%c", mp->interface_name, 0);
878
879 hash_set_mem (vam->sw_if_index_by_interface_name, s,
880 ntohl (mp->sw_if_index));
881
882 /* In sub interface case, fill the sub interface table entry */
883 if (mp->sw_if_index != mp->sup_sw_if_index)
884 {
885 sw_interface_subif_t *sub = NULL;
886
887 vec_add2 (vam->sw_if_subif_table, sub, 1);
888
889 vec_validate (sub->interface_name, strlen ((char *) s) + 1);
890 strncpy ((char *) sub->interface_name, (char *) s,
891 vec_len (sub->interface_name));
892 sub->sw_if_index = ntohl (mp->sw_if_index);
893 sub->sub_id = ntohl (mp->sub_id);
894
895 sub->sub_dot1ad = mp->sub_dot1ad;
896 sub->sub_number_of_tags = mp->sub_number_of_tags;
897 sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
898 sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
899 sub->sub_exact_match = mp->sub_exact_match;
900 sub->sub_default = mp->sub_default;
901 sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
902 sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
903
904 /* vlan tag rewrite */
905 sub->vtr_op = ntohl (mp->vtr_op);
906 sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
907 sub->vtr_tag1 = ntohl (mp->vtr_tag1);
908 sub->vtr_tag2 = ntohl (mp->vtr_tag2);
909 }
910}
911
912static void vl_api_sw_interface_details_t_handler_json
913 (vl_api_sw_interface_details_t * mp)
914{
915 vat_main_t *vam = &vat_main;
916 vat_json_node_t *node = NULL;
917
918 if (VAT_JSON_ARRAY != vam->json_tree.type)
919 {
920 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
921 vat_json_init_array (&vam->json_tree);
922 }
923 node = vat_json_array_add (&vam->json_tree);
924
925 vat_json_init_object (node);
926 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
927 vat_json_object_add_uint (node, "sup_sw_if_index",
928 ntohl (mp->sup_sw_if_index));
929 vat_json_object_add_uint (node, "l2_address_length",
930 ntohl (mp->l2_address_length));
931 vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
932 sizeof (mp->l2_address));
933 vat_json_object_add_string_copy (node, "interface_name",
934 mp->interface_name);
935 vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
936 vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
937 vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
938 vat_json_object_add_uint (node, "link_speed", mp->link_speed);
939 vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
940 vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
941 vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
942 vat_json_object_add_uint (node, "sub_number_of_tags",
943 mp->sub_number_of_tags);
944 vat_json_object_add_uint (node, "sub_outer_vlan_id",
945 ntohs (mp->sub_outer_vlan_id));
946 vat_json_object_add_uint (node, "sub_inner_vlan_id",
947 ntohs (mp->sub_inner_vlan_id));
948 vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
949 vat_json_object_add_uint (node, "sub_default", mp->sub_default);
950 vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
951 mp->sub_outer_vlan_id_any);
952 vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
953 mp->sub_inner_vlan_id_any);
954 vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
955 vat_json_object_add_uint (node, "vtr_push_dot1q",
956 ntohl (mp->vtr_push_dot1q));
957 vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
958 vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
Pavel Kotucek65e84572017-01-16 17:01:56 +0100959 if (mp->sub_dot1ah)
960 {
961 vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
962 format (0, "%U",
963 format_ethernet_address,
964 &mp->b_dmac));
965 vat_json_object_add_string_copy (node, "pbb_vtr_smac",
966 format (0, "%U",
967 format_ethernet_address,
968 &mp->b_smac));
969 vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
970 vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
971 }
Damjan Marion7cd468a2016-12-19 23:05:39 +0100972}
973
Dave Baracha1a093d2017-03-02 13:13:23 -0500974#if VPP_API_TEST_BUILTIN == 0
Damjan Marion7cd468a2016-12-19 23:05:39 +0100975static void vl_api_sw_interface_set_flags_t_handler
976 (vl_api_sw_interface_set_flags_t * mp)
977{
978 vat_main_t *vam = &vat_main;
979 if (vam->interface_event_display)
980 errmsg ("interface flags: sw_if_index %d %s %s",
981 ntohl (mp->sw_if_index),
982 mp->admin_up_down ? "admin-up" : "admin-down",
983 mp->link_up_down ? "link-up" : "link-down");
984}
Dave Baracha1a093d2017-03-02 13:13:23 -0500985#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +0100986
987static void vl_api_sw_interface_set_flags_t_handler_json
988 (vl_api_sw_interface_set_flags_t * mp)
989{
990 /* JSON output not supported */
991}
992
993static void
994vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
995{
996 vat_main_t *vam = &vat_main;
997 i32 retval = ntohl (mp->retval);
998
999 vam->retval = retval;
Damjan Marion7bee80c2017-04-26 15:32:12 +02001000 vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001001 vam->result_ready = 1;
1002}
1003
1004static void
1005vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1006{
1007 vat_main_t *vam = &vat_main;
1008 vat_json_node_t node;
1009 api_main_t *am = &api_main;
1010 void *oldheap;
1011 u8 *reply;
1012
1013 vat_json_init_object (&node);
1014 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1015 vat_json_object_add_uint (&node, "reply_in_shmem",
1016 ntohl (mp->reply_in_shmem));
1017 /* Toss the shared-memory original... */
1018 pthread_mutex_lock (&am->vlib_rp->mutex);
1019 oldheap = svm_push_data_heap (am->vlib_rp);
1020
Damjan Marion7bee80c2017-04-26 15:32:12 +02001021 reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001022 vec_free (reply);
1023
1024 svm_pop_heap (oldheap);
1025 pthread_mutex_unlock (&am->vlib_rp->mutex);
1026
1027 vat_json_print (vam->ofp, &node);
1028 vat_json_free (&node);
1029
1030 vam->retval = ntohl (mp->retval);
1031 vam->result_ready = 1;
1032}
1033
1034static void
1035vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1036{
1037 vat_main_t *vam = &vat_main;
1038 i32 retval = ntohl (mp->retval);
1039
1040 vam->retval = retval;
1041 vam->cmd_reply = mp->reply;
1042 vam->result_ready = 1;
1043}
1044
1045static void
1046vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1047{
1048 vat_main_t *vam = &vat_main;
1049 vat_json_node_t node;
1050
1051 vat_json_init_object (&node);
1052 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1053 vat_json_object_add_string_copy (&node, "reply", mp->reply);
1054
1055 vat_json_print (vam->ofp, &node);
1056 vat_json_free (&node);
1057
1058 vam->retval = ntohl (mp->retval);
1059 vam->result_ready = 1;
1060}
1061
1062static void vl_api_classify_add_del_table_reply_t_handler
1063 (vl_api_classify_add_del_table_reply_t * mp)
1064{
1065 vat_main_t *vam = &vat_main;
1066 i32 retval = ntohl (mp->retval);
1067 if (vam->async_mode)
1068 {
1069 vam->async_errors += (retval < 0);
1070 }
1071 else
1072 {
1073 vam->retval = retval;
1074 if (retval == 0 &&
1075 ((mp->new_table_index != 0xFFFFFFFF) ||
1076 (mp->skip_n_vectors != 0xFFFFFFFF) ||
1077 (mp->match_n_vectors != 0xFFFFFFFF)))
1078 /*
1079 * Note: this is just barely thread-safe, depends on
1080 * the main thread spinning waiting for an answer...
1081 */
1082 errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1083 ntohl (mp->new_table_index),
1084 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1085 vam->result_ready = 1;
1086 }
1087}
1088
1089static void vl_api_classify_add_del_table_reply_t_handler_json
1090 (vl_api_classify_add_del_table_reply_t * mp)
1091{
1092 vat_main_t *vam = &vat_main;
1093 vat_json_node_t node;
1094
1095 vat_json_init_object (&node);
1096 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1097 vat_json_object_add_uint (&node, "new_table_index",
1098 ntohl (mp->new_table_index));
1099 vat_json_object_add_uint (&node, "skip_n_vectors",
1100 ntohl (mp->skip_n_vectors));
1101 vat_json_object_add_uint (&node, "match_n_vectors",
1102 ntohl (mp->match_n_vectors));
1103
1104 vat_json_print (vam->ofp, &node);
1105 vat_json_free (&node);
1106
1107 vam->retval = ntohl (mp->retval);
1108 vam->result_ready = 1;
1109}
1110
1111static void vl_api_get_node_index_reply_t_handler
1112 (vl_api_get_node_index_reply_t * mp)
1113{
1114 vat_main_t *vam = &vat_main;
1115 i32 retval = ntohl (mp->retval);
1116 if (vam->async_mode)
1117 {
1118 vam->async_errors += (retval < 0);
1119 }
1120 else
1121 {
1122 vam->retval = retval;
1123 if (retval == 0)
1124 errmsg ("node index %d", ntohl (mp->node_index));
1125 vam->result_ready = 1;
1126 }
1127}
1128
1129static void vl_api_get_node_index_reply_t_handler_json
1130 (vl_api_get_node_index_reply_t * mp)
1131{
1132 vat_main_t *vam = &vat_main;
1133 vat_json_node_t node;
1134
1135 vat_json_init_object (&node);
1136 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1137 vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1138
1139 vat_json_print (vam->ofp, &node);
1140 vat_json_free (&node);
1141
1142 vam->retval = ntohl (mp->retval);
1143 vam->result_ready = 1;
1144}
1145
1146static void vl_api_get_next_index_reply_t_handler
1147 (vl_api_get_next_index_reply_t * mp)
1148{
1149 vat_main_t *vam = &vat_main;
1150 i32 retval = ntohl (mp->retval);
1151 if (vam->async_mode)
1152 {
1153 vam->async_errors += (retval < 0);
1154 }
1155 else
1156 {
1157 vam->retval = retval;
1158 if (retval == 0)
1159 errmsg ("next node index %d", ntohl (mp->next_index));
1160 vam->result_ready = 1;
1161 }
1162}
1163
1164static void vl_api_get_next_index_reply_t_handler_json
1165 (vl_api_get_next_index_reply_t * mp)
1166{
1167 vat_main_t *vam = &vat_main;
1168 vat_json_node_t node;
1169
1170 vat_json_init_object (&node);
1171 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1172 vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1173
1174 vat_json_print (vam->ofp, &node);
1175 vat_json_free (&node);
1176
1177 vam->retval = ntohl (mp->retval);
1178 vam->result_ready = 1;
1179}
1180
1181static void vl_api_add_node_next_reply_t_handler
1182 (vl_api_add_node_next_reply_t * mp)
1183{
1184 vat_main_t *vam = &vat_main;
1185 i32 retval = ntohl (mp->retval);
1186 if (vam->async_mode)
1187 {
1188 vam->async_errors += (retval < 0);
1189 }
1190 else
1191 {
1192 vam->retval = retval;
1193 if (retval == 0)
1194 errmsg ("next index %d", ntohl (mp->next_index));
1195 vam->result_ready = 1;
1196 }
1197}
1198
1199static void vl_api_add_node_next_reply_t_handler_json
1200 (vl_api_add_node_next_reply_t * mp)
1201{
1202 vat_main_t *vam = &vat_main;
1203 vat_json_node_t node;
1204
1205 vat_json_init_object (&node);
1206 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1207 vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1208
1209 vat_json_print (vam->ofp, &node);
1210 vat_json_free (&node);
1211
1212 vam->retval = ntohl (mp->retval);
1213 vam->result_ready = 1;
1214}
1215
1216static void vl_api_show_version_reply_t_handler
1217 (vl_api_show_version_reply_t * mp)
1218{
1219 vat_main_t *vam = &vat_main;
1220 i32 retval = ntohl (mp->retval);
1221
1222 if (retval >= 0)
1223 {
1224 errmsg (" program: %s", mp->program);
1225 errmsg (" version: %s", mp->version);
1226 errmsg (" build date: %s", mp->build_date);
1227 errmsg ("build directory: %s", mp->build_directory);
1228 }
1229 vam->retval = retval;
1230 vam->result_ready = 1;
1231}
1232
1233static void vl_api_show_version_reply_t_handler_json
1234 (vl_api_show_version_reply_t * mp)
1235{
1236 vat_main_t *vam = &vat_main;
1237 vat_json_node_t node;
1238
1239 vat_json_init_object (&node);
1240 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1241 vat_json_object_add_string_copy (&node, "program", mp->program);
1242 vat_json_object_add_string_copy (&node, "version", mp->version);
1243 vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1244 vat_json_object_add_string_copy (&node, "build_directory",
1245 mp->build_directory);
1246
1247 vat_json_print (vam->ofp, &node);
1248 vat_json_free (&node);
1249
1250 vam->retval = ntohl (mp->retval);
1251 vam->result_ready = 1;
1252}
1253
1254static void
1255vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1256{
Wojciech Dec09a38a62017-03-07 19:30:39 +01001257 u32 sw_if_index = ntohl (mp->sw_if_index);
John Lo20e1f2a2017-03-29 13:35:43 -04001258 errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
Damjan Marion7cd468a2016-12-19 23:05:39 +01001259 mp->mac_ip ? "mac/ip binding" : "address resolution",
John Lo20e1f2a2017-03-29 13:35:43 -04001260 ntohl (mp->pid), format_ip4_address, &mp->address,
Wojciech Dec09a38a62017-03-07 19:30:39 +01001261 format_ethernet_address, mp->new_mac, sw_if_index);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001262}
1263
1264static void
1265vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1266{
1267 /* JSON output not supported */
1268}
1269
1270static void
1271vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1272{
Wojciech Dec09a38a62017-03-07 19:30:39 +01001273 u32 sw_if_index = ntohl (mp->sw_if_index);
John Lo20e1f2a2017-03-29 13:35:43 -04001274 errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
Damjan Marion7cd468a2016-12-19 23:05:39 +01001275 mp->mac_ip ? "mac/ip binding" : "address resolution",
John Lo20e1f2a2017-03-29 13:35:43 -04001276 ntohl (mp->pid), format_ip6_address, mp->address,
Wojciech Dec09a38a62017-03-07 19:30:39 +01001277 format_ethernet_address, mp->new_mac, sw_if_index);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001278}
1279
1280static void
1281vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1282{
1283 /* JSON output not supported */
1284}
1285
Ole Troan01384fe2017-05-12 11:55:35 +02001286#define vl_api_bridge_domain_details_t_endian vl_noop_handler
1287#define vl_api_bridge_domain_details_t_print vl_noop_handler
1288
Damjan Marion7cd468a2016-12-19 23:05:39 +01001289/*
1290 * Special-case: build the bridge domain table, maintain
1291 * the next bd id vbl.
1292 */
1293static void vl_api_bridge_domain_details_t_handler
1294 (vl_api_bridge_domain_details_t * mp)
1295{
1296 vat_main_t *vam = &vat_main;
1297 u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
Ole Troan01384fe2017-05-12 11:55:35 +02001298 int i;
Damjan Marion7cd468a2016-12-19 23:05:39 +01001299
1300 print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1301 " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1302
1303 print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1304 ntohl (mp->bd_id), mp->learn, mp->forward,
1305 mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1306
1307 if (n_sw_ifs)
Ole Troan01384fe2017-05-12 11:55:35 +02001308 {
1309 vl_api_bridge_domain_sw_if_t *sw_ifs;
1310 print (vam->ofp, "\n\n%s %s %s", "sw_if_index", "SHG",
1311 "Interface Name");
1312
1313 sw_ifs = mp->sw_if_details;
1314 for (i = 0; i < n_sw_ifs; i++)
1315 {
1316 u8 *sw_if_name = 0;
1317 u32 sw_if_index;
1318 hash_pair_t *p;
1319
1320 sw_if_index = ntohl (sw_ifs->sw_if_index);
1321
1322 /* *INDENT-OFF* */
1323 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1324 ({
1325 if ((u32) p->value[0] == sw_if_index)
1326 {
1327 sw_if_name = (u8 *)(p->key);
1328 break;
1329 }
1330 }));
1331 /* *INDENT-ON* */
1332 print (vam->ofp, "%7d %3d %s", sw_if_index,
1333 sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1334 "sw_if_index not found!");
1335
1336 sw_ifs++;
1337 }
1338 }
Damjan Marion7cd468a2016-12-19 23:05:39 +01001339}
1340
1341static void vl_api_bridge_domain_details_t_handler_json
1342 (vl_api_bridge_domain_details_t * mp)
1343{
1344 vat_main_t *vam = &vat_main;
1345 vat_json_node_t *node, *array = NULL;
Ole Troan01384fe2017-05-12 11:55:35 +02001346 u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001347
1348 if (VAT_JSON_ARRAY != vam->json_tree.type)
1349 {
1350 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1351 vat_json_init_array (&vam->json_tree);
1352 }
1353 node = vat_json_array_add (&vam->json_tree);
1354
1355 vat_json_init_object (node);
1356 vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1357 vat_json_object_add_uint (node, "flood", mp->flood);
1358 vat_json_object_add_uint (node, "forward", mp->forward);
1359 vat_json_object_add_uint (node, "learn", mp->learn);
1360 vat_json_object_add_uint (node, "bvi_sw_if_index",
1361 ntohl (mp->bvi_sw_if_index));
Ole Troan01384fe2017-05-12 11:55:35 +02001362 vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001363 array = vat_json_object_add (node, "sw_if");
1364 vat_json_init_array (array);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001365
Damjan Marion7cd468a2016-12-19 23:05:39 +01001366
Damjan Marion7cd468a2016-12-19 23:05:39 +01001367
Ole Troan01384fe2017-05-12 11:55:35 +02001368 if (n_sw_ifs)
1369 {
1370 vl_api_bridge_domain_sw_if_t *sw_ifs;
1371 int i;
Damjan Marion7cd468a2016-12-19 23:05:39 +01001372
Ole Troan01384fe2017-05-12 11:55:35 +02001373 sw_ifs = mp->sw_if_details;
1374 for (i = 0; i < n_sw_ifs; i++)
1375 {
1376 node = vat_json_array_add (array);
1377 vat_json_init_object (node);
1378 vat_json_object_add_uint (node, "sw_if_index",
1379 ntohl (sw_ifs->sw_if_index));
1380 vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1381 sw_ifs++;
1382 }
1383 }
Damjan Marion7cd468a2016-12-19 23:05:39 +01001384}
1385
1386static void vl_api_control_ping_reply_t_handler
1387 (vl_api_control_ping_reply_t * mp)
1388{
1389 vat_main_t *vam = &vat_main;
1390 i32 retval = ntohl (mp->retval);
1391 if (vam->async_mode)
1392 {
1393 vam->async_errors += (retval < 0);
1394 }
1395 else
1396 {
1397 vam->retval = retval;
1398 vam->result_ready = 1;
1399 }
1400}
1401
1402static void vl_api_control_ping_reply_t_handler_json
1403 (vl_api_control_ping_reply_t * mp)
1404{
1405 vat_main_t *vam = &vat_main;
1406 i32 retval = ntohl (mp->retval);
1407
1408 if (VAT_JSON_NONE != vam->json_tree.type)
1409 {
1410 vat_json_print (vam->ofp, &vam->json_tree);
1411 vat_json_free (&vam->json_tree);
1412 vam->json_tree.type = VAT_JSON_NONE;
1413 }
1414 else
1415 {
1416 /* just print [] */
1417 vat_json_init_array (&vam->json_tree);
1418 vat_json_print (vam->ofp, &vam->json_tree);
1419 vam->json_tree.type = VAT_JSON_NONE;
1420 }
1421
1422 vam->retval = retval;
1423 vam->result_ready = 1;
1424}
1425
1426static void
Eyal Barifead6702017-04-04 04:46:32 +03001427 vl_api_bridge_domain_set_mac_age_reply_t_handler
1428 (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1429{
1430 vat_main_t *vam = &vat_main;
1431 i32 retval = ntohl (mp->retval);
1432 if (vam->async_mode)
1433 {
1434 vam->async_errors += (retval < 0);
1435 }
1436 else
1437 {
1438 vam->retval = retval;
1439 vam->result_ready = 1;
1440 }
1441}
1442
1443static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1444 (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1445{
1446 vat_main_t *vam = &vat_main;
1447 vat_json_node_t node;
1448
1449 vat_json_init_object (&node);
1450 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1451
1452 vat_json_print (vam->ofp, &node);
1453 vat_json_free (&node);
1454
1455 vam->retval = ntohl (mp->retval);
1456 vam->result_ready = 1;
1457}
1458
1459static void
Damjan Marion7cd468a2016-12-19 23:05:39 +01001460vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1461{
1462 vat_main_t *vam = &vat_main;
1463 i32 retval = ntohl (mp->retval);
1464 if (vam->async_mode)
1465 {
1466 vam->async_errors += (retval < 0);
1467 }
1468 else
1469 {
1470 vam->retval = retval;
1471 vam->result_ready = 1;
1472 }
1473}
1474
1475static void vl_api_l2_flags_reply_t_handler_json
1476 (vl_api_l2_flags_reply_t * mp)
1477{
1478 vat_main_t *vam = &vat_main;
1479 vat_json_node_t node;
1480
1481 vat_json_init_object (&node);
1482 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1483 vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1484 ntohl (mp->resulting_feature_bitmap));
1485
1486 vat_json_print (vam->ofp, &node);
1487 vat_json_free (&node);
1488
1489 vam->retval = ntohl (mp->retval);
1490 vam->result_ready = 1;
1491}
1492
1493static void vl_api_bridge_flags_reply_t_handler
1494 (vl_api_bridge_flags_reply_t * mp)
1495{
1496 vat_main_t *vam = &vat_main;
1497 i32 retval = ntohl (mp->retval);
1498 if (vam->async_mode)
1499 {
1500 vam->async_errors += (retval < 0);
1501 }
1502 else
1503 {
1504 vam->retval = retval;
1505 vam->result_ready = 1;
1506 }
1507}
1508
1509static void vl_api_bridge_flags_reply_t_handler_json
1510 (vl_api_bridge_flags_reply_t * mp)
1511{
1512 vat_main_t *vam = &vat_main;
1513 vat_json_node_t node;
1514
1515 vat_json_init_object (&node);
1516 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1517 vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1518 ntohl (mp->resulting_feature_bitmap));
1519
1520 vat_json_print (vam->ofp, &node);
1521 vat_json_free (&node);
1522
1523 vam->retval = ntohl (mp->retval);
1524 vam->result_ready = 1;
1525}
1526
1527static void vl_api_tap_connect_reply_t_handler
1528 (vl_api_tap_connect_reply_t * mp)
1529{
1530 vat_main_t *vam = &vat_main;
1531 i32 retval = ntohl (mp->retval);
1532 if (vam->async_mode)
1533 {
1534 vam->async_errors += (retval < 0);
1535 }
1536 else
1537 {
1538 vam->retval = retval;
1539 vam->sw_if_index = ntohl (mp->sw_if_index);
1540 vam->result_ready = 1;
1541 }
1542
1543}
1544
1545static void vl_api_tap_connect_reply_t_handler_json
1546 (vl_api_tap_connect_reply_t * mp)
1547{
1548 vat_main_t *vam = &vat_main;
1549 vat_json_node_t node;
1550
1551 vat_json_init_object (&node);
1552 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1553 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1554
1555 vat_json_print (vam->ofp, &node);
1556 vat_json_free (&node);
1557
1558 vam->retval = ntohl (mp->retval);
1559 vam->result_ready = 1;
1560
1561}
1562
1563static void
1564vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1565{
1566 vat_main_t *vam = &vat_main;
1567 i32 retval = ntohl (mp->retval);
1568 if (vam->async_mode)
1569 {
1570 vam->async_errors += (retval < 0);
1571 }
1572 else
1573 {
1574 vam->retval = retval;
1575 vam->sw_if_index = ntohl (mp->sw_if_index);
1576 vam->result_ready = 1;
1577 }
1578}
1579
1580static void vl_api_tap_modify_reply_t_handler_json
1581 (vl_api_tap_modify_reply_t * mp)
1582{
1583 vat_main_t *vam = &vat_main;
1584 vat_json_node_t node;
1585
1586 vat_json_init_object (&node);
1587 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1588 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1589
1590 vat_json_print (vam->ofp, &node);
1591 vat_json_free (&node);
1592
1593 vam->retval = ntohl (mp->retval);
1594 vam->result_ready = 1;
1595}
1596
1597static void
1598vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1599{
1600 vat_main_t *vam = &vat_main;
1601 i32 retval = ntohl (mp->retval);
1602 if (vam->async_mode)
1603 {
1604 vam->async_errors += (retval < 0);
1605 }
1606 else
1607 {
1608 vam->retval = retval;
1609 vam->result_ready = 1;
1610 }
1611}
1612
1613static void vl_api_tap_delete_reply_t_handler_json
1614 (vl_api_tap_delete_reply_t * mp)
1615{
1616 vat_main_t *vam = &vat_main;
1617 vat_json_node_t node;
1618
1619 vat_json_init_object (&node);
1620 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1621
1622 vat_json_print (vam->ofp, &node);
1623 vat_json_free (&node);
1624
1625 vam->retval = ntohl (mp->retval);
1626 vam->result_ready = 1;
1627}
1628
1629static void vl_api_mpls_tunnel_add_del_reply_t_handler
1630 (vl_api_mpls_tunnel_add_del_reply_t * mp)
1631{
1632 vat_main_t *vam = &vat_main;
1633 i32 retval = ntohl (mp->retval);
1634 if (vam->async_mode)
1635 {
1636 vam->async_errors += (retval < 0);
1637 }
1638 else
1639 {
1640 vam->retval = retval;
1641 vam->result_ready = 1;
1642 }
1643}
1644
1645static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1646 (vl_api_mpls_tunnel_add_del_reply_t * mp)
1647{
1648 vat_main_t *vam = &vat_main;
1649 vat_json_node_t node;
1650
1651 vat_json_init_object (&node);
1652 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1653 vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1654 ntohl (mp->sw_if_index));
1655
1656 vat_json_print (vam->ofp, &node);
1657 vat_json_free (&node);
1658
1659 vam->retval = ntohl (mp->retval);
1660 vam->result_ready = 1;
1661}
1662
1663static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1664 (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1665{
1666 vat_main_t *vam = &vat_main;
1667 i32 retval = ntohl (mp->retval);
1668 if (vam->async_mode)
1669 {
1670 vam->async_errors += (retval < 0);
1671 }
1672 else
1673 {
1674 vam->retval = retval;
1675 vam->sw_if_index = ntohl (mp->sw_if_index);
1676 vam->result_ready = 1;
1677 }
1678}
1679
1680static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1681 (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1682{
1683 vat_main_t *vam = &vat_main;
1684 vat_json_node_t node;
1685
1686 vat_json_init_object (&node);
1687 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1688 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1689
1690 vat_json_print (vam->ofp, &node);
1691 vat_json_free (&node);
1692
1693 vam->retval = ntohl (mp->retval);
1694 vam->result_ready = 1;
1695}
1696
1697
Filip Tehlar694396d2017-02-17 14:29:11 +01001698static void vl_api_one_add_del_locator_set_reply_t_handler
1699 (vl_api_one_add_del_locator_set_reply_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01001700{
1701 vat_main_t *vam = &vat_main;
1702 i32 retval = ntohl (mp->retval);
1703 if (vam->async_mode)
1704 {
1705 vam->async_errors += (retval < 0);
1706 }
1707 else
1708 {
1709 vam->retval = retval;
1710 vam->result_ready = 1;
1711 }
1712}
1713
Filip Tehlar694396d2017-02-17 14:29:11 +01001714static void vl_api_one_add_del_locator_set_reply_t_handler_json
1715 (vl_api_one_add_del_locator_set_reply_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01001716{
1717 vat_main_t *vam = &vat_main;
1718 vat_json_node_t node;
1719
1720 vat_json_init_object (&node);
1721 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1722 vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1723
1724 vat_json_print (vam->ofp, &node);
1725 vat_json_free (&node);
1726
1727 vam->retval = ntohl (mp->retval);
1728 vam->result_ready = 1;
1729}
1730
1731static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1732 (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1733{
1734 vat_main_t *vam = &vat_main;
1735 i32 retval = ntohl (mp->retval);
1736 if (vam->async_mode)
1737 {
1738 vam->async_errors += (retval < 0);
1739 }
1740 else
1741 {
1742 vam->retval = retval;
1743 vam->sw_if_index = ntohl (mp->sw_if_index);
1744 vam->result_ready = 1;
1745 }
1746}
1747
1748static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1749 (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1750{
1751 vat_main_t *vam = &vat_main;
1752 vat_json_node_t node;
1753
1754 vat_json_init_object (&node);
1755 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1756 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1757
1758 vat_json_print (vam->ofp, &node);
1759 vat_json_free (&node);
1760
1761 vam->retval = ntohl (mp->retval);
1762 vam->result_ready = 1;
1763}
1764
1765static void vl_api_gre_add_del_tunnel_reply_t_handler
1766 (vl_api_gre_add_del_tunnel_reply_t * mp)
1767{
1768 vat_main_t *vam = &vat_main;
1769 i32 retval = ntohl (mp->retval);
1770 if (vam->async_mode)
1771 {
1772 vam->async_errors += (retval < 0);
1773 }
1774 else
1775 {
1776 vam->retval = retval;
1777 vam->sw_if_index = ntohl (mp->sw_if_index);
1778 vam->result_ready = 1;
1779 }
1780}
1781
1782static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1783 (vl_api_gre_add_del_tunnel_reply_t * mp)
1784{
1785 vat_main_t *vam = &vat_main;
1786 vat_json_node_t node;
1787
1788 vat_json_init_object (&node);
1789 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1790 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1791
1792 vat_json_print (vam->ofp, &node);
1793 vat_json_free (&node);
1794
1795 vam->retval = ntohl (mp->retval);
1796 vam->result_ready = 1;
1797}
1798
1799static void vl_api_create_vhost_user_if_reply_t_handler
1800 (vl_api_create_vhost_user_if_reply_t * mp)
1801{
1802 vat_main_t *vam = &vat_main;
1803 i32 retval = ntohl (mp->retval);
1804 if (vam->async_mode)
1805 {
1806 vam->async_errors += (retval < 0);
1807 }
1808 else
1809 {
1810 vam->retval = retval;
1811 vam->sw_if_index = ntohl (mp->sw_if_index);
1812 vam->result_ready = 1;
1813 }
1814}
1815
1816static void vl_api_create_vhost_user_if_reply_t_handler_json
1817 (vl_api_create_vhost_user_if_reply_t * mp)
1818{
1819 vat_main_t *vam = &vat_main;
1820 vat_json_node_t node;
1821
1822 vat_json_init_object (&node);
1823 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1824 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1825
1826 vat_json_print (vam->ofp, &node);
1827 vat_json_free (&node);
1828
1829 vam->retval = ntohl (mp->retval);
1830 vam->result_ready = 1;
1831}
1832
1833static void vl_api_ip_address_details_t_handler
1834 (vl_api_ip_address_details_t * mp)
1835{
1836 vat_main_t *vam = &vat_main;
1837 static ip_address_details_t empty_ip_address_details = { {0} };
1838 ip_address_details_t *address = NULL;
1839 ip_details_t *current_ip_details = NULL;
1840 ip_details_t *details = NULL;
1841
1842 details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1843
1844 if (!details || vam->current_sw_if_index >= vec_len (details)
1845 || !details[vam->current_sw_if_index].present)
1846 {
1847 errmsg ("ip address details arrived but not stored");
1848 errmsg ("ip_dump should be called first");
1849 return;
1850 }
1851
1852 current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1853
1854#define addresses (current_ip_details->addr)
1855
1856 vec_validate_init_empty (addresses, vec_len (addresses),
1857 empty_ip_address_details);
1858
1859 address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1860
1861 clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1862 address->prefix_length = mp->prefix_length;
1863#undef addresses
1864}
1865
1866static void vl_api_ip_address_details_t_handler_json
1867 (vl_api_ip_address_details_t * mp)
1868{
1869 vat_main_t *vam = &vat_main;
1870 vat_json_node_t *node = NULL;
1871 struct in6_addr ip6;
1872 struct in_addr ip4;
1873
1874 if (VAT_JSON_ARRAY != vam->json_tree.type)
1875 {
1876 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1877 vat_json_init_array (&vam->json_tree);
1878 }
1879 node = vat_json_array_add (&vam->json_tree);
1880
1881 vat_json_init_object (node);
1882 if (vam->is_ipv6)
1883 {
1884 clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1885 vat_json_object_add_ip6 (node, "ip", ip6);
1886 }
1887 else
1888 {
1889 clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1890 vat_json_object_add_ip4 (node, "ip", ip4);
1891 }
1892 vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1893}
1894
1895static void
1896vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1897{
1898 vat_main_t *vam = &vat_main;
1899 static ip_details_t empty_ip_details = { 0 };
1900 ip_details_t *ip = NULL;
1901 u32 sw_if_index = ~0;
1902
1903 sw_if_index = ntohl (mp->sw_if_index);
1904
1905 vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1906 sw_if_index, empty_ip_details);
1907
1908 ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1909 sw_if_index);
1910
1911 ip->present = 1;
1912}
1913
1914static void
1915vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1916{
1917 vat_main_t *vam = &vat_main;
1918
1919 if (VAT_JSON_ARRAY != vam->json_tree.type)
1920 {
1921 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1922 vat_json_init_array (&vam->json_tree);
1923 }
1924 vat_json_array_add_uint (&vam->json_tree,
1925 clib_net_to_host_u32 (mp->sw_if_index));
1926}
1927
1928static void vl_api_map_domain_details_t_handler_json
1929 (vl_api_map_domain_details_t * mp)
1930{
1931 vat_json_node_t *node = NULL;
1932 vat_main_t *vam = &vat_main;
1933 struct in6_addr ip6;
1934 struct in_addr ip4;
1935
1936 if (VAT_JSON_ARRAY != vam->json_tree.type)
1937 {
1938 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1939 vat_json_init_array (&vam->json_tree);
1940 }
1941
1942 node = vat_json_array_add (&vam->json_tree);
1943 vat_json_init_object (node);
1944
1945 vat_json_object_add_uint (node, "domain_index",
1946 clib_net_to_host_u32 (mp->domain_index));
1947 clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1948 vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1949 clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1950 vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1951 clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1952 vat_json_object_add_ip6 (node, "ip6_src", ip6);
1953 vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1954 vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1955 vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1956 vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1957 vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1958 vat_json_object_add_int (node, "psid_length", mp->psid_length);
1959 vat_json_object_add_uint (node, "flags", mp->flags);
1960 vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1961 vat_json_object_add_int (node, "is_translation", mp->is_translation);
1962}
1963
1964static void vl_api_map_domain_details_t_handler
1965 (vl_api_map_domain_details_t * mp)
1966{
1967 vat_main_t *vam = &vat_main;
1968
1969 if (mp->is_translation)
1970 {
1971 print (vam->ofp,
1972 "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
1973 format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1974 format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1975 format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1976 clib_net_to_host_u32 (mp->domain_index));
1977 }
1978 else
1979 {
1980 print (vam->ofp,
1981 "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
1982 format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1983 format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1984 format_ip6_address, mp->ip6_src,
1985 clib_net_to_host_u32 (mp->domain_index));
1986 }
1987 print (vam->ofp, " ea-len %d psid-offset %d psid-len %d mtu %d %s",
1988 mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1989 mp->is_translation ? "map-t" : "");
1990}
1991
1992static void vl_api_map_rule_details_t_handler_json
1993 (vl_api_map_rule_details_t * mp)
1994{
1995 struct in6_addr ip6;
1996 vat_json_node_t *node = NULL;
1997 vat_main_t *vam = &vat_main;
1998
1999 if (VAT_JSON_ARRAY != vam->json_tree.type)
2000 {
2001 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2002 vat_json_init_array (&vam->json_tree);
2003 }
2004
2005 node = vat_json_array_add (&vam->json_tree);
2006 vat_json_init_object (node);
2007
2008 vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
2009 clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
2010 vat_json_object_add_ip6 (node, "ip6_dst", ip6);
2011}
2012
2013static void
2014vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
2015{
2016 vat_main_t *vam = &vat_main;
2017 print (vam->ofp, " %d (psid) %U (ip6-dst)",
2018 clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
2019}
2020
2021static void
2022vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2023{
2024 errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2025 "router_addr %U host_mac %U",
John Lo20e1f2a2017-03-29 13:35:43 -04002026 ntohl (mp->pid), mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
Damjan Marion7cd468a2016-12-19 23:05:39 +01002027 format_ip4_address, &mp->host_address,
2028 format_ip4_address, &mp->router_address,
2029 format_ethernet_address, mp->host_mac);
2030}
2031
2032static void vl_api_dhcp_compl_event_t_handler_json
2033 (vl_api_dhcp_compl_event_t * mp)
2034{
2035 /* JSON output not supported */
2036}
2037
2038static void
2039set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2040 u32 counter)
2041{
2042 vat_main_t *vam = &vat_main;
2043 static u64 default_counter = 0;
2044
2045 vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2046 NULL);
2047 vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2048 sw_if_index, default_counter);
2049 vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2050}
2051
2052static void
2053set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2054 interface_counter_t counter)
2055{
2056 vat_main_t *vam = &vat_main;
2057 static interface_counter_t default_counter = { 0, };
2058
2059 vec_validate_init_empty (vam->combined_interface_counters,
2060 vnet_counter_type, NULL);
2061 vec_validate_init_empty (vam->combined_interface_counters
2062 [vnet_counter_type], sw_if_index, default_counter);
2063 vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2064}
2065
Aloys Augustinee551982017-02-17 14:55:29 +01002066static void vl_api_vnet_interface_simple_counters_t_handler
2067 (vl_api_vnet_interface_simple_counters_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002068{
2069 /* not supported */
2070}
2071
Aloys Augustinee551982017-02-17 14:55:29 +01002072static void vl_api_vnet_interface_combined_counters_t_handler
2073 (vl_api_vnet_interface_combined_counters_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002074{
Aloys Augustinee551982017-02-17 14:55:29 +01002075 /* not supported */
2076}
2077
2078static void vl_api_vnet_interface_simple_counters_t_handler_json
2079 (vl_api_vnet_interface_simple_counters_t * mp)
2080{
Damjan Marion7cd468a2016-12-19 23:05:39 +01002081 u64 *v_packets;
2082 u64 packets;
2083 u32 count;
2084 u32 first_sw_if_index;
2085 int i;
2086
2087 count = ntohl (mp->count);
2088 first_sw_if_index = ntohl (mp->first_sw_if_index);
2089
Aloys Augustinee551982017-02-17 14:55:29 +01002090 v_packets = (u64 *) & mp->data;
2091 for (i = 0; i < count; i++)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002092 {
Aloys Augustinee551982017-02-17 14:55:29 +01002093 packets = clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2094 set_simple_interface_counter (mp->vnet_counter_type,
2095 first_sw_if_index + i, packets);
2096 v_packets++;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002097 }
Aloys Augustinee551982017-02-17 14:55:29 +01002098}
2099
2100static void vl_api_vnet_interface_combined_counters_t_handler_json
2101 (vl_api_vnet_interface_combined_counters_t * mp)
2102{
2103 interface_counter_t counter;
2104 vlib_counter_t *v;
2105 u32 first_sw_if_index;
2106 int i;
2107 u32 count;
2108
2109 count = ntohl (mp->count);
2110 first_sw_if_index = ntohl (mp->first_sw_if_index);
2111
2112 v = (vlib_counter_t *) & mp->data;
2113 for (i = 0; i < count; i++)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002114 {
Aloys Augustinee551982017-02-17 14:55:29 +01002115 counter.packets =
2116 clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2117 counter.bytes =
2118 clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2119 set_combined_interface_counter (mp->vnet_counter_type,
2120 first_sw_if_index + i, counter);
2121 v++;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002122 }
2123}
2124
2125static u32
2126ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2127{
2128 vat_main_t *vam = &vat_main;
2129 u32 i;
2130
2131 for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2132 {
2133 if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2134 {
2135 return i;
2136 }
2137 }
2138 return ~0;
2139}
2140
2141static u32
2142ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2143{
2144 vat_main_t *vam = &vat_main;
2145 u32 i;
2146
2147 for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2148 {
2149 if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2150 {
2151 return i;
2152 }
2153 }
2154 return ~0;
2155}
2156
2157static void vl_api_vnet_ip4_fib_counters_t_handler
2158 (vl_api_vnet_ip4_fib_counters_t * mp)
2159{
2160 /* not supported */
2161}
2162
2163static void vl_api_vnet_ip4_fib_counters_t_handler_json
2164 (vl_api_vnet_ip4_fib_counters_t * mp)
2165{
2166 vat_main_t *vam = &vat_main;
2167 vl_api_ip4_fib_counter_t *v;
2168 ip4_fib_counter_t *counter;
2169 struct in_addr ip4;
2170 u32 vrf_id;
2171 u32 vrf_index;
2172 u32 count;
2173 int i;
2174
2175 vrf_id = ntohl (mp->vrf_id);
2176 vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2177 if (~0 == vrf_index)
2178 {
2179 vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2180 vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2181 vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2182 vec_validate (vam->ip4_fib_counters, vrf_index);
2183 vam->ip4_fib_counters[vrf_index] = NULL;
2184 }
2185
2186 vec_free (vam->ip4_fib_counters[vrf_index]);
2187 v = (vl_api_ip4_fib_counter_t *) & mp->c;
2188 count = ntohl (mp->count);
2189 for (i = 0; i < count; i++)
2190 {
2191 vec_validate (vam->ip4_fib_counters[vrf_index], i);
2192 counter = &vam->ip4_fib_counters[vrf_index][i];
2193 clib_memcpy (&ip4, &v->address, sizeof (ip4));
2194 counter->address = ip4;
2195 counter->address_length = v->address_length;
2196 counter->packets = clib_net_to_host_u64 (v->packets);
2197 counter->bytes = clib_net_to_host_u64 (v->bytes);
2198 v++;
2199 }
2200}
2201
Neale Ranns044183f2017-01-24 01:34:25 -08002202static void vl_api_vnet_ip4_nbr_counters_t_handler
2203 (vl_api_vnet_ip4_nbr_counters_t * mp)
2204{
2205 /* not supported */
2206}
2207
2208static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2209 (vl_api_vnet_ip4_nbr_counters_t * mp)
2210{
2211 vat_main_t *vam = &vat_main;
2212 vl_api_ip4_nbr_counter_t *v;
2213 ip4_nbr_counter_t *counter;
2214 u32 sw_if_index;
2215 u32 count;
2216 int i;
2217
2218 sw_if_index = ntohl (mp->sw_if_index);
2219 count = ntohl (mp->count);
2220 vec_validate (vam->ip4_nbr_counters, sw_if_index);
2221
2222 if (mp->begin)
2223 vec_free (vam->ip4_nbr_counters[sw_if_index]);
2224
2225 v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2226 for (i = 0; i < count; i++)
2227 {
2228 vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2229 counter = &vam->ip4_nbr_counters[sw_if_index][i];
2230 counter->address.s_addr = v->address;
2231 counter->packets = clib_net_to_host_u64 (v->packets);
2232 counter->bytes = clib_net_to_host_u64 (v->bytes);
2233 counter->linkt = v->link_type;
2234 v++;
2235 }
2236}
2237
Damjan Marion7cd468a2016-12-19 23:05:39 +01002238static void vl_api_vnet_ip6_fib_counters_t_handler
2239 (vl_api_vnet_ip6_fib_counters_t * mp)
2240{
2241 /* not supported */
2242}
2243
2244static void vl_api_vnet_ip6_fib_counters_t_handler_json
2245 (vl_api_vnet_ip6_fib_counters_t * mp)
2246{
2247 vat_main_t *vam = &vat_main;
2248 vl_api_ip6_fib_counter_t *v;
2249 ip6_fib_counter_t *counter;
2250 struct in6_addr ip6;
2251 u32 vrf_id;
2252 u32 vrf_index;
2253 u32 count;
2254 int i;
2255
2256 vrf_id = ntohl (mp->vrf_id);
2257 vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2258 if (~0 == vrf_index)
2259 {
2260 vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2261 vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2262 vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2263 vec_validate (vam->ip6_fib_counters, vrf_index);
2264 vam->ip6_fib_counters[vrf_index] = NULL;
2265 }
2266
2267 vec_free (vam->ip6_fib_counters[vrf_index]);
2268 v = (vl_api_ip6_fib_counter_t *) & mp->c;
2269 count = ntohl (mp->count);
2270 for (i = 0; i < count; i++)
2271 {
2272 vec_validate (vam->ip6_fib_counters[vrf_index], i);
2273 counter = &vam->ip6_fib_counters[vrf_index][i];
2274 clib_memcpy (&ip6, &v->address, sizeof (ip6));
2275 counter->address = ip6;
2276 counter->address_length = v->address_length;
2277 counter->packets = clib_net_to_host_u64 (v->packets);
2278 counter->bytes = clib_net_to_host_u64 (v->bytes);
2279 v++;
2280 }
2281}
2282
Neale Ranns044183f2017-01-24 01:34:25 -08002283static void vl_api_vnet_ip6_nbr_counters_t_handler
2284 (vl_api_vnet_ip6_nbr_counters_t * mp)
2285{
2286 /* not supported */
2287}
2288
2289static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2290 (vl_api_vnet_ip6_nbr_counters_t * mp)
2291{
2292 vat_main_t *vam = &vat_main;
2293 vl_api_ip6_nbr_counter_t *v;
2294 ip6_nbr_counter_t *counter;
2295 struct in6_addr ip6;
2296 u32 sw_if_index;
2297 u32 count;
2298 int i;
2299
2300 sw_if_index = ntohl (mp->sw_if_index);
2301 count = ntohl (mp->count);
2302 vec_validate (vam->ip6_nbr_counters, sw_if_index);
2303
2304 if (mp->begin)
2305 vec_free (vam->ip6_nbr_counters[sw_if_index]);
2306
2307 v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2308 for (i = 0; i < count; i++)
2309 {
2310 vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2311 counter = &vam->ip6_nbr_counters[sw_if_index][i];
2312 clib_memcpy (&ip6, &v->address, sizeof (ip6));
2313 counter->address = ip6;
2314 counter->packets = clib_net_to_host_u64 (v->packets);
2315 counter->bytes = clib_net_to_host_u64 (v->bytes);
2316 v++;
2317 }
2318}
2319
Damjan Marion7cd468a2016-12-19 23:05:39 +01002320static void vl_api_get_first_msg_id_reply_t_handler
2321 (vl_api_get_first_msg_id_reply_t * mp)
2322{
2323 vat_main_t *vam = &vat_main;
2324 i32 retval = ntohl (mp->retval);
2325
2326 if (vam->async_mode)
2327 {
2328 vam->async_errors += (retval < 0);
2329 }
2330 else
2331 {
2332 vam->retval = retval;
2333 vam->result_ready = 1;
2334 }
2335 if (retval >= 0)
2336 {
2337 errmsg ("first message id %d", ntohs (mp->first_msg_id));
2338 }
2339}
2340
2341static void vl_api_get_first_msg_id_reply_t_handler_json
2342 (vl_api_get_first_msg_id_reply_t * mp)
2343{
2344 vat_main_t *vam = &vat_main;
2345 vat_json_node_t node;
2346
2347 vat_json_init_object (&node);
2348 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2349 vat_json_object_add_uint (&node, "first_msg_id",
2350 (uint) ntohs (mp->first_msg_id));
2351
2352 vat_json_print (vam->ofp, &node);
2353 vat_json_free (&node);
2354
2355 vam->retval = ntohl (mp->retval);
2356 vam->result_ready = 1;
2357}
2358
2359static void vl_api_get_node_graph_reply_t_handler
2360 (vl_api_get_node_graph_reply_t * mp)
2361{
2362 vat_main_t *vam = &vat_main;
2363 api_main_t *am = &api_main;
2364 i32 retval = ntohl (mp->retval);
2365 u8 *pvt_copy, *reply;
2366 void *oldheap;
2367 vlib_node_t *node;
2368 int i;
2369
2370 if (vam->async_mode)
2371 {
2372 vam->async_errors += (retval < 0);
2373 }
2374 else
2375 {
2376 vam->retval = retval;
2377 vam->result_ready = 1;
2378 }
2379
2380 /* "Should never happen..." */
2381 if (retval != 0)
2382 return;
2383
Damjan Marion7bee80c2017-04-26 15:32:12 +02002384 reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002385 pvt_copy = vec_dup (reply);
2386
2387 /* Toss the shared-memory original... */
2388 pthread_mutex_lock (&am->vlib_rp->mutex);
2389 oldheap = svm_push_data_heap (am->vlib_rp);
2390
2391 vec_free (reply);
2392
2393 svm_pop_heap (oldheap);
2394 pthread_mutex_unlock (&am->vlib_rp->mutex);
2395
2396 if (vam->graph_nodes)
2397 {
2398 hash_free (vam->graph_node_index_by_name);
2399
2400 for (i = 0; i < vec_len (vam->graph_nodes); i++)
2401 {
2402 node = vam->graph_nodes[i];
2403 vec_free (node->name);
2404 vec_free (node->next_nodes);
2405 vec_free (node);
2406 }
2407 vec_free (vam->graph_nodes);
2408 }
2409
2410 vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2411 vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2412 vec_free (pvt_copy);
2413
2414 for (i = 0; i < vec_len (vam->graph_nodes); i++)
2415 {
2416 node = vam->graph_nodes[i];
2417 hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2418 }
2419}
2420
2421static void vl_api_get_node_graph_reply_t_handler_json
2422 (vl_api_get_node_graph_reply_t * mp)
2423{
2424 vat_main_t *vam = &vat_main;
2425 api_main_t *am = &api_main;
2426 void *oldheap;
2427 vat_json_node_t node;
2428 u8 *reply;
2429
2430 /* $$$$ make this real? */
2431 vat_json_init_object (&node);
2432 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2433 vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2434
Damjan Marion7bee80c2017-04-26 15:32:12 +02002435 reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002436
2437 /* Toss the shared-memory original... */
2438 pthread_mutex_lock (&am->vlib_rp->mutex);
2439 oldheap = svm_push_data_heap (am->vlib_rp);
2440
2441 vec_free (reply);
2442
2443 svm_pop_heap (oldheap);
2444 pthread_mutex_unlock (&am->vlib_rp->mutex);
2445
2446 vat_json_print (vam->ofp, &node);
2447 vat_json_free (&node);
2448
2449 vam->retval = ntohl (mp->retval);
2450 vam->result_ready = 1;
2451}
2452
2453static void
Filip Tehlar694396d2017-02-17 14:29:11 +01002454vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002455{
2456 vat_main_t *vam = &vat_main;
2457 u8 *s = 0;
2458
2459 if (mp->local)
2460 {
2461 s = format (s, "%=16d%=16d%=16d",
2462 ntohl (mp->sw_if_index), mp->priority, mp->weight);
2463 }
2464 else
2465 {
2466 s = format (s, "%=16U%=16d%=16d",
2467 mp->is_ipv6 ? format_ip6_address :
2468 format_ip4_address,
2469 mp->ip_address, mp->priority, mp->weight);
2470 }
2471
2472 print (vam->ofp, "%v", s);
2473 vec_free (s);
2474}
2475
2476static void
Filip Tehlar694396d2017-02-17 14:29:11 +01002477vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002478{
2479 vat_main_t *vam = &vat_main;
2480 vat_json_node_t *node = NULL;
2481 struct in6_addr ip6;
2482 struct in_addr ip4;
2483
2484 if (VAT_JSON_ARRAY != vam->json_tree.type)
2485 {
2486 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2487 vat_json_init_array (&vam->json_tree);
2488 }
2489 node = vat_json_array_add (&vam->json_tree);
2490 vat_json_init_object (node);
2491
2492 vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2493 vat_json_object_add_uint (node, "priority", mp->priority);
2494 vat_json_object_add_uint (node, "weight", mp->weight);
2495
2496 if (mp->local)
2497 vat_json_object_add_uint (node, "sw_if_index",
2498 clib_net_to_host_u32 (mp->sw_if_index));
2499 else
2500 {
2501 if (mp->is_ipv6)
2502 {
2503 clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2504 vat_json_object_add_ip6 (node, "address", ip6);
2505 }
2506 else
2507 {
2508 clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2509 vat_json_object_add_ip4 (node, "address", ip4);
2510 }
2511 }
2512}
2513
2514static void
Filip Tehlar694396d2017-02-17 14:29:11 +01002515vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2516 mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002517{
2518 vat_main_t *vam = &vat_main;
2519 u8 *ls_name = 0;
2520
2521 ls_name = format (0, "%s", mp->ls_name);
2522
2523 print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2524 ls_name);
2525 vec_free (ls_name);
2526}
2527
2528static void
Filip Tehlar694396d2017-02-17 14:29:11 +01002529 vl_api_one_locator_set_details_t_handler_json
2530 (vl_api_one_locator_set_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002531{
2532 vat_main_t *vam = &vat_main;
2533 vat_json_node_t *node = 0;
2534 u8 *ls_name = 0;
2535
2536 ls_name = format (0, "%s", mp->ls_name);
2537 vec_add1 (ls_name, 0);
2538
2539 if (VAT_JSON_ARRAY != vam->json_tree.type)
2540 {
2541 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2542 vat_json_init_array (&vam->json_tree);
2543 }
2544 node = vat_json_array_add (&vam->json_tree);
2545
2546 vat_json_init_object (node);
2547 vat_json_object_add_string_copy (node, "ls_name", ls_name);
2548 vat_json_object_add_uint (node, "ls_index",
2549 clib_net_to_host_u32 (mp->ls_index));
2550 vec_free (ls_name);
2551}
2552
2553static u8 *
2554format_lisp_flat_eid (u8 * s, va_list * args)
2555{
2556 u32 type = va_arg (*args, u32);
2557 u8 *eid = va_arg (*args, u8 *);
2558 u32 eid_len = va_arg (*args, u32);
2559
2560 switch (type)
2561 {
2562 case 0:
2563 return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2564 case 1:
2565 return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2566 case 2:
2567 return format (s, "%U", format_ethernet_address, eid);
2568 }
2569 return 0;
2570}
2571
2572static u8 *
2573format_lisp_eid_vat (u8 * s, va_list * args)
2574{
2575 u32 type = va_arg (*args, u32);
2576 u8 *eid = va_arg (*args, u8 *);
2577 u32 eid_len = va_arg (*args, u32);
2578 u8 *seid = va_arg (*args, u8 *);
2579 u32 seid_len = va_arg (*args, u32);
2580 u32 is_src_dst = va_arg (*args, u32);
2581
2582 if (is_src_dst)
2583 s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2584
2585 s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2586
2587 return s;
2588}
2589
2590static void
Filip Tehlar694396d2017-02-17 14:29:11 +01002591vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002592{
2593 vat_main_t *vam = &vat_main;
2594 u8 *s = 0, *eid = 0;
2595
2596 if (~0 == mp->locator_set_index)
2597 s = format (0, "action: %d", mp->action);
2598 else
2599 s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2600
2601 eid = format (0, "%U", format_lisp_eid_vat,
2602 mp->eid_type,
2603 mp->eid,
2604 mp->eid_prefix_len,
2605 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2606 vec_add1 (eid, 0);
2607
2608 print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2609 clib_net_to_host_u32 (mp->vni),
2610 eid,
2611 mp->is_local ? "local" : "remote",
2612 s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2613 clib_net_to_host_u16 (mp->key_id), mp->key);
2614
2615 vec_free (s);
2616 vec_free (eid);
2617}
2618
2619static void
Filip Tehlar694396d2017-02-17 14:29:11 +01002620vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
2621 * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002622{
2623 vat_main_t *vam = &vat_main;
2624 vat_json_node_t *node = 0;
2625 u8 *eid = 0;
2626
2627 if (VAT_JSON_ARRAY != vam->json_tree.type)
2628 {
2629 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2630 vat_json_init_array (&vam->json_tree);
2631 }
2632 node = vat_json_array_add (&vam->json_tree);
2633
2634 vat_json_init_object (node);
2635 if (~0 == mp->locator_set_index)
2636 vat_json_object_add_uint (node, "action", mp->action);
2637 else
2638 vat_json_object_add_uint (node, "locator_set_index",
2639 clib_net_to_host_u32 (mp->locator_set_index));
2640
2641 vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2642 eid = format (0, "%U", format_lisp_eid_vat,
2643 mp->eid_type,
2644 mp->eid,
2645 mp->eid_prefix_len,
2646 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2647 vec_add1 (eid, 0);
2648 vat_json_object_add_string_copy (node, "eid", eid);
2649 vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2650 vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2651 vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2652
2653 if (mp->key_id)
2654 {
2655 vat_json_object_add_uint (node, "key_id",
2656 clib_net_to_host_u16 (mp->key_id));
2657 vat_json_object_add_string_copy (node, "key", mp->key);
2658 }
2659 vec_free (eid);
2660}
2661
2662static void
Filip Tehlar4868ff62017-03-09 16:48:39 +01002663vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
2664{
2665 vat_main_t *vam = &vat_main;
2666 u8 *seid = 0, *deid = 0;
2667 u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
2668
2669 deid = format (0, "%U", format_lisp_eid_vat,
2670 mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
2671
2672 seid = format (0, "%U", format_lisp_eid_vat,
2673 mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
2674
2675 vec_add1 (deid, 0);
2676 vec_add1 (seid, 0);
2677
2678 if (mp->is_ip4)
2679 format_ip_address_fcn = format_ip4_address;
2680 else
2681 format_ip_address_fcn = format_ip6_address;
2682
2683
2684 print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
2685 clib_net_to_host_u32 (mp->vni),
2686 seid, deid,
2687 format_ip_address_fcn, mp->lloc,
2688 format_ip_address_fcn, mp->rloc,
2689 clib_net_to_host_u32 (mp->pkt_count),
2690 clib_net_to_host_u32 (mp->bytes));
2691
2692 vec_free (deid);
2693 vec_free (seid);
2694}
2695
2696static void
2697vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
2698{
2699 struct in6_addr ip6;
2700 struct in_addr ip4;
2701 vat_main_t *vam = &vat_main;
2702 vat_json_node_t *node = 0;
2703 u8 *deid = 0, *seid = 0;
2704
2705 if (VAT_JSON_ARRAY != vam->json_tree.type)
2706 {
2707 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2708 vat_json_init_array (&vam->json_tree);
2709 }
2710 node = vat_json_array_add (&vam->json_tree);
2711
2712 vat_json_init_object (node);
2713 deid = format (0, "%U", format_lisp_eid_vat,
2714 mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
2715
2716 seid = format (0, "%U", format_lisp_eid_vat,
2717 mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
2718
2719 vec_add1 (deid, 0);
2720 vec_add1 (seid, 0);
2721
2722 vat_json_object_add_string_copy (node, "seid", seid);
2723 vat_json_object_add_string_copy (node, "deid", deid);
2724 vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2725
2726 if (mp->is_ip4)
2727 {
2728 clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
2729 vat_json_object_add_ip4 (node, "lloc", ip4);
2730 clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
2731 vat_json_object_add_ip4 (node, "rloc", ip4);
2732 }
2733 else
2734 {
2735 clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
2736 vat_json_object_add_ip6 (node, "lloc", ip6);
2737 clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
2738 vat_json_object_add_ip6 (node, "rloc", ip6);
2739 }
2740 vat_json_object_add_uint (node, "pkt_count",
2741 clib_net_to_host_u32 (mp->pkt_count));
2742 vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
2743
2744 vec_free (deid);
2745 vec_free (seid);
2746}
2747
2748static void
Filip Tehlar694396d2017-02-17 14:29:11 +01002749 vl_api_one_eid_table_map_details_t_handler
2750 (vl_api_one_eid_table_map_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002751{
2752 vat_main_t *vam = &vat_main;
2753
2754 u8 *line = format (0, "%=10d%=10d",
2755 clib_net_to_host_u32 (mp->vni),
2756 clib_net_to_host_u32 (mp->dp_table));
2757 print (vam->ofp, "%v", line);
2758 vec_free (line);
2759}
2760
2761static void
Filip Tehlar694396d2017-02-17 14:29:11 +01002762 vl_api_one_eid_table_map_details_t_handler_json
2763 (vl_api_one_eid_table_map_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002764{
2765 vat_main_t *vam = &vat_main;
2766 vat_json_node_t *node = NULL;
2767
2768 if (VAT_JSON_ARRAY != vam->json_tree.type)
2769 {
2770 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2771 vat_json_init_array (&vam->json_tree);
2772 }
2773 node = vat_json_array_add (&vam->json_tree);
2774 vat_json_init_object (node);
2775 vat_json_object_add_uint (node, "dp_table",
2776 clib_net_to_host_u32 (mp->dp_table));
2777 vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2778}
2779
2780static void
Filip Tehlar694396d2017-02-17 14:29:11 +01002781 vl_api_one_eid_table_vni_details_t_handler
2782 (vl_api_one_eid_table_vni_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002783{
2784 vat_main_t *vam = &vat_main;
2785
2786 u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2787 print (vam->ofp, "%v", line);
2788 vec_free (line);
2789}
2790
2791static void
Filip Tehlar694396d2017-02-17 14:29:11 +01002792 vl_api_one_eid_table_vni_details_t_handler_json
2793 (vl_api_one_eid_table_vni_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002794{
2795 vat_main_t *vam = &vat_main;
2796 vat_json_node_t *node = NULL;
2797
2798 if (VAT_JSON_ARRAY != vam->json_tree.type)
2799 {
2800 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2801 vat_json_init_array (&vam->json_tree);
2802 }
2803 node = vat_json_array_add (&vam->json_tree);
2804 vat_json_init_object (node);
2805 vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2806}
2807
Damjan Marion7cd468a2016-12-19 23:05:39 +01002808static void
Filip Tehlar694396d2017-02-17 14:29:11 +01002809 vl_api_show_one_map_register_state_reply_t_handler
2810 (vl_api_show_one_map_register_state_reply_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002811{
2812 vat_main_t *vam = &vat_main;
2813 int retval = clib_net_to_host_u32 (mp->retval);
2814
2815 print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2816
2817 vam->retval = retval;
2818 vam->result_ready = 1;
2819}
2820
2821static void
Filip Tehlar694396d2017-02-17 14:29:11 +01002822 vl_api_show_one_map_register_state_reply_t_handler_json
2823 (vl_api_show_one_map_register_state_reply_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002824{
2825 vat_main_t *vam = &vat_main;
2826 vat_json_node_t _node, *node = &_node;
2827 int retval = clib_net_to_host_u32 (mp->retval);
2828
2829 u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2830
2831 vat_json_init_object (node);
2832 vat_json_object_add_string_copy (node, "state", s);
2833
2834 vat_json_print (vam->ofp, node);
2835 vat_json_free (node);
2836
2837 vam->retval = retval;
2838 vam->result_ready = 1;
2839 vec_free (s);
2840}
2841
2842static void
Filip Tehlar694396d2017-02-17 14:29:11 +01002843 vl_api_show_one_rloc_probe_state_reply_t_handler
2844 (vl_api_show_one_rloc_probe_state_reply_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002845{
2846 vat_main_t *vam = &vat_main;
2847 int retval = clib_net_to_host_u32 (mp->retval);
2848
2849 if (retval)
2850 goto end;
2851
2852 print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2853end:
2854 vam->retval = retval;
2855 vam->result_ready = 1;
2856}
2857
2858static void
Filip Tehlar694396d2017-02-17 14:29:11 +01002859 vl_api_show_one_rloc_probe_state_reply_t_handler_json
2860 (vl_api_show_one_rloc_probe_state_reply_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002861{
2862 vat_main_t *vam = &vat_main;
2863 vat_json_node_t _node, *node = &_node;
2864 int retval = clib_net_to_host_u32 (mp->retval);
2865
2866 u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2867 vat_json_init_object (node);
2868 vat_json_object_add_string_copy (node, "state", s);
2869
2870 vat_json_print (vam->ofp, node);
2871 vat_json_free (node);
2872
2873 vam->retval = retval;
2874 vam->result_ready = 1;
2875 vec_free (s);
2876}
2877
2878static void
Filip Tehlar4868ff62017-03-09 16:48:39 +01002879 vl_api_show_one_stats_enable_disable_reply_t_handler
2880 (vl_api_show_one_stats_enable_disable_reply_t * mp)
2881{
2882 vat_main_t *vam = &vat_main;
2883 int retval = clib_net_to_host_u32 (mp->retval);
2884
2885 if (retval)
2886 goto end;
2887
2888 print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
2889end:
2890 vam->retval = retval;
2891 vam->result_ready = 1;
2892}
2893
2894static void
2895 vl_api_show_one_stats_enable_disable_reply_t_handler_json
2896 (vl_api_show_one_stats_enable_disable_reply_t * mp)
2897{
2898 vat_main_t *vam = &vat_main;
2899 vat_json_node_t _node, *node = &_node;
2900 int retval = clib_net_to_host_u32 (mp->retval);
2901
2902 u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
2903 vat_json_init_object (node);
2904 vat_json_object_add_string_copy (node, "state", s);
2905
2906 vat_json_print (vam->ofp, node);
2907 vat_json_free (node);
2908
2909 vam->retval = retval;
2910 vam->result_ready = 1;
2911 vec_free (s);
2912}
2913
2914static void
Filip Tehlar82786c42017-02-20 15:20:37 +01002915api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
Filip Tehlar5fae99c2017-01-18 12:57:37 +01002916{
2917 e->dp_table = clib_net_to_host_u32 (e->dp_table);
2918 e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
Filip Tehlar0eb874e2017-05-18 14:23:32 +02002919 e->vni = clib_net_to_host_u32 (e->vni);
Filip Tehlar5fae99c2017-01-18 12:57:37 +01002920}
2921
2922static void
Filip Tehlar82786c42017-02-20 15:20:37 +01002923 gpe_fwd_entries_get_reply_t_net_to_host
2924 (vl_api_gpe_fwd_entries_get_reply_t * mp)
Filip Tehlar5fae99c2017-01-18 12:57:37 +01002925{
2926 u32 i;
2927
2928 mp->count = clib_net_to_host_u32 (mp->count);
2929 for (i = 0; i < mp->count; i++)
2930 {
Filip Tehlar82786c42017-02-20 15:20:37 +01002931 api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
Filip Tehlar5fae99c2017-01-18 12:57:37 +01002932 }
2933}
2934
Filip Tehlar3e7b56932017-02-21 18:28:34 +01002935static u8 *
2936format_gpe_encap_mode (u8 * s, va_list * args)
2937{
2938 u32 mode = va_arg (*args, u32);
2939
2940 switch (mode)
2941 {
2942 case 0:
2943 return format (s, "lisp");
2944 case 1:
2945 return format (s, "vxlan");
2946 }
2947 return 0;
2948}
2949
2950static void
2951 vl_api_gpe_get_encap_mode_reply_t_handler
2952 (vl_api_gpe_get_encap_mode_reply_t * mp)
2953{
2954 vat_main_t *vam = &vat_main;
2955
2956 print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
2957 vam->retval = ntohl (mp->retval);
2958 vam->result_ready = 1;
2959}
2960
2961static void
2962 vl_api_gpe_get_encap_mode_reply_t_handler_json
2963 (vl_api_gpe_get_encap_mode_reply_t * mp)
2964{
2965 vat_main_t *vam = &vat_main;
2966 vat_json_node_t node;
2967
2968 u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
2969 vec_add1 (encap_mode, 0);
2970
2971 vat_json_init_object (&node);
2972 vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
2973
2974 vec_free (encap_mode);
2975 vat_json_print (vam->ofp, &node);
2976 vat_json_free (&node);
2977
2978 vam->retval = ntohl (mp->retval);
2979 vam->result_ready = 1;
2980}
2981
Filip Tehlar5fae99c2017-01-18 12:57:37 +01002982static void
Filip Tehlar82786c42017-02-20 15:20:37 +01002983 vl_api_gpe_fwd_entry_path_details_t_handler
2984 (vl_api_gpe_fwd_entry_path_details_t * mp)
Filip Tehlar5fae99c2017-01-18 12:57:37 +01002985{
2986 vat_main_t *vam = &vat_main;
2987 u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
2988
2989 if (mp->lcl_loc.is_ip4)
2990 format_ip_address_fcn = format_ip4_address;
2991 else
2992 format_ip_address_fcn = format_ip6_address;
2993
2994 print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
2995 format_ip_address_fcn, &mp->lcl_loc,
2996 format_ip_address_fcn, &mp->rmt_loc);
2997}
2998
2999static void
Filip Tehlar82786c42017-02-20 15:20:37 +01003000lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
Filip Tehlar5fae99c2017-01-18 12:57:37 +01003001{
3002 struct in6_addr ip6;
3003 struct in_addr ip4;
3004
3005 if (loc->is_ip4)
3006 {
3007 clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3008 vat_json_object_add_ip4 (n, "address", ip4);
3009 }
3010 else
3011 {
3012 clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3013 vat_json_object_add_ip6 (n, "address", ip6);
3014 }
3015 vat_json_object_add_uint (n, "weight", loc->weight);
3016}
3017
3018static void
Filip Tehlar82786c42017-02-20 15:20:37 +01003019 vl_api_gpe_fwd_entry_path_details_t_handler_json
3020 (vl_api_gpe_fwd_entry_path_details_t * mp)
Filip Tehlar5fae99c2017-01-18 12:57:37 +01003021{
3022 vat_main_t *vam = &vat_main;
3023 vat_json_node_t *node = NULL;
3024 vat_json_node_t *loc_node;
3025
3026 if (VAT_JSON_ARRAY != vam->json_tree.type)
3027 {
3028 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3029 vat_json_init_array (&vam->json_tree);
3030 }
3031 node = vat_json_array_add (&vam->json_tree);
3032 vat_json_init_object (node);
3033
3034 loc_node = vat_json_object_add (node, "local_locator");
3035 vat_json_init_object (loc_node);
3036 lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3037
3038 loc_node = vat_json_object_add (node, "remote_locator");
3039 vat_json_init_object (loc_node);
3040 lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3041}
3042
3043static void
Filip Tehlar82786c42017-02-20 15:20:37 +01003044 vl_api_gpe_fwd_entries_get_reply_t_handler
3045 (vl_api_gpe_fwd_entries_get_reply_t * mp)
Filip Tehlar5fae99c2017-01-18 12:57:37 +01003046{
3047 vat_main_t *vam = &vat_main;
3048 u32 i;
3049 int retval = clib_net_to_host_u32 (mp->retval);
Filip Tehlar82786c42017-02-20 15:20:37 +01003050 vl_api_gpe_fwd_entry_t *e;
Filip Tehlar5fae99c2017-01-18 12:57:37 +01003051
3052 if (retval)
3053 goto end;
3054
Filip Tehlar82786c42017-02-20 15:20:37 +01003055 gpe_fwd_entries_get_reply_t_net_to_host (mp);
Filip Tehlar5fae99c2017-01-18 12:57:37 +01003056
3057 for (i = 0; i < mp->count; i++)
3058 {
3059 e = &mp->entries[i];
3060 print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3061 format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3062 format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3063 }
3064
3065end:
3066 vam->retval = retval;
3067 vam->result_ready = 1;
3068}
3069
3070static void
Filip Tehlar82786c42017-02-20 15:20:37 +01003071 vl_api_gpe_fwd_entries_get_reply_t_handler_json
3072 (vl_api_gpe_fwd_entries_get_reply_t * mp)
Filip Tehlar5fae99c2017-01-18 12:57:37 +01003073{
3074 u8 *s = 0;
3075 vat_main_t *vam = &vat_main;
3076 vat_json_node_t *e = 0, root;
3077 u32 i;
3078 int retval = clib_net_to_host_u32 (mp->retval);
Filip Tehlar82786c42017-02-20 15:20:37 +01003079 vl_api_gpe_fwd_entry_t *fwd;
Filip Tehlar5fae99c2017-01-18 12:57:37 +01003080
3081 if (retval)
3082 goto end;
3083
Filip Tehlar82786c42017-02-20 15:20:37 +01003084 gpe_fwd_entries_get_reply_t_net_to_host (mp);
Filip Tehlar5fae99c2017-01-18 12:57:37 +01003085 vat_json_init_array (&root);
3086
3087 for (i = 0; i < mp->count; i++)
3088 {
3089 e = vat_json_array_add (&root);
3090 fwd = &mp->entries[i];
3091
3092 vat_json_init_object (e);
3093 vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3094 vat_json_object_add_int (e, "dp_table", fwd->dp_table);
Filip Tehlar0eb874e2017-05-18 14:23:32 +02003095 vat_json_object_add_int (e, "vni", fwd->vni);
3096 vat_json_object_add_int (e, "action", fwd->action);
Filip Tehlar5fae99c2017-01-18 12:57:37 +01003097
3098 s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3099 fwd->leid_prefix_len);
3100 vec_add1 (s, 0);
3101 vat_json_object_add_string_copy (e, "leid", s);
3102 vec_free (s);
3103
3104 s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3105 fwd->reid_prefix_len);
3106 vec_add1 (s, 0);
3107 vat_json_object_add_string_copy (e, "reid", s);
3108 vec_free (s);
3109 }
3110
3111 vat_json_print (vam->ofp, &root);
3112 vat_json_free (&root);
3113
3114end:
3115 vam->retval = retval;
3116 vam->result_ready = 1;
3117}
3118
3119static void
Filip Tehlar0eb874e2017-05-18 14:23:32 +02003120 vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3121 (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3122{
3123 vat_main_t *vam = &vat_main;
3124 u32 i, n;
3125 int retval = clib_net_to_host_u32 (mp->retval);
3126
3127 if (retval)
3128 goto end;
3129
3130 n = clib_net_to_host_u32 (mp->count);
3131
3132 for (i = 0; i < n; i++)
3133 print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3134
3135end:
3136 vam->retval = retval;
3137 vam->result_ready = 1;
3138}
3139
3140static void
3141 vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3142 (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3143{
3144 vat_main_t *vam = &vat_main;
3145 vat_json_node_t root;
3146 u32 i, n;
3147 int retval = clib_net_to_host_u32 (mp->retval);
3148
3149 if (retval)
3150 goto end;
3151
3152 n = clib_net_to_host_u32 (mp->count);
3153 vat_json_init_array (&root);
3154
3155 for (i = 0; i < n; i++)
3156 vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3157
3158 vat_json_print (vam->ofp, &root);
3159 vat_json_free (&root);
3160
3161end:
3162 vam->retval = retval;
3163 vam->result_ready = 1;
3164}
3165
3166static void
Filip Tehlar694396d2017-02-17 14:29:11 +01003167 vl_api_one_adjacencies_get_reply_t_handler
3168 (vl_api_one_adjacencies_get_reply_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01003169{
3170 vat_main_t *vam = &vat_main;
3171 u32 i, n;
3172 int retval = clib_net_to_host_u32 (mp->retval);
Filip Tehlar694396d2017-02-17 14:29:11 +01003173 vl_api_one_adjacency_t *a;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003174
3175 if (retval)
3176 goto end;
3177
3178 n = clib_net_to_host_u32 (mp->count);
3179
3180 for (i = 0; i < n; i++)
3181 {
3182 a = &mp->adjacencies[i];
3183 print (vam->ofp, "%U %40U",
3184 format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3185 format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3186 }
3187
3188end:
3189 vam->retval = retval;
3190 vam->result_ready = 1;
3191}
3192
3193static void
Filip Tehlar694396d2017-02-17 14:29:11 +01003194 vl_api_one_adjacencies_get_reply_t_handler_json
3195 (vl_api_one_adjacencies_get_reply_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01003196{
3197 u8 *s = 0;
3198 vat_main_t *vam = &vat_main;
3199 vat_json_node_t *e = 0, root;
3200 u32 i, n;
3201 int retval = clib_net_to_host_u32 (mp->retval);
Filip Tehlar694396d2017-02-17 14:29:11 +01003202 vl_api_one_adjacency_t *a;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003203
3204 if (retval)
3205 goto end;
3206
3207 n = clib_net_to_host_u32 (mp->count);
3208 vat_json_init_array (&root);
3209
3210 for (i = 0; i < n; i++)
3211 {
3212 e = vat_json_array_add (&root);
3213 a = &mp->adjacencies[i];
3214
3215 vat_json_init_object (e);
3216 s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
3217 a->leid_prefix_len);
3218 vec_add1 (s, 0);
3219 vat_json_object_add_string_copy (e, "leid", s);
3220 vec_free (s);
3221
3222 s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
3223 a->reid_prefix_len);
3224 vec_add1 (s, 0);
3225 vat_json_object_add_string_copy (e, "reid", s);
3226 vec_free (s);
3227 }
3228
3229 vat_json_print (vam->ofp, &root);
3230 vat_json_free (&root);
3231
3232end:
3233 vam->retval = retval;
3234 vam->result_ready = 1;
3235}
3236
3237static void
Filip Tehlar694396d2017-02-17 14:29:11 +01003238vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01003239{
3240 vat_main_t *vam = &vat_main;
3241
3242 print (vam->ofp, "%=20U",
3243 mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3244 mp->ip_address);
3245}
3246
3247static void
Filip Tehlar694396d2017-02-17 14:29:11 +01003248 vl_api_one_map_server_details_t_handler_json
3249 (vl_api_one_map_server_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01003250{
3251 vat_main_t *vam = &vat_main;
3252 vat_json_node_t *node = NULL;
3253 struct in6_addr ip6;
3254 struct in_addr ip4;
3255
3256 if (VAT_JSON_ARRAY != vam->json_tree.type)
3257 {
3258 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3259 vat_json_init_array (&vam->json_tree);
3260 }
3261 node = vat_json_array_add (&vam->json_tree);
3262
3263 vat_json_init_object (node);
3264 if (mp->is_ipv6)
3265 {
3266 clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3267 vat_json_object_add_ip6 (node, "map-server", ip6);
3268 }
3269 else
3270 {
3271 clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3272 vat_json_object_add_ip4 (node, "map-server", ip4);
3273 }
3274}
3275
3276static void
Filip Tehlar694396d2017-02-17 14:29:11 +01003277vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
3278 * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01003279{
3280 vat_main_t *vam = &vat_main;
3281
3282 print (vam->ofp, "%=20U",
3283 mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3284 mp->ip_address);
3285}
3286
3287static void
Filip Tehlar694396d2017-02-17 14:29:11 +01003288 vl_api_one_map_resolver_details_t_handler_json
3289 (vl_api_one_map_resolver_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01003290{
3291 vat_main_t *vam = &vat_main;
3292 vat_json_node_t *node = NULL;
3293 struct in6_addr ip6;
3294 struct in_addr ip4;
3295
3296 if (VAT_JSON_ARRAY != vam->json_tree.type)
3297 {
3298 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3299 vat_json_init_array (&vam->json_tree);
3300 }
3301 node = vat_json_array_add (&vam->json_tree);
3302
3303 vat_json_init_object (node);
3304 if (mp->is_ipv6)
3305 {
3306 clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3307 vat_json_object_add_ip6 (node, "map resolver", ip6);
3308 }
3309 else
3310 {
3311 clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3312 vat_json_object_add_ip4 (node, "map resolver", ip4);
3313 }
3314}
3315
3316static void
Filip Tehlar694396d2017-02-17 14:29:11 +01003317vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01003318{
3319 vat_main_t *vam = &vat_main;
3320 i32 retval = ntohl (mp->retval);
3321
3322 if (0 <= retval)
3323 {
3324 print (vam->ofp, "feature: %s\ngpe: %s",
3325 mp->feature_status ? "enabled" : "disabled",
3326 mp->gpe_status ? "enabled" : "disabled");
3327 }
3328
3329 vam->retval = retval;
3330 vam->result_ready = 1;
3331}
3332
3333static void
Filip Tehlar694396d2017-02-17 14:29:11 +01003334 vl_api_show_one_status_reply_t_handler_json
3335 (vl_api_show_one_status_reply_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01003336{
3337 vat_main_t *vam = &vat_main;
3338 vat_json_node_t node;
3339 u8 *gpe_status = NULL;
3340 u8 *feature_status = NULL;
3341
3342 gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
3343 feature_status = format (0, "%s",
3344 mp->feature_status ? "enabled" : "disabled");
3345 vec_add1 (gpe_status, 0);
3346 vec_add1 (feature_status, 0);
3347
3348 vat_json_init_object (&node);
3349 vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
3350 vat_json_object_add_string_copy (&node, "feature_status", feature_status);
3351
3352 vec_free (gpe_status);
3353 vec_free (feature_status);
3354
3355 vat_json_print (vam->ofp, &node);
3356 vat_json_free (&node);
3357
3358 vam->retval = ntohl (mp->retval);
3359 vam->result_ready = 1;
3360}
3361
3362static void
Filip Tehlar694396d2017-02-17 14:29:11 +01003363 vl_api_one_get_map_request_itr_rlocs_reply_t_handler
3364 (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01003365{
3366 vat_main_t *vam = &vat_main;
3367 i32 retval = ntohl (mp->retval);
3368
3369 if (retval >= 0)
3370 {
3371 print (vam->ofp, "%=20s", mp->locator_set_name);
3372 }
3373
3374 vam->retval = retval;
3375 vam->result_ready = 1;
3376}
3377
3378static void
Filip Tehlar694396d2017-02-17 14:29:11 +01003379 vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
3380 (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01003381{
3382 vat_main_t *vam = &vat_main;
3383 vat_json_node_t *node = NULL;
3384
3385 if (VAT_JSON_ARRAY != vam->json_tree.type)
3386 {
3387 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3388 vat_json_init_array (&vam->json_tree);
3389 }
3390 node = vat_json_array_add (&vam->json_tree);
3391
3392 vat_json_init_object (node);
3393 vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
3394
3395 vat_json_print (vam->ofp, node);
3396 vat_json_free (node);
3397
3398 vam->retval = ntohl (mp->retval);
3399 vam->result_ready = 1;
3400}
3401
3402static u8 *
3403format_lisp_map_request_mode (u8 * s, va_list * args)
3404{
3405 u32 mode = va_arg (*args, u32);
3406
3407 switch (mode)
3408 {
3409 case 0:
3410 return format (0, "dst-only");
3411 case 1:
3412 return format (0, "src-dst");
3413 }
3414 return 0;
3415}
3416
3417static void
Filip Tehlar694396d2017-02-17 14:29:11 +01003418 vl_api_show_one_map_request_mode_reply_t_handler
3419 (vl_api_show_one_map_request_mode_reply_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01003420{
3421 vat_main_t *vam = &vat_main;
3422 i32 retval = ntohl (mp->retval);
3423
3424 if (0 <= retval)
3425 {
3426 u32 mode = mp->mode;
3427 print (vam->ofp, "map_request_mode: %U",
3428 format_lisp_map_request_mode, mode);
3429 }
3430
3431 vam->retval = retval;
3432 vam->result_ready = 1;
3433}
3434
3435static void
Filip Tehlar694396d2017-02-17 14:29:11 +01003436 vl_api_show_one_map_request_mode_reply_t_handler_json
3437 (vl_api_show_one_map_request_mode_reply_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01003438{
3439 vat_main_t *vam = &vat_main;
3440 vat_json_node_t node;
3441 u8 *s = 0;
3442 u32 mode;
3443
3444 mode = mp->mode;
3445 s = format (0, "%U", format_lisp_map_request_mode, mode);
3446 vec_add1 (s, 0);
3447
3448 vat_json_init_object (&node);
3449 vat_json_object_add_string_copy (&node, "map_request_mode", s);
3450 vat_json_print (vam->ofp, &node);
3451 vat_json_free (&node);
3452
3453 vec_free (s);
3454 vam->retval = ntohl (mp->retval);
3455 vam->result_ready = 1;
3456}
3457
3458static void
Filip Tehlar67a99f82017-03-10 13:18:02 +01003459 vl_api_show_one_use_petr_reply_t_handler
3460 (vl_api_show_one_use_petr_reply_t * mp)
3461{
3462 vat_main_t *vam = &vat_main;
3463 i32 retval = ntohl (mp->retval);
3464
3465 if (0 <= retval)
3466 {
3467 print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
3468 if (mp->status)
3469 {
3470 print (vam->ofp, "Proxy-ETR address; %U",
3471 mp->is_ip4 ? format_ip4_address : format_ip6_address,
3472 mp->address);
3473 }
3474 }
3475
3476 vam->retval = retval;
3477 vam->result_ready = 1;
3478}
3479
3480static void
3481 vl_api_show_one_use_petr_reply_t_handler_json
3482 (vl_api_show_one_use_petr_reply_t * mp)
3483{
3484 vat_main_t *vam = &vat_main;
3485 vat_json_node_t node;
3486 u8 *status = 0;
3487 struct in_addr ip4;
3488 struct in6_addr ip6;
3489
3490 status = format (0, "%s", mp->status ? "enabled" : "disabled");
3491 vec_add1 (status, 0);
3492
3493 vat_json_init_object (&node);
3494 vat_json_object_add_string_copy (&node, "status", status);
3495 if (mp->status)
3496 {
3497 if (mp->is_ip4)
3498 {
3499 clib_memcpy (&ip6, mp->address, sizeof (ip6));
3500 vat_json_object_add_ip6 (&node, "address", ip6);
3501 }
3502 else
3503 {
3504 clib_memcpy (&ip4, mp->address, sizeof (ip4));
3505 vat_json_object_add_ip4 (&node, "address", ip4);
3506 }
3507 }
3508
3509 vec_free (status);
3510
3511 vat_json_print (vam->ofp, &node);
3512 vat_json_free (&node);
3513
3514 vam->retval = ntohl (mp->retval);
3515 vam->result_ready = 1;
3516}
3517
3518static void
Filip Tehlar694396d2017-02-17 14:29:11 +01003519vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01003520{
3521 vat_main_t *vam = &vat_main;
3522 i32 retval = ntohl (mp->retval);
3523
3524 if (0 <= retval)
3525 {
3526 print (vam->ofp, "%-20s%-16s",
3527 mp->status ? "enabled" : "disabled",
3528 mp->status ? (char *) mp->locator_set_name : "");
3529 }
3530
3531 vam->retval = retval;
3532 vam->result_ready = 1;
3533}
3534
3535static void
Filip Tehlar694396d2017-02-17 14:29:11 +01003536vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01003537{
3538 vat_main_t *vam = &vat_main;
3539 vat_json_node_t node;
3540 u8 *status = 0;
3541
3542 status = format (0, "%s", mp->status ? "enabled" : "disabled");
3543 vec_add1 (status, 0);
3544
3545 vat_json_init_object (&node);
3546 vat_json_object_add_string_copy (&node, "status", status);
3547 if (mp->status)
3548 {
3549 vat_json_object_add_string_copy (&node, "locator_set",
3550 mp->locator_set_name);
3551 }
3552
3553 vec_free (status);
3554
3555 vat_json_print (vam->ofp, &node);
3556 vat_json_free (&node);
3557
3558 vam->retval = ntohl (mp->retval);
3559 vam->result_ready = 1;
3560}
3561
3562static u8 *
3563format_policer_type (u8 * s, va_list * va)
3564{
3565 u32 i = va_arg (*va, u32);
3566
3567 if (i == SSE2_QOS_POLICER_TYPE_1R2C)
3568 s = format (s, "1r2c");
3569 else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
3570 s = format (s, "1r3c");
3571 else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
3572 s = format (s, "2r3c-2698");
3573 else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
3574 s = format (s, "2r3c-4115");
3575 else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
3576 s = format (s, "2r3c-mef5cf1");
3577 else
3578 s = format (s, "ILLEGAL");
3579 return s;
3580}
3581
3582static u8 *
3583format_policer_rate_type (u8 * s, va_list * va)
3584{
3585 u32 i = va_arg (*va, u32);
3586
3587 if (i == SSE2_QOS_RATE_KBPS)
3588 s = format (s, "kbps");
3589 else if (i == SSE2_QOS_RATE_PPS)
3590 s = format (s, "pps");
3591 else
3592 s = format (s, "ILLEGAL");
3593 return s;
3594}
3595
3596static u8 *
3597format_policer_round_type (u8 * s, va_list * va)
3598{
3599 u32 i = va_arg (*va, u32);
3600
3601 if (i == SSE2_QOS_ROUND_TO_CLOSEST)
3602 s = format (s, "closest");
3603 else if (i == SSE2_QOS_ROUND_TO_UP)
3604 s = format (s, "up");
3605 else if (i == SSE2_QOS_ROUND_TO_DOWN)
3606 s = format (s, "down");
3607 else
3608 s = format (s, "ILLEGAL");
3609 return s;
3610}
3611
3612static u8 *
3613format_policer_action_type (u8 * s, va_list * va)
3614{
3615 u32 i = va_arg (*va, u32);
3616
3617 if (i == SSE2_QOS_ACTION_DROP)
3618 s = format (s, "drop");
3619 else if (i == SSE2_QOS_ACTION_TRANSMIT)
3620 s = format (s, "transmit");
3621 else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3622 s = format (s, "mark-and-transmit");
3623 else
3624 s = format (s, "ILLEGAL");
3625 return s;
3626}
3627
3628static u8 *
3629format_dscp (u8 * s, va_list * va)
3630{
3631 u32 i = va_arg (*va, u32);
3632 char *t = 0;
3633
3634 switch (i)
3635 {
3636#define _(v,f,str) case VNET_DSCP_##f: t = str; break;
3637 foreach_vnet_dscp
3638#undef _
3639 default:
3640 return format (s, "ILLEGAL");
3641 }
3642 s = format (s, "%s", t);
3643 return s;
3644}
3645
3646static void
3647vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
3648{
3649 vat_main_t *vam = &vat_main;
3650 u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
3651
3652 if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3653 conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3654 else
3655 conform_dscp_str = format (0, "");
3656
3657 if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3658 exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3659 else
3660 exceed_dscp_str = format (0, "");
3661
3662 if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3663 violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3664 else
3665 violate_dscp_str = format (0, "");
3666
3667 print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
3668 "rate type %U, round type %U, %s rate, %s color-aware, "
3669 "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
3670 "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
3671 "conform action %U%s, exceed action %U%s, violate action %U%s",
3672 mp->name,
3673 format_policer_type, mp->type,
3674 ntohl (mp->cir),
3675 ntohl (mp->eir),
3676 clib_net_to_host_u64 (mp->cb),
3677 clib_net_to_host_u64 (mp->eb),
3678 format_policer_rate_type, mp->rate_type,
3679 format_policer_round_type, mp->round_type,
3680 mp->single_rate ? "single" : "dual",
3681 mp->color_aware ? "is" : "not",
3682 ntohl (mp->cir_tokens_per_period),
3683 ntohl (mp->pir_tokens_per_period),
3684 ntohl (mp->scale),
3685 ntohl (mp->current_limit),
3686 ntohl (mp->current_bucket),
3687 ntohl (mp->extended_limit),
3688 ntohl (mp->extended_bucket),
3689 clib_net_to_host_u64 (mp->last_update_time),
3690 format_policer_action_type, mp->conform_action_type,
3691 conform_dscp_str,
3692 format_policer_action_type, mp->exceed_action_type,
3693 exceed_dscp_str,
3694 format_policer_action_type, mp->violate_action_type,
3695 violate_dscp_str);
3696
3697 vec_free (conform_dscp_str);
3698 vec_free (exceed_dscp_str);
3699 vec_free (violate_dscp_str);
3700}
3701
3702static void vl_api_policer_details_t_handler_json
3703 (vl_api_policer_details_t * mp)
3704{
3705 vat_main_t *vam = &vat_main;
3706 vat_json_node_t *node;
3707 u8 *rate_type_str, *round_type_str, *type_str;
3708 u8 *conform_action_str, *exceed_action_str, *violate_action_str;
3709
3710 rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
3711 round_type_str =
3712 format (0, "%U", format_policer_round_type, mp->round_type);
3713 type_str = format (0, "%U", format_policer_type, mp->type);
3714 conform_action_str = format (0, "%U", format_policer_action_type,
3715 mp->conform_action_type);
3716 exceed_action_str = format (0, "%U", format_policer_action_type,
3717 mp->exceed_action_type);
3718 violate_action_str = format (0, "%U", format_policer_action_type,
3719 mp->violate_action_type);
3720
3721 if (VAT_JSON_ARRAY != vam->json_tree.type)
3722 {
3723 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3724 vat_json_init_array (&vam->json_tree);
3725 }
3726 node = vat_json_array_add (&vam->json_tree);
3727
3728 vat_json_init_object (node);
3729 vat_json_object_add_string_copy (node, "name", mp->name);
3730 vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3731 vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
Marek Gradzki59ed4902017-03-21 11:51:54 +01003732 vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
3733 vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
Damjan Marion7cd468a2016-12-19 23:05:39 +01003734 vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3735 vat_json_object_add_string_copy (node, "round_type", round_type_str);
3736 vat_json_object_add_string_copy (node, "type", type_str);
3737 vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3738 vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3739 vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3740 vat_json_object_add_uint (node, "cir_tokens_per_period",
3741 ntohl (mp->cir_tokens_per_period));
3742 vat_json_object_add_uint (node, "eir_tokens_per_period",
3743 ntohl (mp->pir_tokens_per_period));
3744 vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3745 vat_json_object_add_uint (node, "current_bucket",
3746 ntohl (mp->current_bucket));
3747 vat_json_object_add_uint (node, "extended_limit",
3748 ntohl (mp->extended_limit));
3749 vat_json_object_add_uint (node, "extended_bucket",
3750 ntohl (mp->extended_bucket));
3751 vat_json_object_add_uint (node, "last_update_time",
3752 ntohl (mp->last_update_time));
3753 vat_json_object_add_string_copy (node, "conform_action",
3754 conform_action_str);
3755 if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3756 {
3757 u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3758 vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3759 vec_free (dscp_str);
3760 }
3761 vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3762 if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3763 {
3764 u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3765 vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3766 vec_free (dscp_str);
3767 }
3768 vat_json_object_add_string_copy (node, "violate_action",
3769 violate_action_str);
3770 if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3771 {
3772 u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3773 vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3774 vec_free (dscp_str);
3775 }
3776
3777 vec_free (rate_type_str);
3778 vec_free (round_type_str);
3779 vec_free (type_str);
3780 vec_free (conform_action_str);
3781 vec_free (exceed_action_str);
3782 vec_free (violate_action_str);
3783}
3784
3785static void
3786vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3787 mp)
3788{
3789 vat_main_t *vam = &vat_main;
3790 int i, count = ntohl (mp->count);
3791
3792 if (count > 0)
3793 print (vam->ofp, "classify table ids (%d) : ", count);
3794 for (i = 0; i < count; i++)
3795 {
3796 print (vam->ofp, "%d", ntohl (mp->ids[i]));
3797 print (vam->ofp, (i < count - 1) ? "," : "");
3798 }
3799 vam->retval = ntohl (mp->retval);
3800 vam->result_ready = 1;
3801}
3802
3803static void
3804 vl_api_classify_table_ids_reply_t_handler_json
3805 (vl_api_classify_table_ids_reply_t * mp)
3806{
3807 vat_main_t *vam = &vat_main;
3808 int i, count = ntohl (mp->count);
3809
3810 if (count > 0)
3811 {
3812 vat_json_node_t node;
3813
3814 vat_json_init_object (&node);
3815 for (i = 0; i < count; i++)
3816 {
3817 vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3818 }
3819 vat_json_print (vam->ofp, &node);
3820 vat_json_free (&node);
3821 }
3822 vam->retval = ntohl (mp->retval);
3823 vam->result_ready = 1;
3824}
3825
3826static void
3827 vl_api_classify_table_by_interface_reply_t_handler
3828 (vl_api_classify_table_by_interface_reply_t * mp)
3829{
3830 vat_main_t *vam = &vat_main;
3831 u32 table_id;
3832
3833 table_id = ntohl (mp->l2_table_id);
3834 if (table_id != ~0)
3835 print (vam->ofp, "l2 table id : %d", table_id);
3836 else
3837 print (vam->ofp, "l2 table id : No input ACL tables configured");
3838 table_id = ntohl (mp->ip4_table_id);
3839 if (table_id != ~0)
3840 print (vam->ofp, "ip4 table id : %d", table_id);
3841 else
3842 print (vam->ofp, "ip4 table id : No input ACL tables configured");
3843 table_id = ntohl (mp->ip6_table_id);
3844 if (table_id != ~0)
3845 print (vam->ofp, "ip6 table id : %d", table_id);
3846 else
3847 print (vam->ofp, "ip6 table id : No input ACL tables configured");
3848 vam->retval = ntohl (mp->retval);
3849 vam->result_ready = 1;
3850}
3851
3852static void
3853 vl_api_classify_table_by_interface_reply_t_handler_json
3854 (vl_api_classify_table_by_interface_reply_t * mp)
3855{
3856 vat_main_t *vam = &vat_main;
3857 vat_json_node_t node;
3858
3859 vat_json_init_object (&node);
3860
3861 vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3862 vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3863 vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3864
3865 vat_json_print (vam->ofp, &node);
3866 vat_json_free (&node);
3867
3868 vam->retval = ntohl (mp->retval);
3869 vam->result_ready = 1;
3870}
3871
3872static void vl_api_policer_add_del_reply_t_handler
3873 (vl_api_policer_add_del_reply_t * mp)
3874{
3875 vat_main_t *vam = &vat_main;
3876 i32 retval = ntohl (mp->retval);
3877 if (vam->async_mode)
3878 {
3879 vam->async_errors += (retval < 0);
3880 }
3881 else
3882 {
3883 vam->retval = retval;
3884 vam->result_ready = 1;
3885 if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3886 /*
3887 * Note: this is just barely thread-safe, depends on
3888 * the main thread spinning waiting for an answer...
3889 */
3890 errmsg ("policer index %d", ntohl (mp->policer_index));
3891 }
3892}
3893
3894static void vl_api_policer_add_del_reply_t_handler_json
3895 (vl_api_policer_add_del_reply_t * mp)
3896{
3897 vat_main_t *vam = &vat_main;
3898 vat_json_node_t node;
3899
3900 vat_json_init_object (&node);
3901 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3902 vat_json_object_add_uint (&node, "policer_index",
3903 ntohl (mp->policer_index));
3904
3905 vat_json_print (vam->ofp, &node);
3906 vat_json_free (&node);
3907
3908 vam->retval = ntohl (mp->retval);
3909 vam->result_ready = 1;
3910}
3911
3912/* Format hex dump. */
3913u8 *
3914format_hex_bytes (u8 * s, va_list * va)
3915{
3916 u8 *bytes = va_arg (*va, u8 *);
3917 int n_bytes = va_arg (*va, int);
3918 uword i;
3919
3920 /* Print short or long form depending on byte count. */
3921 uword short_form = n_bytes <= 32;
3922 uword indent = format_get_indent (s);
3923
3924 if (n_bytes == 0)
3925 return s;
3926
3927 for (i = 0; i < n_bytes; i++)
3928 {
3929 if (!short_form && (i % 32) == 0)
3930 s = format (s, "%08x: ", i);
3931 s = format (s, "%02x", bytes[i]);
3932 if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3933 s = format (s, "\n%U", format_white_space, indent);
3934 }
3935
3936 return s;
3937}
3938
3939static void
3940vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3941 * mp)
3942{
3943 vat_main_t *vam = &vat_main;
3944 i32 retval = ntohl (mp->retval);
3945 if (retval == 0)
3946 {
3947 print (vam->ofp, "classify table info :");
3948 print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
3949 ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3950 ntohl (mp->miss_next_index));
3951 print (vam->ofp, "nbuckets: %d skip: %d match: %d",
3952 ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3953 ntohl (mp->match_n_vectors));
3954 print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
3955 ntohl (mp->mask_length));
3956 }
3957 vam->retval = retval;
3958 vam->result_ready = 1;
3959}
3960
3961static void
3962 vl_api_classify_table_info_reply_t_handler_json
3963 (vl_api_classify_table_info_reply_t * mp)
3964{
3965 vat_main_t *vam = &vat_main;
3966 vat_json_node_t node;
3967
3968 i32 retval = ntohl (mp->retval);
3969 if (retval == 0)
3970 {
3971 vat_json_init_object (&node);
3972
3973 vat_json_object_add_int (&node, "sessions",
3974 ntohl (mp->active_sessions));
3975 vat_json_object_add_int (&node, "nexttbl",
3976 ntohl (mp->next_table_index));
3977 vat_json_object_add_int (&node, "nextnode",
3978 ntohl (mp->miss_next_index));
3979 vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3980 vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3981 vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3982 u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3983 ntohl (mp->mask_length), 0);
3984 vat_json_object_add_string_copy (&node, "mask", s);
3985
3986 vat_json_print (vam->ofp, &node);
3987 vat_json_free (&node);
3988 }
3989 vam->retval = ntohl (mp->retval);
3990 vam->result_ready = 1;
3991}
3992
3993static void
3994vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3995 mp)
3996{
3997 vat_main_t *vam = &vat_main;
3998
3999 print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4000 ntohl (mp->hit_next_index), ntohl (mp->advance),
4001 ntohl (mp->opaque_index));
4002 print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4003 ntohl (mp->match_length));
4004}
4005
4006static void
4007 vl_api_classify_session_details_t_handler_json
4008 (vl_api_classify_session_details_t * mp)
4009{
4010 vat_main_t *vam = &vat_main;
4011 vat_json_node_t *node = NULL;
4012
4013 if (VAT_JSON_ARRAY != vam->json_tree.type)
4014 {
4015 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4016 vat_json_init_array (&vam->json_tree);
4017 }
4018 node = vat_json_array_add (&vam->json_tree);
4019
4020 vat_json_init_object (node);
4021 vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4022 vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4023 vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4024 u8 *s =
4025 format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4026 0);
4027 vat_json_object_add_string_copy (node, "match", s);
4028}
4029
4030static void vl_api_pg_create_interface_reply_t_handler
4031 (vl_api_pg_create_interface_reply_t * mp)
4032{
4033 vat_main_t *vam = &vat_main;
4034
4035 vam->retval = ntohl (mp->retval);
4036 vam->result_ready = 1;
4037}
4038
4039static void vl_api_pg_create_interface_reply_t_handler_json
4040 (vl_api_pg_create_interface_reply_t * mp)
4041{
4042 vat_main_t *vam = &vat_main;
4043 vat_json_node_t node;
4044
4045 i32 retval = ntohl (mp->retval);
4046 if (retval == 0)
4047 {
4048 vat_json_init_object (&node);
4049
4050 vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4051
4052 vat_json_print (vam->ofp, &node);
4053 vat_json_free (&node);
4054 }
4055 vam->retval = ntohl (mp->retval);
4056 vam->result_ready = 1;
4057}
4058
4059static void vl_api_policer_classify_details_t_handler
4060 (vl_api_policer_classify_details_t * mp)
4061{
4062 vat_main_t *vam = &vat_main;
4063
4064 print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4065 ntohl (mp->table_index));
4066}
4067
4068static void vl_api_policer_classify_details_t_handler_json
4069 (vl_api_policer_classify_details_t * mp)
4070{
4071 vat_main_t *vam = &vat_main;
4072 vat_json_node_t *node;
4073
4074 if (VAT_JSON_ARRAY != vam->json_tree.type)
4075 {
4076 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4077 vat_json_init_array (&vam->json_tree);
4078 }
4079 node = vat_json_array_add (&vam->json_tree);
4080
4081 vat_json_init_object (node);
4082 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4083 vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4084}
4085
4086static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
4087 (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4088{
4089 vat_main_t *vam = &vat_main;
4090 i32 retval = ntohl (mp->retval);
4091 if (vam->async_mode)
4092 {
4093 vam->async_errors += (retval < 0);
4094 }
4095 else
4096 {
4097 vam->retval = retval;
4098 vam->sw_if_index = ntohl (mp->sw_if_index);
4099 vam->result_ready = 1;
4100 }
4101}
4102
4103static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
4104 (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4105{
4106 vat_main_t *vam = &vat_main;
4107 vat_json_node_t node;
4108
4109 vat_json_init_object (&node);
4110 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4111 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
4112
4113 vat_json_print (vam->ofp, &node);
4114 vat_json_free (&node);
4115
4116 vam->retval = ntohl (mp->retval);
4117 vam->result_ready = 1;
4118}
4119
4120static void vl_api_flow_classify_details_t_handler
4121 (vl_api_flow_classify_details_t * mp)
4122{
4123 vat_main_t *vam = &vat_main;
4124
4125 print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4126 ntohl (mp->table_index));
4127}
4128
4129static void vl_api_flow_classify_details_t_handler_json
4130 (vl_api_flow_classify_details_t * mp)
4131{
4132 vat_main_t *vam = &vat_main;
4133 vat_json_node_t *node;
4134
4135 if (VAT_JSON_ARRAY != vam->json_tree.type)
4136 {
4137 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4138 vat_json_init_array (&vam->json_tree);
4139 }
4140 node = vat_json_array_add (&vam->json_tree);
4141
4142 vat_json_init_object (node);
4143 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4144 vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4145}
4146
Aloys Augustinee551982017-02-17 14:55:29 +01004147#define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
4148#define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
4149#define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
4150#define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
Damjan Marion7cd468a2016-12-19 23:05:39 +01004151#define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
4152#define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
4153#define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
4154#define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
Neale Ranns044183f2017-01-24 01:34:25 -08004155#define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
4156#define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
4157#define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
4158#define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
Filip Tehlar694396d2017-02-17 14:29:11 +01004159#define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
4160#define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
Damjan Marion7cd468a2016-12-19 23:05:39 +01004161
4162/*
4163 * Generate boilerplate reply handlers, which
4164 * dig the return value out of the xxx_reply_t API message,
4165 * stick it into vam->retval, and set vam->result_ready
4166 *
4167 * Could also do this by pointing N message decode slots at
4168 * a single function, but that could break in subtle ways.
4169 */
4170
4171#define foreach_standard_reply_retval_handler \
4172_(sw_interface_set_flags_reply) \
4173_(sw_interface_add_del_address_reply) \
4174_(sw_interface_set_table_reply) \
4175_(sw_interface_set_mpls_enable_reply) \
4176_(sw_interface_set_vpath_reply) \
4177_(sw_interface_set_vxlan_bypass_reply) \
4178_(sw_interface_set_l2_bridge_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01004179_(bridge_domain_add_del_reply) \
4180_(sw_interface_set_l2_xconnect_reply) \
4181_(l2fib_add_del_reply) \
Eyal Barif24991c2017-04-05 05:33:21 +03004182_(l2fib_flush_int_reply) \
4183_(l2fib_flush_bd_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01004184_(ip_add_del_route_reply) \
Neale Ranns32e1c012016-11-22 17:07:28 +00004185_(ip_mroute_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01004186_(mpls_route_add_del_reply) \
4187_(mpls_ip_bind_unbind_reply) \
4188_(proxy_arp_add_del_reply) \
4189_(proxy_arp_intfc_enable_disable_reply) \
4190_(sw_interface_set_unnumbered_reply) \
4191_(ip_neighbor_add_del_reply) \
4192_(reset_vrf_reply) \
4193_(oam_add_del_reply) \
4194_(reset_fib_reply) \
4195_(dhcp_proxy_config_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01004196_(dhcp_proxy_set_vss_reply) \
4197_(dhcp_client_config_reply) \
4198_(set_ip_flow_hash_reply) \
4199_(sw_interface_ip6_enable_disable_reply) \
4200_(sw_interface_ip6_set_link_local_address_reply) \
Neale Ranns3f844d02017-02-18 00:03:54 -08004201_(ip6nd_proxy_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01004202_(sw_interface_ip6nd_ra_prefix_reply) \
4203_(sw_interface_ip6nd_ra_config_reply) \
4204_(set_arp_neighbor_limit_reply) \
4205_(l2_patch_add_del_reply) \
Pablo Camarillofb380952016-12-07 18:34:18 +01004206_(sr_policy_add_reply) \
4207_(sr_policy_mod_reply) \
4208_(sr_policy_del_reply) \
4209_(sr_localsid_add_del_reply) \
4210_(sr_steering_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01004211_(classify_add_del_session_reply) \
4212_(classify_set_interface_ip_table_reply) \
4213_(classify_set_interface_l2_tables_reply) \
4214_(l2tpv3_set_tunnel_cookies_reply) \
4215_(l2tpv3_interface_enable_disable_reply) \
4216_(l2tpv3_set_lookup_key_reply) \
4217_(l2_fib_clear_table_reply) \
4218_(l2_interface_efp_filter_reply) \
4219_(l2_interface_vlan_tag_rewrite_reply) \
4220_(modify_vhost_user_if_reply) \
4221_(delete_vhost_user_if_reply) \
4222_(want_ip4_arp_events_reply) \
4223_(want_ip6_nd_events_reply) \
4224_(input_acl_set_interface_reply) \
4225_(ipsec_spd_add_del_reply) \
4226_(ipsec_interface_add_del_spd_reply) \
4227_(ipsec_spd_add_del_entry_reply) \
4228_(ipsec_sad_add_del_entry_reply) \
4229_(ipsec_sa_set_key_reply) \
Matthew Smithb0972cb2017-05-02 16:20:41 -05004230_(ipsec_tunnel_if_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01004231_(ikev2_profile_add_del_reply) \
4232_(ikev2_profile_set_auth_reply) \
4233_(ikev2_profile_set_id_reply) \
4234_(ikev2_profile_set_ts_reply) \
4235_(ikev2_set_local_key_reply) \
Radu Nicolaucb33dc22017-02-16 16:49:46 +00004236_(ikev2_set_responder_reply) \
4237_(ikev2_set_ike_transforms_reply) \
4238_(ikev2_set_esp_transforms_reply) \
4239_(ikev2_set_sa_lifetime_reply) \
4240_(ikev2_initiate_sa_init_reply) \
4241_(ikev2_initiate_del_ike_sa_reply) \
4242_(ikev2_initiate_del_child_sa_reply) \
4243_(ikev2_initiate_rekey_child_sa_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01004244_(delete_loopback_reply) \
4245_(bd_ip_mac_add_del_reply) \
4246_(map_del_domain_reply) \
4247_(map_add_del_rule_reply) \
4248_(want_interface_events_reply) \
4249_(want_stats_reply) \
4250_(cop_interface_enable_disable_reply) \
4251_(cop_whitelist_enable_disable_reply) \
4252_(sw_interface_clear_stats_reply) \
4253_(ioam_enable_reply) \
4254_(ioam_disable_reply) \
Filip Tehlar694396d2017-02-17 14:29:11 +01004255_(one_add_del_locator_reply) \
4256_(one_add_del_local_eid_reply) \
4257_(one_add_del_remote_mapping_reply) \
4258_(one_add_del_adjacency_reply) \
4259_(one_add_del_map_resolver_reply) \
4260_(one_add_del_map_server_reply) \
4261_(one_enable_disable_reply) \
4262_(one_rloc_probe_enable_disable_reply) \
4263_(one_map_register_enable_disable_reply) \
4264_(one_pitr_set_locator_set_reply) \
4265_(one_map_request_mode_reply) \
4266_(one_add_del_map_request_itr_rlocs_reply) \
4267_(one_eid_table_add_del_map_reply) \
Filip Tehlar67a99f82017-03-10 13:18:02 +01004268_(one_use_petr_reply) \
Filip Tehlar4868ff62017-03-09 16:48:39 +01004269_(one_stats_enable_disable_reply) \
Filip Tehlar21511912017-04-07 10:41:42 +02004270_(one_stats_flush_reply) \
Filip Tehlar82786c42017-02-20 15:20:37 +01004271_(gpe_add_del_fwd_entry_reply) \
Filip Tehlar82786c42017-02-20 15:20:37 +01004272_(gpe_enable_disable_reply) \
Filip Tehlar3e7b56932017-02-21 18:28:34 +01004273_(gpe_set_encap_mode_reply) \
Filip Tehlar82786c42017-02-20 15:20:37 +01004274_(gpe_add_del_iface_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01004275_(vxlan_gpe_add_del_tunnel_reply) \
4276_(af_packet_delete_reply) \
4277_(policer_classify_set_interface_reply) \
4278_(netmap_create_reply) \
4279_(netmap_delete_reply) \
4280_(set_ipfix_exporter_reply) \
4281_(set_ipfix_classify_stream_reply) \
4282_(ipfix_classify_table_add_del_reply) \
4283_(flow_classify_set_interface_reply) \
4284_(sw_interface_span_enable_disable_reply) \
4285_(pg_capture_reply) \
4286_(pg_enable_disable_reply) \
4287_(ip_source_and_port_range_check_add_del_reply) \
4288_(ip_source_and_port_range_check_interface_add_del_reply)\
4289_(delete_subif_reply) \
4290_(l2_interface_pbb_tag_rewrite_reply) \
4291_(punt_reply) \
4292_(feature_enable_disable_reply) \
4293_(sw_interface_tag_add_del_reply) \
4294_(sw_interface_set_mtu_reply)
4295
4296#define _(n) \
4297 static void vl_api_##n##_t_handler \
4298 (vl_api_##n##_t * mp) \
4299 { \
4300 vat_main_t * vam = &vat_main; \
4301 i32 retval = ntohl(mp->retval); \
4302 if (vam->async_mode) { \
4303 vam->async_errors += (retval < 0); \
4304 } else { \
4305 vam->retval = retval; \
4306 vam->result_ready = 1; \
4307 } \
4308 }
4309foreach_standard_reply_retval_handler;
4310#undef _
4311
4312#define _(n) \
4313 static void vl_api_##n##_t_handler_json \
4314 (vl_api_##n##_t * mp) \
4315 { \
4316 vat_main_t * vam = &vat_main; \
4317 vat_json_node_t node; \
4318 vat_json_init_object(&node); \
4319 vat_json_object_add_int(&node, "retval", ntohl(mp->retval)); \
4320 vat_json_print(vam->ofp, &node); \
4321 vam->retval = ntohl(mp->retval); \
4322 vam->result_ready = 1; \
4323 }
4324foreach_standard_reply_retval_handler;
4325#undef _
4326
4327/*
4328 * Table of message reply handlers, must include boilerplate handlers
4329 * we just generated
4330 */
4331
4332#define foreach_vpe_api_reply_msg \
4333_(CREATE_LOOPBACK_REPLY, create_loopback_reply) \
Jon Loeligerc83c3b72017-02-23 13:57:35 -06004334_(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01004335_(SW_INTERFACE_DETAILS, sw_interface_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01004336_(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply) \
4337_(CONTROL_PING_REPLY, control_ping_reply) \
4338_(CLI_REPLY, cli_reply) \
4339_(CLI_INBAND_REPLY, cli_inband_reply) \
4340_(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY, \
4341 sw_interface_add_del_address_reply) \
4342_(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply) \
4343_(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
4344_(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply) \
4345_(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
4346_(SW_INTERFACE_SET_L2_XCONNECT_REPLY, \
4347 sw_interface_set_l2_xconnect_reply) \
4348_(SW_INTERFACE_SET_L2_BRIDGE_REPLY, \
4349 sw_interface_set_l2_bridge_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01004350_(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply) \
4351_(BRIDGE_DOMAIN_DETAILS, bridge_domain_details) \
Eyal Barifead6702017-04-04 04:46:32 +03004352_(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01004353_(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply) \
Eyal Barif24991c2017-04-05 05:33:21 +03004354_(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply) \
4355_(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01004356_(L2_FLAGS_REPLY, l2_flags_reply) \
4357_(BRIDGE_FLAGS_REPLY, bridge_flags_reply) \
4358_(TAP_CONNECT_REPLY, tap_connect_reply) \
4359_(TAP_MODIFY_REPLY, tap_modify_reply) \
4360_(TAP_DELETE_REPLY, tap_delete_reply) \
4361_(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details) \
4362_(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply) \
Neale Ranns32e1c012016-11-22 17:07:28 +00004363_(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01004364_(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply) \
4365_(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply) \
4366_(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply) \
4367_(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY, \
4368 proxy_arp_intfc_enable_disable_reply) \
4369_(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply) \
4370_(SW_INTERFACE_SET_UNNUMBERED_REPLY, \
4371 sw_interface_set_unnumbered_reply) \
4372_(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply) \
4373_(RESET_VRF_REPLY, reset_vrf_reply) \
4374_(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply) \
4375_(CREATE_SUBIF_REPLY, create_subif_reply) \
4376_(OAM_ADD_DEL_REPLY, oam_add_del_reply) \
4377_(RESET_FIB_REPLY, reset_fib_reply) \
4378_(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01004379_(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply) \
Neale Ranns20a175a2017-02-14 07:28:41 -08004380_(DHCP_PROXY_DETAILS, dhcp_proxy_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01004381_(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply) \
4382_(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply) \
4383_(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY, \
4384 sw_interface_ip6_enable_disable_reply) \
4385_(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY, \
4386 sw_interface_ip6_set_link_local_address_reply) \
Neale Ranns3f844d02017-02-18 00:03:54 -08004387_(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply) \
4388_(IP6ND_PROXY_DETAILS, ip6nd_proxy_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01004389_(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY, \
4390 sw_interface_ip6nd_ra_prefix_reply) \
4391_(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY, \
4392 sw_interface_ip6nd_ra_config_reply) \
4393_(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply) \
4394_(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply) \
Pablo Camarillofb380952016-12-07 18:34:18 +01004395_(SR_POLICY_ADD_REPLY, sr_policy_add_reply) \
4396_(SR_POLICY_MOD_REPLY, sr_policy_mod_reply) \
4397_(SR_POLICY_DEL_REPLY, sr_policy_del_reply) \
4398_(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply) \
4399_(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01004400_(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply) \
4401_(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply) \
4402_(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY, \
4403classify_set_interface_ip_table_reply) \
4404_(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY, \
4405 classify_set_interface_l2_tables_reply) \
4406_(GET_NODE_INDEX_REPLY, get_node_index_reply) \
4407_(ADD_NODE_NEXT_REPLY, add_node_next_reply) \
4408_(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply) \
4409_(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply) \
4410_(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY, \
4411 l2tpv3_interface_enable_disable_reply) \
4412_(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply) \
4413_(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details) \
4414_(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply) \
4415_(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details) \
4416_(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply) \
4417_(GRE_TUNNEL_DETAILS, gre_tunnel_details) \
4418_(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply) \
4419_(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply) \
4420_(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
4421_(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details) \
4422_(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply) \
4423_(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply) \
4424_(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply) \
4425_(SHOW_VERSION_REPLY, show_version_reply) \
Ole Troan01384fe2017-05-12 11:55:35 +02004426_(L2_FIB_TABLE_DETAILS, l2_fib_table_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01004427_(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply) \
4428_(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details) \
4429_(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply) \
4430_(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply) \
4431_(IP4_ARP_EVENT, ip4_arp_event) \
4432_(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply) \
4433_(IP6_ND_EVENT, ip6_nd_event) \
4434_(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply) \
4435_(IP_ADDRESS_DETAILS, ip_address_details) \
4436_(IP_DETAILS, ip_details) \
4437_(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply) \
4438_(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
4439_(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply) \
4440_(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply) \
4441_(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply) \
Matthew Smithb0972cb2017-05-02 16:20:41 -05004442_(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01004443_(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply) \
4444_(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply) \
4445_(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply) \
4446_(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply) \
4447_(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply) \
Radu Nicolaucb33dc22017-02-16 16:49:46 +00004448_(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply) \
4449_(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply) \
4450_(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply) \
4451_(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply) \
4452_(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply) \
4453_(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply) \
4454_(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
4455_(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01004456_(DELETE_LOOPBACK_REPLY, delete_loopback_reply) \
4457_(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply) \
4458_(DHCP_COMPL_EVENT, dhcp_compl_event) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01004459_(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply) \
4460_(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply) \
4461_(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply) \
4462_(MAP_DOMAIN_DETAILS, map_domain_details) \
4463_(MAP_RULE_DETAILS, map_rule_details) \
4464_(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply) \
4465_(WANT_STATS_REPLY, want_stats_reply) \
4466_(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply) \
4467_(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
4468_(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
4469_(GET_NODE_GRAPH_REPLY, get_node_graph_reply) \
4470_(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply) \
4471_(IOAM_ENABLE_REPLY, ioam_enable_reply) \
4472_(IOAM_DISABLE_REPLY, ioam_disable_reply) \
Filip Tehlar694396d2017-02-17 14:29:11 +01004473_(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply) \
4474_(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply) \
4475_(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply) \
4476_(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply) \
4477_(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply) \
4478_(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply) \
4479_(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply) \
4480_(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply) \
4481_(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY, \
4482 one_map_register_enable_disable_reply) \
4483_(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY, \
4484 one_rloc_probe_enable_disable_reply) \
4485_(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply) \
Filip Tehlar67a99f82017-03-10 13:18:02 +01004486_(ONE_USE_PETR_REPLY, one_use_petr_reply) \
Filip Tehlar694396d2017-02-17 14:29:11 +01004487_(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply) \
4488_(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply) \
4489_(ONE_LOCATOR_SET_DETAILS, one_locator_set_details) \
4490_(ONE_LOCATOR_DETAILS, one_locator_details) \
4491_(ONE_EID_TABLE_DETAILS, one_eid_table_details) \
4492_(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details) \
4493_(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details) \
4494_(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details) \
4495_(ONE_MAP_SERVER_DETAILS, one_map_server_details) \
4496_(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply) \
Filip Tehlar4868ff62017-03-09 16:48:39 +01004497_(ONE_STATS_DETAILS, one_stats_details) \
Filip Tehlar21511912017-04-07 10:41:42 +02004498_(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply) \
Filip Tehlar4868ff62017-03-09 16:48:39 +01004499_(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply) \
4500_(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY, \
4501 show_one_stats_enable_disable_reply) \
Filip Tehlar3e7b56932017-02-21 18:28:34 +01004502_(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply) \
4503_(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply) \
Filip Tehlar82786c42017-02-20 15:20:37 +01004504_(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply) \
Filip Tehlar694396d2017-02-17 14:29:11 +01004505_(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply) \
4506_(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply) \
Filip Tehlar0eb874e2017-05-18 14:23:32 +02004507_(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply) \
Filip Tehlar82786c42017-02-20 15:20:37 +01004508_(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply) \
4509_(GPE_FWD_ENTRY_PATH_DETAILS, \
4510 gpe_fwd_entry_path_details) \
Filip Tehlar694396d2017-02-17 14:29:11 +01004511_(SHOW_ONE_STATUS_REPLY, show_one_status_reply) \
4512_(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY, \
4513 one_add_del_map_request_itr_rlocs_reply) \
4514_(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY, \
4515 one_get_map_request_itr_rlocs_reply) \
4516_(SHOW_ONE_PITR_REPLY, show_one_pitr_reply) \
Filip Tehlar67a99f82017-03-10 13:18:02 +01004517_(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply) \
Filip Tehlar694396d2017-02-17 14:29:11 +01004518_(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply) \
4519_(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply) \
4520_(SHOW_ONE_MAP_REGISTER_STATE_REPLY, \
4521 show_one_map_register_state_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01004522_(AF_PACKET_CREATE_REPLY, af_packet_create_reply) \
4523_(AF_PACKET_DELETE_REPLY, af_packet_delete_reply) \
4524_(POLICER_ADD_DEL_REPLY, policer_add_del_reply) \
4525_(POLICER_DETAILS, policer_details) \
4526_(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
4527_(POLICER_CLASSIFY_DETAILS, policer_classify_details) \
4528_(NETMAP_CREATE_REPLY, netmap_create_reply) \
4529_(NETMAP_DELETE_REPLY, netmap_delete_reply) \
4530_(MPLS_TUNNEL_DETAILS, mpls_tunnel_details) \
4531_(MPLS_FIB_DETAILS, mpls_fib_details) \
4532_(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply) \
4533_(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
4534_(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply) \
4535_(CLASSIFY_SESSION_DETAILS, classify_session_details) \
4536_(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply) \
4537_(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details) \
4538_(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply) \
4539_(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details) \
4540_(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
4541_(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details) \
4542_(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
4543_(FLOW_CLASSIFY_DETAILS, flow_classify_details) \
4544_(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
4545_(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details) \
4546_(GET_NEXT_INDEX_REPLY, get_next_index_reply) \
4547_(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply) \
4548_(PG_CAPTURE_REPLY, pg_capture_reply) \
4549_(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply) \
4550_(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY, \
4551 ip_source_and_port_range_check_add_del_reply) \
4552_(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY, \
4553 ip_source_and_port_range_check_interface_add_del_reply) \
4554_(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply) \
4555_(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details) \
4556_(DELETE_SUBIF_REPLY, delete_subif_reply) \
4557_(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
4558_(PUNT_REPLY, punt_reply) \
4559_(IP_FIB_DETAILS, ip_fib_details) \
4560_(IP6_FIB_DETAILS, ip6_fib_details) \
4561_(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply) \
4562_(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply) \
4563_(L2_XCONNECT_DETAILS, l2_xconnect_details) \
4564_(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply) \
4565_(IP_NEIGHBOR_DETAILS, ip_neighbor_details) \
4566_(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)
4567
Dave Baracha1a093d2017-03-02 13:13:23 -05004568#define foreach_standalone_reply_msg \
4569_(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags) \
Aloys Augustinee551982017-02-17 14:55:29 +01004570_(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters) \
4571_(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters) \
Dave Baracha1a093d2017-03-02 13:13:23 -05004572_(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters) \
4573_(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters) \
4574_(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters) \
4575_(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)
4576
Damjan Marion7cd468a2016-12-19 23:05:39 +01004577typedef struct
4578{
4579 u8 *name;
4580 u32 value;
4581} name_sort_t;
4582
4583
4584#define STR_VTR_OP_CASE(op) \
4585 case L2_VTR_ ## op: \
4586 return "" # op;
4587
4588static const char *
4589str_vtr_op (u32 vtr_op)
4590{
4591 switch (vtr_op)
4592 {
4593 STR_VTR_OP_CASE (DISABLED);
4594 STR_VTR_OP_CASE (PUSH_1);
4595 STR_VTR_OP_CASE (PUSH_2);
4596 STR_VTR_OP_CASE (POP_1);
4597 STR_VTR_OP_CASE (POP_2);
4598 STR_VTR_OP_CASE (TRANSLATE_1_1);
4599 STR_VTR_OP_CASE (TRANSLATE_1_2);
4600 STR_VTR_OP_CASE (TRANSLATE_2_1);
4601 STR_VTR_OP_CASE (TRANSLATE_2_2);
4602 }
4603
4604 return "UNKNOWN";
4605}
4606
4607static int
4608dump_sub_interface_table (vat_main_t * vam)
4609{
4610 const sw_interface_subif_t *sub = NULL;
4611
4612 if (vam->json_output)
4613 {
4614 clib_warning
4615 ("JSON output supported only for VPE API calls and dump_stats_table");
4616 return -99;
4617 }
4618
4619 print (vam->ofp,
4620 "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
4621 "Interface", "sw_if_index",
4622 "sub id", "dot1ad", "tags", "outer id",
4623 "inner id", "exact", "default", "outer any", "inner any");
4624
4625 vec_foreach (sub, vam->sw_if_subif_table)
4626 {
4627 print (vam->ofp,
4628 "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
4629 sub->interface_name,
4630 sub->sw_if_index,
4631 sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
4632 sub->sub_number_of_tags, sub->sub_outer_vlan_id,
4633 sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
4634 sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
4635 if (sub->vtr_op != L2_VTR_DISABLED)
4636 {
4637 print (vam->ofp,
4638 " vlan-tag-rewrite - op: %-14s [ dot1q: %d "
4639 "tag1: %d tag2: %d ]",
4640 str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
4641 sub->vtr_tag1, sub->vtr_tag2);
4642 }
4643 }
4644
4645 return 0;
4646}
4647
4648static int
4649name_sort_cmp (void *a1, void *a2)
4650{
4651 name_sort_t *n1 = a1;
4652 name_sort_t *n2 = a2;
4653
4654 return strcmp ((char *) n1->name, (char *) n2->name);
4655}
4656
4657static int
4658dump_interface_table (vat_main_t * vam)
4659{
4660 hash_pair_t *p;
4661 name_sort_t *nses = 0, *ns;
4662
4663 if (vam->json_output)
4664 {
4665 clib_warning
4666 ("JSON output supported only for VPE API calls and dump_stats_table");
4667 return -99;
4668 }
4669
4670 /* *INDENT-OFF* */
4671 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4672 ({
4673 vec_add2 (nses, ns, 1);
4674 ns->name = (u8 *)(p->key);
4675 ns->value = (u32) p->value[0];
4676 }));
4677 /* *INDENT-ON* */
4678
4679 vec_sort_with_function (nses, name_sort_cmp);
4680
4681 print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
4682 vec_foreach (ns, nses)
4683 {
4684 print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
4685 }
4686 vec_free (nses);
4687 return 0;
4688}
4689
4690static int
4691dump_ip_table (vat_main_t * vam, int is_ipv6)
4692{
4693 const ip_details_t *det = NULL;
4694 const ip_address_details_t *address = NULL;
4695 u32 i = ~0;
4696
4697 print (vam->ofp, "%-12s", "sw_if_index");
4698
4699 vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
4700 {
4701 i++;
4702 if (!det->present)
4703 {
4704 continue;
4705 }
4706 print (vam->ofp, "%-12d", i);
4707 print (vam->ofp, " %-30s%-13s", "Address", "Prefix length");
4708 if (!det->addr)
4709 {
4710 continue;
4711 }
4712 vec_foreach (address, det->addr)
4713 {
4714 print (vam->ofp,
4715 " %-30U%-13d",
4716 is_ipv6 ? format_ip6_address : format_ip4_address,
4717 address->ip, address->prefix_length);
4718 }
4719 }
4720
4721 return 0;
4722}
4723
4724static int
4725dump_ipv4_table (vat_main_t * vam)
4726{
4727 if (vam->json_output)
4728 {
4729 clib_warning
4730 ("JSON output supported only for VPE API calls and dump_stats_table");
4731 return -99;
4732 }
4733
4734 return dump_ip_table (vam, 0);
4735}
4736
4737static int
4738dump_ipv6_table (vat_main_t * vam)
4739{
4740 if (vam->json_output)
4741 {
4742 clib_warning
4743 ("JSON output supported only for VPE API calls and dump_stats_table");
4744 return -99;
4745 }
4746
4747 return dump_ip_table (vam, 1);
4748}
4749
4750static char *
4751counter_type_to_str (u8 counter_type, u8 is_combined)
4752{
4753 if (!is_combined)
4754 {
4755 switch (counter_type)
4756 {
4757 case VNET_INTERFACE_COUNTER_DROP:
4758 return "drop";
4759 case VNET_INTERFACE_COUNTER_PUNT:
4760 return "punt";
4761 case VNET_INTERFACE_COUNTER_IP4:
4762 return "ip4";
4763 case VNET_INTERFACE_COUNTER_IP6:
4764 return "ip6";
4765 case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4766 return "rx-no-buf";
4767 case VNET_INTERFACE_COUNTER_RX_MISS:
4768 return "rx-miss";
4769 case VNET_INTERFACE_COUNTER_RX_ERROR:
4770 return "rx-error";
4771 case VNET_INTERFACE_COUNTER_TX_ERROR:
4772 return "tx-error";
4773 default:
4774 return "INVALID-COUNTER-TYPE";
4775 }
4776 }
4777 else
4778 {
4779 switch (counter_type)
4780 {
4781 case VNET_INTERFACE_COUNTER_RX:
4782 return "rx";
4783 case VNET_INTERFACE_COUNTER_TX:
4784 return "tx";
4785 default:
4786 return "INVALID-COUNTER-TYPE";
4787 }
4788 }
4789}
4790
4791static int
4792dump_stats_table (vat_main_t * vam)
4793{
4794 vat_json_node_t node;
4795 vat_json_node_t *msg_array;
4796 vat_json_node_t *msg;
4797 vat_json_node_t *counter_array;
4798 vat_json_node_t *counter;
4799 interface_counter_t c;
4800 u64 packets;
4801 ip4_fib_counter_t *c4;
4802 ip6_fib_counter_t *c6;
Neale Ranns044183f2017-01-24 01:34:25 -08004803 ip4_nbr_counter_t *n4;
4804 ip6_nbr_counter_t *n6;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004805 int i, j;
4806
4807 if (!vam->json_output)
4808 {
4809 clib_warning ("dump_stats_table supported only in JSON format");
4810 return -99;
4811 }
4812
4813 vat_json_init_object (&node);
4814
4815 /* interface counters */
4816 msg_array = vat_json_object_add (&node, "interface_counters");
4817 vat_json_init_array (msg_array);
4818 for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4819 {
4820 msg = vat_json_array_add (msg_array);
4821 vat_json_init_object (msg);
4822 vat_json_object_add_string_copy (msg, "vnet_counter_type",
4823 (u8 *) counter_type_to_str (i, 0));
4824 vat_json_object_add_int (msg, "is_combined", 0);
4825 counter_array = vat_json_object_add (msg, "data");
4826 vat_json_init_array (counter_array);
4827 for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4828 {
4829 packets = vam->simple_interface_counters[i][j];
4830 vat_json_array_add_uint (counter_array, packets);
4831 }
4832 }
4833 for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4834 {
4835 msg = vat_json_array_add (msg_array);
4836 vat_json_init_object (msg);
4837 vat_json_object_add_string_copy (msg, "vnet_counter_type",
4838 (u8 *) counter_type_to_str (i, 1));
4839 vat_json_object_add_int (msg, "is_combined", 1);
4840 counter_array = vat_json_object_add (msg, "data");
4841 vat_json_init_array (counter_array);
4842 for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4843 {
4844 c = vam->combined_interface_counters[i][j];
4845 counter = vat_json_array_add (counter_array);
4846 vat_json_init_object (counter);
4847 vat_json_object_add_uint (counter, "packets", c.packets);
4848 vat_json_object_add_uint (counter, "bytes", c.bytes);
4849 }
4850 }
4851
4852 /* ip4 fib counters */
4853 msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4854 vat_json_init_array (msg_array);
4855 for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4856 {
4857 msg = vat_json_array_add (msg_array);
4858 vat_json_init_object (msg);
4859 vat_json_object_add_uint (msg, "vrf_id",
4860 vam->ip4_fib_counters_vrf_id_by_index[i]);
4861 counter_array = vat_json_object_add (msg, "c");
4862 vat_json_init_array (counter_array);
4863 for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4864 {
4865 counter = vat_json_array_add (counter_array);
4866 vat_json_init_object (counter);
4867 c4 = &vam->ip4_fib_counters[i][j];
4868 vat_json_object_add_ip4 (counter, "address", c4->address);
4869 vat_json_object_add_uint (counter, "address_length",
4870 c4->address_length);
4871 vat_json_object_add_uint (counter, "packets", c4->packets);
4872 vat_json_object_add_uint (counter, "bytes", c4->bytes);
4873 }
4874 }
4875
4876 /* ip6 fib counters */
4877 msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4878 vat_json_init_array (msg_array);
4879 for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4880 {
4881 msg = vat_json_array_add (msg_array);
4882 vat_json_init_object (msg);
4883 vat_json_object_add_uint (msg, "vrf_id",
4884 vam->ip6_fib_counters_vrf_id_by_index[i]);
4885 counter_array = vat_json_object_add (msg, "c");
4886 vat_json_init_array (counter_array);
4887 for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4888 {
4889 counter = vat_json_array_add (counter_array);
4890 vat_json_init_object (counter);
4891 c6 = &vam->ip6_fib_counters[i][j];
4892 vat_json_object_add_ip6 (counter, "address", c6->address);
4893 vat_json_object_add_uint (counter, "address_length",
4894 c6->address_length);
4895 vat_json_object_add_uint (counter, "packets", c6->packets);
4896 vat_json_object_add_uint (counter, "bytes", c6->bytes);
4897 }
4898 }
4899
Neale Ranns044183f2017-01-24 01:34:25 -08004900 /* ip4 nbr counters */
4901 msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
4902 vat_json_init_array (msg_array);
4903 for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
4904 {
4905 msg = vat_json_array_add (msg_array);
4906 vat_json_init_object (msg);
4907 vat_json_object_add_uint (msg, "sw_if_index", i);
4908 counter_array = vat_json_object_add (msg, "c");
4909 vat_json_init_array (counter_array);
4910 for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
4911 {
4912 counter = vat_json_array_add (counter_array);
4913 vat_json_init_object (counter);
4914 n4 = &vam->ip4_nbr_counters[i][j];
4915 vat_json_object_add_ip4 (counter, "address", n4->address);
4916 vat_json_object_add_uint (counter, "link-type", n4->linkt);
4917 vat_json_object_add_uint (counter, "packets", n4->packets);
4918 vat_json_object_add_uint (counter, "bytes", n4->bytes);
4919 }
4920 }
4921
4922 /* ip6 nbr counters */
4923 msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
4924 vat_json_init_array (msg_array);
4925 for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
4926 {
4927 msg = vat_json_array_add (msg_array);
4928 vat_json_init_object (msg);
4929 vat_json_object_add_uint (msg, "sw_if_index", i);
4930 counter_array = vat_json_object_add (msg, "c");
4931 vat_json_init_array (counter_array);
4932 for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
4933 {
4934 counter = vat_json_array_add (counter_array);
4935 vat_json_init_object (counter);
4936 n6 = &vam->ip6_nbr_counters[i][j];
4937 vat_json_object_add_ip6 (counter, "address", n6->address);
4938 vat_json_object_add_uint (counter, "packets", n6->packets);
4939 vat_json_object_add_uint (counter, "bytes", n6->bytes);
4940 }
4941 }
4942
Damjan Marion7cd468a2016-12-19 23:05:39 +01004943 vat_json_print (vam->ofp, &node);
4944 vat_json_free (&node);
4945
4946 return 0;
4947}
4948
4949int
4950exec (vat_main_t * vam)
4951{
4952 api_main_t *am = &api_main;
Ole Troan01384fe2017-05-12 11:55:35 +02004953 vl_api_cli_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004954 f64 timeout;
4955 void *oldheap;
4956 u8 *cmd = 0;
4957 unformat_input_t *i = vam->input;
4958
4959 if (vec_len (i->buffer) == 0)
4960 return -1;
4961
4962 if (vam->exec_mode == 0 && unformat (i, "mode"))
4963 {
4964 vam->exec_mode = 1;
4965 return 0;
4966 }
4967 if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4968 {
4969 vam->exec_mode = 0;
4970 return 0;
4971 }
4972
4973
Ole Troan01384fe2017-05-12 11:55:35 +02004974 M (CLI, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004975
4976 /*
4977 * Copy cmd into shared memory.
4978 * In order for the CLI command to work, it
4979 * must be a vector ending in \n, not a C-string ending
4980 * in \n\0.
4981 */
4982 pthread_mutex_lock (&am->vlib_rp->mutex);
4983 oldheap = svm_push_data_heap (am->vlib_rp);
4984
4985 vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4986 clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4987
4988 svm_pop_heap (oldheap);
4989 pthread_mutex_unlock (&am->vlib_rp->mutex);
4990
Damjan Marion7bee80c2017-04-26 15:32:12 +02004991 mp->cmd_in_shmem = pointer_to_uword (cmd);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004992 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004993 timeout = vat_time_now (vam) + 10.0;
4994
4995 while (vat_time_now (vam) < timeout)
4996 {
4997 if (vam->result_ready == 1)
4998 {
4999 u8 *free_me;
5000 if (vam->shmem_result != NULL)
5001 print (vam->ofp, "%s", vam->shmem_result);
5002 pthread_mutex_lock (&am->vlib_rp->mutex);
5003 oldheap = svm_push_data_heap (am->vlib_rp);
5004
5005 free_me = (u8 *) vam->shmem_result;
5006 vec_free (free_me);
5007
5008 svm_pop_heap (oldheap);
5009 pthread_mutex_unlock (&am->vlib_rp->mutex);
5010 return 0;
5011 }
5012 }
5013 return -99;
5014}
5015
5016/*
5017 * Future replacement of exec() that passes CLI buffers directly in
5018 * the API messages instead of an additional shared memory area.
5019 */
5020static int
5021exec_inband (vat_main_t * vam)
5022{
5023 vl_api_cli_inband_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005024 unformat_input_t *i = vam->input;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005025 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005026
5027 if (vec_len (i->buffer) == 0)
5028 return -1;
5029
5030 if (vam->exec_mode == 0 && unformat (i, "mode"))
5031 {
5032 vam->exec_mode = 1;
5033 return 0;
5034 }
5035 if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5036 {
5037 vam->exec_mode = 0;
5038 return 0;
5039 }
5040
5041 /*
5042 * In order for the CLI command to work, it
5043 * must be a vector ending in \n, not a C-string ending
5044 * in \n\0.
5045 */
5046 u32 len = vec_len (vam->input->buffer);
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005047 M2 (CLI_INBAND, mp, len);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005048 clib_memcpy (mp->cmd, vam->input->buffer, len);
5049 mp->length = htonl (len);
5050
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005051 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06005052 W2 (ret, print (vam->ofp, "%s", vam->cmd_reply));
5053 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005054}
5055
5056static int
5057api_create_loopback (vat_main_t * vam)
5058{
5059 unformat_input_t *i = vam->input;
5060 vl_api_create_loopback_t *mp;
Jon Loeligerc83c3b72017-02-23 13:57:35 -06005061 vl_api_create_loopback_instance_t *mp_lbi;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005062 u8 mac_address[6];
5063 u8 mac_set = 0;
Jon Loeligerc83c3b72017-02-23 13:57:35 -06005064 u8 is_specified = 0;
5065 u32 user_instance = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005066 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005067
5068 memset (mac_address, 0, sizeof (mac_address));
5069
5070 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5071 {
5072 if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5073 mac_set = 1;
Jon Loeligerc83c3b72017-02-23 13:57:35 -06005074 if (unformat (i, "instance %d", &user_instance))
5075 is_specified = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005076 else
5077 break;
5078 }
5079
Jon Loeligerc83c3b72017-02-23 13:57:35 -06005080 if (is_specified)
5081 {
5082 M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5083 mp_lbi->is_specified = is_specified;
5084 if (is_specified)
5085 mp_lbi->user_instance = htonl (user_instance);
5086 if (mac_set)
5087 clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5088 S (mp_lbi);
5089 }
5090 else
5091 {
5092 /* Construct the API message */
5093 M (CREATE_LOOPBACK, mp);
5094 if (mac_set)
5095 clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5096 S (mp);
5097 }
Damjan Marion7cd468a2016-12-19 23:05:39 +01005098
Jon Loeliger56c7b012017-02-01 12:31:41 -06005099 W (ret);
5100 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005101}
5102
5103static int
5104api_delete_loopback (vat_main_t * vam)
5105{
5106 unformat_input_t *i = vam->input;
5107 vl_api_delete_loopback_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005108 u32 sw_if_index = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005109 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005110
5111 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5112 {
5113 if (unformat (i, "sw_if_index %d", &sw_if_index))
5114 ;
5115 else
5116 break;
5117 }
5118
5119 if (sw_if_index == ~0)
5120 {
5121 errmsg ("missing sw_if_index");
5122 return -99;
5123 }
5124
5125 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005126 M (DELETE_LOOPBACK, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005127 mp->sw_if_index = ntohl (sw_if_index);
5128
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005129 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06005130 W (ret);
5131 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005132}
5133
5134static int
5135api_want_stats (vat_main_t * vam)
5136{
5137 unformat_input_t *i = vam->input;
5138 vl_api_want_stats_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005139 int enable = -1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005140 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005141
5142 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5143 {
5144 if (unformat (i, "enable"))
5145 enable = 1;
5146 else if (unformat (i, "disable"))
5147 enable = 0;
5148 else
5149 break;
5150 }
5151
5152 if (enable == -1)
5153 {
5154 errmsg ("missing enable|disable");
5155 return -99;
5156 }
5157
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005158 M (WANT_STATS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005159 mp->enable_disable = enable;
5160
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005161 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06005162 W (ret);
5163 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005164}
5165
5166static int
5167api_want_interface_events (vat_main_t * vam)
5168{
5169 unformat_input_t *i = vam->input;
5170 vl_api_want_interface_events_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005171 int enable = -1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005172 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005173
5174 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5175 {
5176 if (unformat (i, "enable"))
5177 enable = 1;
5178 else if (unformat (i, "disable"))
5179 enable = 0;
5180 else
5181 break;
5182 }
5183
5184 if (enable == -1)
5185 {
5186 errmsg ("missing enable|disable");
5187 return -99;
5188 }
5189
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005190 M (WANT_INTERFACE_EVENTS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005191 mp->enable_disable = enable;
5192
5193 vam->interface_event_display = enable;
5194
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005195 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06005196 W (ret);
5197 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005198}
5199
5200
5201/* Note: non-static, called once to set up the initial intfc table */
5202int
5203api_sw_interface_dump (vat_main_t * vam)
5204{
5205 vl_api_sw_interface_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -06005206 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005207 hash_pair_t *p;
5208 name_sort_t *nses = 0, *ns;
5209 sw_interface_subif_t *sub = NULL;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005210 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005211
5212 /* Toss the old name table */
5213 /* *INDENT-OFF* */
5214 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5215 ({
5216 vec_add2 (nses, ns, 1);
5217 ns->name = (u8 *)(p->key);
5218 ns->value = (u32) p->value[0];
5219 }));
5220 /* *INDENT-ON* */
5221
5222 hash_free (vam->sw_if_index_by_interface_name);
5223
5224 vec_foreach (ns, nses) vec_free (ns->name);
5225
5226 vec_free (nses);
5227
5228 vec_foreach (sub, vam->sw_if_subif_table)
5229 {
5230 vec_free (sub->interface_name);
5231 }
5232 vec_free (vam->sw_if_subif_table);
5233
5234 /* recreate the interface name hash table */
5235 vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5236
5237 /* Get list of ethernets */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005238 M (SW_INTERFACE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005239 mp->name_filter_valid = 1;
5240 strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005241 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005242
5243 /* and local / loopback interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005244 M (SW_INTERFACE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005245 mp->name_filter_valid = 1;
5246 strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005247 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005248
5249 /* and packet-generator interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005250 M (SW_INTERFACE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005251 mp->name_filter_valid = 1;
5252 strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005253 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005254
5255 /* and vxlan-gpe tunnel interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005256 M (SW_INTERFACE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005257 mp->name_filter_valid = 1;
5258 strncpy ((char *) mp->name_filter, "vxlan_gpe",
5259 sizeof (mp->name_filter) - 1);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005260 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005261
5262 /* and vxlan tunnel interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005263 M (SW_INTERFACE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005264 mp->name_filter_valid = 1;
5265 strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005266 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005267
5268 /* and host (af_packet) interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005269 M (SW_INTERFACE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005270 mp->name_filter_valid = 1;
5271 strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005272 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005273
5274 /* and l2tpv3 tunnel interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005275 M (SW_INTERFACE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005276 mp->name_filter_valid = 1;
5277 strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
5278 sizeof (mp->name_filter) - 1);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005279 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005280
5281 /* and GRE tunnel interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005282 M (SW_INTERFACE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005283 mp->name_filter_valid = 1;
5284 strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005285 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005286
5287 /* and LISP-GPE interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005288 M (SW_INTERFACE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005289 mp->name_filter_valid = 1;
5290 strncpy ((char *) mp->name_filter, "lisp_gpe",
5291 sizeof (mp->name_filter) - 1);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005292 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005293
5294 /* and IPSEC tunnel interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005295 M (SW_INTERFACE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005296 mp->name_filter_valid = 1;
5297 strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005298 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005299
5300 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -06005301 M (CONTROL_PING, mp_ping);
5302 S (mp_ping);
5303
Jon Loeliger56c7b012017-02-01 12:31:41 -06005304 W (ret);
5305 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005306}
5307
5308static int
5309api_sw_interface_set_flags (vat_main_t * vam)
5310{
5311 unformat_input_t *i = vam->input;
5312 vl_api_sw_interface_set_flags_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005313 u32 sw_if_index;
5314 u8 sw_if_index_set = 0;
5315 u8 admin_up = 0, link_up = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005316 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005317
5318 /* Parse args required to build the message */
5319 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5320 {
5321 if (unformat (i, "admin-up"))
5322 admin_up = 1;
5323 else if (unformat (i, "admin-down"))
5324 admin_up = 0;
5325 else if (unformat (i, "link-up"))
5326 link_up = 1;
5327 else if (unformat (i, "link-down"))
5328 link_up = 0;
5329 else
5330 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5331 sw_if_index_set = 1;
5332 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5333 sw_if_index_set = 1;
5334 else
5335 break;
5336 }
5337
5338 if (sw_if_index_set == 0)
5339 {
5340 errmsg ("missing interface name or sw_if_index");
5341 return -99;
5342 }
5343
5344 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005345 M (SW_INTERFACE_SET_FLAGS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005346 mp->sw_if_index = ntohl (sw_if_index);
5347 mp->admin_up_down = admin_up;
5348 mp->link_up_down = link_up;
5349
5350 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005351 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005352
5353 /* Wait for a reply, return the good/bad news... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06005354 W (ret);
5355 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005356}
5357
5358static int
5359api_sw_interface_clear_stats (vat_main_t * vam)
5360{
5361 unformat_input_t *i = vam->input;
5362 vl_api_sw_interface_clear_stats_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005363 u32 sw_if_index;
5364 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005365 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005366
5367 /* Parse args required to build the message */
5368 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5369 {
5370 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5371 sw_if_index_set = 1;
5372 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5373 sw_if_index_set = 1;
5374 else
5375 break;
5376 }
5377
5378 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005379 M (SW_INTERFACE_CLEAR_STATS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005380
5381 if (sw_if_index_set == 1)
5382 mp->sw_if_index = ntohl (sw_if_index);
5383 else
5384 mp->sw_if_index = ~0;
5385
5386 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005387 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005388
5389 /* Wait for a reply, return the good/bad news... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06005390 W (ret);
5391 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005392}
5393
Damjan Marion7cd468a2016-12-19 23:05:39 +01005394static int
5395api_sw_interface_add_del_address (vat_main_t * vam)
5396{
5397 unformat_input_t *i = vam->input;
5398 vl_api_sw_interface_add_del_address_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005399 u32 sw_if_index;
5400 u8 sw_if_index_set = 0;
5401 u8 is_add = 1, del_all = 0;
5402 u32 address_length = 0;
5403 u8 v4_address_set = 0;
5404 u8 v6_address_set = 0;
5405 ip4_address_t v4address;
5406 ip6_address_t v6address;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005407 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005408
5409 /* Parse args required to build the message */
5410 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5411 {
5412 if (unformat (i, "del-all"))
5413 del_all = 1;
5414 else if (unformat (i, "del"))
5415 is_add = 0;
5416 else
5417 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5418 sw_if_index_set = 1;
5419 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5420 sw_if_index_set = 1;
5421 else if (unformat (i, "%U/%d",
5422 unformat_ip4_address, &v4address, &address_length))
5423 v4_address_set = 1;
5424 else if (unformat (i, "%U/%d",
5425 unformat_ip6_address, &v6address, &address_length))
5426 v6_address_set = 1;
5427 else
5428 break;
5429 }
5430
5431 if (sw_if_index_set == 0)
5432 {
5433 errmsg ("missing interface name or sw_if_index");
5434 return -99;
5435 }
5436 if (v4_address_set && v6_address_set)
5437 {
5438 errmsg ("both v4 and v6 addresses set");
5439 return -99;
5440 }
5441 if (!v4_address_set && !v6_address_set && !del_all)
5442 {
5443 errmsg ("no addresses set");
5444 return -99;
5445 }
5446
5447 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005448 M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005449
5450 mp->sw_if_index = ntohl (sw_if_index);
5451 mp->is_add = is_add;
5452 mp->del_all = del_all;
5453 if (v6_address_set)
5454 {
5455 mp->is_ipv6 = 1;
5456 clib_memcpy (mp->address, &v6address, sizeof (v6address));
5457 }
5458 else
5459 {
5460 clib_memcpy (mp->address, &v4address, sizeof (v4address));
5461 }
5462 mp->address_length = address_length;
5463
5464 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005465 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005466
5467 /* Wait for a reply, return good/bad news */
Jon Loeliger56c7b012017-02-01 12:31:41 -06005468 W (ret);
5469 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005470}
5471
5472static int
5473api_sw_interface_set_mpls_enable (vat_main_t * vam)
5474{
5475 unformat_input_t *i = vam->input;
5476 vl_api_sw_interface_set_mpls_enable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005477 u32 sw_if_index;
5478 u8 sw_if_index_set = 0;
5479 u8 enable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005480 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005481
5482 /* Parse args required to build the message */
5483 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5484 {
5485 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5486 sw_if_index_set = 1;
5487 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5488 sw_if_index_set = 1;
5489 else if (unformat (i, "disable"))
5490 enable = 0;
5491 else if (unformat (i, "dis"))
5492 enable = 0;
5493 else
5494 break;
5495 }
5496
5497 if (sw_if_index_set == 0)
5498 {
5499 errmsg ("missing interface name or sw_if_index");
5500 return -99;
5501 }
5502
5503 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005504 M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005505
5506 mp->sw_if_index = ntohl (sw_if_index);
5507 mp->enable = enable;
5508
5509 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005510 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005511
5512 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06005513 W (ret);
5514 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005515}
5516
5517static int
5518api_sw_interface_set_table (vat_main_t * vam)
5519{
5520 unformat_input_t *i = vam->input;
5521 vl_api_sw_interface_set_table_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005522 u32 sw_if_index, vrf_id = 0;
5523 u8 sw_if_index_set = 0;
5524 u8 is_ipv6 = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005525 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005526
5527 /* Parse args required to build the message */
5528 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5529 {
5530 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5531 sw_if_index_set = 1;
5532 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5533 sw_if_index_set = 1;
5534 else if (unformat (i, "vrf %d", &vrf_id))
5535 ;
5536 else if (unformat (i, "ipv6"))
5537 is_ipv6 = 1;
5538 else
5539 break;
5540 }
5541
5542 if (sw_if_index_set == 0)
5543 {
5544 errmsg ("missing interface name or sw_if_index");
5545 return -99;
5546 }
5547
5548 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005549 M (SW_INTERFACE_SET_TABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005550
5551 mp->sw_if_index = ntohl (sw_if_index);
5552 mp->is_ipv6 = is_ipv6;
5553 mp->vrf_id = ntohl (vrf_id);
5554
5555 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005556 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005557
5558 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06005559 W (ret);
5560 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005561}
5562
5563static void vl_api_sw_interface_get_table_reply_t_handler
5564 (vl_api_sw_interface_get_table_reply_t * mp)
5565{
5566 vat_main_t *vam = &vat_main;
5567
5568 print (vam->ofp, "%d", ntohl (mp->vrf_id));
5569
5570 vam->retval = ntohl (mp->retval);
5571 vam->result_ready = 1;
5572
5573}
5574
5575static void vl_api_sw_interface_get_table_reply_t_handler_json
5576 (vl_api_sw_interface_get_table_reply_t * mp)
5577{
5578 vat_main_t *vam = &vat_main;
5579 vat_json_node_t node;
5580
5581 vat_json_init_object (&node);
5582 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5583 vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
5584
5585 vat_json_print (vam->ofp, &node);
5586 vat_json_free (&node);
5587
5588 vam->retval = ntohl (mp->retval);
5589 vam->result_ready = 1;
5590}
5591
5592static int
5593api_sw_interface_get_table (vat_main_t * vam)
5594{
5595 unformat_input_t *i = vam->input;
5596 vl_api_sw_interface_get_table_t *mp;
5597 u32 sw_if_index;
5598 u8 sw_if_index_set = 0;
5599 u8 is_ipv6 = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005600 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005601
5602 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5603 {
5604 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5605 sw_if_index_set = 1;
5606 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5607 sw_if_index_set = 1;
5608 else if (unformat (i, "ipv6"))
5609 is_ipv6 = 1;
5610 else
5611 break;
5612 }
5613
5614 if (sw_if_index_set == 0)
5615 {
5616 errmsg ("missing interface name or sw_if_index");
5617 return -99;
5618 }
5619
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005620 M (SW_INTERFACE_GET_TABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005621 mp->sw_if_index = htonl (sw_if_index);
5622 mp->is_ipv6 = is_ipv6;
5623
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005624 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06005625 W (ret);
5626 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005627}
5628
5629static int
5630api_sw_interface_set_vpath (vat_main_t * vam)
5631{
5632 unformat_input_t *i = vam->input;
5633 vl_api_sw_interface_set_vpath_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005634 u32 sw_if_index = 0;
5635 u8 sw_if_index_set = 0;
5636 u8 is_enable = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005637 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005638
5639 /* Parse args required to build the message */
5640 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5641 {
5642 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5643 sw_if_index_set = 1;
5644 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5645 sw_if_index_set = 1;
5646 else if (unformat (i, "enable"))
5647 is_enable = 1;
5648 else if (unformat (i, "disable"))
5649 is_enable = 0;
5650 else
5651 break;
5652 }
5653
5654 if (sw_if_index_set == 0)
5655 {
5656 errmsg ("missing interface name or sw_if_index");
5657 return -99;
5658 }
5659
5660 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005661 M (SW_INTERFACE_SET_VPATH, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005662
5663 mp->sw_if_index = ntohl (sw_if_index);
5664 mp->enable = is_enable;
5665
5666 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005667 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005668
5669 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06005670 W (ret);
5671 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005672}
5673
5674static int
5675api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
5676{
5677 unformat_input_t *i = vam->input;
5678 vl_api_sw_interface_set_vxlan_bypass_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005679 u32 sw_if_index = 0;
5680 u8 sw_if_index_set = 0;
John Lo2b81eb82017-01-30 13:12:10 -05005681 u8 is_enable = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005682 u8 is_ipv6 = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005683 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005684
5685 /* Parse args required to build the message */
5686 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5687 {
5688 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5689 sw_if_index_set = 1;
5690 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5691 sw_if_index_set = 1;
5692 else if (unformat (i, "enable"))
5693 is_enable = 1;
5694 else if (unformat (i, "disable"))
5695 is_enable = 0;
5696 else if (unformat (i, "ip4"))
5697 is_ipv6 = 0;
5698 else if (unformat (i, "ip6"))
5699 is_ipv6 = 1;
5700 else
5701 break;
5702 }
5703
5704 if (sw_if_index_set == 0)
5705 {
5706 errmsg ("missing interface name or sw_if_index");
5707 return -99;
5708 }
5709
5710 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005711 M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005712
5713 mp->sw_if_index = ntohl (sw_if_index);
5714 mp->enable = is_enable;
5715 mp->is_ipv6 = is_ipv6;
5716
5717 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005718 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005719
5720 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06005721 W (ret);
5722 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005723}
5724
5725static int
5726api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5727{
5728 unformat_input_t *i = vam->input;
5729 vl_api_sw_interface_set_l2_xconnect_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005730 u32 rx_sw_if_index;
5731 u8 rx_sw_if_index_set = 0;
5732 u32 tx_sw_if_index;
5733 u8 tx_sw_if_index_set = 0;
5734 u8 enable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005735 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005736
5737 /* Parse args required to build the message */
5738 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5739 {
5740 if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5741 rx_sw_if_index_set = 1;
5742 else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5743 tx_sw_if_index_set = 1;
5744 else if (unformat (i, "rx"))
5745 {
5746 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5747 {
5748 if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5749 &rx_sw_if_index))
5750 rx_sw_if_index_set = 1;
5751 }
5752 else
5753 break;
5754 }
5755 else if (unformat (i, "tx"))
5756 {
5757 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5758 {
5759 if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5760 &tx_sw_if_index))
5761 tx_sw_if_index_set = 1;
5762 }
5763 else
5764 break;
5765 }
5766 else if (unformat (i, "enable"))
5767 enable = 1;
5768 else if (unformat (i, "disable"))
5769 enable = 0;
5770 else
5771 break;
5772 }
5773
5774 if (rx_sw_if_index_set == 0)
5775 {
5776 errmsg ("missing rx interface name or rx_sw_if_index");
5777 return -99;
5778 }
5779
5780 if (enable && (tx_sw_if_index_set == 0))
5781 {
5782 errmsg ("missing tx interface name or tx_sw_if_index");
5783 return -99;
5784 }
5785
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005786 M (SW_INTERFACE_SET_L2_XCONNECT, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005787
5788 mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5789 mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5790 mp->enable = enable;
5791
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005792 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06005793 W (ret);
5794 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005795}
5796
5797static int
5798api_sw_interface_set_l2_bridge (vat_main_t * vam)
5799{
5800 unformat_input_t *i = vam->input;
5801 vl_api_sw_interface_set_l2_bridge_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005802 u32 rx_sw_if_index;
5803 u8 rx_sw_if_index_set = 0;
5804 u32 bd_id;
5805 u8 bd_id_set = 0;
5806 u8 bvi = 0;
5807 u32 shg = 0;
5808 u8 enable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005809 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005810
5811 /* Parse args required to build the message */
5812 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5813 {
5814 if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5815 rx_sw_if_index_set = 1;
5816 else if (unformat (i, "bd_id %d", &bd_id))
5817 bd_id_set = 1;
5818 else
5819 if (unformat
5820 (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
5821 rx_sw_if_index_set = 1;
5822 else if (unformat (i, "shg %d", &shg))
5823 ;
5824 else if (unformat (i, "bvi"))
5825 bvi = 1;
5826 else if (unformat (i, "enable"))
5827 enable = 1;
5828 else if (unformat (i, "disable"))
5829 enable = 0;
5830 else
5831 break;
5832 }
5833
5834 if (rx_sw_if_index_set == 0)
5835 {
5836 errmsg ("missing rx interface name or sw_if_index");
5837 return -99;
5838 }
5839
5840 if (enable && (bd_id_set == 0))
5841 {
5842 errmsg ("missing bridge domain");
5843 return -99;
5844 }
5845
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005846 M (SW_INTERFACE_SET_L2_BRIDGE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005847
5848 mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5849 mp->bd_id = ntohl (bd_id);
5850 mp->shg = (u8) shg;
5851 mp->bvi = bvi;
5852 mp->enable = enable;
5853
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005854 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06005855 W (ret);
5856 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005857}
5858
5859static int
5860api_bridge_domain_dump (vat_main_t * vam)
5861{
5862 unformat_input_t *i = vam->input;
5863 vl_api_bridge_domain_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -06005864 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005865 u32 bd_id = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005866 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005867
5868 /* Parse args required to build the message */
5869 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5870 {
5871 if (unformat (i, "bd_id %d", &bd_id))
5872 ;
5873 else
5874 break;
5875 }
5876
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005877 M (BRIDGE_DOMAIN_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005878 mp->bd_id = ntohl (bd_id);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005879 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005880
5881 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -06005882 M (CONTROL_PING, mp_ping);
5883 S (mp_ping);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005884
Jon Loeliger56c7b012017-02-01 12:31:41 -06005885 W (ret);
5886 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005887}
5888
5889static int
5890api_bridge_domain_add_del (vat_main_t * vam)
5891{
5892 unformat_input_t *i = vam->input;
5893 vl_api_bridge_domain_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005894 u32 bd_id = ~0;
5895 u8 is_add = 1;
5896 u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5897 u32 mac_age = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005898 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005899
5900 /* Parse args required to build the message */
5901 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5902 {
5903 if (unformat (i, "bd_id %d", &bd_id))
5904 ;
5905 else if (unformat (i, "flood %d", &flood))
5906 ;
5907 else if (unformat (i, "uu-flood %d", &uu_flood))
5908 ;
5909 else if (unformat (i, "forward %d", &forward))
5910 ;
5911 else if (unformat (i, "learn %d", &learn))
5912 ;
5913 else if (unformat (i, "arp-term %d", &arp_term))
5914 ;
5915 else if (unformat (i, "mac-age %d", &mac_age))
5916 ;
5917 else if (unformat (i, "del"))
5918 {
5919 is_add = 0;
5920 flood = uu_flood = forward = learn = 0;
5921 }
5922 else
5923 break;
5924 }
5925
5926 if (bd_id == ~0)
5927 {
5928 errmsg ("missing bridge domain");
5929 return -99;
5930 }
5931
5932 if (mac_age > 255)
5933 {
5934 errmsg ("mac age must be less than 256 ");
5935 return -99;
5936 }
5937
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005938 M (BRIDGE_DOMAIN_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005939
5940 mp->bd_id = ntohl (bd_id);
5941 mp->flood = flood;
5942 mp->uu_flood = uu_flood;
5943 mp->forward = forward;
5944 mp->learn = learn;
5945 mp->arp_term = arp_term;
5946 mp->is_add = is_add;
5947 mp->mac_age = (u8) mac_age;
5948
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005949 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06005950 W (ret);
5951 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005952}
5953
5954static int
Eyal Barif24991c2017-04-05 05:33:21 +03005955api_l2fib_flush_bd (vat_main_t * vam)
5956{
5957 unformat_input_t *i = vam->input;
5958 vl_api_l2fib_flush_bd_t *mp;
5959 u32 bd_id = ~0;
5960 int ret;
5961
5962 /* Parse args required to build the message */
5963 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5964 {
5965 if (unformat (i, "bd_id %d", &bd_id));
5966 else
5967 break;
5968 }
5969
5970 if (bd_id == ~0)
5971 {
5972 errmsg ("missing bridge domain");
5973 return -99;
5974 }
5975
5976 M (L2FIB_FLUSH_BD, mp);
5977
5978 mp->bd_id = htonl (bd_id);
5979
5980 S (mp);
5981 W (ret);
5982 return ret;
5983}
5984
5985static int
5986api_l2fib_flush_int (vat_main_t * vam)
5987{
5988 unformat_input_t *i = vam->input;
5989 vl_api_l2fib_flush_int_t *mp;
5990 u32 sw_if_index = ~0;
5991 int ret;
5992
5993 /* Parse args required to build the message */
5994 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5995 {
5996 if (unformat (i, "sw_if_index %d", &sw_if_index));
5997 else
5998 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
5999 else
6000 break;
6001 }
6002
6003 if (sw_if_index == ~0)
6004 {
6005 errmsg ("missing interface name or sw_if_index");
6006 return -99;
6007 }
6008
6009 M (L2FIB_FLUSH_INT, mp);
6010
6011 mp->sw_if_index = ntohl (sw_if_index);
6012
6013 S (mp);
6014 W (ret);
6015 return ret;
6016}
6017
6018static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01006019api_l2fib_add_del (vat_main_t * vam)
6020{
6021 unformat_input_t *i = vam->input;
6022 vl_api_l2fib_add_del_t *mp;
6023 f64 timeout;
6024 u64 mac = 0;
6025 u8 mac_set = 0;
6026 u32 bd_id;
6027 u8 bd_id_set = 0;
6028 u32 sw_if_index = ~0;
6029 u8 sw_if_index_set = 0;
6030 u8 is_add = 1;
6031 u8 static_mac = 0;
6032 u8 filter_mac = 0;
6033 u8 bvi_mac = 0;
6034 int count = 1;
6035 f64 before = 0;
6036 int j;
6037
6038 /* Parse args required to build the message */
6039 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6040 {
6041 if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
6042 mac_set = 1;
6043 else if (unformat (i, "bd_id %d", &bd_id))
6044 bd_id_set = 1;
6045 else if (unformat (i, "sw_if_index %d", &sw_if_index))
6046 sw_if_index_set = 1;
6047 else if (unformat (i, "sw_if"))
6048 {
6049 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6050 {
6051 if (unformat
6052 (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6053 sw_if_index_set = 1;
6054 }
6055 else
6056 break;
6057 }
6058 else if (unformat (i, "static"))
6059 static_mac = 1;
6060 else if (unformat (i, "filter"))
6061 {
6062 filter_mac = 1;
6063 static_mac = 1;
6064 }
6065 else if (unformat (i, "bvi"))
6066 {
6067 bvi_mac = 1;
6068 static_mac = 1;
6069 }
6070 else if (unformat (i, "del"))
6071 is_add = 0;
6072 else if (unformat (i, "count %d", &count))
6073 ;
6074 else
6075 break;
6076 }
6077
6078 if (mac_set == 0)
6079 {
6080 errmsg ("missing mac address");
6081 return -99;
6082 }
6083
6084 if (bd_id_set == 0)
6085 {
6086 errmsg ("missing bridge domain");
6087 return -99;
6088 }
6089
6090 if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6091 {
6092 errmsg ("missing interface name or sw_if_index");
6093 return -99;
6094 }
6095
6096 if (count > 1)
6097 {
6098 /* Turn on async mode */
6099 vam->async_mode = 1;
6100 vam->async_errors = 0;
6101 before = vat_time_now (vam);
6102 }
6103
6104 for (j = 0; j < count; j++)
6105 {
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006106 M (L2FIB_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006107
6108 mp->mac = mac;
6109 mp->bd_id = ntohl (bd_id);
6110 mp->is_add = is_add;
6111
6112 if (is_add)
6113 {
6114 mp->sw_if_index = ntohl (sw_if_index);
6115 mp->static_mac = static_mac;
6116 mp->filter_mac = filter_mac;
6117 mp->bvi_mac = bvi_mac;
6118 }
6119 increment_mac_address (&mac);
6120 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006121 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006122 }
6123
6124 if (count > 1)
6125 {
Jon Loeliger2d23eca2017-02-01 13:09:58 -06006126 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006127 f64 after;
6128
6129 /* Shut off async mode */
6130 vam->async_mode = 0;
6131
Jon Loeliger2d23eca2017-02-01 13:09:58 -06006132 M (CONTROL_PING, mp_ping);
6133 S (mp_ping);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006134
6135 timeout = vat_time_now (vam) + 1.0;
6136 while (vat_time_now (vam) < timeout)
6137 if (vam->result_ready == 1)
6138 goto out;
6139 vam->retval = -99;
6140
6141 out:
6142 if (vam->retval == -99)
6143 errmsg ("timeout");
6144
6145 if (vam->async_errors > 0)
6146 {
6147 errmsg ("%d asynchronous errors", vam->async_errors);
6148 vam->retval = -98;
6149 }
6150 vam->async_errors = 0;
6151 after = vat_time_now (vam);
6152
6153 print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6154 count, after - before, count / (after - before));
6155 }
6156 else
6157 {
Jon Loeliger56c7b012017-02-01 12:31:41 -06006158 int ret;
6159
Damjan Marion7cd468a2016-12-19 23:05:39 +01006160 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06006161 W (ret);
6162 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006163 }
6164 /* Return the good/bad news */
6165 return (vam->retval);
6166}
6167
6168static int
Eyal Barifead6702017-04-04 04:46:32 +03006169api_bridge_domain_set_mac_age (vat_main_t * vam)
6170{
6171 unformat_input_t *i = vam->input;
6172 vl_api_bridge_domain_set_mac_age_t *mp;
6173 u32 bd_id = ~0;
6174 u32 mac_age = 0;
6175 int ret;
6176
6177 /* Parse args required to build the message */
6178 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6179 {
6180 if (unformat (i, "bd_id %d", &bd_id));
6181 else if (unformat (i, "mac-age %d", &mac_age));
6182 else
6183 break;
6184 }
6185
6186 if (bd_id == ~0)
6187 {
6188 errmsg ("missing bridge domain");
6189 return -99;
6190 }
6191
6192 if (mac_age > 255)
6193 {
6194 errmsg ("mac age must be less than 256 ");
6195 return -99;
6196 }
6197
6198 M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
6199
6200 mp->bd_id = htonl (bd_id);
6201 mp->mac_age = (u8) mac_age;
6202
6203 S (mp);
6204 W (ret);
6205 return ret;
6206}
6207
6208static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01006209api_l2_flags (vat_main_t * vam)
6210{
6211 unformat_input_t *i = vam->input;
6212 vl_api_l2_flags_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006213 u32 sw_if_index;
6214 u32 feature_bitmap = 0;
6215 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006216 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006217
6218 /* Parse args required to build the message */
6219 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6220 {
6221 if (unformat (i, "sw_if_index %d", &sw_if_index))
6222 sw_if_index_set = 1;
6223 else if (unformat (i, "sw_if"))
6224 {
6225 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6226 {
6227 if (unformat
6228 (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6229 sw_if_index_set = 1;
6230 }
6231 else
6232 break;
6233 }
6234 else if (unformat (i, "learn"))
6235 feature_bitmap |= L2INPUT_FEAT_LEARN;
6236 else if (unformat (i, "forward"))
6237 feature_bitmap |= L2INPUT_FEAT_FWD;
6238 else if (unformat (i, "flood"))
6239 feature_bitmap |= L2INPUT_FEAT_FLOOD;
6240 else if (unformat (i, "uu-flood"))
6241 feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
6242 else
6243 break;
6244 }
6245
6246 if (sw_if_index_set == 0)
6247 {
6248 errmsg ("missing interface name or sw_if_index");
6249 return -99;
6250 }
6251
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006252 M (L2_FLAGS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006253
6254 mp->sw_if_index = ntohl (sw_if_index);
6255 mp->feature_bitmap = ntohl (feature_bitmap);
6256
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006257 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06006258 W (ret);
6259 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006260}
6261
6262static int
6263api_bridge_flags (vat_main_t * vam)
6264{
6265 unformat_input_t *i = vam->input;
6266 vl_api_bridge_flags_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006267 u32 bd_id;
6268 u8 bd_id_set = 0;
6269 u8 is_set = 1;
6270 u32 flags = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006271 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006272
6273 /* Parse args required to build the message */
6274 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6275 {
6276 if (unformat (i, "bd_id %d", &bd_id))
6277 bd_id_set = 1;
6278 else if (unformat (i, "learn"))
6279 flags |= L2_LEARN;
6280 else if (unformat (i, "forward"))
6281 flags |= L2_FWD;
6282 else if (unformat (i, "flood"))
6283 flags |= L2_FLOOD;
6284 else if (unformat (i, "uu-flood"))
6285 flags |= L2_UU_FLOOD;
6286 else if (unformat (i, "arp-term"))
6287 flags |= L2_ARP_TERM;
6288 else if (unformat (i, "off"))
6289 is_set = 0;
6290 else if (unformat (i, "disable"))
6291 is_set = 0;
6292 else
6293 break;
6294 }
6295
6296 if (bd_id_set == 0)
6297 {
6298 errmsg ("missing bridge domain");
6299 return -99;
6300 }
6301
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006302 M (BRIDGE_FLAGS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006303
6304 mp->bd_id = ntohl (bd_id);
6305 mp->feature_bitmap = ntohl (flags);
6306 mp->is_set = is_set;
6307
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006308 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06006309 W (ret);
6310 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006311}
6312
6313static int
6314api_bd_ip_mac_add_del (vat_main_t * vam)
6315{
6316 unformat_input_t *i = vam->input;
6317 vl_api_bd_ip_mac_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006318 u32 bd_id;
6319 u8 is_ipv6 = 0;
6320 u8 is_add = 1;
6321 u8 bd_id_set = 0;
6322 u8 ip_set = 0;
6323 u8 mac_set = 0;
6324 ip4_address_t v4addr;
6325 ip6_address_t v6addr;
6326 u8 macaddr[6];
Jon Loeliger56c7b012017-02-01 12:31:41 -06006327 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006328
6329
6330 /* Parse args required to build the message */
6331 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6332 {
6333 if (unformat (i, "bd_id %d", &bd_id))
6334 {
6335 bd_id_set++;
6336 }
6337 else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
6338 {
6339 ip_set++;
6340 }
6341 else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
6342 {
6343 ip_set++;
6344 is_ipv6++;
6345 }
6346 else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
6347 {
6348 mac_set++;
6349 }
6350 else if (unformat (i, "del"))
6351 is_add = 0;
6352 else
6353 break;
6354 }
6355
6356 if (bd_id_set == 0)
6357 {
6358 errmsg ("missing bridge domain");
6359 return -99;
6360 }
6361 else if (ip_set == 0)
6362 {
6363 errmsg ("missing IP address");
6364 return -99;
6365 }
6366 else if (mac_set == 0)
6367 {
6368 errmsg ("missing MAC address");
6369 return -99;
6370 }
6371
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006372 M (BD_IP_MAC_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006373
6374 mp->bd_id = ntohl (bd_id);
6375 mp->is_ipv6 = is_ipv6;
6376 mp->is_add = is_add;
6377 if (is_ipv6)
6378 clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
6379 else
6380 clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
6381 clib_memcpy (mp->mac_address, macaddr, 6);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006382 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06006383 W (ret);
6384 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006385}
6386
6387static int
6388api_tap_connect (vat_main_t * vam)
6389{
6390 unformat_input_t *i = vam->input;
6391 vl_api_tap_connect_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006392 u8 mac_address[6];
6393 u8 random_mac = 1;
6394 u8 name_set = 0;
6395 u8 *tap_name;
6396 u8 *tag = 0;
Dave Barach2feaffc2017-01-14 10:30:50 -05006397 ip4_address_t ip4_address;
6398 u32 ip4_mask_width;
6399 int ip4_address_set = 0;
6400 ip6_address_t ip6_address;
6401 u32 ip6_mask_width;
6402 int ip6_address_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006403 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006404
6405 memset (mac_address, 0, sizeof (mac_address));
6406
6407 /* Parse args required to build the message */
6408 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6409 {
6410 if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6411 {
6412 random_mac = 0;
6413 }
6414 else if (unformat (i, "random-mac"))
6415 random_mac = 1;
6416 else if (unformat (i, "tapname %s", &tap_name))
6417 name_set = 1;
6418 else if (unformat (i, "tag %s", &tag))
6419 ;
Dave Barach2feaffc2017-01-14 10:30:50 -05006420 else if (unformat (i, "address %U/%d",
6421 unformat_ip4_address, &ip4_address, &ip4_mask_width))
6422 ip4_address_set = 1;
6423 else if (unformat (i, "address %U/%d",
6424 unformat_ip6_address, &ip6_address, &ip6_mask_width))
6425 ip6_address_set = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006426 else
6427 break;
6428 }
6429
6430 if (name_set == 0)
6431 {
6432 errmsg ("missing tap name");
6433 return -99;
6434 }
6435 if (vec_len (tap_name) > 63)
6436 {
6437 errmsg ("tap name too long");
6438 return -99;
6439 }
6440 vec_add1 (tap_name, 0);
6441
6442 if (vec_len (tag) > 63)
6443 {
6444 errmsg ("tag too long");
6445 return -99;
6446 }
6447
6448 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006449 M (TAP_CONNECT, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006450
6451 mp->use_random_mac = random_mac;
6452 clib_memcpy (mp->mac_address, mac_address, 6);
6453 clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6454 if (tag)
6455 clib_memcpy (mp->tag, tag, vec_len (tag));
6456
Dave Barach2feaffc2017-01-14 10:30:50 -05006457 if (ip4_address_set)
6458 {
6459 mp->ip4_address_set = 1;
6460 clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
6461 mp->ip4_mask_width = ip4_mask_width;
6462 }
6463 if (ip6_address_set)
6464 {
6465 mp->ip6_address_set = 1;
6466 clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
6467 mp->ip6_mask_width = ip6_mask_width;
6468 }
6469
Damjan Marion7cd468a2016-12-19 23:05:39 +01006470 vec_free (tap_name);
6471 vec_free (tag);
6472
6473 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006474 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006475
6476 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06006477 W (ret);
6478 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006479}
6480
6481static int
6482api_tap_modify (vat_main_t * vam)
6483{
6484 unformat_input_t *i = vam->input;
6485 vl_api_tap_modify_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006486 u8 mac_address[6];
6487 u8 random_mac = 1;
6488 u8 name_set = 0;
6489 u8 *tap_name;
6490 u32 sw_if_index = ~0;
6491 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006492 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006493
6494 memset (mac_address, 0, sizeof (mac_address));
6495
6496 /* Parse args required to build the message */
6497 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6498 {
6499 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6500 sw_if_index_set = 1;
6501 else if (unformat (i, "sw_if_index %d", &sw_if_index))
6502 sw_if_index_set = 1;
6503 else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6504 {
6505 random_mac = 0;
6506 }
6507 else if (unformat (i, "random-mac"))
6508 random_mac = 1;
6509 else if (unformat (i, "tapname %s", &tap_name))
6510 name_set = 1;
6511 else
6512 break;
6513 }
6514
6515 if (sw_if_index_set == 0)
6516 {
6517 errmsg ("missing vpp interface name");
6518 return -99;
6519 }
6520 if (name_set == 0)
6521 {
6522 errmsg ("missing tap name");
6523 return -99;
6524 }
6525 if (vec_len (tap_name) > 63)
6526 {
6527 errmsg ("tap name too long");
6528 }
6529 vec_add1 (tap_name, 0);
6530
6531 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006532 M (TAP_MODIFY, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006533
6534 mp->use_random_mac = random_mac;
6535 mp->sw_if_index = ntohl (sw_if_index);
6536 clib_memcpy (mp->mac_address, mac_address, 6);
6537 clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6538 vec_free (tap_name);
6539
6540 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006541 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006542
6543 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06006544 W (ret);
6545 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006546}
6547
6548static int
6549api_tap_delete (vat_main_t * vam)
6550{
6551 unformat_input_t *i = vam->input;
6552 vl_api_tap_delete_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006553 u32 sw_if_index = ~0;
6554 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006555 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006556
6557 /* Parse args required to build the message */
6558 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6559 {
6560 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6561 sw_if_index_set = 1;
6562 else if (unformat (i, "sw_if_index %d", &sw_if_index))
6563 sw_if_index_set = 1;
6564 else
6565 break;
6566 }
6567
6568 if (sw_if_index_set == 0)
6569 {
6570 errmsg ("missing vpp interface name");
6571 return -99;
6572 }
6573
6574 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006575 M (TAP_DELETE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006576
6577 mp->sw_if_index = ntohl (sw_if_index);
6578
6579 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006580 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006581
6582 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06006583 W (ret);
6584 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006585}
6586
6587static int
6588api_ip_add_del_route (vat_main_t * vam)
6589{
6590 unformat_input_t *i = vam->input;
6591 vl_api_ip_add_del_route_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006592 u32 sw_if_index = ~0, vrf_id = 0;
6593 u8 is_ipv6 = 0;
6594 u8 is_local = 0, is_drop = 0;
6595 u8 is_unreach = 0, is_prohibit = 0;
6596 u8 create_vrf_if_needed = 0;
6597 u8 is_add = 1;
6598 u32 next_hop_weight = 1;
6599 u8 not_last = 0;
6600 u8 is_multipath = 0;
6601 u8 address_set = 0;
6602 u8 address_length_set = 0;
6603 u32 next_hop_table_id = 0;
6604 u32 resolve_attempts = 0;
6605 u32 dst_address_length = 0;
6606 u8 next_hop_set = 0;
6607 ip4_address_t v4_dst_address, v4_next_hop_address;
6608 ip6_address_t v6_dst_address, v6_next_hop_address;
6609 int count = 1;
6610 int j;
6611 f64 before = 0;
6612 u32 random_add_del = 0;
6613 u32 *random_vector = 0;
6614 uword *random_hash;
6615 u32 random_seed = 0xdeaddabe;
6616 u32 classify_table_index = ~0;
6617 u8 is_classify = 0;
6618 u8 resolve_host = 0, resolve_attached = 0;
6619 mpls_label_t *next_hop_out_label_stack = NULL;
6620 mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6621 mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6622
6623 /* Parse args required to build the message */
6624 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6625 {
6626 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6627 ;
6628 else if (unformat (i, "sw_if_index %d", &sw_if_index))
6629 ;
6630 else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
6631 {
6632 address_set = 1;
6633 is_ipv6 = 0;
6634 }
6635 else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
6636 {
6637 address_set = 1;
6638 is_ipv6 = 1;
6639 }
6640 else if (unformat (i, "/%d", &dst_address_length))
6641 {
6642 address_length_set = 1;
6643 }
6644
6645 else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
6646 &v4_next_hop_address))
6647 {
6648 next_hop_set = 1;
6649 }
6650 else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
6651 &v6_next_hop_address))
6652 {
6653 next_hop_set = 1;
6654 }
6655 else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6656 ;
6657 else if (unformat (i, "weight %d", &next_hop_weight))
6658 ;
6659 else if (unformat (i, "drop"))
6660 {
6661 is_drop = 1;
6662 }
6663 else if (unformat (i, "null-send-unreach"))
6664 {
6665 is_unreach = 1;
6666 }
6667 else if (unformat (i, "null-send-prohibit"))
6668 {
6669 is_prohibit = 1;
6670 }
6671 else if (unformat (i, "local"))
6672 {
6673 is_local = 1;
6674 }
6675 else if (unformat (i, "classify %d", &classify_table_index))
6676 {
6677 is_classify = 1;
6678 }
6679 else if (unformat (i, "del"))
6680 is_add = 0;
6681 else if (unformat (i, "add"))
6682 is_add = 1;
6683 else if (unformat (i, "not-last"))
6684 not_last = 1;
6685 else if (unformat (i, "resolve-via-host"))
6686 resolve_host = 1;
6687 else if (unformat (i, "resolve-via-attached"))
6688 resolve_attached = 1;
6689 else if (unformat (i, "multipath"))
6690 is_multipath = 1;
6691 else if (unformat (i, "vrf %d", &vrf_id))
6692 ;
6693 else if (unformat (i, "create-vrf"))
6694 create_vrf_if_needed = 1;
6695 else if (unformat (i, "count %d", &count))
6696 ;
6697 else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
6698 ;
6699 else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6700 ;
6701 else if (unformat (i, "out-label %d", &next_hop_out_label))
6702 vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6703 else if (unformat (i, "via-label %d", &next_hop_via_label))
6704 ;
6705 else if (unformat (i, "random"))
6706 random_add_del = 1;
6707 else if (unformat (i, "seed %d", &random_seed))
6708 ;
6709 else
6710 {
6711 clib_warning ("parse error '%U'", format_unformat_error, i);
6712 return -99;
6713 }
6714 }
6715
6716 if (!next_hop_set && !is_drop && !is_local &&
6717 !is_classify && !is_unreach && !is_prohibit &&
6718 MPLS_LABEL_INVALID == next_hop_via_label)
6719 {
6720 errmsg
6721 ("next hop / local / drop / unreach / prohibit / classify not set");
6722 return -99;
6723 }
6724
6725 if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
6726 {
6727 errmsg ("next hop and next-hop via label set");
6728 return -99;
6729 }
6730 if (address_set == 0)
6731 {
6732 errmsg ("missing addresses");
6733 return -99;
6734 }
6735
6736 if (address_length_set == 0)
6737 {
6738 errmsg ("missing address length");
6739 return -99;
6740 }
6741
6742 /* Generate a pile of unique, random routes */
6743 if (random_add_del)
6744 {
6745 u32 this_random_address;
6746 random_hash = hash_create (count, sizeof (uword));
6747
6748 hash_set (random_hash, v4_next_hop_address.as_u32, 1);
6749 for (j = 0; j <= count; j++)
6750 {
6751 do
6752 {
6753 this_random_address = random_u32 (&random_seed);
6754 this_random_address =
6755 clib_host_to_net_u32 (this_random_address);
6756 }
6757 while (hash_get (random_hash, this_random_address));
6758 vec_add1 (random_vector, this_random_address);
6759 hash_set (random_hash, this_random_address, 1);
6760 }
6761 hash_free (random_hash);
6762 v4_dst_address.as_u32 = random_vector[0];
6763 }
6764
6765 if (count > 1)
6766 {
6767 /* Turn on async mode */
6768 vam->async_mode = 1;
6769 vam->async_errors = 0;
6770 before = vat_time_now (vam);
6771 }
6772
6773 for (j = 0; j < count; j++)
6774 {
6775 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006776 M2 (IP_ADD_DEL_ROUTE, mp,
Damjan Marion7cd468a2016-12-19 23:05:39 +01006777 sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6778
6779 mp->next_hop_sw_if_index = ntohl (sw_if_index);
6780 mp->table_id = ntohl (vrf_id);
6781 mp->create_vrf_if_needed = create_vrf_if_needed;
6782
6783 mp->is_add = is_add;
6784 mp->is_drop = is_drop;
6785 mp->is_unreach = is_unreach;
6786 mp->is_prohibit = is_prohibit;
6787 mp->is_ipv6 = is_ipv6;
6788 mp->is_local = is_local;
6789 mp->is_classify = is_classify;
6790 mp->is_multipath = is_multipath;
6791 mp->is_resolve_host = resolve_host;
6792 mp->is_resolve_attached = resolve_attached;
6793 mp->not_last = not_last;
6794 mp->next_hop_weight = next_hop_weight;
6795 mp->dst_address_length = dst_address_length;
6796 mp->next_hop_table_id = ntohl (next_hop_table_id);
6797 mp->classify_table_index = ntohl (classify_table_index);
6798 mp->next_hop_via_label = ntohl (next_hop_via_label);
6799 mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6800 if (0 != mp->next_hop_n_out_labels)
6801 {
6802 memcpy (mp->next_hop_out_label_stack,
6803 next_hop_out_label_stack,
6804 vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6805 vec_free (next_hop_out_label_stack);
6806 }
6807
6808 if (is_ipv6)
6809 {
6810 clib_memcpy (mp->dst_address, &v6_dst_address,
6811 sizeof (v6_dst_address));
6812 if (next_hop_set)
6813 clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
6814 sizeof (v6_next_hop_address));
6815 increment_v6_address (&v6_dst_address);
6816 }
6817 else
6818 {
6819 clib_memcpy (mp->dst_address, &v4_dst_address,
6820 sizeof (v4_dst_address));
6821 if (next_hop_set)
6822 clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
6823 sizeof (v4_next_hop_address));
6824 if (random_add_del)
6825 v4_dst_address.as_u32 = random_vector[j + 1];
6826 else
6827 increment_v4_address (&v4_dst_address);
6828 }
6829 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006830 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006831 /* If we receive SIGTERM, stop now... */
6832 if (vam->do_exit)
6833 break;
6834 }
6835
6836 /* When testing multiple add/del ops, use a control-ping to sync */
6837 if (count > 1)
6838 {
Jon Loeliger2d23eca2017-02-01 13:09:58 -06006839 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006840 f64 after;
Jon Loeliger1f9191f2017-01-31 15:27:19 -06006841 f64 timeout;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006842
6843 /* Shut off async mode */
6844 vam->async_mode = 0;
6845
Jon Loeliger2d23eca2017-02-01 13:09:58 -06006846 M (CONTROL_PING, mp_ping);
6847 S (mp_ping);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006848
6849 timeout = vat_time_now (vam) + 1.0;
6850 while (vat_time_now (vam) < timeout)
6851 if (vam->result_ready == 1)
6852 goto out;
6853 vam->retval = -99;
6854
6855 out:
6856 if (vam->retval == -99)
6857 errmsg ("timeout");
6858
6859 if (vam->async_errors > 0)
6860 {
6861 errmsg ("%d asynchronous errors", vam->async_errors);
6862 vam->retval = -98;
6863 }
6864 vam->async_errors = 0;
6865 after = vat_time_now (vam);
6866
6867 /* slim chance, but we might have eaten SIGTERM on the first iteration */
6868 if (j > 0)
6869 count = j;
6870
6871 print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6872 count, after - before, count / (after - before));
6873 }
6874 else
6875 {
Jon Loeliger56c7b012017-02-01 12:31:41 -06006876 int ret;
6877
Damjan Marion7cd468a2016-12-19 23:05:39 +01006878 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06006879 W (ret);
6880 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006881 }
6882
6883 /* Return the good/bad news */
6884 return (vam->retval);
6885}
6886
6887static int
Neale Ranns32e1c012016-11-22 17:07:28 +00006888api_ip_mroute_add_del (vat_main_t * vam)
6889{
6890 unformat_input_t *i = vam->input;
6891 vl_api_ip_mroute_add_del_t *mp;
Neale Ranns32e1c012016-11-22 17:07:28 +00006892 u32 sw_if_index = ~0, vrf_id = 0;
6893 u8 is_ipv6 = 0;
6894 u8 is_local = 0;
6895 u8 create_vrf_if_needed = 0;
6896 u8 is_add = 1;
6897 u8 address_set = 0;
6898 u32 grp_address_length = 0;
6899 ip4_address_t v4_grp_address, v4_src_address;
6900 ip6_address_t v6_grp_address, v6_src_address;
6901 mfib_itf_flags_t iflags = 0;
6902 mfib_entry_flags_t eflags = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006903 int ret;
Neale Ranns32e1c012016-11-22 17:07:28 +00006904
6905 /* Parse args required to build the message */
6906 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6907 {
6908 if (unformat (i, "sw_if_index %d", &sw_if_index))
6909 ;
6910 else if (unformat (i, "%U %U",
6911 unformat_ip4_address, &v4_src_address,
6912 unformat_ip4_address, &v4_grp_address))
6913 {
6914 grp_address_length = 64;
6915 address_set = 1;
6916 is_ipv6 = 0;
6917 }
6918 else if (unformat (i, "%U %U",
6919 unformat_ip6_address, &v6_src_address,
6920 unformat_ip6_address, &v6_grp_address))
6921 {
6922 grp_address_length = 256;
6923 address_set = 1;
6924 is_ipv6 = 1;
6925 }
6926 else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
6927 {
6928 memset (&v4_src_address, 0, sizeof (v4_src_address));
6929 grp_address_length = 32;
6930 address_set = 1;
6931 is_ipv6 = 0;
6932 }
6933 else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
6934 {
6935 memset (&v6_src_address, 0, sizeof (v6_src_address));
6936 grp_address_length = 128;
6937 address_set = 1;
6938 is_ipv6 = 1;
6939 }
6940 else if (unformat (i, "/%d", &grp_address_length))
6941 ;
6942 else if (unformat (i, "local"))
6943 {
6944 is_local = 1;
6945 }
6946 else if (unformat (i, "del"))
6947 is_add = 0;
6948 else if (unformat (i, "add"))
6949 is_add = 1;
6950 else if (unformat (i, "vrf %d", &vrf_id))
6951 ;
6952 else if (unformat (i, "create-vrf"))
6953 create_vrf_if_needed = 1;
6954 else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
6955 ;
6956 else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
6957 ;
6958 else
6959 {
6960 clib_warning ("parse error '%U'", format_unformat_error, i);
6961 return -99;
6962 }
6963 }
6964
6965 if (address_set == 0)
6966 {
6967 errmsg ("missing addresses\n");
6968 return -99;
6969 }
6970
6971 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006972 M (IP_MROUTE_ADD_DEL, mp);
Neale Ranns32e1c012016-11-22 17:07:28 +00006973
6974 mp->next_hop_sw_if_index = ntohl (sw_if_index);
6975 mp->table_id = ntohl (vrf_id);
6976 mp->create_vrf_if_needed = create_vrf_if_needed;
6977
6978 mp->is_add = is_add;
6979 mp->is_ipv6 = is_ipv6;
6980 mp->is_local = is_local;
6981 mp->itf_flags = ntohl (iflags);
6982 mp->entry_flags = ntohl (eflags);
6983 mp->grp_address_length = grp_address_length;
6984 mp->grp_address_length = ntohs (mp->grp_address_length);
6985
6986 if (is_ipv6)
6987 {
6988 clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
6989 clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
6990 }
6991 else
6992 {
6993 clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
6994 clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
6995
6996 }
6997
6998 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006999 S (mp);
Neale Ranns32e1c012016-11-22 17:07:28 +00007000 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06007001 W (ret);
7002 return ret;
Neale Ranns32e1c012016-11-22 17:07:28 +00007003}
7004
7005static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01007006api_mpls_route_add_del (vat_main_t * vam)
7007{
7008 unformat_input_t *i = vam->input;
7009 vl_api_mpls_route_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007010 u32 sw_if_index = ~0, table_id = 0;
7011 u8 create_table_if_needed = 0;
7012 u8 is_add = 1;
7013 u32 next_hop_weight = 1;
7014 u8 is_multipath = 0;
7015 u32 next_hop_table_id = 0;
7016 u8 next_hop_set = 0;
7017 ip4_address_t v4_next_hop_address = {
7018 .as_u32 = 0,
7019 };
7020 ip6_address_t v6_next_hop_address = { {0} };
7021 int count = 1;
7022 int j;
7023 f64 before = 0;
7024 u32 classify_table_index = ~0;
7025 u8 is_classify = 0;
7026 u8 resolve_host = 0, resolve_attached = 0;
7027 mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
7028 mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
7029 mpls_label_t *next_hop_out_label_stack = NULL;
7030 mpls_label_t local_label = MPLS_LABEL_INVALID;
7031 u8 is_eos = 0;
7032 u8 next_hop_proto_is_ip4 = 1;
7033
7034 /* Parse args required to build the message */
7035 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7036 {
7037 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7038 ;
7039 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7040 ;
7041 else if (unformat (i, "%d", &local_label))
7042 ;
7043 else if (unformat (i, "eos"))
7044 is_eos = 1;
7045 else if (unformat (i, "non-eos"))
7046 is_eos = 0;
7047 else if (unformat (i, "via %U", unformat_ip4_address,
7048 &v4_next_hop_address))
7049 {
7050 next_hop_set = 1;
7051 next_hop_proto_is_ip4 = 1;
7052 }
7053 else if (unformat (i, "via %U", unformat_ip6_address,
7054 &v6_next_hop_address))
7055 {
7056 next_hop_set = 1;
7057 next_hop_proto_is_ip4 = 0;
7058 }
7059 else if (unformat (i, "weight %d", &next_hop_weight))
7060 ;
7061 else if (unformat (i, "create-table"))
7062 create_table_if_needed = 1;
7063 else if (unformat (i, "classify %d", &classify_table_index))
7064 {
7065 is_classify = 1;
7066 }
7067 else if (unformat (i, "del"))
7068 is_add = 0;
7069 else if (unformat (i, "add"))
7070 is_add = 1;
7071 else if (unformat (i, "resolve-via-host"))
7072 resolve_host = 1;
7073 else if (unformat (i, "resolve-via-attached"))
7074 resolve_attached = 1;
7075 else if (unformat (i, "multipath"))
7076 is_multipath = 1;
7077 else if (unformat (i, "count %d", &count))
7078 ;
7079 else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
7080 {
7081 next_hop_set = 1;
7082 next_hop_proto_is_ip4 = 1;
7083 }
7084 else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
7085 {
7086 next_hop_set = 1;
7087 next_hop_proto_is_ip4 = 0;
7088 }
7089 else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7090 ;
7091 else if (unformat (i, "via-label %d", &next_hop_via_label))
7092 ;
7093 else if (unformat (i, "out-label %d", &next_hop_out_label))
7094 vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
7095 else
7096 {
7097 clib_warning ("parse error '%U'", format_unformat_error, i);
7098 return -99;
7099 }
7100 }
7101
7102 if (!next_hop_set && !is_classify)
7103 {
7104 errmsg ("next hop / classify not set");
7105 return -99;
7106 }
7107
7108 if (MPLS_LABEL_INVALID == local_label)
7109 {
7110 errmsg ("missing label");
7111 return -99;
7112 }
7113
7114 if (count > 1)
7115 {
7116 /* Turn on async mode */
7117 vam->async_mode = 1;
7118 vam->async_errors = 0;
7119 before = vat_time_now (vam);
7120 }
7121
7122 for (j = 0; j < count; j++)
7123 {
7124 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007125 M2 (MPLS_ROUTE_ADD_DEL, mp,
Damjan Marion7cd468a2016-12-19 23:05:39 +01007126 sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
7127
7128 mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
7129 mp->mr_table_id = ntohl (table_id);
7130 mp->mr_create_table_if_needed = create_table_if_needed;
7131
7132 mp->mr_is_add = is_add;
7133 mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7134 mp->mr_is_classify = is_classify;
7135 mp->mr_is_multipath = is_multipath;
7136 mp->mr_is_resolve_host = resolve_host;
7137 mp->mr_is_resolve_attached = resolve_attached;
7138 mp->mr_next_hop_weight = next_hop_weight;
7139 mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
7140 mp->mr_classify_table_index = ntohl (classify_table_index);
7141 mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
7142 mp->mr_label = ntohl (local_label);
7143 mp->mr_eos = is_eos;
7144
7145 mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
7146 if (0 != mp->mr_next_hop_n_out_labels)
7147 {
7148 memcpy (mp->mr_next_hop_out_label_stack,
7149 next_hop_out_label_stack,
7150 vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
7151 vec_free (next_hop_out_label_stack);
7152 }
7153
7154 if (next_hop_set)
7155 {
7156 if (next_hop_proto_is_ip4)
7157 {
7158 clib_memcpy (mp->mr_next_hop,
7159 &v4_next_hop_address,
7160 sizeof (v4_next_hop_address));
7161 }
7162 else
7163 {
7164 clib_memcpy (mp->mr_next_hop,
7165 &v6_next_hop_address,
7166 sizeof (v6_next_hop_address));
7167 }
7168 }
7169 local_label++;
7170
7171 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007172 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007173 /* If we receive SIGTERM, stop now... */
7174 if (vam->do_exit)
7175 break;
7176 }
7177
7178 /* When testing multiple add/del ops, use a control-ping to sync */
7179 if (count > 1)
7180 {
Jon Loeliger2d23eca2017-02-01 13:09:58 -06007181 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007182 f64 after;
Jon Loeliger1f9191f2017-01-31 15:27:19 -06007183 f64 timeout;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007184
7185 /* Shut off async mode */
7186 vam->async_mode = 0;
7187
Jon Loeliger2d23eca2017-02-01 13:09:58 -06007188 M (CONTROL_PING, mp_ping);
7189 S (mp_ping);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007190
7191 timeout = vat_time_now (vam) + 1.0;
7192 while (vat_time_now (vam) < timeout)
7193 if (vam->result_ready == 1)
7194 goto out;
7195 vam->retval = -99;
7196
7197 out:
7198 if (vam->retval == -99)
7199 errmsg ("timeout");
7200
7201 if (vam->async_errors > 0)
7202 {
7203 errmsg ("%d asynchronous errors", vam->async_errors);
7204 vam->retval = -98;
7205 }
7206 vam->async_errors = 0;
7207 after = vat_time_now (vam);
7208
7209 /* slim chance, but we might have eaten SIGTERM on the first iteration */
7210 if (j > 0)
7211 count = j;
7212
7213 print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7214 count, after - before, count / (after - before));
7215 }
7216 else
7217 {
Jon Loeliger56c7b012017-02-01 12:31:41 -06007218 int ret;
7219
Damjan Marion7cd468a2016-12-19 23:05:39 +01007220 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06007221 W (ret);
7222 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007223 }
7224
7225 /* Return the good/bad news */
7226 return (vam->retval);
7227}
7228
7229static int
7230api_mpls_ip_bind_unbind (vat_main_t * vam)
7231{
7232 unformat_input_t *i = vam->input;
7233 vl_api_mpls_ip_bind_unbind_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007234 u32 ip_table_id = 0;
7235 u8 create_table_if_needed = 0;
7236 u8 is_bind = 1;
7237 u8 is_ip4 = 1;
7238 ip4_address_t v4_address;
7239 ip6_address_t v6_address;
7240 u32 address_length;
7241 u8 address_set = 0;
7242 mpls_label_t local_label = MPLS_LABEL_INVALID;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007243 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007244
7245 /* Parse args required to build the message */
7246 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7247 {
7248 if (unformat (i, "%U/%d", unformat_ip4_address,
7249 &v4_address, &address_length))
7250 {
7251 is_ip4 = 1;
7252 address_set = 1;
7253 }
7254 else if (unformat (i, "%U/%d", unformat_ip6_address,
7255 &v6_address, &address_length))
7256 {
7257 is_ip4 = 0;
7258 address_set = 1;
7259 }
7260 else if (unformat (i, "%d", &local_label))
7261 ;
7262 else if (unformat (i, "create-table"))
7263 create_table_if_needed = 1;
7264 else if (unformat (i, "table-id %d", &ip_table_id))
7265 ;
7266 else if (unformat (i, "unbind"))
7267 is_bind = 0;
7268 else if (unformat (i, "bind"))
7269 is_bind = 1;
7270 else
7271 {
7272 clib_warning ("parse error '%U'", format_unformat_error, i);
7273 return -99;
7274 }
7275 }
7276
7277 if (!address_set)
7278 {
7279 errmsg ("IP addres not set");
7280 return -99;
7281 }
7282
7283 if (MPLS_LABEL_INVALID == local_label)
7284 {
7285 errmsg ("missing label");
7286 return -99;
7287 }
7288
7289 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007290 M (MPLS_IP_BIND_UNBIND, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007291
7292 mp->mb_create_table_if_needed = create_table_if_needed;
7293 mp->mb_is_bind = is_bind;
7294 mp->mb_is_ip4 = is_ip4;
7295 mp->mb_ip_table_id = ntohl (ip_table_id);
7296 mp->mb_mpls_table_id = 0;
7297 mp->mb_label = ntohl (local_label);
7298 mp->mb_address_length = address_length;
7299
7300 if (is_ip4)
7301 clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
7302 else
7303 clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
7304
7305 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007306 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007307
7308 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06007309 W (ret);
7310 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007311}
7312
7313static int
7314api_proxy_arp_add_del (vat_main_t * vam)
7315{
7316 unformat_input_t *i = vam->input;
7317 vl_api_proxy_arp_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007318 u32 vrf_id = 0;
7319 u8 is_add = 1;
7320 ip4_address_t lo, hi;
7321 u8 range_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007322 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007323
7324 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7325 {
7326 if (unformat (i, "vrf %d", &vrf_id))
7327 ;
7328 else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
7329 unformat_ip4_address, &hi))
7330 range_set = 1;
7331 else if (unformat (i, "del"))
7332 is_add = 0;
7333 else
7334 {
7335 clib_warning ("parse error '%U'", format_unformat_error, i);
7336 return -99;
7337 }
7338 }
7339
7340 if (range_set == 0)
7341 {
7342 errmsg ("address range not set");
7343 return -99;
7344 }
7345
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007346 M (PROXY_ARP_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007347
7348 mp->vrf_id = ntohl (vrf_id);
7349 mp->is_add = is_add;
7350 clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
7351 clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
7352
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007353 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007354 W (ret);
7355 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007356}
7357
7358static int
7359api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
7360{
7361 unformat_input_t *i = vam->input;
7362 vl_api_proxy_arp_intfc_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007363 u32 sw_if_index;
7364 u8 enable = 1;
7365 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007366 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007367
7368 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7369 {
7370 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7371 sw_if_index_set = 1;
7372 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7373 sw_if_index_set = 1;
7374 else if (unformat (i, "enable"))
7375 enable = 1;
7376 else if (unformat (i, "disable"))
7377 enable = 0;
7378 else
7379 {
7380 clib_warning ("parse error '%U'", format_unformat_error, i);
7381 return -99;
7382 }
7383 }
7384
7385 if (sw_if_index_set == 0)
7386 {
7387 errmsg ("missing interface name or sw_if_index");
7388 return -99;
7389 }
7390
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007391 M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007392
7393 mp->sw_if_index = ntohl (sw_if_index);
7394 mp->enable_disable = enable;
7395
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007396 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007397 W (ret);
7398 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007399}
7400
7401static int
7402api_mpls_tunnel_add_del (vat_main_t * vam)
7403{
7404 unformat_input_t *i = vam->input;
7405 vl_api_mpls_tunnel_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007406
7407 u8 is_add = 1;
7408 u8 l2_only = 0;
7409 u32 sw_if_index = ~0;
7410 u32 next_hop_sw_if_index = ~0;
7411 u32 next_hop_proto_is_ip4 = 1;
7412
7413 u32 next_hop_table_id = 0;
7414 ip4_address_t v4_next_hop_address = {
7415 .as_u32 = 0,
7416 };
7417 ip6_address_t v6_next_hop_address = { {0} };
7418 mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007419 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007420
7421 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7422 {
7423 if (unformat (i, "add"))
7424 is_add = 1;
7425 else if (unformat (i, "del sw_if_index %d", &sw_if_index))
7426 is_add = 0;
7427 else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
7428 ;
7429 else if (unformat (i, "via %U",
7430 unformat_ip4_address, &v4_next_hop_address))
7431 {
7432 next_hop_proto_is_ip4 = 1;
7433 }
7434 else if (unformat (i, "via %U",
7435 unformat_ip6_address, &v6_next_hop_address))
7436 {
7437 next_hop_proto_is_ip4 = 0;
7438 }
7439 else if (unformat (i, "l2-only"))
7440 l2_only = 1;
7441 else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7442 ;
7443 else if (unformat (i, "out-label %d", &next_hop_out_label))
7444 vec_add1 (labels, ntohl (next_hop_out_label));
7445 else
7446 {
7447 clib_warning ("parse error '%U'", format_unformat_error, i);
7448 return -99;
7449 }
7450 }
7451
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007452 M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
Damjan Marion7cd468a2016-12-19 23:05:39 +01007453
7454 mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
7455 mp->mt_sw_if_index = ntohl (sw_if_index);
7456 mp->mt_is_add = is_add;
7457 mp->mt_l2_only = l2_only;
7458 mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
7459 mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7460
7461 mp->mt_next_hop_n_out_labels = vec_len (labels);
7462
7463 if (0 != mp->mt_next_hop_n_out_labels)
7464 {
7465 clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
7466 sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
7467 vec_free (labels);
7468 }
7469
7470 if (next_hop_proto_is_ip4)
7471 {
7472 clib_memcpy (mp->mt_next_hop,
7473 &v4_next_hop_address, sizeof (v4_next_hop_address));
7474 }
7475 else
7476 {
7477 clib_memcpy (mp->mt_next_hop,
7478 &v6_next_hop_address, sizeof (v6_next_hop_address));
7479 }
7480
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007481 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007482 W (ret);
7483 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007484}
7485
7486static int
7487api_sw_interface_set_unnumbered (vat_main_t * vam)
7488{
7489 unformat_input_t *i = vam->input;
7490 vl_api_sw_interface_set_unnumbered_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007491 u32 sw_if_index;
7492 u32 unnum_sw_index = ~0;
7493 u8 is_add = 1;
7494 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007495 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007496
7497 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7498 {
7499 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7500 sw_if_index_set = 1;
7501 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7502 sw_if_index_set = 1;
7503 else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
7504 ;
7505 else if (unformat (i, "del"))
7506 is_add = 0;
7507 else
7508 {
7509 clib_warning ("parse error '%U'", format_unformat_error, i);
7510 return -99;
7511 }
7512 }
7513
7514 if (sw_if_index_set == 0)
7515 {
7516 errmsg ("missing interface name or sw_if_index");
7517 return -99;
7518 }
7519
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007520 M (SW_INTERFACE_SET_UNNUMBERED, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007521
7522 mp->sw_if_index = ntohl (sw_if_index);
7523 mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
7524 mp->is_add = is_add;
7525
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007526 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007527 W (ret);
7528 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007529}
7530
7531static int
7532api_ip_neighbor_add_del (vat_main_t * vam)
7533{
7534 unformat_input_t *i = vam->input;
7535 vl_api_ip_neighbor_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007536 u32 sw_if_index;
7537 u8 sw_if_index_set = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007538 u8 is_add = 1;
7539 u8 is_static = 0;
Neale Rannsb3b2de72017-03-08 05:17:22 -08007540 u8 is_no_fib_entry = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007541 u8 mac_address[6];
7542 u8 mac_set = 0;
7543 u8 v4_address_set = 0;
7544 u8 v6_address_set = 0;
7545 ip4_address_t v4address;
7546 ip6_address_t v6address;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007547 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007548
7549 memset (mac_address, 0, sizeof (mac_address));
7550
7551 /* Parse args required to build the message */
7552 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7553 {
7554 if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7555 {
7556 mac_set = 1;
7557 }
7558 else if (unformat (i, "del"))
7559 is_add = 0;
7560 else
7561 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7562 sw_if_index_set = 1;
7563 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7564 sw_if_index_set = 1;
7565 else if (unformat (i, "is_static"))
7566 is_static = 1;
Neale Rannsb3b2de72017-03-08 05:17:22 -08007567 else if (unformat (i, "no-fib-entry"))
7568 is_no_fib_entry = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007569 else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
7570 v4_address_set = 1;
7571 else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
7572 v6_address_set = 1;
7573 else
7574 {
7575 clib_warning ("parse error '%U'", format_unformat_error, i);
7576 return -99;
7577 }
7578 }
7579
7580 if (sw_if_index_set == 0)
7581 {
7582 errmsg ("missing interface name or sw_if_index");
7583 return -99;
7584 }
7585 if (v4_address_set && v6_address_set)
7586 {
7587 errmsg ("both v4 and v6 addresses set");
7588 return -99;
7589 }
7590 if (!v4_address_set && !v6_address_set)
7591 {
7592 errmsg ("no address set");
7593 return -99;
7594 }
7595
7596 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007597 M (IP_NEIGHBOR_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007598
7599 mp->sw_if_index = ntohl (sw_if_index);
7600 mp->is_add = is_add;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007601 mp->is_static = is_static;
Neale Rannsb3b2de72017-03-08 05:17:22 -08007602 mp->is_no_adj_fib = is_no_fib_entry;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007603 if (mac_set)
7604 clib_memcpy (mp->mac_address, mac_address, 6);
7605 if (v6_address_set)
7606 {
7607 mp->is_ipv6 = 1;
7608 clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
7609 }
7610 else
7611 {
7612 /* mp->is_ipv6 = 0; via memset in M macro above */
7613 clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
7614 }
7615
7616 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007617 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007618
7619 /* Wait for a reply, return good/bad news */
Jon Loeliger56c7b012017-02-01 12:31:41 -06007620 W (ret);
7621 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007622}
7623
7624static int
7625api_reset_vrf (vat_main_t * vam)
7626{
7627 unformat_input_t *i = vam->input;
7628 vl_api_reset_vrf_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007629 u32 vrf_id = 0;
7630 u8 is_ipv6 = 0;
7631 u8 vrf_id_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007632 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007633
7634 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7635 {
7636 if (unformat (i, "vrf %d", &vrf_id))
7637 vrf_id_set = 1;
7638 else if (unformat (i, "ipv6"))
7639 is_ipv6 = 1;
7640 else
7641 {
7642 clib_warning ("parse error '%U'", format_unformat_error, i);
7643 return -99;
7644 }
7645 }
7646
7647 if (vrf_id_set == 0)
7648 {
7649 errmsg ("missing vrf id");
7650 return -99;
7651 }
7652
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007653 M (RESET_VRF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007654
7655 mp->vrf_id = ntohl (vrf_id);
7656 mp->is_ipv6 = is_ipv6;
7657
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007658 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007659 W (ret);
7660 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007661}
7662
7663static int
7664api_create_vlan_subif (vat_main_t * vam)
7665{
7666 unformat_input_t *i = vam->input;
7667 vl_api_create_vlan_subif_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007668 u32 sw_if_index;
7669 u8 sw_if_index_set = 0;
7670 u32 vlan_id;
7671 u8 vlan_id_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007672 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007673
7674 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7675 {
7676 if (unformat (i, "sw_if_index %d", &sw_if_index))
7677 sw_if_index_set = 1;
7678 else
7679 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7680 sw_if_index_set = 1;
7681 else if (unformat (i, "vlan %d", &vlan_id))
7682 vlan_id_set = 1;
7683 else
7684 {
7685 clib_warning ("parse error '%U'", format_unformat_error, i);
7686 return -99;
7687 }
7688 }
7689
7690 if (sw_if_index_set == 0)
7691 {
7692 errmsg ("missing interface name or sw_if_index");
7693 return -99;
7694 }
7695
7696 if (vlan_id_set == 0)
7697 {
7698 errmsg ("missing vlan_id");
7699 return -99;
7700 }
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007701 M (CREATE_VLAN_SUBIF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007702
7703 mp->sw_if_index = ntohl (sw_if_index);
7704 mp->vlan_id = ntohl (vlan_id);
7705
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007706 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007707 W (ret);
7708 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007709}
7710
7711#define foreach_create_subif_bit \
7712_(no_tags) \
7713_(one_tag) \
7714_(two_tags) \
7715_(dot1ad) \
7716_(exact_match) \
7717_(default_sub) \
7718_(outer_vlan_id_any) \
7719_(inner_vlan_id_any)
7720
7721static int
7722api_create_subif (vat_main_t * vam)
7723{
7724 unformat_input_t *i = vam->input;
7725 vl_api_create_subif_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007726 u32 sw_if_index;
7727 u8 sw_if_index_set = 0;
7728 u32 sub_id;
7729 u8 sub_id_set = 0;
7730 u32 no_tags = 0;
7731 u32 one_tag = 0;
7732 u32 two_tags = 0;
7733 u32 dot1ad = 0;
7734 u32 exact_match = 0;
7735 u32 default_sub = 0;
7736 u32 outer_vlan_id_any = 0;
7737 u32 inner_vlan_id_any = 0;
7738 u32 tmp;
7739 u16 outer_vlan_id = 0;
7740 u16 inner_vlan_id = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007741 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007742
7743 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7744 {
7745 if (unformat (i, "sw_if_index %d", &sw_if_index))
7746 sw_if_index_set = 1;
7747 else
7748 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7749 sw_if_index_set = 1;
7750 else if (unformat (i, "sub_id %d", &sub_id))
7751 sub_id_set = 1;
7752 else if (unformat (i, "outer_vlan_id %d", &tmp))
7753 outer_vlan_id = tmp;
7754 else if (unformat (i, "inner_vlan_id %d", &tmp))
7755 inner_vlan_id = tmp;
7756
7757#define _(a) else if (unformat (i, #a)) a = 1 ;
7758 foreach_create_subif_bit
7759#undef _
7760 else
7761 {
7762 clib_warning ("parse error '%U'", format_unformat_error, i);
7763 return -99;
7764 }
7765 }
7766
7767 if (sw_if_index_set == 0)
7768 {
7769 errmsg ("missing interface name or sw_if_index");
7770 return -99;
7771 }
7772
7773 if (sub_id_set == 0)
7774 {
7775 errmsg ("missing sub_id");
7776 return -99;
7777 }
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007778 M (CREATE_SUBIF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007779
7780 mp->sw_if_index = ntohl (sw_if_index);
7781 mp->sub_id = ntohl (sub_id);
7782
7783#define _(a) mp->a = a;
7784 foreach_create_subif_bit;
7785#undef _
7786
7787 mp->outer_vlan_id = ntohs (outer_vlan_id);
7788 mp->inner_vlan_id = ntohs (inner_vlan_id);
7789
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007790 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007791 W (ret);
7792 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007793}
7794
7795static int
7796api_oam_add_del (vat_main_t * vam)
7797{
7798 unformat_input_t *i = vam->input;
7799 vl_api_oam_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007800 u32 vrf_id = 0;
7801 u8 is_add = 1;
7802 ip4_address_t src, dst;
7803 u8 src_set = 0;
7804 u8 dst_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007805 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007806
7807 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7808 {
7809 if (unformat (i, "vrf %d", &vrf_id))
7810 ;
7811 else if (unformat (i, "src %U", unformat_ip4_address, &src))
7812 src_set = 1;
7813 else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
7814 dst_set = 1;
7815 else if (unformat (i, "del"))
7816 is_add = 0;
7817 else
7818 {
7819 clib_warning ("parse error '%U'", format_unformat_error, i);
7820 return -99;
7821 }
7822 }
7823
7824 if (src_set == 0)
7825 {
7826 errmsg ("missing src addr");
7827 return -99;
7828 }
7829
7830 if (dst_set == 0)
7831 {
7832 errmsg ("missing dst addr");
7833 return -99;
7834 }
7835
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007836 M (OAM_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007837
7838 mp->vrf_id = ntohl (vrf_id);
7839 mp->is_add = is_add;
7840 clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
7841 clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
7842
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007843 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007844 W (ret);
7845 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007846}
7847
7848static int
7849api_reset_fib (vat_main_t * vam)
7850{
7851 unformat_input_t *i = vam->input;
7852 vl_api_reset_fib_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007853 u32 vrf_id = 0;
7854 u8 is_ipv6 = 0;
7855 u8 vrf_id_set = 0;
7856
Jon Loeliger56c7b012017-02-01 12:31:41 -06007857 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007858 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7859 {
7860 if (unformat (i, "vrf %d", &vrf_id))
7861 vrf_id_set = 1;
7862 else if (unformat (i, "ipv6"))
7863 is_ipv6 = 1;
7864 else
7865 {
7866 clib_warning ("parse error '%U'", format_unformat_error, i);
7867 return -99;
7868 }
7869 }
7870
7871 if (vrf_id_set == 0)
7872 {
7873 errmsg ("missing vrf id");
7874 return -99;
7875 }
7876
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007877 M (RESET_FIB, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007878
7879 mp->vrf_id = ntohl (vrf_id);
7880 mp->is_ipv6 = is_ipv6;
7881
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007882 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007883 W (ret);
7884 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007885}
7886
7887static int
7888api_dhcp_proxy_config (vat_main_t * vam)
7889{
7890 unformat_input_t *i = vam->input;
7891 vl_api_dhcp_proxy_config_t *mp;
Neale Ranns20a175a2017-02-14 07:28:41 -08007892 u32 rx_vrf_id = 0;
7893 u32 server_vrf_id = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007894 u8 is_add = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007895 u8 v4_address_set = 0;
7896 u8 v6_address_set = 0;
7897 ip4_address_t v4address;
7898 ip6_address_t v6address;
7899 u8 v4_src_address_set = 0;
7900 u8 v6_src_address_set = 0;
7901 ip4_address_t v4srcaddress;
7902 ip6_address_t v6srcaddress;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007903 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007904
7905 /* Parse args required to build the message */
7906 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7907 {
7908 if (unformat (i, "del"))
7909 is_add = 0;
Neale Ranns20a175a2017-02-14 07:28:41 -08007910 else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
Damjan Marion7cd468a2016-12-19 23:05:39 +01007911 ;
Neale Ranns20a175a2017-02-14 07:28:41 -08007912 else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
Damjan Marion7cd468a2016-12-19 23:05:39 +01007913 ;
7914 else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7915 v4_address_set = 1;
7916 else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7917 v6_address_set = 1;
7918 else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7919 v4_src_address_set = 1;
7920 else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7921 v6_src_address_set = 1;
7922 else
7923 break;
7924 }
7925
7926 if (v4_address_set && v6_address_set)
7927 {
7928 errmsg ("both v4 and v6 server addresses set");
7929 return -99;
7930 }
7931 if (!v4_address_set && !v6_address_set)
7932 {
7933 errmsg ("no server addresses set");
7934 return -99;
7935 }
7936
7937 if (v4_src_address_set && v6_src_address_set)
7938 {
7939 errmsg ("both v4 and v6 src addresses set");
7940 return -99;
7941 }
7942 if (!v4_src_address_set && !v6_src_address_set)
7943 {
7944 errmsg ("no src addresses set");
7945 return -99;
7946 }
7947
7948 if (!(v4_src_address_set && v4_address_set) &&
7949 !(v6_src_address_set && v6_address_set))
7950 {
7951 errmsg ("no matching server and src addresses set");
7952 return -99;
7953 }
7954
7955 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007956 M (DHCP_PROXY_CONFIG, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007957
Damjan Marion7cd468a2016-12-19 23:05:39 +01007958 mp->is_add = is_add;
Neale Ranns20a175a2017-02-14 07:28:41 -08007959 mp->rx_vrf_id = ntohl (rx_vrf_id);
7960 mp->server_vrf_id = ntohl (server_vrf_id);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007961 if (v6_address_set)
7962 {
7963 mp->is_ipv6 = 1;
7964 clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7965 clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7966 }
7967 else
7968 {
7969 clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7970 clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7971 }
7972
7973 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007974 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007975
7976 /* Wait for a reply, return good/bad news */
Jon Loeliger56c7b012017-02-01 12:31:41 -06007977 W (ret);
7978 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007979}
7980
Neale Ranns20a175a2017-02-14 07:28:41 -08007981#define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
7982#define vl_api_dhcp_proxy_details_t_print vl_noop_handler
7983
7984static void
7985vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01007986{
Neale Ranns20a175a2017-02-14 07:28:41 -08007987 vat_main_t *vam = &vat_main;
Neale Ranns3466c302017-02-16 07:45:03 -08007988 u32 i, count = mp->count;
7989 vl_api_dhcp_server_t *s;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007990
Neale Ranns20a175a2017-02-14 07:28:41 -08007991 if (mp->is_ipv6)
7992 print (vam->ofp,
Neale Ranns3466c302017-02-16 07:45:03 -08007993 "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
Neale Ranns20a175a2017-02-14 07:28:41 -08007994 ntohl (mp->rx_vrf_id),
Neale Ranns20a175a2017-02-14 07:28:41 -08007995 format_ip6_address, mp->dhcp_src_address,
7996 ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
7997 else
7998 print (vam->ofp,
Neale Ranns3466c302017-02-16 07:45:03 -08007999 "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
Neale Ranns20a175a2017-02-14 07:28:41 -08008000 ntohl (mp->rx_vrf_id),
Neale Ranns20a175a2017-02-14 07:28:41 -08008001 format_ip4_address, mp->dhcp_src_address,
8002 ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
Neale Ranns3466c302017-02-16 07:45:03 -08008003
8004 for (i = 0; i < count; i++)
8005 {
8006 s = &mp->servers[i];
8007
8008 if (mp->is_ipv6)
8009 print (vam->ofp,
8010 " Server Table-ID %d, Server Address %U",
8011 ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
8012 else
8013 print (vam->ofp,
8014 " Server Table-ID %d, Server Address %U",
8015 ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
8016 }
Neale Ranns20a175a2017-02-14 07:28:41 -08008017}
Damjan Marion7cd468a2016-12-19 23:05:39 +01008018
Neale Ranns20a175a2017-02-14 07:28:41 -08008019static void vl_api_dhcp_proxy_details_t_handler_json
8020 (vl_api_dhcp_proxy_details_t * mp)
8021{
8022 vat_main_t *vam = &vat_main;
8023 vat_json_node_t *node = NULL;
Neale Ranns3466c302017-02-16 07:45:03 -08008024 u32 i, count = mp->count;
Neale Ranns20a175a2017-02-14 07:28:41 -08008025 struct in_addr ip4;
8026 struct in6_addr ip6;
Neale Ranns3466c302017-02-16 07:45:03 -08008027 vl_api_dhcp_server_t *s;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008028
Neale Ranns20a175a2017-02-14 07:28:41 -08008029 if (VAT_JSON_ARRAY != vam->json_tree.type)
Damjan Marion7cd468a2016-12-19 23:05:39 +01008030 {
Neale Ranns20a175a2017-02-14 07:28:41 -08008031 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
8032 vat_json_init_array (&vam->json_tree);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008033 }
Neale Ranns20a175a2017-02-14 07:28:41 -08008034 node = vat_json_array_add (&vam->json_tree);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008035
Neale Ranns20a175a2017-02-14 07:28:41 -08008036 vat_json_init_object (node);
8037 vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
Neale Ranns3466c302017-02-16 07:45:03 -08008038 vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
8039 vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
8040
Neale Ranns20a175a2017-02-14 07:28:41 -08008041 if (mp->is_ipv6)
Damjan Marion7cd468a2016-12-19 23:05:39 +01008042 {
Neale Ranns20a175a2017-02-14 07:28:41 -08008043 clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
8044 vat_json_object_add_ip6 (node, "src_address", ip6);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008045 }
8046 else
8047 {
Neale Ranns20a175a2017-02-14 07:28:41 -08008048 clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
8049 vat_json_object_add_ip4 (node, "src_address", ip4);
8050 }
Neale Ranns3466c302017-02-16 07:45:03 -08008051
8052 for (i = 0; i < count; i++)
8053 {
8054 s = &mp->servers[i];
8055
8056 vat_json_object_add_uint (node, "server-table-id",
8057 ntohl (s->server_vrf_id));
8058
8059 if (mp->is_ipv6)
8060 {
8061 clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
8062 vat_json_object_add_ip4 (node, "src_address", ip4);
8063 }
8064 else
8065 {
8066 clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
8067 vat_json_object_add_ip6 (node, "server_address", ip6);
8068 }
8069 }
Neale Ranns20a175a2017-02-14 07:28:41 -08008070}
8071
8072static int
8073api_dhcp_proxy_dump (vat_main_t * vam)
8074{
8075 unformat_input_t *i = vam->input;
8076 vl_api_control_ping_t *mp_ping;
8077 vl_api_dhcp_proxy_dump_t *mp;
8078 u8 is_ipv6 = 0;
8079 int ret;
8080
8081 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8082 {
8083 if (unformat (i, "ipv6"))
8084 is_ipv6 = 1;
8085 else
8086 {
8087 clib_warning ("parse error '%U'", format_unformat_error, i);
8088 return -99;
8089 }
Damjan Marion7cd468a2016-12-19 23:05:39 +01008090 }
8091
Neale Ranns20a175a2017-02-14 07:28:41 -08008092 M (DHCP_PROXY_DUMP, mp);
8093
8094 mp->is_ip6 = is_ipv6;
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008095 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008096
Neale Ranns20a175a2017-02-14 07:28:41 -08008097 /* Use a control ping for synchronization */
8098 M (CONTROL_PING, mp_ping);
8099 S (mp_ping);
8100
Jon Loeliger56c7b012017-02-01 12:31:41 -06008101 W (ret);
8102 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008103}
8104
8105static int
8106api_dhcp_proxy_set_vss (vat_main_t * vam)
8107{
8108 unformat_input_t *i = vam->input;
8109 vl_api_dhcp_proxy_set_vss_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008110 u8 is_ipv6 = 0;
8111 u8 is_add = 1;
8112 u32 tbl_id;
8113 u8 tbl_id_set = 0;
8114 u32 oui;
8115 u8 oui_set = 0;
8116 u32 fib_id;
8117 u8 fib_id_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008118 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008119
8120 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8121 {
8122 if (unformat (i, "tbl_id %d", &tbl_id))
8123 tbl_id_set = 1;
8124 if (unformat (i, "fib_id %d", &fib_id))
8125 fib_id_set = 1;
8126 if (unformat (i, "oui %d", &oui))
8127 oui_set = 1;
8128 else if (unformat (i, "ipv6"))
8129 is_ipv6 = 1;
8130 else if (unformat (i, "del"))
8131 is_add = 0;
8132 else
8133 {
8134 clib_warning ("parse error '%U'", format_unformat_error, i);
8135 return -99;
8136 }
8137 }
8138
8139 if (tbl_id_set == 0)
8140 {
8141 errmsg ("missing tbl id");
8142 return -99;
8143 }
8144
8145 if (fib_id_set == 0)
8146 {
8147 errmsg ("missing fib id");
8148 return -99;
8149 }
8150 if (oui_set == 0)
8151 {
8152 errmsg ("missing oui");
8153 return -99;
8154 }
8155
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008156 M (DHCP_PROXY_SET_VSS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008157 mp->tbl_id = ntohl (tbl_id);
8158 mp->fib_id = ntohl (fib_id);
8159 mp->oui = ntohl (oui);
8160 mp->is_ipv6 = is_ipv6;
8161 mp->is_add = is_add;
8162
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008163 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008164 W (ret);
8165 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008166}
8167
8168static int
8169api_dhcp_client_config (vat_main_t * vam)
8170{
8171 unformat_input_t *i = vam->input;
8172 vl_api_dhcp_client_config_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008173 u32 sw_if_index;
8174 u8 sw_if_index_set = 0;
8175 u8 is_add = 1;
8176 u8 *hostname = 0;
8177 u8 disable_event = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008178 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008179
8180 /* Parse args required to build the message */
8181 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8182 {
8183 if (unformat (i, "del"))
8184 is_add = 0;
8185 else
8186 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8187 sw_if_index_set = 1;
8188 else if (unformat (i, "sw_if_index %d", &sw_if_index))
8189 sw_if_index_set = 1;
8190 else if (unformat (i, "hostname %s", &hostname))
8191 ;
8192 else if (unformat (i, "disable_event"))
8193 disable_event = 1;
8194 else
8195 break;
8196 }
8197
8198 if (sw_if_index_set == 0)
8199 {
8200 errmsg ("missing interface name or sw_if_index");
8201 return -99;
8202 }
8203
8204 if (vec_len (hostname) > 63)
8205 {
8206 errmsg ("hostname too long");
8207 }
8208 vec_add1 (hostname, 0);
8209
8210 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008211 M (DHCP_CLIENT_CONFIG, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008212
John Lo20e1f2a2017-03-29 13:35:43 -04008213 mp->sw_if_index = htonl (sw_if_index);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008214 clib_memcpy (mp->hostname, hostname, vec_len (hostname));
8215 vec_free (hostname);
8216 mp->is_add = is_add;
8217 mp->want_dhcp_event = disable_event ? 0 : 1;
John Lo20e1f2a2017-03-29 13:35:43 -04008218 mp->pid = htonl (getpid ());
Damjan Marion7cd468a2016-12-19 23:05:39 +01008219
8220 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008221 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008222
8223 /* Wait for a reply, return good/bad news */
Jon Loeliger56c7b012017-02-01 12:31:41 -06008224 W (ret);
8225 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008226}
8227
8228static int
8229api_set_ip_flow_hash (vat_main_t * vam)
8230{
8231 unformat_input_t *i = vam->input;
8232 vl_api_set_ip_flow_hash_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008233 u32 vrf_id = 0;
8234 u8 is_ipv6 = 0;
8235 u8 vrf_id_set = 0;
8236 u8 src = 0;
8237 u8 dst = 0;
8238 u8 sport = 0;
8239 u8 dport = 0;
8240 u8 proto = 0;
8241 u8 reverse = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008242 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008243
8244 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8245 {
8246 if (unformat (i, "vrf %d", &vrf_id))
8247 vrf_id_set = 1;
8248 else if (unformat (i, "ipv6"))
8249 is_ipv6 = 1;
8250 else if (unformat (i, "src"))
8251 src = 1;
8252 else if (unformat (i, "dst"))
8253 dst = 1;
8254 else if (unformat (i, "sport"))
8255 sport = 1;
8256 else if (unformat (i, "dport"))
8257 dport = 1;
8258 else if (unformat (i, "proto"))
8259 proto = 1;
8260 else if (unformat (i, "reverse"))
8261 reverse = 1;
8262
8263 else
8264 {
8265 clib_warning ("parse error '%U'", format_unformat_error, i);
8266 return -99;
8267 }
8268 }
8269
8270 if (vrf_id_set == 0)
8271 {
8272 errmsg ("missing vrf id");
8273 return -99;
8274 }
8275
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008276 M (SET_IP_FLOW_HASH, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008277 mp->src = src;
8278 mp->dst = dst;
8279 mp->sport = sport;
8280 mp->dport = dport;
8281 mp->proto = proto;
8282 mp->reverse = reverse;
8283 mp->vrf_id = ntohl (vrf_id);
8284 mp->is_ipv6 = is_ipv6;
8285
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008286 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008287 W (ret);
8288 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008289}
8290
8291static int
8292api_sw_interface_ip6_enable_disable (vat_main_t * vam)
8293{
8294 unformat_input_t *i = vam->input;
8295 vl_api_sw_interface_ip6_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008296 u32 sw_if_index;
8297 u8 sw_if_index_set = 0;
8298 u8 enable = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008299 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008300
8301 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8302 {
8303 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8304 sw_if_index_set = 1;
8305 else if (unformat (i, "sw_if_index %d", &sw_if_index))
8306 sw_if_index_set = 1;
8307 else if (unformat (i, "enable"))
8308 enable = 1;
8309 else if (unformat (i, "disable"))
8310 enable = 0;
8311 else
8312 {
8313 clib_warning ("parse error '%U'", format_unformat_error, i);
8314 return -99;
8315 }
8316 }
8317
8318 if (sw_if_index_set == 0)
8319 {
8320 errmsg ("missing interface name or sw_if_index");
8321 return -99;
8322 }
8323
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008324 M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008325
8326 mp->sw_if_index = ntohl (sw_if_index);
8327 mp->enable = enable;
8328
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008329 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008330 W (ret);
8331 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008332}
8333
8334static int
8335api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
8336{
8337 unformat_input_t *i = vam->input;
8338 vl_api_sw_interface_ip6_set_link_local_address_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008339 u32 sw_if_index;
8340 u8 sw_if_index_set = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008341 u8 v6_address_set = 0;
8342 ip6_address_t v6address;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008343 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008344
8345 /* Parse args required to build the message */
8346 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8347 {
8348 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8349 sw_if_index_set = 1;
8350 else if (unformat (i, "sw_if_index %d", &sw_if_index))
8351 sw_if_index_set = 1;
Neale Ranns75152282017-01-09 01:00:45 -08008352 else if (unformat (i, "%U", unformat_ip6_address, &v6address))
Damjan Marion7cd468a2016-12-19 23:05:39 +01008353 v6_address_set = 1;
8354 else
8355 break;
8356 }
8357
8358 if (sw_if_index_set == 0)
8359 {
8360 errmsg ("missing interface name or sw_if_index");
8361 return -99;
8362 }
8363 if (!v6_address_set)
8364 {
8365 errmsg ("no address set");
8366 return -99;
8367 }
8368
8369 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008370 M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008371
8372 mp->sw_if_index = ntohl (sw_if_index);
8373 clib_memcpy (mp->address, &v6address, sizeof (v6address));
Damjan Marion7cd468a2016-12-19 23:05:39 +01008374
8375 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008376 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008377
8378 /* Wait for a reply, return good/bad news */
Jon Loeliger56c7b012017-02-01 12:31:41 -06008379 W (ret);
8380 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008381}
8382
Neale Ranns3f844d02017-02-18 00:03:54 -08008383static int
8384api_ip6nd_proxy_add_del (vat_main_t * vam)
8385{
8386 unformat_input_t *i = vam->input;
8387 vl_api_ip6nd_proxy_add_del_t *mp;
8388 u32 sw_if_index = ~0;
8389 u8 v6_address_set = 0;
8390 ip6_address_t v6address;
8391 u8 is_del = 0;
8392 int ret;
8393
8394 /* Parse args required to build the message */
8395 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8396 {
8397 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8398 ;
8399 else if (unformat (i, "sw_if_index %d", &sw_if_index))
8400 ;
8401 else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8402 v6_address_set = 1;
8403 if (unformat (i, "del"))
8404 is_del = 1;
8405 else
8406 {
8407 clib_warning ("parse error '%U'", format_unformat_error, i);
8408 return -99;
8409 }
8410 }
8411
8412 if (sw_if_index == ~0)
8413 {
8414 errmsg ("missing interface name or sw_if_index");
8415 return -99;
8416 }
8417 if (!v6_address_set)
8418 {
8419 errmsg ("no address set");
8420 return -99;
8421 }
8422
8423 /* Construct the API message */
8424 M (IP6ND_PROXY_ADD_DEL, mp);
8425
8426 mp->is_del = is_del;
8427 mp->sw_if_index = ntohl (sw_if_index);
8428 clib_memcpy (mp->address, &v6address, sizeof (v6address));
8429
8430 /* send it... */
8431 S (mp);
8432
8433 /* Wait for a reply, return good/bad news */
8434 W (ret);
8435 return ret;
8436}
8437
8438static int
8439api_ip6nd_proxy_dump (vat_main_t * vam)
8440{
8441 vl_api_ip6nd_proxy_dump_t *mp;
8442 vl_api_control_ping_t *mp_ping;
8443 int ret;
8444
8445 M (IP6ND_PROXY_DUMP, mp);
8446
8447 S (mp);
8448
8449 /* Use a control ping for synchronization */
8450 M (CONTROL_PING, mp_ping);
8451 S (mp_ping);
8452
8453 W (ret);
8454 return ret;
8455}
8456
8457static void vl_api_ip6nd_proxy_details_t_handler
8458 (vl_api_ip6nd_proxy_details_t * mp)
8459{
8460 vat_main_t *vam = &vat_main;
8461
8462 print (vam->ofp, "host %U sw_if_index %d",
8463 format_ip6_address, mp->address, ntohl (mp->sw_if_index));
8464}
8465
8466static void vl_api_ip6nd_proxy_details_t_handler_json
8467 (vl_api_ip6nd_proxy_details_t * mp)
8468{
8469 vat_main_t *vam = &vat_main;
8470 struct in6_addr ip6;
8471 vat_json_node_t *node = NULL;
8472
8473 if (VAT_JSON_ARRAY != vam->json_tree.type)
8474 {
8475 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
8476 vat_json_init_array (&vam->json_tree);
8477 }
8478 node = vat_json_array_add (&vam->json_tree);
8479
8480 vat_json_init_object (node);
8481 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
8482
8483 clib_memcpy (&ip6, mp->address, sizeof (ip6));
8484 vat_json_object_add_ip6 (node, "host", ip6);
8485}
Damjan Marion7cd468a2016-12-19 23:05:39 +01008486
8487static int
8488api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
8489{
8490 unformat_input_t *i = vam->input;
8491 vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008492 u32 sw_if_index;
8493 u8 sw_if_index_set = 0;
8494 u32 address_length = 0;
8495 u8 v6_address_set = 0;
8496 ip6_address_t v6address;
8497 u8 use_default = 0;
8498 u8 no_advertise = 0;
8499 u8 off_link = 0;
8500 u8 no_autoconfig = 0;
8501 u8 no_onlink = 0;
8502 u8 is_no = 0;
8503 u32 val_lifetime = 0;
8504 u32 pref_lifetime = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008505 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008506
8507 /* Parse args required to build the message */
8508 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8509 {
8510 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8511 sw_if_index_set = 1;
8512 else if (unformat (i, "sw_if_index %d", &sw_if_index))
8513 sw_if_index_set = 1;
8514 else if (unformat (i, "%U/%d",
8515 unformat_ip6_address, &v6address, &address_length))
8516 v6_address_set = 1;
8517 else if (unformat (i, "val_life %d", &val_lifetime))
8518 ;
8519 else if (unformat (i, "pref_life %d", &pref_lifetime))
8520 ;
8521 else if (unformat (i, "def"))
8522 use_default = 1;
8523 else if (unformat (i, "noadv"))
8524 no_advertise = 1;
8525 else if (unformat (i, "offl"))
8526 off_link = 1;
8527 else if (unformat (i, "noauto"))
8528 no_autoconfig = 1;
8529 else if (unformat (i, "nolink"))
8530 no_onlink = 1;
8531 else if (unformat (i, "isno"))
8532 is_no = 1;
8533 else
8534 {
8535 clib_warning ("parse error '%U'", format_unformat_error, i);
8536 return -99;
8537 }
8538 }
8539
8540 if (sw_if_index_set == 0)
8541 {
8542 errmsg ("missing interface name or sw_if_index");
8543 return -99;
8544 }
8545 if (!v6_address_set)
8546 {
8547 errmsg ("no address set");
8548 return -99;
8549 }
8550
8551 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008552 M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008553
8554 mp->sw_if_index = ntohl (sw_if_index);
8555 clib_memcpy (mp->address, &v6address, sizeof (v6address));
8556 mp->address_length = address_length;
8557 mp->use_default = use_default;
8558 mp->no_advertise = no_advertise;
8559 mp->off_link = off_link;
8560 mp->no_autoconfig = no_autoconfig;
8561 mp->no_onlink = no_onlink;
8562 mp->is_no = is_no;
8563 mp->val_lifetime = ntohl (val_lifetime);
8564 mp->pref_lifetime = ntohl (pref_lifetime);
8565
8566 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008567 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008568
8569 /* Wait for a reply, return good/bad news */
Jon Loeliger56c7b012017-02-01 12:31:41 -06008570 W (ret);
8571 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008572}
8573
8574static int
8575api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
8576{
8577 unformat_input_t *i = vam->input;
8578 vl_api_sw_interface_ip6nd_ra_config_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008579 u32 sw_if_index;
8580 u8 sw_if_index_set = 0;
8581 u8 suppress = 0;
8582 u8 managed = 0;
8583 u8 other = 0;
8584 u8 ll_option = 0;
8585 u8 send_unicast = 0;
8586 u8 cease = 0;
8587 u8 is_no = 0;
8588 u8 default_router = 0;
8589 u32 max_interval = 0;
8590 u32 min_interval = 0;
8591 u32 lifetime = 0;
8592 u32 initial_count = 0;
8593 u32 initial_interval = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008594 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008595
8596
8597 /* Parse args required to build the message */
8598 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8599 {
8600 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8601 sw_if_index_set = 1;
8602 else if (unformat (i, "sw_if_index %d", &sw_if_index))
8603 sw_if_index_set = 1;
8604 else if (unformat (i, "maxint %d", &max_interval))
8605 ;
8606 else if (unformat (i, "minint %d", &min_interval))
8607 ;
8608 else if (unformat (i, "life %d", &lifetime))
8609 ;
8610 else if (unformat (i, "count %d", &initial_count))
8611 ;
8612 else if (unformat (i, "interval %d", &initial_interval))
8613 ;
8614 else if (unformat (i, "suppress") || unformat (i, "surpress"))
8615 suppress = 1;
8616 else if (unformat (i, "managed"))
8617 managed = 1;
8618 else if (unformat (i, "other"))
8619 other = 1;
8620 else if (unformat (i, "ll"))
8621 ll_option = 1;
8622 else if (unformat (i, "send"))
8623 send_unicast = 1;
8624 else if (unformat (i, "cease"))
8625 cease = 1;
8626 else if (unformat (i, "isno"))
8627 is_no = 1;
8628 else if (unformat (i, "def"))
8629 default_router = 1;
8630 else
8631 {
8632 clib_warning ("parse error '%U'", format_unformat_error, i);
8633 return -99;
8634 }
8635 }
8636
8637 if (sw_if_index_set == 0)
8638 {
8639 errmsg ("missing interface name or sw_if_index");
8640 return -99;
8641 }
8642
8643 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008644 M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008645
8646 mp->sw_if_index = ntohl (sw_if_index);
8647 mp->max_interval = ntohl (max_interval);
8648 mp->min_interval = ntohl (min_interval);
8649 mp->lifetime = ntohl (lifetime);
8650 mp->initial_count = ntohl (initial_count);
8651 mp->initial_interval = ntohl (initial_interval);
8652 mp->suppress = suppress;
8653 mp->managed = managed;
8654 mp->other = other;
8655 mp->ll_option = ll_option;
8656 mp->send_unicast = send_unicast;
8657 mp->cease = cease;
8658 mp->is_no = is_no;
8659 mp->default_router = default_router;
8660
8661 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008662 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008663
8664 /* Wait for a reply, return good/bad news */
Jon Loeliger56c7b012017-02-01 12:31:41 -06008665 W (ret);
8666 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008667}
8668
8669static int
8670api_set_arp_neighbor_limit (vat_main_t * vam)
8671{
8672 unformat_input_t *i = vam->input;
8673 vl_api_set_arp_neighbor_limit_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008674 u32 arp_nbr_limit;
8675 u8 limit_set = 0;
8676 u8 is_ipv6 = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008677 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008678
8679 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8680 {
8681 if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
8682 limit_set = 1;
8683 else if (unformat (i, "ipv6"))
8684 is_ipv6 = 1;
8685 else
8686 {
8687 clib_warning ("parse error '%U'", format_unformat_error, i);
8688 return -99;
8689 }
8690 }
8691
8692 if (limit_set == 0)
8693 {
8694 errmsg ("missing limit value");
8695 return -99;
8696 }
8697
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008698 M (SET_ARP_NEIGHBOR_LIMIT, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008699
8700 mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
8701 mp->is_ipv6 = is_ipv6;
8702
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008703 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008704 W (ret);
8705 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008706}
8707
8708static int
8709api_l2_patch_add_del (vat_main_t * vam)
8710{
8711 unformat_input_t *i = vam->input;
8712 vl_api_l2_patch_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008713 u32 rx_sw_if_index;
8714 u8 rx_sw_if_index_set = 0;
8715 u32 tx_sw_if_index;
8716 u8 tx_sw_if_index_set = 0;
8717 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008718 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008719
8720 /* Parse args required to build the message */
8721 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8722 {
8723 if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
8724 rx_sw_if_index_set = 1;
8725 else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
8726 tx_sw_if_index_set = 1;
8727 else if (unformat (i, "rx"))
8728 {
8729 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8730 {
8731 if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8732 &rx_sw_if_index))
8733 rx_sw_if_index_set = 1;
8734 }
8735 else
8736 break;
8737 }
8738 else if (unformat (i, "tx"))
8739 {
8740 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8741 {
8742 if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8743 &tx_sw_if_index))
8744 tx_sw_if_index_set = 1;
8745 }
8746 else
8747 break;
8748 }
8749 else if (unformat (i, "del"))
8750 is_add = 0;
8751 else
8752 break;
8753 }
8754
8755 if (rx_sw_if_index_set == 0)
8756 {
8757 errmsg ("missing rx interface name or rx_sw_if_index");
8758 return -99;
8759 }
8760
8761 if (tx_sw_if_index_set == 0)
8762 {
8763 errmsg ("missing tx interface name or tx_sw_if_index");
8764 return -99;
8765 }
8766
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008767 M (L2_PATCH_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008768
8769 mp->rx_sw_if_index = ntohl (rx_sw_if_index);
8770 mp->tx_sw_if_index = ntohl (tx_sw_if_index);
8771 mp->is_add = is_add;
8772
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008773 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008774 W (ret);
8775 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008776}
8777
Pablo Camarillofb380952016-12-07 18:34:18 +01008778u8 is_del;
8779u8 localsid_addr[16];
8780u8 end_psp;
8781u8 behavior;
8782u32 sw_if_index;
8783u32 vlan_index;
8784u32 fib_table;
8785u8 nh_addr[16];
8786
8787static int
8788api_sr_localsid_add_del (vat_main_t * vam)
8789{
8790 unformat_input_t *i = vam->input;
8791 vl_api_sr_localsid_add_del_t *mp;
8792
8793 u8 is_del;
8794 ip6_address_t localsid;
8795 u8 end_psp = 0;
8796 u8 behavior = ~0;
8797 u32 sw_if_index;
8798 u32 fib_table = ~(u32) 0;
8799 ip6_address_t next_hop;
8800
8801 bool nexthop_set = 0;
8802
8803 int ret;
8804
8805 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8806 {
8807 if (unformat (i, "del"))
8808 is_del = 1;
8809 else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
8810 else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
8811 nexthop_set = 1;
8812 else if (unformat (i, "behavior %u", &behavior));
8813 else if (unformat (i, "sw_if_index %u", &sw_if_index));
8814 else if (unformat (i, "fib-table %u", &fib_table));
8815 else if (unformat (i, "end.psp %u", &behavior));
8816 else
8817 break;
8818 }
8819
8820 M (SR_LOCALSID_ADD_DEL, mp);
8821
8822 clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
8823 if (nexthop_set)
8824 clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
8825 mp->behavior = behavior;
8826 mp->sw_if_index = ntohl (sw_if_index);
8827 mp->fib_table = ntohl (fib_table);
8828 mp->end_psp = end_psp;
8829 mp->is_del = is_del;
8830
8831 S (mp);
8832 W (ret);
8833 return ret;
8834}
8835
Damjan Marion7cd468a2016-12-19 23:05:39 +01008836static int
8837api_ioam_enable (vat_main_t * vam)
8838{
8839 unformat_input_t *input = vam->input;
8840 vl_api_ioam_enable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008841 u32 id = 0;
8842 int has_trace_option = 0;
8843 int has_pot_option = 0;
8844 int has_seqno_option = 0;
8845 int has_analyse_option = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008846 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008847
8848 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8849 {
8850 if (unformat (input, "trace"))
8851 has_trace_option = 1;
8852 else if (unformat (input, "pot"))
8853 has_pot_option = 1;
8854 else if (unformat (input, "seqno"))
8855 has_seqno_option = 1;
8856 else if (unformat (input, "analyse"))
8857 has_analyse_option = 1;
8858 else
8859 break;
8860 }
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008861 M (IOAM_ENABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008862 mp->id = htons (id);
8863 mp->seqno = has_seqno_option;
8864 mp->analyse = has_analyse_option;
8865 mp->pot_enable = has_pot_option;
8866 mp->trace_enable = has_trace_option;
8867
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008868 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008869 W (ret);
8870 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008871}
8872
8873
8874static int
8875api_ioam_disable (vat_main_t * vam)
8876{
8877 vl_api_ioam_disable_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008878 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008879
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008880 M (IOAM_DISABLE, mp);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008881 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008882 W (ret);
8883 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008884}
8885
Damjan Marion7cd468a2016-12-19 23:05:39 +01008886#define foreach_tcp_proto_field \
8887_(src_port) \
8888_(dst_port)
8889
8890#define foreach_udp_proto_field \
8891_(src_port) \
8892_(dst_port)
8893
8894#define foreach_ip4_proto_field \
8895_(src_address) \
8896_(dst_address) \
8897_(tos) \
8898_(length) \
8899_(fragment_id) \
8900_(ttl) \
8901_(protocol) \
8902_(checksum)
8903
Dave Barach4a3f69c2017-02-22 12:44:56 -05008904typedef struct
8905{
8906 u16 src_port, dst_port;
8907} tcpudp_header_t;
8908
8909#if VPP_API_TEST_BUILTIN == 0
Damjan Marion7cd468a2016-12-19 23:05:39 +01008910uword
8911unformat_tcp_mask (unformat_input_t * input, va_list * args)
8912{
8913 u8 **maskp = va_arg (*args, u8 **);
8914 u8 *mask = 0;
8915 u8 found_something = 0;
8916 tcp_header_t *tcp;
8917
8918#define _(a) u8 a=0;
8919 foreach_tcp_proto_field;
8920#undef _
8921
8922 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8923 {
8924 if (0);
8925#define _(a) else if (unformat (input, #a)) a=1;
8926 foreach_tcp_proto_field
8927#undef _
8928 else
8929 break;
8930 }
8931
8932#define _(a) found_something += a;
8933 foreach_tcp_proto_field;
8934#undef _
8935
8936 if (found_something == 0)
8937 return 0;
8938
8939 vec_validate (mask, sizeof (*tcp) - 1);
8940
8941 tcp = (tcp_header_t *) mask;
8942
8943#define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8944 foreach_tcp_proto_field;
8945#undef _
8946
8947 *maskp = mask;
8948 return 1;
8949}
8950
8951uword
8952unformat_udp_mask (unformat_input_t * input, va_list * args)
8953{
8954 u8 **maskp = va_arg (*args, u8 **);
8955 u8 *mask = 0;
8956 u8 found_something = 0;
8957 udp_header_t *udp;
8958
8959#define _(a) u8 a=0;
8960 foreach_udp_proto_field;
8961#undef _
8962
8963 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8964 {
8965 if (0);
8966#define _(a) else if (unformat (input, #a)) a=1;
8967 foreach_udp_proto_field
8968#undef _
8969 else
8970 break;
8971 }
8972
8973#define _(a) found_something += a;
8974 foreach_udp_proto_field;
8975#undef _
8976
8977 if (found_something == 0)
8978 return 0;
8979
8980 vec_validate (mask, sizeof (*udp) - 1);
8981
8982 udp = (udp_header_t *) mask;
8983
8984#define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8985 foreach_udp_proto_field;
8986#undef _
8987
8988 *maskp = mask;
8989 return 1;
8990}
8991
Damjan Marion7cd468a2016-12-19 23:05:39 +01008992uword
8993unformat_l4_mask (unformat_input_t * input, va_list * args)
8994{
8995 u8 **maskp = va_arg (*args, u8 **);
8996 u16 src_port = 0, dst_port = 0;
8997 tcpudp_header_t *tcpudp;
8998
8999 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9000 {
9001 if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
9002 return 1;
9003 else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
9004 return 1;
9005 else if (unformat (input, "src_port"))
9006 src_port = 0xFFFF;
9007 else if (unformat (input, "dst_port"))
9008 dst_port = 0xFFFF;
9009 else
9010 return 0;
9011 }
9012
9013 if (!src_port && !dst_port)
9014 return 0;
9015
9016 u8 *mask = 0;
9017 vec_validate (mask, sizeof (tcpudp_header_t) - 1);
9018
9019 tcpudp = (tcpudp_header_t *) mask;
9020 tcpudp->src_port = src_port;
9021 tcpudp->dst_port = dst_port;
9022
9023 *maskp = mask;
9024
9025 return 1;
9026}
9027
9028uword
9029unformat_ip4_mask (unformat_input_t * input, va_list * args)
9030{
9031 u8 **maskp = va_arg (*args, u8 **);
9032 u8 *mask = 0;
9033 u8 found_something = 0;
9034 ip4_header_t *ip;
9035
9036#define _(a) u8 a=0;
9037 foreach_ip4_proto_field;
9038#undef _
9039 u8 version = 0;
9040 u8 hdr_length = 0;
9041
9042
9043 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9044 {
9045 if (unformat (input, "version"))
9046 version = 1;
9047 else if (unformat (input, "hdr_length"))
9048 hdr_length = 1;
9049 else if (unformat (input, "src"))
9050 src_address = 1;
9051 else if (unformat (input, "dst"))
9052 dst_address = 1;
9053 else if (unformat (input, "proto"))
9054 protocol = 1;
9055
9056#define _(a) else if (unformat (input, #a)) a=1;
9057 foreach_ip4_proto_field
9058#undef _
9059 else
9060 break;
9061 }
9062
9063#define _(a) found_something += a;
9064 foreach_ip4_proto_field;
9065#undef _
9066
9067 if (found_something == 0)
9068 return 0;
9069
9070 vec_validate (mask, sizeof (*ip) - 1);
9071
9072 ip = (ip4_header_t *) mask;
9073
9074#define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
9075 foreach_ip4_proto_field;
9076#undef _
9077
9078 ip->ip_version_and_header_length = 0;
9079
9080 if (version)
9081 ip->ip_version_and_header_length |= 0xF0;
9082
9083 if (hdr_length)
9084 ip->ip_version_and_header_length |= 0x0F;
9085
9086 *maskp = mask;
9087 return 1;
9088}
9089
9090#define foreach_ip6_proto_field \
9091_(src_address) \
9092_(dst_address) \
9093_(payload_length) \
9094_(hop_limit) \
9095_(protocol)
9096
9097uword
9098unformat_ip6_mask (unformat_input_t * input, va_list * args)
9099{
9100 u8 **maskp = va_arg (*args, u8 **);
9101 u8 *mask = 0;
9102 u8 found_something = 0;
9103 ip6_header_t *ip;
9104 u32 ip_version_traffic_class_and_flow_label;
9105
9106#define _(a) u8 a=0;
9107 foreach_ip6_proto_field;
9108#undef _
9109 u8 version = 0;
9110 u8 traffic_class = 0;
9111 u8 flow_label = 0;
9112
9113 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9114 {
9115 if (unformat (input, "version"))
9116 version = 1;
9117 else if (unformat (input, "traffic-class"))
9118 traffic_class = 1;
9119 else if (unformat (input, "flow-label"))
9120 flow_label = 1;
9121 else if (unformat (input, "src"))
9122 src_address = 1;
9123 else if (unformat (input, "dst"))
9124 dst_address = 1;
9125 else if (unformat (input, "proto"))
9126 protocol = 1;
9127
9128#define _(a) else if (unformat (input, #a)) a=1;
9129 foreach_ip6_proto_field
9130#undef _
9131 else
9132 break;
9133 }
9134
9135#define _(a) found_something += a;
9136 foreach_ip6_proto_field;
9137#undef _
9138
9139 if (found_something == 0)
9140 return 0;
9141
9142 vec_validate (mask, sizeof (*ip) - 1);
9143
9144 ip = (ip6_header_t *) mask;
9145
9146#define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
9147 foreach_ip6_proto_field;
9148#undef _
9149
9150 ip_version_traffic_class_and_flow_label = 0;
9151
9152 if (version)
9153 ip_version_traffic_class_and_flow_label |= 0xF0000000;
9154
9155 if (traffic_class)
9156 ip_version_traffic_class_and_flow_label |= 0x0FF00000;
9157
9158 if (flow_label)
9159 ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
9160
9161 ip->ip_version_traffic_class_and_flow_label =
9162 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9163
9164 *maskp = mask;
9165 return 1;
9166}
9167
9168uword
9169unformat_l3_mask (unformat_input_t * input, va_list * args)
9170{
9171 u8 **maskp = va_arg (*args, u8 **);
9172
9173 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9174 {
9175 if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
9176 return 1;
9177 else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
9178 return 1;
9179 else
9180 break;
9181 }
9182 return 0;
9183}
9184
9185uword
9186unformat_l2_mask (unformat_input_t * input, va_list * args)
9187{
9188 u8 **maskp = va_arg (*args, u8 **);
9189 u8 *mask = 0;
9190 u8 src = 0;
9191 u8 dst = 0;
9192 u8 proto = 0;
9193 u8 tag1 = 0;
9194 u8 tag2 = 0;
9195 u8 ignore_tag1 = 0;
9196 u8 ignore_tag2 = 0;
9197 u8 cos1 = 0;
9198 u8 cos2 = 0;
9199 u8 dot1q = 0;
9200 u8 dot1ad = 0;
9201 int len = 14;
9202
9203 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9204 {
9205 if (unformat (input, "src"))
9206 src = 1;
9207 else if (unformat (input, "dst"))
9208 dst = 1;
9209 else if (unformat (input, "proto"))
9210 proto = 1;
9211 else if (unformat (input, "tag1"))
9212 tag1 = 1;
9213 else if (unformat (input, "tag2"))
9214 tag2 = 1;
9215 else if (unformat (input, "ignore-tag1"))
9216 ignore_tag1 = 1;
9217 else if (unformat (input, "ignore-tag2"))
9218 ignore_tag2 = 1;
9219 else if (unformat (input, "cos1"))
9220 cos1 = 1;
9221 else if (unformat (input, "cos2"))
9222 cos2 = 1;
9223 else if (unformat (input, "dot1q"))
9224 dot1q = 1;
9225 else if (unformat (input, "dot1ad"))
9226 dot1ad = 1;
9227 else
9228 break;
9229 }
9230 if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9231 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9232 return 0;
9233
9234 if (tag1 || ignore_tag1 || cos1 || dot1q)
9235 len = 18;
9236 if (tag2 || ignore_tag2 || cos2 || dot1ad)
9237 len = 22;
9238
9239 vec_validate (mask, len - 1);
9240
9241 if (dst)
9242 memset (mask, 0xff, 6);
9243
9244 if (src)
9245 memset (mask + 6, 0xff, 6);
9246
9247 if (tag2 || dot1ad)
9248 {
9249 /* inner vlan tag */
9250 if (tag2)
9251 {
9252 mask[19] = 0xff;
9253 mask[18] = 0x0f;
9254 }
9255 if (cos2)
9256 mask[18] |= 0xe0;
9257 if (proto)
9258 mask[21] = mask[20] = 0xff;
9259 if (tag1)
9260 {
9261 mask[15] = 0xff;
9262 mask[14] = 0x0f;
9263 }
9264 if (cos1)
9265 mask[14] |= 0xe0;
9266 *maskp = mask;
9267 return 1;
9268 }
9269 if (tag1 | dot1q)
9270 {
9271 if (tag1)
9272 {
9273 mask[15] = 0xff;
9274 mask[14] = 0x0f;
9275 }
9276 if (cos1)
9277 mask[14] |= 0xe0;
9278 if (proto)
9279 mask[16] = mask[17] = 0xff;
9280
9281 *maskp = mask;
9282 return 1;
9283 }
9284 if (cos2)
9285 mask[18] |= 0xe0;
9286 if (cos1)
9287 mask[14] |= 0xe0;
9288 if (proto)
9289 mask[12] = mask[13] = 0xff;
9290
9291 *maskp = mask;
9292 return 1;
9293}
9294
9295uword
9296unformat_classify_mask (unformat_input_t * input, va_list * args)
9297{
9298 u8 **maskp = va_arg (*args, u8 **);
9299 u32 *skipp = va_arg (*args, u32 *);
9300 u32 *matchp = va_arg (*args, u32 *);
9301 u32 match;
9302 u8 *mask = 0;
9303 u8 *l2 = 0;
9304 u8 *l3 = 0;
9305 u8 *l4 = 0;
9306 int i;
9307
9308 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9309 {
9310 if (unformat (input, "hex %U", unformat_hex_string, &mask))
9311 ;
9312 else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
9313 ;
9314 else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
9315 ;
9316 else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
9317 ;
9318 else
9319 break;
9320 }
9321
9322 if (l4 && !l3)
9323 {
9324 vec_free (mask);
9325 vec_free (l2);
9326 vec_free (l4);
9327 return 0;
9328 }
9329
9330 if (mask || l2 || l3 || l4)
9331 {
9332 if (l2 || l3 || l4)
9333 {
9334 /* "With a free Ethernet header in every package" */
9335 if (l2 == 0)
9336 vec_validate (l2, 13);
9337 mask = l2;
9338 if (vec_len (l3))
9339 {
9340 vec_append (mask, l3);
9341 vec_free (l3);
9342 }
9343 if (vec_len (l4))
9344 {
9345 vec_append (mask, l4);
9346 vec_free (l4);
9347 }
9348 }
9349
9350 /* Scan forward looking for the first significant mask octet */
9351 for (i = 0; i < vec_len (mask); i++)
9352 if (mask[i])
9353 break;
9354
9355 /* compute (skip, match) params */
9356 *skipp = i / sizeof (u32x4);
9357 vec_delete (mask, *skipp * sizeof (u32x4), 0);
9358
9359 /* Pad mask to an even multiple of the vector size */
9360 while (vec_len (mask) % sizeof (u32x4))
9361 vec_add1 (mask, 0);
9362
9363 match = vec_len (mask) / sizeof (u32x4);
9364
9365 for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9366 {
9367 u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9368 if (*tmp || *(tmp + 1))
9369 break;
9370 match--;
9371 }
9372 if (match == 0)
9373 clib_warning ("BUG: match 0");
9374
9375 _vec_len (mask) = match * sizeof (u32x4);
9376
9377 *matchp = match;
9378 *maskp = mask;
9379
9380 return 1;
9381 }
9382
9383 return 0;
9384}
Dave Barach4a3f69c2017-02-22 12:44:56 -05009385#endif /* VPP_API_TEST_BUILTIN */
Damjan Marion7cd468a2016-12-19 23:05:39 +01009386
9387#define foreach_l2_next \
9388_(drop, DROP) \
9389_(ethernet, ETHERNET_INPUT) \
9390_(ip4, IP4_INPUT) \
9391_(ip6, IP6_INPUT)
9392
9393uword
9394unformat_l2_next_index (unformat_input_t * input, va_list * args)
9395{
9396 u32 *miss_next_indexp = va_arg (*args, u32 *);
9397 u32 next_index = 0;
9398 u32 tmp;
9399
9400#define _(n,N) \
9401 if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9402 foreach_l2_next;
9403#undef _
9404
9405 if (unformat (input, "%d", &tmp))
9406 {
9407 next_index = tmp;
9408 goto out;
9409 }
9410
9411 return 0;
9412
9413out:
9414 *miss_next_indexp = next_index;
9415 return 1;
9416}
9417
9418#define foreach_ip_next \
9419_(drop, DROP) \
9420_(local, LOCAL) \
9421_(rewrite, REWRITE)
9422
9423uword
Dave Barach4a3f69c2017-02-22 12:44:56 -05009424api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
Damjan Marion7cd468a2016-12-19 23:05:39 +01009425{
9426 u32 *miss_next_indexp = va_arg (*args, u32 *);
9427 u32 next_index = 0;
9428 u32 tmp;
9429
9430#define _(n,N) \
9431 if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9432 foreach_ip_next;
9433#undef _
9434
9435 if (unformat (input, "%d", &tmp))
9436 {
9437 next_index = tmp;
9438 goto out;
9439 }
9440
9441 return 0;
9442
9443out:
9444 *miss_next_indexp = next_index;
9445 return 1;
9446}
9447
9448#define foreach_acl_next \
9449_(deny, DENY)
9450
9451uword
Dave Barach4a3f69c2017-02-22 12:44:56 -05009452api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
Damjan Marion7cd468a2016-12-19 23:05:39 +01009453{
9454 u32 *miss_next_indexp = va_arg (*args, u32 *);
9455 u32 next_index = 0;
9456 u32 tmp;
9457
9458#define _(n,N) \
9459 if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
9460 foreach_acl_next;
9461#undef _
9462
9463 if (unformat (input, "permit"))
9464 {
9465 next_index = ~0;
9466 goto out;
9467 }
9468 else if (unformat (input, "%d", &tmp))
9469 {
9470 next_index = tmp;
9471 goto out;
9472 }
9473
9474 return 0;
9475
9476out:
9477 *miss_next_indexp = next_index;
9478 return 1;
9479}
9480
9481uword
9482unformat_policer_precolor (unformat_input_t * input, va_list * args)
9483{
9484 u32 *r = va_arg (*args, u32 *);
9485
9486 if (unformat (input, "conform-color"))
9487 *r = POLICE_CONFORM;
9488 else if (unformat (input, "exceed-color"))
9489 *r = POLICE_EXCEED;
9490 else
9491 return 0;
9492
9493 return 1;
9494}
9495
9496static int
9497api_classify_add_del_table (vat_main_t * vam)
9498{
9499 unformat_input_t *i = vam->input;
9500 vl_api_classify_add_del_table_t *mp;
9501
9502 u32 nbuckets = 2;
9503 u32 skip = ~0;
9504 u32 match = ~0;
9505 int is_add = 1;
9506 int del_chain = 0;
9507 u32 table_index = ~0;
9508 u32 next_table_index = ~0;
9509 u32 miss_next_index = ~0;
9510 u32 memory_size = 32 << 20;
9511 u8 *mask = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009512 u32 current_data_flag = 0;
9513 int current_data_offset = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009514 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009515
9516 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9517 {
9518 if (unformat (i, "del"))
9519 is_add = 0;
9520 else if (unformat (i, "del-chain"))
9521 {
9522 is_add = 0;
9523 del_chain = 1;
9524 }
9525 else if (unformat (i, "buckets %d", &nbuckets))
9526 ;
9527 else if (unformat (i, "memory_size %d", &memory_size))
9528 ;
9529 else if (unformat (i, "skip %d", &skip))
9530 ;
9531 else if (unformat (i, "match %d", &match))
9532 ;
9533 else if (unformat (i, "table %d", &table_index))
9534 ;
9535 else if (unformat (i, "mask %U", unformat_classify_mask,
9536 &mask, &skip, &match))
9537 ;
9538 else if (unformat (i, "next-table %d", &next_table_index))
9539 ;
Dave Barach4a3f69c2017-02-22 12:44:56 -05009540 else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
Damjan Marion7cd468a2016-12-19 23:05:39 +01009541 &miss_next_index))
9542 ;
9543 else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
9544 &miss_next_index))
9545 ;
Dave Barach4a3f69c2017-02-22 12:44:56 -05009546 else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
Damjan Marion7cd468a2016-12-19 23:05:39 +01009547 &miss_next_index))
9548 ;
9549 else if (unformat (i, "current-data-flag %d", &current_data_flag))
9550 ;
9551 else if (unformat (i, "current-data-offset %d", &current_data_offset))
9552 ;
9553 else
9554 break;
9555 }
9556
9557 if (is_add && mask == 0)
9558 {
9559 errmsg ("Mask required");
9560 return -99;
9561 }
9562
9563 if (is_add && skip == ~0)
9564 {
9565 errmsg ("skip count required");
9566 return -99;
9567 }
9568
9569 if (is_add && match == ~0)
9570 {
9571 errmsg ("match count required");
9572 return -99;
9573 }
9574
9575 if (!is_add && table_index == ~0)
9576 {
9577 errmsg ("table index required for delete");
9578 return -99;
9579 }
9580
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009581 M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
Damjan Marion7cd468a2016-12-19 23:05:39 +01009582
9583 mp->is_add = is_add;
9584 mp->del_chain = del_chain;
9585 mp->table_index = ntohl (table_index);
9586 mp->nbuckets = ntohl (nbuckets);
9587 mp->memory_size = ntohl (memory_size);
9588 mp->skip_n_vectors = ntohl (skip);
9589 mp->match_n_vectors = ntohl (match);
9590 mp->next_table_index = ntohl (next_table_index);
9591 mp->miss_next_index = ntohl (miss_next_index);
9592 mp->current_data_flag = ntohl (current_data_flag);
9593 mp->current_data_offset = ntohl (current_data_offset);
9594 clib_memcpy (mp->mask, mask, vec_len (mask));
9595
9596 vec_free (mask);
9597
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009598 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06009599 W (ret);
9600 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009601}
9602
Dave Barach4a3f69c2017-02-22 12:44:56 -05009603#if VPP_API_TEST_BUILTIN == 0
Damjan Marion7cd468a2016-12-19 23:05:39 +01009604uword
9605unformat_l4_match (unformat_input_t * input, va_list * args)
9606{
9607 u8 **matchp = va_arg (*args, u8 **);
9608
9609 u8 *proto_header = 0;
9610 int src_port = 0;
9611 int dst_port = 0;
9612
9613 tcpudp_header_t h;
9614
9615 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9616 {
9617 if (unformat (input, "src_port %d", &src_port))
9618 ;
9619 else if (unformat (input, "dst_port %d", &dst_port))
9620 ;
9621 else
9622 return 0;
9623 }
9624
9625 h.src_port = clib_host_to_net_u16 (src_port);
9626 h.dst_port = clib_host_to_net_u16 (dst_port);
9627 vec_validate (proto_header, sizeof (h) - 1);
9628 memcpy (proto_header, &h, sizeof (h));
9629
9630 *matchp = proto_header;
9631
9632 return 1;
9633}
9634
9635uword
9636unformat_ip4_match (unformat_input_t * input, va_list * args)
9637{
9638 u8 **matchp = va_arg (*args, u8 **);
9639 u8 *match = 0;
9640 ip4_header_t *ip;
9641 int version = 0;
9642 u32 version_val;
9643 int hdr_length = 0;
9644 u32 hdr_length_val;
9645 int src = 0, dst = 0;
9646 ip4_address_t src_val, dst_val;
9647 int proto = 0;
9648 u32 proto_val;
9649 int tos = 0;
9650 u32 tos_val;
9651 int length = 0;
9652 u32 length_val;
9653 int fragment_id = 0;
9654 u32 fragment_id_val;
9655 int ttl = 0;
9656 int ttl_val;
9657 int checksum = 0;
9658 u32 checksum_val;
9659
9660 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9661 {
9662 if (unformat (input, "version %d", &version_val))
9663 version = 1;
9664 else if (unformat (input, "hdr_length %d", &hdr_length_val))
9665 hdr_length = 1;
9666 else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
9667 src = 1;
9668 else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
9669 dst = 1;
9670 else if (unformat (input, "proto %d", &proto_val))
9671 proto = 1;
9672 else if (unformat (input, "tos %d", &tos_val))
9673 tos = 1;
9674 else if (unformat (input, "length %d", &length_val))
9675 length = 1;
9676 else if (unformat (input, "fragment_id %d", &fragment_id_val))
9677 fragment_id = 1;
9678 else if (unformat (input, "ttl %d", &ttl_val))
9679 ttl = 1;
9680 else if (unformat (input, "checksum %d", &checksum_val))
9681 checksum = 1;
9682 else
9683 break;
9684 }
9685
9686 if (version + hdr_length + src + dst + proto + tos + length + fragment_id
9687 + ttl + checksum == 0)
9688 return 0;
9689
9690 /*
9691 * Aligned because we use the real comparison functions
9692 */
9693 vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9694
9695 ip = (ip4_header_t *) match;
9696
9697 /* These are realistically matched in practice */
9698 if (src)
9699 ip->src_address.as_u32 = src_val.as_u32;
9700
9701 if (dst)
9702 ip->dst_address.as_u32 = dst_val.as_u32;
9703
9704 if (proto)
9705 ip->protocol = proto_val;
9706
9707
9708 /* These are not, but they're included for completeness */
9709 if (version)
9710 ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
9711
9712 if (hdr_length)
9713 ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
9714
9715 if (tos)
9716 ip->tos = tos_val;
9717
9718 if (length)
9719 ip->length = clib_host_to_net_u16 (length_val);
9720
9721 if (ttl)
9722 ip->ttl = ttl_val;
9723
9724 if (checksum)
9725 ip->checksum = clib_host_to_net_u16 (checksum_val);
9726
9727 *matchp = match;
9728 return 1;
9729}
9730
9731uword
9732unformat_ip6_match (unformat_input_t * input, va_list * args)
9733{
9734 u8 **matchp = va_arg (*args, u8 **);
9735 u8 *match = 0;
9736 ip6_header_t *ip;
9737 int version = 0;
9738 u32 version_val;
9739 u8 traffic_class = 0;
9740 u32 traffic_class_val = 0;
9741 u8 flow_label = 0;
9742 u8 flow_label_val;
9743 int src = 0, dst = 0;
9744 ip6_address_t src_val, dst_val;
9745 int proto = 0;
9746 u32 proto_val;
9747 int payload_length = 0;
9748 u32 payload_length_val;
9749 int hop_limit = 0;
9750 int hop_limit_val;
9751 u32 ip_version_traffic_class_and_flow_label;
9752
9753 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9754 {
9755 if (unformat (input, "version %d", &version_val))
9756 version = 1;
9757 else if (unformat (input, "traffic_class %d", &traffic_class_val))
9758 traffic_class = 1;
9759 else if (unformat (input, "flow_label %d", &flow_label_val))
9760 flow_label = 1;
9761 else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
9762 src = 1;
9763 else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
9764 dst = 1;
9765 else if (unformat (input, "proto %d", &proto_val))
9766 proto = 1;
9767 else if (unformat (input, "payload_length %d", &payload_length_val))
9768 payload_length = 1;
9769 else if (unformat (input, "hop_limit %d", &hop_limit_val))
9770 hop_limit = 1;
9771 else
9772 break;
9773 }
9774
9775 if (version + traffic_class + flow_label + src + dst + proto +
9776 payload_length + hop_limit == 0)
9777 return 0;
9778
9779 /*
9780 * Aligned because we use the real comparison functions
9781 */
9782 vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9783
9784 ip = (ip6_header_t *) match;
9785
9786 if (src)
9787 clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9788
9789 if (dst)
9790 clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9791
9792 if (proto)
9793 ip->protocol = proto_val;
9794
9795 ip_version_traffic_class_and_flow_label = 0;
9796
9797 if (version)
9798 ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9799
9800 if (traffic_class)
9801 ip_version_traffic_class_and_flow_label |=
9802 (traffic_class_val & 0xFF) << 20;
9803
9804 if (flow_label)
9805 ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9806
9807 ip->ip_version_traffic_class_and_flow_label =
9808 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9809
9810 if (payload_length)
9811 ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9812
9813 if (hop_limit)
9814 ip->hop_limit = hop_limit_val;
9815
9816 *matchp = match;
9817 return 1;
9818}
9819
9820uword
9821unformat_l3_match (unformat_input_t * input, va_list * args)
9822{
9823 u8 **matchp = va_arg (*args, u8 **);
9824
9825 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9826 {
9827 if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9828 return 1;
9829 else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9830 return 1;
9831 else
9832 break;
9833 }
9834 return 0;
9835}
9836
9837uword
9838unformat_vlan_tag (unformat_input_t * input, va_list * args)
9839{
9840 u8 *tagp = va_arg (*args, u8 *);
9841 u32 tag;
9842
9843 if (unformat (input, "%d", &tag))
9844 {
9845 tagp[0] = (tag >> 8) & 0x0F;
9846 tagp[1] = tag & 0xFF;
9847 return 1;
9848 }
9849
9850 return 0;
9851}
9852
9853uword
9854unformat_l2_match (unformat_input_t * input, va_list * args)
9855{
9856 u8 **matchp = va_arg (*args, u8 **);
9857 u8 *match = 0;
9858 u8 src = 0;
9859 u8 src_val[6];
9860 u8 dst = 0;
9861 u8 dst_val[6];
9862 u8 proto = 0;
9863 u16 proto_val;
9864 u8 tag1 = 0;
9865 u8 tag1_val[2];
9866 u8 tag2 = 0;
9867 u8 tag2_val[2];
9868 int len = 14;
9869 u8 ignore_tag1 = 0;
9870 u8 ignore_tag2 = 0;
9871 u8 cos1 = 0;
9872 u8 cos2 = 0;
9873 u32 cos1_val = 0;
9874 u32 cos2_val = 0;
9875
9876 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9877 {
9878 if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9879 src = 1;
9880 else
9881 if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9882 dst = 1;
9883 else if (unformat (input, "proto %U",
9884 unformat_ethernet_type_host_byte_order, &proto_val))
9885 proto = 1;
9886 else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9887 tag1 = 1;
9888 else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9889 tag2 = 1;
9890 else if (unformat (input, "ignore-tag1"))
9891 ignore_tag1 = 1;
9892 else if (unformat (input, "ignore-tag2"))
9893 ignore_tag2 = 1;
9894 else if (unformat (input, "cos1 %d", &cos1_val))
9895 cos1 = 1;
9896 else if (unformat (input, "cos2 %d", &cos2_val))
9897 cos2 = 1;
9898 else
9899 break;
9900 }
9901 if ((src + dst + proto + tag1 + tag2 +
9902 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9903 return 0;
9904
9905 if (tag1 || ignore_tag1 || cos1)
9906 len = 18;
9907 if (tag2 || ignore_tag2 || cos2)
9908 len = 22;
9909
9910 vec_validate_aligned (match, len - 1, sizeof (u32x4));
9911
9912 if (dst)
9913 clib_memcpy (match, dst_val, 6);
9914
9915 if (src)
9916 clib_memcpy (match + 6, src_val, 6);
9917
9918 if (tag2)
9919 {
9920 /* inner vlan tag */
9921 match[19] = tag2_val[1];
9922 match[18] = tag2_val[0];
9923 if (cos2)
9924 match[18] |= (cos2_val & 0x7) << 5;
9925 if (proto)
9926 {
9927 match[21] = proto_val & 0xff;
9928 match[20] = proto_val >> 8;
9929 }
9930 if (tag1)
9931 {
9932 match[15] = tag1_val[1];
9933 match[14] = tag1_val[0];
9934 }
9935 if (cos1)
9936 match[14] |= (cos1_val & 0x7) << 5;
9937 *matchp = match;
9938 return 1;
9939 }
9940 if (tag1)
9941 {
9942 match[15] = tag1_val[1];
9943 match[14] = tag1_val[0];
9944 if (proto)
9945 {
9946 match[17] = proto_val & 0xff;
9947 match[16] = proto_val >> 8;
9948 }
9949 if (cos1)
9950 match[14] |= (cos1_val & 0x7) << 5;
9951
9952 *matchp = match;
9953 return 1;
9954 }
9955 if (cos2)
9956 match[18] |= (cos2_val & 0x7) << 5;
9957 if (cos1)
9958 match[14] |= (cos1_val & 0x7) << 5;
9959 if (proto)
9960 {
9961 match[13] = proto_val & 0xff;
9962 match[12] = proto_val >> 8;
9963 }
9964
9965 *matchp = match;
9966 return 1;
9967}
Dave Barach4a3f69c2017-02-22 12:44:56 -05009968#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +01009969
9970uword
Dave Barach4a3f69c2017-02-22 12:44:56 -05009971api_unformat_classify_match (unformat_input_t * input, va_list * args)
Damjan Marion7cd468a2016-12-19 23:05:39 +01009972{
9973 u8 **matchp = va_arg (*args, u8 **);
9974 u32 skip_n_vectors = va_arg (*args, u32);
9975 u32 match_n_vectors = va_arg (*args, u32);
9976
9977 u8 *match = 0;
9978 u8 *l2 = 0;
9979 u8 *l3 = 0;
9980 u8 *l4 = 0;
9981
9982 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9983 {
9984 if (unformat (input, "hex %U", unformat_hex_string, &match))
9985 ;
9986 else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9987 ;
9988 else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9989 ;
9990 else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9991 ;
9992 else
9993 break;
9994 }
9995
9996 if (l4 && !l3)
9997 {
9998 vec_free (match);
9999 vec_free (l2);
10000 vec_free (l4);
10001 return 0;
10002 }
10003
10004 if (match || l2 || l3 || l4)
10005 {
10006 if (l2 || l3 || l4)
10007 {
10008 /* "Win a free Ethernet header in every packet" */
10009 if (l2 == 0)
10010 vec_validate_aligned (l2, 13, sizeof (u32x4));
10011 match = l2;
10012 if (vec_len (l3))
10013 {
10014 vec_append_aligned (match, l3, sizeof (u32x4));
10015 vec_free (l3);
10016 }
10017 if (vec_len (l4))
10018 {
10019 vec_append_aligned (match, l4, sizeof (u32x4));
10020 vec_free (l4);
10021 }
10022 }
10023
10024 /* Make sure the vector is big enough even if key is all 0's */
10025 vec_validate_aligned
10026 (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
10027 sizeof (u32x4));
10028
10029 /* Set size, include skipped vectors */
10030 _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
10031
10032 *matchp = match;
10033
10034 return 1;
10035 }
10036
10037 return 0;
10038}
10039
10040static int
10041api_classify_add_del_session (vat_main_t * vam)
10042{
10043 unformat_input_t *i = vam->input;
10044 vl_api_classify_add_del_session_t *mp;
10045 int is_add = 1;
10046 u32 table_index = ~0;
10047 u32 hit_next_index = ~0;
10048 u32 opaque_index = ~0;
10049 u8 *match = 0;
10050 i32 advance = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010051 u32 skip_n_vectors = 0;
10052 u32 match_n_vectors = 0;
10053 u32 action = 0;
10054 u32 metadata = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010055 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010056
10057 /*
10058 * Warning: you have to supply skip_n and match_n
10059 * because the API client cant simply look at the classify
10060 * table object.
10061 */
10062
10063 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10064 {
10065 if (unformat (i, "del"))
10066 is_add = 0;
Dave Barach4a3f69c2017-02-22 12:44:56 -050010067 else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
Damjan Marion7cd468a2016-12-19 23:05:39 +010010068 &hit_next_index))
10069 ;
10070 else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
10071 &hit_next_index))
10072 ;
Dave Barach4a3f69c2017-02-22 12:44:56 -050010073 else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
Damjan Marion7cd468a2016-12-19 23:05:39 +010010074 &hit_next_index))
10075 ;
10076 else if (unformat (i, "policer-hit-next %d", &hit_next_index))
10077 ;
10078 else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
10079 ;
10080 else if (unformat (i, "opaque-index %d", &opaque_index))
10081 ;
10082 else if (unformat (i, "skip_n %d", &skip_n_vectors))
10083 ;
10084 else if (unformat (i, "match_n %d", &match_n_vectors))
10085 ;
Dave Barach4a3f69c2017-02-22 12:44:56 -050010086 else if (unformat (i, "match %U", api_unformat_classify_match,
Damjan Marion7cd468a2016-12-19 23:05:39 +010010087 &match, skip_n_vectors, match_n_vectors))
10088 ;
10089 else if (unformat (i, "advance %d", &advance))
10090 ;
10091 else if (unformat (i, "table-index %d", &table_index))
10092 ;
10093 else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
10094 action = 1;
10095 else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
10096 action = 2;
10097 else if (unformat (i, "action %d", &action))
10098 ;
10099 else if (unformat (i, "metadata %d", &metadata))
10100 ;
10101 else
10102 break;
10103 }
10104
10105 if (table_index == ~0)
10106 {
10107 errmsg ("Table index required");
10108 return -99;
10109 }
10110
10111 if (is_add && match == 0)
10112 {
10113 errmsg ("Match value required");
10114 return -99;
10115 }
10116
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010117 M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
Damjan Marion7cd468a2016-12-19 23:05:39 +010010118
10119 mp->is_add = is_add;
10120 mp->table_index = ntohl (table_index);
10121 mp->hit_next_index = ntohl (hit_next_index);
10122 mp->opaque_index = ntohl (opaque_index);
10123 mp->advance = ntohl (advance);
10124 mp->action = action;
10125 mp->metadata = ntohl (metadata);
10126 clib_memcpy (mp->match, match, vec_len (match));
10127 vec_free (match);
10128
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010129 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010130 W (ret);
10131 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010132}
10133
10134static int
10135api_classify_set_interface_ip_table (vat_main_t * vam)
10136{
10137 unformat_input_t *i = vam->input;
10138 vl_api_classify_set_interface_ip_table_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010139 u32 sw_if_index;
10140 int sw_if_index_set;
10141 u32 table_index = ~0;
10142 u8 is_ipv6 = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010143 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010144
10145 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10146 {
10147 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10148 sw_if_index_set = 1;
10149 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10150 sw_if_index_set = 1;
10151 else if (unformat (i, "table %d", &table_index))
10152 ;
10153 else
10154 {
10155 clib_warning ("parse error '%U'", format_unformat_error, i);
10156 return -99;
10157 }
10158 }
10159
10160 if (sw_if_index_set == 0)
10161 {
10162 errmsg ("missing interface name or sw_if_index");
10163 return -99;
10164 }
10165
10166
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010167 M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010168
10169 mp->sw_if_index = ntohl (sw_if_index);
10170 mp->table_index = ntohl (table_index);
10171 mp->is_ipv6 = is_ipv6;
10172
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010173 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010174 W (ret);
10175 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010176}
10177
10178static int
10179api_classify_set_interface_l2_tables (vat_main_t * vam)
10180{
10181 unformat_input_t *i = vam->input;
10182 vl_api_classify_set_interface_l2_tables_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010183 u32 sw_if_index;
10184 int sw_if_index_set;
10185 u32 ip4_table_index = ~0;
10186 u32 ip6_table_index = ~0;
10187 u32 other_table_index = ~0;
10188 u32 is_input = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010189 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010190
10191 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10192 {
10193 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10194 sw_if_index_set = 1;
10195 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10196 sw_if_index_set = 1;
10197 else if (unformat (i, "ip4-table %d", &ip4_table_index))
10198 ;
10199 else if (unformat (i, "ip6-table %d", &ip6_table_index))
10200 ;
10201 else if (unformat (i, "other-table %d", &other_table_index))
10202 ;
10203 else if (unformat (i, "is-input %d", &is_input))
10204 ;
10205 else
10206 {
10207 clib_warning ("parse error '%U'", format_unformat_error, i);
10208 return -99;
10209 }
10210 }
10211
10212 if (sw_if_index_set == 0)
10213 {
10214 errmsg ("missing interface name or sw_if_index");
10215 return -99;
10216 }
10217
10218
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010219 M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010220
10221 mp->sw_if_index = ntohl (sw_if_index);
10222 mp->ip4_table_index = ntohl (ip4_table_index);
10223 mp->ip6_table_index = ntohl (ip6_table_index);
10224 mp->other_table_index = ntohl (other_table_index);
10225 mp->is_input = (u8) is_input;
10226
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010227 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010228 W (ret);
10229 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010230}
10231
10232static int
10233api_set_ipfix_exporter (vat_main_t * vam)
10234{
10235 unformat_input_t *i = vam->input;
10236 vl_api_set_ipfix_exporter_t *mp;
10237 ip4_address_t collector_address;
10238 u8 collector_address_set = 0;
10239 u32 collector_port = ~0;
10240 ip4_address_t src_address;
10241 u8 src_address_set = 0;
10242 u32 vrf_id = ~0;
10243 u32 path_mtu = ~0;
10244 u32 template_interval = ~0;
10245 u8 udp_checksum = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010246 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010247
10248 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10249 {
10250 if (unformat (i, "collector_address %U", unformat_ip4_address,
10251 &collector_address))
10252 collector_address_set = 1;
10253 else if (unformat (i, "collector_port %d", &collector_port))
10254 ;
10255 else if (unformat (i, "src_address %U", unformat_ip4_address,
10256 &src_address))
10257 src_address_set = 1;
10258 else if (unformat (i, "vrf_id %d", &vrf_id))
10259 ;
10260 else if (unformat (i, "path_mtu %d", &path_mtu))
10261 ;
10262 else if (unformat (i, "template_interval %d", &template_interval))
10263 ;
10264 else if (unformat (i, "udp_checksum"))
10265 udp_checksum = 1;
10266 else
10267 break;
10268 }
10269
10270 if (collector_address_set == 0)
10271 {
10272 errmsg ("collector_address required");
10273 return -99;
10274 }
10275
10276 if (src_address_set == 0)
10277 {
10278 errmsg ("src_address required");
10279 return -99;
10280 }
10281
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010282 M (SET_IPFIX_EXPORTER, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010283
10284 memcpy (mp->collector_address, collector_address.data,
10285 sizeof (collector_address.data));
10286 mp->collector_port = htons ((u16) collector_port);
10287 memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
10288 mp->vrf_id = htonl (vrf_id);
10289 mp->path_mtu = htonl (path_mtu);
10290 mp->template_interval = htonl (template_interval);
10291 mp->udp_checksum = udp_checksum;
10292
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010293 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010294 W (ret);
10295 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010296}
10297
10298static int
10299api_set_ipfix_classify_stream (vat_main_t * vam)
10300{
10301 unformat_input_t *i = vam->input;
10302 vl_api_set_ipfix_classify_stream_t *mp;
10303 u32 domain_id = 0;
10304 u32 src_port = UDP_DST_PORT_ipfix;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010305 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010306
10307 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10308 {
10309 if (unformat (i, "domain %d", &domain_id))
10310 ;
10311 else if (unformat (i, "src_port %d", &src_port))
10312 ;
10313 else
10314 {
10315 errmsg ("unknown input `%U'", format_unformat_error, i);
10316 return -99;
10317 }
10318 }
10319
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010320 M (SET_IPFIX_CLASSIFY_STREAM, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010321
10322 mp->domain_id = htonl (domain_id);
10323 mp->src_port = htons ((u16) src_port);
10324
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010325 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010326 W (ret);
10327 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010328}
10329
10330static int
10331api_ipfix_classify_table_add_del (vat_main_t * vam)
10332{
10333 unformat_input_t *i = vam->input;
10334 vl_api_ipfix_classify_table_add_del_t *mp;
10335 int is_add = -1;
10336 u32 classify_table_index = ~0;
10337 u8 ip_version = 0;
10338 u8 transport_protocol = 255;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010339 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010340
10341 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10342 {
10343 if (unformat (i, "add"))
10344 is_add = 1;
10345 else if (unformat (i, "del"))
10346 is_add = 0;
10347 else if (unformat (i, "table %d", &classify_table_index))
10348 ;
10349 else if (unformat (i, "ip4"))
10350 ip_version = 4;
10351 else if (unformat (i, "ip6"))
10352 ip_version = 6;
10353 else if (unformat (i, "tcp"))
10354 transport_protocol = 6;
10355 else if (unformat (i, "udp"))
10356 transport_protocol = 17;
10357 else
10358 {
10359 errmsg ("unknown input `%U'", format_unformat_error, i);
10360 return -99;
10361 }
10362 }
10363
10364 if (is_add == -1)
10365 {
10366 errmsg ("expecting: add|del");
10367 return -99;
10368 }
10369 if (classify_table_index == ~0)
10370 {
10371 errmsg ("classifier table not specified");
10372 return -99;
10373 }
10374 if (ip_version == 0)
10375 {
10376 errmsg ("IP version not specified");
10377 return -99;
10378 }
10379
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010380 M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010381
10382 mp->is_add = is_add;
10383 mp->table_id = htonl (classify_table_index);
10384 mp->ip_version = ip_version;
10385 mp->transport_protocol = transport_protocol;
10386
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010387 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010388 W (ret);
10389 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010390}
10391
10392static int
10393api_get_node_index (vat_main_t * vam)
10394{
10395 unformat_input_t *i = vam->input;
10396 vl_api_get_node_index_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010397 u8 *name = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010398 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010399
10400 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10401 {
10402 if (unformat (i, "node %s", &name))
10403 ;
10404 else
10405 break;
10406 }
10407 if (name == 0)
10408 {
10409 errmsg ("node name required");
10410 return -99;
10411 }
10412 if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10413 {
10414 errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10415 return -99;
10416 }
10417
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010418 M (GET_NODE_INDEX, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010419 clib_memcpy (mp->node_name, name, vec_len (name));
10420 vec_free (name);
10421
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010422 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010423 W (ret);
10424 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010425}
10426
10427static int
10428api_get_next_index (vat_main_t * vam)
10429{
10430 unformat_input_t *i = vam->input;
10431 vl_api_get_next_index_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010432 u8 *node_name = 0, *next_node_name = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010433 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010434
10435 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10436 {
10437 if (unformat (i, "node-name %s", &node_name))
10438 ;
10439 else if (unformat (i, "next-node-name %s", &next_node_name))
10440 break;
10441 }
10442
10443 if (node_name == 0)
10444 {
10445 errmsg ("node name required");
10446 return -99;
10447 }
10448 if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
10449 {
10450 errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10451 return -99;
10452 }
10453
10454 if (next_node_name == 0)
10455 {
10456 errmsg ("next node name required");
10457 return -99;
10458 }
10459 if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
10460 {
10461 errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
10462 return -99;
10463 }
10464
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010465 M (GET_NEXT_INDEX, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010466 clib_memcpy (mp->node_name, node_name, vec_len (node_name));
10467 clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
10468 vec_free (node_name);
10469 vec_free (next_node_name);
10470
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010471 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010472 W (ret);
10473 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010474}
10475
10476static int
10477api_add_node_next (vat_main_t * vam)
10478{
10479 unformat_input_t *i = vam->input;
10480 vl_api_add_node_next_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010481 u8 *name = 0;
10482 u8 *next = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010483 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010484
10485 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10486 {
10487 if (unformat (i, "node %s", &name))
10488 ;
10489 else if (unformat (i, "next %s", &next))
10490 ;
10491 else
10492 break;
10493 }
10494 if (name == 0)
10495 {
10496 errmsg ("node name required");
10497 return -99;
10498 }
10499 if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10500 {
10501 errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10502 return -99;
10503 }
10504 if (next == 0)
10505 {
10506 errmsg ("next node required");
10507 return -99;
10508 }
10509 if (vec_len (next) >= ARRAY_LEN (mp->next_name))
10510 {
10511 errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
10512 return -99;
10513 }
10514
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010515 M (ADD_NODE_NEXT, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010516 clib_memcpy (mp->node_name, name, vec_len (name));
10517 clib_memcpy (mp->next_name, next, vec_len (next));
10518 vec_free (name);
10519 vec_free (next);
10520
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010521 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010522 W (ret);
10523 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010524}
10525
10526static int
10527api_l2tpv3_create_tunnel (vat_main_t * vam)
10528{
10529 unformat_input_t *i = vam->input;
10530 ip6_address_t client_address, our_address;
10531 int client_address_set = 0;
10532 int our_address_set = 0;
10533 u32 local_session_id = 0;
10534 u32 remote_session_id = 0;
10535 u64 local_cookie = 0;
10536 u64 remote_cookie = 0;
10537 u8 l2_sublayer_present = 0;
10538 vl_api_l2tpv3_create_tunnel_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010539 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010540
10541 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10542 {
10543 if (unformat (i, "client_address %U", unformat_ip6_address,
10544 &client_address))
10545 client_address_set = 1;
10546 else if (unformat (i, "our_address %U", unformat_ip6_address,
10547 &our_address))
10548 our_address_set = 1;
10549 else if (unformat (i, "local_session_id %d", &local_session_id))
10550 ;
10551 else if (unformat (i, "remote_session_id %d", &remote_session_id))
10552 ;
10553 else if (unformat (i, "local_cookie %lld", &local_cookie))
10554 ;
10555 else if (unformat (i, "remote_cookie %lld", &remote_cookie))
10556 ;
10557 else if (unformat (i, "l2-sublayer-present"))
10558 l2_sublayer_present = 1;
10559 else
10560 break;
10561 }
10562
10563 if (client_address_set == 0)
10564 {
10565 errmsg ("client_address required");
10566 return -99;
10567 }
10568
10569 if (our_address_set == 0)
10570 {
10571 errmsg ("our_address required");
10572 return -99;
10573 }
10574
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010575 M (L2TPV3_CREATE_TUNNEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010576
10577 clib_memcpy (mp->client_address, client_address.as_u8,
10578 sizeof (mp->client_address));
10579
10580 clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
10581
10582 mp->local_session_id = ntohl (local_session_id);
10583 mp->remote_session_id = ntohl (remote_session_id);
10584 mp->local_cookie = clib_host_to_net_u64 (local_cookie);
10585 mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
10586 mp->l2_sublayer_present = l2_sublayer_present;
10587 mp->is_ipv6 = 1;
10588
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010589 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010590 W (ret);
10591 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010592}
10593
10594static int
10595api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
10596{
10597 unformat_input_t *i = vam->input;
10598 u32 sw_if_index;
10599 u8 sw_if_index_set = 0;
10600 u64 new_local_cookie = 0;
10601 u64 new_remote_cookie = 0;
10602 vl_api_l2tpv3_set_tunnel_cookies_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010603 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010604
10605 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10606 {
10607 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10608 sw_if_index_set = 1;
10609 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10610 sw_if_index_set = 1;
10611 else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
10612 ;
10613 else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
10614 ;
10615 else
10616 break;
10617 }
10618
10619 if (sw_if_index_set == 0)
10620 {
10621 errmsg ("missing interface name or sw_if_index");
10622 return -99;
10623 }
10624
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010625 M (L2TPV3_SET_TUNNEL_COOKIES, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010626
10627 mp->sw_if_index = ntohl (sw_if_index);
10628 mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
10629 mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
10630
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010631 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010632 W (ret);
10633 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010634}
10635
10636static int
10637api_l2tpv3_interface_enable_disable (vat_main_t * vam)
10638{
10639 unformat_input_t *i = vam->input;
10640 vl_api_l2tpv3_interface_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010641 u32 sw_if_index;
10642 u8 sw_if_index_set = 0;
10643 u8 enable_disable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010644 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010645
10646 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10647 {
10648 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10649 sw_if_index_set = 1;
10650 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10651 sw_if_index_set = 1;
10652 else if (unformat (i, "enable"))
10653 enable_disable = 1;
10654 else if (unformat (i, "disable"))
10655 enable_disable = 0;
10656 else
10657 break;
10658 }
10659
10660 if (sw_if_index_set == 0)
10661 {
10662 errmsg ("missing interface name or sw_if_index");
10663 return -99;
10664 }
10665
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010666 M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010667
10668 mp->sw_if_index = ntohl (sw_if_index);
10669 mp->enable_disable = enable_disable;
10670
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010671 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010672 W (ret);
10673 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010674}
10675
10676static int
10677api_l2tpv3_set_lookup_key (vat_main_t * vam)
10678{
10679 unformat_input_t *i = vam->input;
10680 vl_api_l2tpv3_set_lookup_key_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010681 u8 key = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010682 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010683
10684 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10685 {
10686 if (unformat (i, "lookup_v6_src"))
10687 key = L2T_LOOKUP_SRC_ADDRESS;
10688 else if (unformat (i, "lookup_v6_dst"))
10689 key = L2T_LOOKUP_DST_ADDRESS;
10690 else if (unformat (i, "lookup_session_id"))
10691 key = L2T_LOOKUP_SESSION_ID;
10692 else
10693 break;
10694 }
10695
10696 if (key == (u8) ~ 0)
10697 {
10698 errmsg ("l2tp session lookup key unset");
10699 return -99;
10700 }
10701
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010702 M (L2TPV3_SET_LOOKUP_KEY, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010703
10704 mp->key = key;
10705
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010706 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010707 W (ret);
10708 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010709}
10710
10711static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
10712 (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10713{
10714 vat_main_t *vam = &vat_main;
10715
10716 print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
10717 format_ip6_address, mp->our_address,
10718 format_ip6_address, mp->client_address,
10719 clib_net_to_host_u32 (mp->sw_if_index));
10720
10721 print (vam->ofp,
10722 " local cookies %016llx %016llx remote cookie %016llx",
10723 clib_net_to_host_u64 (mp->local_cookie[0]),
10724 clib_net_to_host_u64 (mp->local_cookie[1]),
10725 clib_net_to_host_u64 (mp->remote_cookie));
10726
10727 print (vam->ofp, " local session-id %d remote session-id %d",
10728 clib_net_to_host_u32 (mp->local_session_id),
10729 clib_net_to_host_u32 (mp->remote_session_id));
10730
10731 print (vam->ofp, " l2 specific sublayer %s\n",
10732 mp->l2_sublayer_present ? "preset" : "absent");
10733
10734}
10735
10736static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
10737 (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10738{
10739 vat_main_t *vam = &vat_main;
10740 vat_json_node_t *node = NULL;
10741 struct in6_addr addr;
10742
10743 if (VAT_JSON_ARRAY != vam->json_tree.type)
10744 {
10745 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10746 vat_json_init_array (&vam->json_tree);
10747 }
10748 node = vat_json_array_add (&vam->json_tree);
10749
10750 vat_json_init_object (node);
10751
10752 clib_memcpy (&addr, mp->our_address, sizeof (addr));
10753 vat_json_object_add_ip6 (node, "our_address", addr);
10754 clib_memcpy (&addr, mp->client_address, sizeof (addr));
10755 vat_json_object_add_ip6 (node, "client_address", addr);
10756
10757 vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
10758 vat_json_init_array (lc);
10759 vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
10760 vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
10761 vat_json_object_add_uint (node, "remote_cookie",
10762 clib_net_to_host_u64 (mp->remote_cookie));
10763
10764 printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
10765 vat_json_object_add_uint (node, "local_session_id",
10766 clib_net_to_host_u32 (mp->local_session_id));
10767 vat_json_object_add_uint (node, "remote_session_id",
10768 clib_net_to_host_u32 (mp->remote_session_id));
10769 vat_json_object_add_string_copy (node, "l2_sublayer",
10770 mp->l2_sublayer_present ? (u8 *) "present"
10771 : (u8 *) "absent");
10772}
10773
10774static int
10775api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
10776{
10777 vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010778 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010779 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010780
10781 /* Get list of l2tpv3-tunnel interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010782 M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010783 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010784
10785 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010786 M (CONTROL_PING, mp_ping);
10787 S (mp_ping);
10788
Jon Loeliger56c7b012017-02-01 12:31:41 -060010789 W (ret);
10790 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010791}
10792
10793
10794static void vl_api_sw_interface_tap_details_t_handler
10795 (vl_api_sw_interface_tap_details_t * mp)
10796{
10797 vat_main_t *vam = &vat_main;
10798
10799 print (vam->ofp, "%-16s %d",
10800 mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10801}
10802
10803static void vl_api_sw_interface_tap_details_t_handler_json
10804 (vl_api_sw_interface_tap_details_t * mp)
10805{
10806 vat_main_t *vam = &vat_main;
10807 vat_json_node_t *node = NULL;
10808
10809 if (VAT_JSON_ARRAY != vam->json_tree.type)
10810 {
10811 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10812 vat_json_init_array (&vam->json_tree);
10813 }
10814 node = vat_json_array_add (&vam->json_tree);
10815
10816 vat_json_init_object (node);
10817 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10818 vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10819}
10820
10821static int
10822api_sw_interface_tap_dump (vat_main_t * vam)
10823{
10824 vl_api_sw_interface_tap_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010825 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010826 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010827
10828 print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
10829 /* Get list of tap interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010830 M (SW_INTERFACE_TAP_DUMP, mp);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010831 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010832
10833 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010834 M (CONTROL_PING, mp_ping);
10835 S (mp_ping);
10836
Jon Loeliger56c7b012017-02-01 12:31:41 -060010837 W (ret);
10838 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010839}
10840
10841static uword unformat_vxlan_decap_next
10842 (unformat_input_t * input, va_list * args)
10843{
10844 u32 *result = va_arg (*args, u32 *);
10845 u32 tmp;
10846
10847 if (unformat (input, "l2"))
10848 *result = VXLAN_INPUT_NEXT_L2_INPUT;
10849 else if (unformat (input, "%d", &tmp))
10850 *result = tmp;
10851 else
10852 return 0;
10853 return 1;
10854}
10855
10856static int
10857api_vxlan_add_del_tunnel (vat_main_t * vam)
10858{
10859 unformat_input_t *line_input = vam->input;
10860 vl_api_vxlan_add_del_tunnel_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010861 ip46_address_t src, dst;
10862 u8 is_add = 1;
10863 u8 ipv4_set = 0, ipv6_set = 0;
10864 u8 src_set = 0;
10865 u8 dst_set = 0;
10866 u8 grp_set = 0;
10867 u32 mcast_sw_if_index = ~0;
10868 u32 encap_vrf_id = 0;
10869 u32 decap_next_index = ~0;
10870 u32 vni = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010871 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010872
10873 /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
10874 memset (&src, 0, sizeof src);
10875 memset (&dst, 0, sizeof dst);
10876
10877 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10878 {
10879 if (unformat (line_input, "del"))
10880 is_add = 0;
10881 else
10882 if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
10883 {
10884 ipv4_set = 1;
10885 src_set = 1;
10886 }
10887 else
10888 if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
10889 {
10890 ipv4_set = 1;
10891 dst_set = 1;
10892 }
10893 else
10894 if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
10895 {
10896 ipv6_set = 1;
10897 src_set = 1;
10898 }
10899 else
10900 if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
10901 {
10902 ipv6_set = 1;
10903 dst_set = 1;
10904 }
10905 else if (unformat (line_input, "group %U %U",
10906 unformat_ip4_address, &dst.ip4,
10907 api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10908 {
10909 grp_set = dst_set = 1;
10910 ipv4_set = 1;
10911 }
10912 else if (unformat (line_input, "group %U",
10913 unformat_ip4_address, &dst.ip4))
10914 {
10915 grp_set = dst_set = 1;
10916 ipv4_set = 1;
10917 }
10918 else if (unformat (line_input, "group %U %U",
10919 unformat_ip6_address, &dst.ip6,
10920 api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10921 {
10922 grp_set = dst_set = 1;
10923 ipv6_set = 1;
10924 }
10925 else if (unformat (line_input, "group %U",
10926 unformat_ip6_address, &dst.ip6))
10927 {
10928 grp_set = dst_set = 1;
10929 ipv6_set = 1;
10930 }
10931 else
10932 if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10933 ;
10934 else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10935 ;
10936 else if (unformat (line_input, "decap-next %U",
10937 unformat_vxlan_decap_next, &decap_next_index))
10938 ;
10939 else if (unformat (line_input, "vni %d", &vni))
10940 ;
10941 else
10942 {
10943 errmsg ("parse error '%U'", format_unformat_error, line_input);
10944 return -99;
10945 }
10946 }
10947
10948 if (src_set == 0)
10949 {
10950 errmsg ("tunnel src address not specified");
10951 return -99;
10952 }
10953 if (dst_set == 0)
10954 {
10955 errmsg ("tunnel dst address not specified");
10956 return -99;
10957 }
10958
10959 if (grp_set && !ip46_address_is_multicast (&dst))
10960 {
10961 errmsg ("tunnel group address not multicast");
10962 return -99;
10963 }
10964 if (grp_set && mcast_sw_if_index == ~0)
10965 {
10966 errmsg ("tunnel nonexistent multicast device");
10967 return -99;
10968 }
10969 if (grp_set == 0 && ip46_address_is_multicast (&dst))
10970 {
10971 errmsg ("tunnel dst address must be unicast");
10972 return -99;
10973 }
10974
10975
10976 if (ipv4_set && ipv6_set)
10977 {
10978 errmsg ("both IPv4 and IPv6 addresses specified");
10979 return -99;
10980 }
10981
10982 if ((vni == 0) || (vni >> 24))
10983 {
10984 errmsg ("vni not specified or out of range");
10985 return -99;
10986 }
10987
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010988 M (VXLAN_ADD_DEL_TUNNEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010989
10990 if (ipv6_set)
10991 {
10992 clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
10993 clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
10994 }
10995 else
10996 {
10997 clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
10998 clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
10999 }
11000 mp->encap_vrf_id = ntohl (encap_vrf_id);
11001 mp->decap_next_index = ntohl (decap_next_index);
11002 mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
11003 mp->vni = ntohl (vni);
11004 mp->is_add = is_add;
11005 mp->is_ipv6 = ipv6_set;
11006
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011007 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011008 W (ret);
11009 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011010}
11011
11012static void vl_api_vxlan_tunnel_details_t_handler
11013 (vl_api_vxlan_tunnel_details_t * mp)
11014{
11015 vat_main_t *vam = &vat_main;
Eyal Barie101e1f2017-03-15 08:23:42 +020011016 ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
11017 ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011018
11019 print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
11020 ntohl (mp->sw_if_index),
11021 format_ip46_address, &src, IP46_TYPE_ANY,
11022 format_ip46_address, &dst, IP46_TYPE_ANY,
11023 ntohl (mp->encap_vrf_id),
11024 ntohl (mp->decap_next_index), ntohl (mp->vni),
11025 ntohl (mp->mcast_sw_if_index));
11026}
11027
11028static void vl_api_vxlan_tunnel_details_t_handler_json
11029 (vl_api_vxlan_tunnel_details_t * mp)
11030{
11031 vat_main_t *vam = &vat_main;
11032 vat_json_node_t *node = NULL;
11033
11034 if (VAT_JSON_ARRAY != vam->json_tree.type)
11035 {
11036 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11037 vat_json_init_array (&vam->json_tree);
11038 }
11039 node = vat_json_array_add (&vam->json_tree);
11040
11041 vat_json_init_object (node);
11042 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11043 if (mp->is_ipv6)
11044 {
11045 struct in6_addr ip6;
11046
11047 clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
11048 vat_json_object_add_ip6 (node, "src_address", ip6);
11049 clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
11050 vat_json_object_add_ip6 (node, "dst_address", ip6);
11051 }
11052 else
11053 {
11054 struct in_addr ip4;
11055
11056 clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
11057 vat_json_object_add_ip4 (node, "src_address", ip4);
11058 clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
11059 vat_json_object_add_ip4 (node, "dst_address", ip4);
11060 }
11061 vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11062 vat_json_object_add_uint (node, "decap_next_index",
11063 ntohl (mp->decap_next_index));
11064 vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11065 vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11066 vat_json_object_add_uint (node, "mcast_sw_if_index",
11067 ntohl (mp->mcast_sw_if_index));
11068}
11069
11070static int
11071api_vxlan_tunnel_dump (vat_main_t * vam)
11072{
11073 unformat_input_t *i = vam->input;
11074 vl_api_vxlan_tunnel_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011075 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011076 u32 sw_if_index;
11077 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011078 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011079
11080 /* Parse args required to build the message */
11081 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11082 {
11083 if (unformat (i, "sw_if_index %d", &sw_if_index))
11084 sw_if_index_set = 1;
11085 else
11086 break;
11087 }
11088
11089 if (sw_if_index_set == 0)
11090 {
11091 sw_if_index = ~0;
11092 }
11093
11094 if (!vam->json_output)
11095 {
11096 print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
11097 "sw_if_index", "src_address", "dst_address",
11098 "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
11099 }
11100
11101 /* Get list of vxlan-tunnel interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011102 M (VXLAN_TUNNEL_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011103
11104 mp->sw_if_index = htonl (sw_if_index);
11105
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011106 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011107
11108 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011109 M (CONTROL_PING, mp_ping);
11110 S (mp_ping);
11111
Jon Loeliger56c7b012017-02-01 12:31:41 -060011112 W (ret);
11113 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011114}
11115
11116static int
11117api_gre_add_del_tunnel (vat_main_t * vam)
11118{
11119 unformat_input_t *line_input = vam->input;
11120 vl_api_gre_add_del_tunnel_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011121 ip4_address_t src4, dst4;
Ciara Loftus7eac9162016-09-30 15:47:03 +010011122 ip6_address_t src6, dst6;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011123 u8 is_add = 1;
Ciara Loftus7eac9162016-09-30 15:47:03 +010011124 u8 ipv4_set = 0;
11125 u8 ipv6_set = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011126 u8 teb = 0;
11127 u8 src_set = 0;
11128 u8 dst_set = 0;
11129 u32 outer_fib_id = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011130 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011131
Ciara Loftus7eac9162016-09-30 15:47:03 +010011132 memset (&src4, 0, sizeof src4);
11133 memset (&dst4, 0, sizeof dst4);
11134 memset (&src6, 0, sizeof src6);
11135 memset (&dst6, 0, sizeof dst6);
11136
Damjan Marion7cd468a2016-12-19 23:05:39 +010011137 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11138 {
11139 if (unformat (line_input, "del"))
11140 is_add = 0;
11141 else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
Ciara Loftus7eac9162016-09-30 15:47:03 +010011142 {
11143 src_set = 1;
11144 ipv4_set = 1;
11145 }
Damjan Marion7cd468a2016-12-19 23:05:39 +010011146 else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
Ciara Loftus7eac9162016-09-30 15:47:03 +010011147 {
11148 dst_set = 1;
11149 ipv4_set = 1;
11150 }
11151 else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
11152 {
11153 src_set = 1;
11154 ipv6_set = 1;
11155 }
11156 else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
11157 {
11158 dst_set = 1;
11159 ipv6_set = 1;
11160 }
Damjan Marion7cd468a2016-12-19 23:05:39 +010011161 else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
11162 ;
11163 else if (unformat (line_input, "teb"))
11164 teb = 1;
11165 else
11166 {
11167 errmsg ("parse error '%U'", format_unformat_error, line_input);
11168 return -99;
11169 }
11170 }
11171
11172 if (src_set == 0)
11173 {
11174 errmsg ("tunnel src address not specified");
11175 return -99;
11176 }
11177 if (dst_set == 0)
11178 {
11179 errmsg ("tunnel dst address not specified");
11180 return -99;
11181 }
Ciara Loftus7eac9162016-09-30 15:47:03 +010011182 if (ipv4_set && ipv6_set)
11183 {
11184 errmsg ("both IPv4 and IPv6 addresses specified");
11185 return -99;
11186 }
Damjan Marion7cd468a2016-12-19 23:05:39 +010011187
11188
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011189 M (GRE_ADD_DEL_TUNNEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011190
Ciara Loftus7eac9162016-09-30 15:47:03 +010011191 if (ipv4_set)
11192 {
11193 clib_memcpy (&mp->src_address, &src4, 4);
11194 clib_memcpy (&mp->dst_address, &dst4, 4);
11195 }
11196 else
11197 {
11198 clib_memcpy (&mp->src_address, &src6, 16);
11199 clib_memcpy (&mp->dst_address, &dst6, 16);
11200 }
Damjan Marion7cd468a2016-12-19 23:05:39 +010011201 mp->outer_fib_id = ntohl (outer_fib_id);
11202 mp->is_add = is_add;
11203 mp->teb = teb;
Ciara Loftus7eac9162016-09-30 15:47:03 +010011204 mp->is_ipv6 = ipv6_set;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011205
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011206 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011207 W (ret);
11208 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011209}
11210
11211static void vl_api_gre_tunnel_details_t_handler
11212 (vl_api_gre_tunnel_details_t * mp)
11213{
11214 vat_main_t *vam = &vat_main;
Ciara Loftus7eac9162016-09-30 15:47:03 +010011215 ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
11216 ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011217
Ciara Loftus7eac9162016-09-30 15:47:03 +010011218 print (vam->ofp, "%11d%24U%24U%6d%14d",
Damjan Marion7cd468a2016-12-19 23:05:39 +010011219 ntohl (mp->sw_if_index),
Ciara Loftus7eac9162016-09-30 15:47:03 +010011220 format_ip46_address, &src, IP46_TYPE_ANY,
11221 format_ip46_address, &dst, IP46_TYPE_ANY,
Damjan Marion7cd468a2016-12-19 23:05:39 +010011222 mp->teb, ntohl (mp->outer_fib_id));
11223}
11224
11225static void vl_api_gre_tunnel_details_t_handler_json
11226 (vl_api_gre_tunnel_details_t * mp)
11227{
11228 vat_main_t *vam = &vat_main;
11229 vat_json_node_t *node = NULL;
11230 struct in_addr ip4;
Ciara Loftus7eac9162016-09-30 15:47:03 +010011231 struct in6_addr ip6;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011232
11233 if (VAT_JSON_ARRAY != vam->json_tree.type)
11234 {
11235 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11236 vat_json_init_array (&vam->json_tree);
11237 }
11238 node = vat_json_array_add (&vam->json_tree);
11239
11240 vat_json_init_object (node);
11241 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
Ciara Loftus7eac9162016-09-30 15:47:03 +010011242 if (!mp->is_ipv6)
11243 {
11244 clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
11245 vat_json_object_add_ip4 (node, "src_address", ip4);
11246 clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
11247 vat_json_object_add_ip4 (node, "dst_address", ip4);
11248 }
11249 else
11250 {
11251 clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
11252 vat_json_object_add_ip6 (node, "src_address", ip6);
11253 clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
11254 vat_json_object_add_ip6 (node, "dst_address", ip6);
11255 }
Damjan Marion7cd468a2016-12-19 23:05:39 +010011256 vat_json_object_add_uint (node, "teb", mp->teb);
11257 vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
Ciara Loftus7eac9162016-09-30 15:47:03 +010011258 vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011259}
11260
11261static int
11262api_gre_tunnel_dump (vat_main_t * vam)
11263{
11264 unformat_input_t *i = vam->input;
11265 vl_api_gre_tunnel_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011266 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011267 u32 sw_if_index;
11268 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011269 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011270
11271 /* Parse args required to build the message */
11272 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11273 {
11274 if (unformat (i, "sw_if_index %d", &sw_if_index))
11275 sw_if_index_set = 1;
11276 else
11277 break;
11278 }
11279
11280 if (sw_if_index_set == 0)
11281 {
11282 sw_if_index = ~0;
11283 }
11284
11285 if (!vam->json_output)
11286 {
Ciara Loftus7eac9162016-09-30 15:47:03 +010011287 print (vam->ofp, "%11s%24s%24s%6s%14s",
Damjan Marion7cd468a2016-12-19 23:05:39 +010011288 "sw_if_index", "src_address", "dst_address", "teb",
11289 "outer_fib_id");
11290 }
11291
11292 /* Get list of gre-tunnel interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011293 M (GRE_TUNNEL_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011294
11295 mp->sw_if_index = htonl (sw_if_index);
11296
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011297 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011298
11299 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011300 M (CONTROL_PING, mp_ping);
11301 S (mp_ping);
11302
Jon Loeliger56c7b012017-02-01 12:31:41 -060011303 W (ret);
11304 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011305}
11306
11307static int
11308api_l2_fib_clear_table (vat_main_t * vam)
11309{
11310// unformat_input_t * i = vam->input;
11311 vl_api_l2_fib_clear_table_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011312 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011313
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011314 M (L2_FIB_CLEAR_TABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011315
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011316 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011317 W (ret);
11318 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011319}
11320
11321static int
11322api_l2_interface_efp_filter (vat_main_t * vam)
11323{
11324 unformat_input_t *i = vam->input;
11325 vl_api_l2_interface_efp_filter_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011326 u32 sw_if_index;
11327 u8 enable = 1;
11328 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011329 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011330
11331 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11332 {
11333 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11334 sw_if_index_set = 1;
11335 else if (unformat (i, "sw_if_index %d", &sw_if_index))
11336 sw_if_index_set = 1;
11337 else if (unformat (i, "enable"))
11338 enable = 1;
11339 else if (unformat (i, "disable"))
11340 enable = 0;
11341 else
11342 {
11343 clib_warning ("parse error '%U'", format_unformat_error, i);
11344 return -99;
11345 }
11346 }
11347
11348 if (sw_if_index_set == 0)
11349 {
11350 errmsg ("missing sw_if_index");
11351 return -99;
11352 }
11353
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011354 M (L2_INTERFACE_EFP_FILTER, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011355
11356 mp->sw_if_index = ntohl (sw_if_index);
11357 mp->enable_disable = enable;
11358
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011359 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011360 W (ret);
11361 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011362}
11363
11364#define foreach_vtr_op \
11365_("disable", L2_VTR_DISABLED) \
11366_("push-1", L2_VTR_PUSH_1) \
11367_("push-2", L2_VTR_PUSH_2) \
11368_("pop-1", L2_VTR_POP_1) \
11369_("pop-2", L2_VTR_POP_2) \
11370_("translate-1-1", L2_VTR_TRANSLATE_1_1) \
11371_("translate-1-2", L2_VTR_TRANSLATE_1_2) \
11372_("translate-2-1", L2_VTR_TRANSLATE_2_1) \
11373_("translate-2-2", L2_VTR_TRANSLATE_2_2)
11374
11375static int
11376api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
11377{
11378 unformat_input_t *i = vam->input;
11379 vl_api_l2_interface_vlan_tag_rewrite_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011380 u32 sw_if_index;
11381 u8 sw_if_index_set = 0;
11382 u8 vtr_op_set = 0;
11383 u32 vtr_op = 0;
11384 u32 push_dot1q = 1;
11385 u32 tag1 = ~0;
11386 u32 tag2 = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011387 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011388
11389 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11390 {
11391 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11392 sw_if_index_set = 1;
11393 else if (unformat (i, "sw_if_index %d", &sw_if_index))
11394 sw_if_index_set = 1;
11395 else if (unformat (i, "vtr_op %d", &vtr_op))
11396 vtr_op_set = 1;
11397#define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
11398 foreach_vtr_op
11399#undef _
11400 else if (unformat (i, "push_dot1q %d", &push_dot1q))
11401 ;
11402 else if (unformat (i, "tag1 %d", &tag1))
11403 ;
11404 else if (unformat (i, "tag2 %d", &tag2))
11405 ;
11406 else
11407 {
11408 clib_warning ("parse error '%U'", format_unformat_error, i);
11409 return -99;
11410 }
11411 }
11412
11413 if ((sw_if_index_set == 0) || (vtr_op_set == 0))
11414 {
11415 errmsg ("missing vtr operation or sw_if_index");
11416 return -99;
11417 }
11418
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011419 M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
11420 mp->sw_if_index = ntohl (sw_if_index);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011421 mp->vtr_op = ntohl (vtr_op);
11422 mp->push_dot1q = ntohl (push_dot1q);
11423 mp->tag1 = ntohl (tag1);
11424 mp->tag2 = ntohl (tag2);
11425
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011426 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011427 W (ret);
11428 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011429}
11430
11431static int
11432api_create_vhost_user_if (vat_main_t * vam)
11433{
11434 unformat_input_t *i = vam->input;
11435 vl_api_create_vhost_user_if_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011436 u8 *file_name;
11437 u8 is_server = 0;
11438 u8 file_name_set = 0;
11439 u32 custom_dev_instance = ~0;
11440 u8 hwaddr[6];
11441 u8 use_custom_mac = 0;
11442 u8 *tag = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011443 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011444
11445 /* Shut up coverity */
11446 memset (hwaddr, 0, sizeof (hwaddr));
11447
11448 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11449 {
11450 if (unformat (i, "socket %s", &file_name))
11451 {
11452 file_name_set = 1;
11453 }
11454 else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11455 ;
11456 else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
11457 use_custom_mac = 1;
11458 else if (unformat (i, "server"))
11459 is_server = 1;
11460 else if (unformat (i, "tag %s", &tag))
11461 ;
11462 else
11463 break;
11464 }
11465
11466 if (file_name_set == 0)
11467 {
11468 errmsg ("missing socket file name");
11469 return -99;
11470 }
11471
11472 if (vec_len (file_name) > 255)
11473 {
11474 errmsg ("socket file name too long");
11475 return -99;
11476 }
11477 vec_add1 (file_name, 0);
11478
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011479 M (CREATE_VHOST_USER_IF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011480
11481 mp->is_server = is_server;
11482 clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11483 vec_free (file_name);
11484 if (custom_dev_instance != ~0)
11485 {
11486 mp->renumber = 1;
11487 mp->custom_dev_instance = ntohl (custom_dev_instance);
11488 }
11489 mp->use_custom_mac = use_custom_mac;
11490 clib_memcpy (mp->mac_address, hwaddr, 6);
11491 if (tag)
11492 strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
11493 vec_free (tag);
11494
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011495 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011496 W (ret);
11497 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011498}
11499
11500static int
11501api_modify_vhost_user_if (vat_main_t * vam)
11502{
11503 unformat_input_t *i = vam->input;
11504 vl_api_modify_vhost_user_if_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011505 u8 *file_name;
11506 u8 is_server = 0;
11507 u8 file_name_set = 0;
11508 u32 custom_dev_instance = ~0;
11509 u8 sw_if_index_set = 0;
11510 u32 sw_if_index = (u32) ~ 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011511 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011512
11513 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11514 {
11515 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11516 sw_if_index_set = 1;
11517 else if (unformat (i, "sw_if_index %d", &sw_if_index))
11518 sw_if_index_set = 1;
11519 else if (unformat (i, "socket %s", &file_name))
11520 {
11521 file_name_set = 1;
11522 }
11523 else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11524 ;
11525 else if (unformat (i, "server"))
11526 is_server = 1;
11527 else
11528 break;
11529 }
11530
11531 if (sw_if_index_set == 0)
11532 {
11533 errmsg ("missing sw_if_index or interface name");
11534 return -99;
11535 }
11536
11537 if (file_name_set == 0)
11538 {
11539 errmsg ("missing socket file name");
11540 return -99;
11541 }
11542
11543 if (vec_len (file_name) > 255)
11544 {
11545 errmsg ("socket file name too long");
11546 return -99;
11547 }
11548 vec_add1 (file_name, 0);
11549
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011550 M (MODIFY_VHOST_USER_IF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011551
11552 mp->sw_if_index = ntohl (sw_if_index);
11553 mp->is_server = is_server;
11554 clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11555 vec_free (file_name);
11556 if (custom_dev_instance != ~0)
11557 {
11558 mp->renumber = 1;
11559 mp->custom_dev_instance = ntohl (custom_dev_instance);
11560 }
11561
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011562 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011563 W (ret);
11564 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011565}
11566
11567static int
11568api_delete_vhost_user_if (vat_main_t * vam)
11569{
11570 unformat_input_t *i = vam->input;
11571 vl_api_delete_vhost_user_if_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011572 u32 sw_if_index = ~0;
11573 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011574 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011575
11576 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11577 {
11578 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11579 sw_if_index_set = 1;
11580 else if (unformat (i, "sw_if_index %d", &sw_if_index))
11581 sw_if_index_set = 1;
11582 else
11583 break;
11584 }
11585
11586 if (sw_if_index_set == 0)
11587 {
11588 errmsg ("missing sw_if_index or interface name");
11589 return -99;
11590 }
11591
11592
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011593 M (DELETE_VHOST_USER_IF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011594
11595 mp->sw_if_index = ntohl (sw_if_index);
11596
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011597 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011598 W (ret);
11599 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011600}
11601
11602static void vl_api_sw_interface_vhost_user_details_t_handler
11603 (vl_api_sw_interface_vhost_user_details_t * mp)
11604{
11605 vat_main_t *vam = &vat_main;
11606
Stevenf3b53642017-05-01 14:03:02 -070011607 print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
Damjan Marion7cd468a2016-12-19 23:05:39 +010011608 (char *) mp->interface_name,
11609 ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
11610 clib_net_to_host_u64 (mp->features), mp->is_server,
Stevenf3b53642017-05-01 14:03:02 -070011611 ntohl (mp->num_regions), (char *) mp->sock_filename);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011612 print (vam->ofp, " Status: '%s'", strerror (ntohl (mp->sock_errno)));
11613}
11614
11615static void vl_api_sw_interface_vhost_user_details_t_handler_json
11616 (vl_api_sw_interface_vhost_user_details_t * mp)
11617{
11618 vat_main_t *vam = &vat_main;
11619 vat_json_node_t *node = NULL;
11620
11621 if (VAT_JSON_ARRAY != vam->json_tree.type)
11622 {
11623 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11624 vat_json_init_array (&vam->json_tree);
11625 }
11626 node = vat_json_array_add (&vam->json_tree);
11627
11628 vat_json_init_object (node);
11629 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11630 vat_json_object_add_string_copy (node, "interface_name",
11631 mp->interface_name);
11632 vat_json_object_add_uint (node, "virtio_net_hdr_sz",
11633 ntohl (mp->virtio_net_hdr_sz));
11634 vat_json_object_add_uint (node, "features",
11635 clib_net_to_host_u64 (mp->features));
11636 vat_json_object_add_uint (node, "is_server", mp->is_server);
11637 vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
11638 vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
11639 vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
11640}
11641
11642static int
11643api_sw_interface_vhost_user_dump (vat_main_t * vam)
11644{
11645 vl_api_sw_interface_vhost_user_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011646 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011647 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011648 print (vam->ofp,
Stevenf3b53642017-05-01 14:03:02 -070011649 "Interface name idx hdr_sz features server regions filename");
Damjan Marion7cd468a2016-12-19 23:05:39 +010011650
11651 /* Get list of vhost-user interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011652 M (SW_INTERFACE_VHOST_USER_DUMP, mp);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011653 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011654
11655 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011656 M (CONTROL_PING, mp_ping);
11657 S (mp_ping);
11658
Jon Loeliger56c7b012017-02-01 12:31:41 -060011659 W (ret);
11660 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011661}
11662
11663static int
11664api_show_version (vat_main_t * vam)
11665{
11666 vl_api_show_version_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011667 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011668
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011669 M (SHOW_VERSION, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011670
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011671 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011672 W (ret);
11673 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011674}
11675
11676
11677static int
11678api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
11679{
11680 unformat_input_t *line_input = vam->input;
11681 vl_api_vxlan_gpe_add_del_tunnel_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011682 ip4_address_t local4, remote4;
11683 ip6_address_t local6, remote6;
11684 u8 is_add = 1;
11685 u8 ipv4_set = 0, ipv6_set = 0;
11686 u8 local_set = 0;
11687 u8 remote_set = 0;
11688 u32 encap_vrf_id = 0;
11689 u32 decap_vrf_id = 0;
11690 u8 protocol = ~0;
11691 u32 vni;
11692 u8 vni_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011693 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011694
11695 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11696 {
11697 if (unformat (line_input, "del"))
11698 is_add = 0;
11699 else if (unformat (line_input, "local %U",
11700 unformat_ip4_address, &local4))
11701 {
11702 local_set = 1;
11703 ipv4_set = 1;
11704 }
11705 else if (unformat (line_input, "remote %U",
11706 unformat_ip4_address, &remote4))
11707 {
11708 remote_set = 1;
11709 ipv4_set = 1;
11710 }
11711 else if (unformat (line_input, "local %U",
11712 unformat_ip6_address, &local6))
11713 {
11714 local_set = 1;
11715 ipv6_set = 1;
11716 }
11717 else if (unformat (line_input, "remote %U",
11718 unformat_ip6_address, &remote6))
11719 {
11720 remote_set = 1;
11721 ipv6_set = 1;
11722 }
11723 else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11724 ;
11725 else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
11726 ;
11727 else if (unformat (line_input, "vni %d", &vni))
11728 vni_set = 1;
11729 else if (unformat (line_input, "next-ip4"))
11730 protocol = 1;
11731 else if (unformat (line_input, "next-ip6"))
11732 protocol = 2;
11733 else if (unformat (line_input, "next-ethernet"))
11734 protocol = 3;
11735 else if (unformat (line_input, "next-nsh"))
11736 protocol = 4;
11737 else
11738 {
11739 errmsg ("parse error '%U'", format_unformat_error, line_input);
11740 return -99;
11741 }
11742 }
11743
11744 if (local_set == 0)
11745 {
11746 errmsg ("tunnel local address not specified");
11747 return -99;
11748 }
11749 if (remote_set == 0)
11750 {
11751 errmsg ("tunnel remote address not specified");
11752 return -99;
11753 }
11754 if (ipv4_set && ipv6_set)
11755 {
11756 errmsg ("both IPv4 and IPv6 addresses specified");
11757 return -99;
11758 }
11759
11760 if (vni_set == 0)
11761 {
11762 errmsg ("vni not specified");
11763 return -99;
11764 }
11765
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011766 M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011767
11768
11769 if (ipv6_set)
11770 {
11771 clib_memcpy (&mp->local, &local6, sizeof (local6));
11772 clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
11773 }
11774 else
11775 {
11776 clib_memcpy (&mp->local, &local4, sizeof (local4));
11777 clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
11778 }
11779
11780 mp->encap_vrf_id = ntohl (encap_vrf_id);
11781 mp->decap_vrf_id = ntohl (decap_vrf_id);
11782 mp->protocol = protocol;
11783 mp->vni = ntohl (vni);
11784 mp->is_add = is_add;
11785 mp->is_ipv6 = ipv6_set;
11786
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011787 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011788 W (ret);
11789 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011790}
11791
11792static void vl_api_vxlan_gpe_tunnel_details_t_handler
11793 (vl_api_vxlan_gpe_tunnel_details_t * mp)
11794{
11795 vat_main_t *vam = &vat_main;
11796
11797 print (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d",
11798 ntohl (mp->sw_if_index),
11799 format_ip46_address, &(mp->local[0]),
11800 format_ip46_address, &(mp->remote[0]),
11801 ntohl (mp->vni),
11802 ntohl (mp->protocol),
11803 ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
11804}
11805
11806static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
11807 (vl_api_vxlan_gpe_tunnel_details_t * mp)
11808{
11809 vat_main_t *vam = &vat_main;
11810 vat_json_node_t *node = NULL;
11811 struct in_addr ip4;
11812 struct in6_addr ip6;
11813
11814 if (VAT_JSON_ARRAY != vam->json_tree.type)
11815 {
11816 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11817 vat_json_init_array (&vam->json_tree);
11818 }
11819 node = vat_json_array_add (&vam->json_tree);
11820
11821 vat_json_init_object (node);
11822 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11823 if (mp->is_ipv6)
11824 {
11825 clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
11826 vat_json_object_add_ip6 (node, "local", ip6);
11827 clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
11828 vat_json_object_add_ip6 (node, "remote", ip6);
11829 }
11830 else
11831 {
11832 clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
11833 vat_json_object_add_ip4 (node, "local", ip4);
11834 clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
11835 vat_json_object_add_ip4 (node, "remote", ip4);
11836 }
11837 vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11838 vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
11839 vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11840 vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
11841 vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11842}
11843
11844static int
11845api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
11846{
11847 unformat_input_t *i = vam->input;
11848 vl_api_vxlan_gpe_tunnel_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011849 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011850 u32 sw_if_index;
11851 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011852 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011853
11854 /* Parse args required to build the message */
11855 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11856 {
11857 if (unformat (i, "sw_if_index %d", &sw_if_index))
11858 sw_if_index_set = 1;
11859 else
11860 break;
11861 }
11862
11863 if (sw_if_index_set == 0)
11864 {
11865 sw_if_index = ~0;
11866 }
11867
11868 if (!vam->json_output)
11869 {
11870 print (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s",
11871 "sw_if_index", "local", "remote", "vni",
11872 "protocol", "encap_vrf_id", "decap_vrf_id");
11873 }
11874
11875 /* Get list of vxlan-tunnel interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011876 M (VXLAN_GPE_TUNNEL_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011877
11878 mp->sw_if_index = htonl (sw_if_index);
11879
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011880 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011881
11882 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011883 M (CONTROL_PING, mp_ping);
11884 S (mp_ping);
11885
Jon Loeliger56c7b012017-02-01 12:31:41 -060011886 W (ret);
11887 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011888}
11889
11890u8 *
11891format_l2_fib_mac_address (u8 * s, va_list * args)
11892{
11893 u8 *a = va_arg (*args, u8 *);
11894
11895 return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11896 a[2], a[3], a[4], a[5], a[6], a[7]);
11897}
11898
Ole Troan01384fe2017-05-12 11:55:35 +020011899static void vl_api_l2_fib_table_details_t_handler
11900 (vl_api_l2_fib_table_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010011901{
11902 vat_main_t *vam = &vat_main;
11903
11904 print (vam->ofp, "%3" PRIu32 " %U %3" PRIu32
11905 " %d %d %d",
11906 ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11907 ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11908 mp->bvi_mac);
11909}
11910
Ole Troan01384fe2017-05-12 11:55:35 +020011911static void vl_api_l2_fib_table_details_t_handler_json
11912 (vl_api_l2_fib_table_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010011913{
11914 vat_main_t *vam = &vat_main;
11915 vat_json_node_t *node = NULL;
11916
11917 if (VAT_JSON_ARRAY != vam->json_tree.type)
11918 {
11919 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11920 vat_json_init_array (&vam->json_tree);
11921 }
11922 node = vat_json_array_add (&vam->json_tree);
11923
11924 vat_json_init_object (node);
11925 vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11926 vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11927 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11928 vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11929 vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11930 vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11931}
11932
11933static int
11934api_l2_fib_table_dump (vat_main_t * vam)
11935{
11936 unformat_input_t *i = vam->input;
11937 vl_api_l2_fib_table_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011938 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011939 u32 bd_id;
11940 u8 bd_id_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011941 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011942
11943 /* Parse args required to build the message */
11944 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11945 {
11946 if (unformat (i, "bd_id %d", &bd_id))
11947 bd_id_set = 1;
11948 else
11949 break;
11950 }
11951
11952 if (bd_id_set == 0)
11953 {
11954 errmsg ("missing bridge domain");
11955 return -99;
11956 }
11957
11958 print (vam->ofp, "BD-ID Mac Address sw-ndx Static Filter BVI");
11959
11960 /* Get list of l2 fib entries */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011961 M (L2_FIB_TABLE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011962
11963 mp->bd_id = ntohl (bd_id);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011964 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011965
11966 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011967 M (CONTROL_PING, mp_ping);
11968 S (mp_ping);
11969
Jon Loeliger56c7b012017-02-01 12:31:41 -060011970 W (ret);
11971 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011972}
11973
11974
11975static int
11976api_interface_name_renumber (vat_main_t * vam)
11977{
11978 unformat_input_t *line_input = vam->input;
11979 vl_api_interface_name_renumber_t *mp;
11980 u32 sw_if_index = ~0;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011981 u32 new_show_dev_instance = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011982 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011983
11984 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11985 {
11986 if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
11987 &sw_if_index))
11988 ;
11989 else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11990 ;
11991 else if (unformat (line_input, "new_show_dev_instance %d",
11992 &new_show_dev_instance))
11993 ;
11994 else
11995 break;
11996 }
11997
11998 if (sw_if_index == ~0)
11999 {
12000 errmsg ("missing interface name or sw_if_index");
12001 return -99;
12002 }
12003
12004 if (new_show_dev_instance == ~0)
12005 {
12006 errmsg ("missing new_show_dev_instance");
12007 return -99;
12008 }
12009
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012010 M (INTERFACE_NAME_RENUMBER, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012011
12012 mp->sw_if_index = ntohl (sw_if_index);
12013 mp->new_show_dev_instance = ntohl (new_show_dev_instance);
12014
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012015 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012016 W (ret);
12017 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012018}
12019
12020static int
12021api_want_ip4_arp_events (vat_main_t * vam)
12022{
12023 unformat_input_t *line_input = vam->input;
12024 vl_api_want_ip4_arp_events_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012025 ip4_address_t address;
12026 int address_set = 0;
12027 u32 enable_disable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012028 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012029
12030 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12031 {
12032 if (unformat (line_input, "address %U", unformat_ip4_address, &address))
12033 address_set = 1;
12034 else if (unformat (line_input, "del"))
12035 enable_disable = 0;
12036 else
12037 break;
12038 }
12039
12040 if (address_set == 0)
12041 {
12042 errmsg ("missing addresses");
12043 return -99;
12044 }
12045
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012046 M (WANT_IP4_ARP_EVENTS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012047 mp->enable_disable = enable_disable;
John Lo20e1f2a2017-03-29 13:35:43 -040012048 mp->pid = htonl (getpid ());
Damjan Marion7cd468a2016-12-19 23:05:39 +010012049 mp->address = address.as_u32;
12050
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012051 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012052 W (ret);
12053 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012054}
12055
12056static int
12057api_want_ip6_nd_events (vat_main_t * vam)
12058{
12059 unformat_input_t *line_input = vam->input;
12060 vl_api_want_ip6_nd_events_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012061 ip6_address_t address;
12062 int address_set = 0;
12063 u32 enable_disable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012064 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012065
12066 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12067 {
12068 if (unformat (line_input, "address %U", unformat_ip6_address, &address))
12069 address_set = 1;
12070 else if (unformat (line_input, "del"))
12071 enable_disable = 0;
12072 else
12073 break;
12074 }
12075
12076 if (address_set == 0)
12077 {
12078 errmsg ("missing addresses");
12079 return -99;
12080 }
12081
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012082 M (WANT_IP6_ND_EVENTS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012083 mp->enable_disable = enable_disable;
John Lo20e1f2a2017-03-29 13:35:43 -040012084 mp->pid = htonl (getpid ());
Damjan Marion7cd468a2016-12-19 23:05:39 +010012085 clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
12086
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012087 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012088 W (ret);
12089 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012090}
12091
12092static int
12093api_input_acl_set_interface (vat_main_t * vam)
12094{
12095 unformat_input_t *i = vam->input;
12096 vl_api_input_acl_set_interface_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012097 u32 sw_if_index;
12098 int sw_if_index_set;
12099 u32 ip4_table_index = ~0;
12100 u32 ip6_table_index = ~0;
12101 u32 l2_table_index = ~0;
12102 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012103 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012104
12105 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12106 {
12107 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12108 sw_if_index_set = 1;
12109 else if (unformat (i, "sw_if_index %d", &sw_if_index))
12110 sw_if_index_set = 1;
12111 else if (unformat (i, "del"))
12112 is_add = 0;
12113 else if (unformat (i, "ip4-table %d", &ip4_table_index))
12114 ;
12115 else if (unformat (i, "ip6-table %d", &ip6_table_index))
12116 ;
12117 else if (unformat (i, "l2-table %d", &l2_table_index))
12118 ;
12119 else
12120 {
12121 clib_warning ("parse error '%U'", format_unformat_error, i);
12122 return -99;
12123 }
12124 }
12125
12126 if (sw_if_index_set == 0)
12127 {
12128 errmsg ("missing interface name or sw_if_index");
12129 return -99;
12130 }
12131
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012132 M (INPUT_ACL_SET_INTERFACE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012133
12134 mp->sw_if_index = ntohl (sw_if_index);
12135 mp->ip4_table_index = ntohl (ip4_table_index);
12136 mp->ip6_table_index = ntohl (ip6_table_index);
12137 mp->l2_table_index = ntohl (l2_table_index);
12138 mp->is_add = is_add;
12139
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012140 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012141 W (ret);
12142 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012143}
12144
12145static int
12146api_ip_address_dump (vat_main_t * vam)
12147{
12148 unformat_input_t *i = vam->input;
12149 vl_api_ip_address_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012150 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012151 u32 sw_if_index = ~0;
12152 u8 sw_if_index_set = 0;
12153 u8 ipv4_set = 0;
12154 u8 ipv6_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012155 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012156
12157 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12158 {
12159 if (unformat (i, "sw_if_index %d", &sw_if_index))
12160 sw_if_index_set = 1;
12161 else
12162 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12163 sw_if_index_set = 1;
12164 else if (unformat (i, "ipv4"))
12165 ipv4_set = 1;
12166 else if (unformat (i, "ipv6"))
12167 ipv6_set = 1;
12168 else
12169 break;
12170 }
12171
12172 if (ipv4_set && ipv6_set)
12173 {
12174 errmsg ("ipv4 and ipv6 flags cannot be both set");
12175 return -99;
12176 }
12177
12178 if ((!ipv4_set) && (!ipv6_set))
12179 {
12180 errmsg ("no ipv4 nor ipv6 flag set");
12181 return -99;
12182 }
12183
12184 if (sw_if_index_set == 0)
12185 {
12186 errmsg ("missing interface name or sw_if_index");
12187 return -99;
12188 }
12189
12190 vam->current_sw_if_index = sw_if_index;
12191 vam->is_ipv6 = ipv6_set;
12192
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012193 M (IP_ADDRESS_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012194 mp->sw_if_index = ntohl (sw_if_index);
12195 mp->is_ipv6 = ipv6_set;
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012196 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012197
12198 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012199 M (CONTROL_PING, mp_ping);
12200 S (mp_ping);
12201
Jon Loeliger56c7b012017-02-01 12:31:41 -060012202 W (ret);
12203 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012204}
12205
12206static int
12207api_ip_dump (vat_main_t * vam)
12208{
12209 vl_api_ip_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012210 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012211 unformat_input_t *in = vam->input;
12212 int ipv4_set = 0;
12213 int ipv6_set = 0;
12214 int is_ipv6;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012215 int i;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012216 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012217
12218 while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
12219 {
12220 if (unformat (in, "ipv4"))
12221 ipv4_set = 1;
12222 else if (unformat (in, "ipv6"))
12223 ipv6_set = 1;
12224 else
12225 break;
12226 }
12227
12228 if (ipv4_set && ipv6_set)
12229 {
12230 errmsg ("ipv4 and ipv6 flags cannot be both set");
12231 return -99;
12232 }
12233
12234 if ((!ipv4_set) && (!ipv6_set))
12235 {
12236 errmsg ("no ipv4 nor ipv6 flag set");
12237 return -99;
12238 }
12239
12240 is_ipv6 = ipv6_set;
12241 vam->is_ipv6 = is_ipv6;
12242
12243 /* free old data */
12244 for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
12245 {
12246 vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
12247 }
12248 vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
12249
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012250 M (IP_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012251 mp->is_ipv6 = ipv6_set;
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012252 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012253
12254 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012255 M (CONTROL_PING, mp_ping);
12256 S (mp_ping);
12257
Jon Loeliger56c7b012017-02-01 12:31:41 -060012258 W (ret);
12259 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012260}
12261
12262static int
12263api_ipsec_spd_add_del (vat_main_t * vam)
12264{
12265 unformat_input_t *i = vam->input;
12266 vl_api_ipsec_spd_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012267 u32 spd_id = ~0;
12268 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012269 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012270
12271 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12272 {
12273 if (unformat (i, "spd_id %d", &spd_id))
12274 ;
12275 else if (unformat (i, "del"))
12276 is_add = 0;
12277 else
12278 {
12279 clib_warning ("parse error '%U'", format_unformat_error, i);
12280 return -99;
12281 }
12282 }
12283 if (spd_id == ~0)
12284 {
12285 errmsg ("spd_id must be set");
12286 return -99;
12287 }
12288
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012289 M (IPSEC_SPD_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012290
12291 mp->spd_id = ntohl (spd_id);
12292 mp->is_add = is_add;
12293
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012294 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012295 W (ret);
12296 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012297}
12298
12299static int
12300api_ipsec_interface_add_del_spd (vat_main_t * vam)
12301{
12302 unformat_input_t *i = vam->input;
12303 vl_api_ipsec_interface_add_del_spd_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012304 u32 sw_if_index;
12305 u8 sw_if_index_set = 0;
12306 u32 spd_id = (u32) ~ 0;
12307 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012308 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012309
12310 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12311 {
12312 if (unformat (i, "del"))
12313 is_add = 0;
12314 else if (unformat (i, "spd_id %d", &spd_id))
12315 ;
12316 else
12317 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12318 sw_if_index_set = 1;
12319 else if (unformat (i, "sw_if_index %d", &sw_if_index))
12320 sw_if_index_set = 1;
12321 else
12322 {
12323 clib_warning ("parse error '%U'", format_unformat_error, i);
12324 return -99;
12325 }
12326
12327 }
12328
12329 if (spd_id == (u32) ~ 0)
12330 {
12331 errmsg ("spd_id must be set");
12332 return -99;
12333 }
12334
12335 if (sw_if_index_set == 0)
12336 {
12337 errmsg ("missing interface name or sw_if_index");
12338 return -99;
12339 }
12340
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012341 M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012342
12343 mp->spd_id = ntohl (spd_id);
12344 mp->sw_if_index = ntohl (sw_if_index);
12345 mp->is_add = is_add;
12346
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012347 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012348 W (ret);
12349 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012350}
12351
12352static int
12353api_ipsec_spd_add_del_entry (vat_main_t * vam)
12354{
12355 unformat_input_t *i = vam->input;
12356 vl_api_ipsec_spd_add_del_entry_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012357 u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
12358 u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
12359 i32 priority = 0;
12360 u32 rport_start = 0, rport_stop = (u32) ~ 0;
12361 u32 lport_start = 0, lport_stop = (u32) ~ 0;
12362 ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
12363 ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012364 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012365
12366 laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
12367 laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
12368 laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
12369 laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
12370 laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
12371 laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
12372
12373 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12374 {
12375 if (unformat (i, "del"))
12376 is_add = 0;
12377 if (unformat (i, "outbound"))
12378 is_outbound = 1;
12379 if (unformat (i, "inbound"))
12380 is_outbound = 0;
12381 else if (unformat (i, "spd_id %d", &spd_id))
12382 ;
12383 else if (unformat (i, "sa_id %d", &sa_id))
12384 ;
12385 else if (unformat (i, "priority %d", &priority))
12386 ;
12387 else if (unformat (i, "protocol %d", &protocol))
12388 ;
12389 else if (unformat (i, "lport_start %d", &lport_start))
12390 ;
12391 else if (unformat (i, "lport_stop %d", &lport_stop))
12392 ;
12393 else if (unformat (i, "rport_start %d", &rport_start))
12394 ;
12395 else if (unformat (i, "rport_stop %d", &rport_stop))
12396 ;
12397 else
12398 if (unformat
12399 (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
12400 {
12401 is_ipv6 = 0;
12402 is_ip_any = 0;
12403 }
12404 else
12405 if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
12406 {
12407 is_ipv6 = 0;
12408 is_ip_any = 0;
12409 }
12410 else
12411 if (unformat
12412 (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
12413 {
12414 is_ipv6 = 0;
12415 is_ip_any = 0;
12416 }
12417 else
12418 if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
12419 {
12420 is_ipv6 = 0;
12421 is_ip_any = 0;
12422 }
12423 else
12424 if (unformat
12425 (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
12426 {
12427 is_ipv6 = 1;
12428 is_ip_any = 0;
12429 }
12430 else
12431 if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
12432 {
12433 is_ipv6 = 1;
12434 is_ip_any = 0;
12435 }
12436 else
12437 if (unformat
12438 (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
12439 {
12440 is_ipv6 = 1;
12441 is_ip_any = 0;
12442 }
12443 else
12444 if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
12445 {
12446 is_ipv6 = 1;
12447 is_ip_any = 0;
12448 }
12449 else
12450 if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
12451 {
12452 if (policy == IPSEC_POLICY_ACTION_RESOLVE)
12453 {
12454 clib_warning ("unsupported action: 'resolve'");
12455 return -99;
12456 }
12457 }
12458 else
12459 {
12460 clib_warning ("parse error '%U'", format_unformat_error, i);
12461 return -99;
12462 }
12463
12464 }
12465
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012466 M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012467
12468 mp->spd_id = ntohl (spd_id);
12469 mp->priority = ntohl (priority);
12470 mp->is_outbound = is_outbound;
12471
12472 mp->is_ipv6 = is_ipv6;
12473 if (is_ipv6 || is_ip_any)
12474 {
12475 clib_memcpy (mp->remote_address_start, &raddr6_start,
12476 sizeof (ip6_address_t));
12477 clib_memcpy (mp->remote_address_stop, &raddr6_stop,
12478 sizeof (ip6_address_t));
12479 clib_memcpy (mp->local_address_start, &laddr6_start,
12480 sizeof (ip6_address_t));
12481 clib_memcpy (mp->local_address_stop, &laddr6_stop,
12482 sizeof (ip6_address_t));
12483 }
12484 else
12485 {
12486 clib_memcpy (mp->remote_address_start, &raddr4_start,
12487 sizeof (ip4_address_t));
12488 clib_memcpy (mp->remote_address_stop, &raddr4_stop,
12489 sizeof (ip4_address_t));
12490 clib_memcpy (mp->local_address_start, &laddr4_start,
12491 sizeof (ip4_address_t));
12492 clib_memcpy (mp->local_address_stop, &laddr4_stop,
12493 sizeof (ip4_address_t));
12494 }
12495 mp->protocol = (u8) protocol;
12496 mp->local_port_start = ntohs ((u16) lport_start);
12497 mp->local_port_stop = ntohs ((u16) lport_stop);
12498 mp->remote_port_start = ntohs ((u16) rport_start);
12499 mp->remote_port_stop = ntohs ((u16) rport_stop);
12500 mp->policy = (u8) policy;
12501 mp->sa_id = ntohl (sa_id);
12502 mp->is_add = is_add;
12503 mp->is_ip_any = is_ip_any;
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012504 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012505 W (ret);
12506 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012507}
12508
12509static int
12510api_ipsec_sad_add_del_entry (vat_main_t * vam)
12511{
12512 unformat_input_t *i = vam->input;
12513 vl_api_ipsec_sad_add_del_entry_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012514 u32 sad_id = 0, spi = 0;
12515 u8 *ck = 0, *ik = 0;
12516 u8 is_add = 1;
12517
12518 u8 protocol = IPSEC_PROTOCOL_AH;
12519 u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
12520 u32 crypto_alg = 0, integ_alg = 0;
12521 ip4_address_t tun_src4;
12522 ip4_address_t tun_dst4;
12523 ip6_address_t tun_src6;
12524 ip6_address_t tun_dst6;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012525 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012526
12527 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12528 {
12529 if (unformat (i, "del"))
12530 is_add = 0;
12531 else if (unformat (i, "sad_id %d", &sad_id))
12532 ;
12533 else if (unformat (i, "spi %d", &spi))
12534 ;
12535 else if (unformat (i, "esp"))
12536 protocol = IPSEC_PROTOCOL_ESP;
12537 else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
12538 {
12539 is_tunnel = 1;
12540 is_tunnel_ipv6 = 0;
12541 }
12542 else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
12543 {
12544 is_tunnel = 1;
12545 is_tunnel_ipv6 = 0;
12546 }
12547 else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
12548 {
12549 is_tunnel = 1;
12550 is_tunnel_ipv6 = 1;
12551 }
12552 else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
12553 {
12554 is_tunnel = 1;
12555 is_tunnel_ipv6 = 1;
12556 }
12557 else
12558 if (unformat
12559 (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
12560 {
12561 if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
12562 crypto_alg >= IPSEC_CRYPTO_N_ALG)
12563 {
12564 clib_warning ("unsupported crypto-alg: '%U'",
12565 format_ipsec_crypto_alg, crypto_alg);
12566 return -99;
12567 }
12568 }
12569 else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12570 ;
12571 else
12572 if (unformat
12573 (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
12574 {
Damjan Marion7cd468a2016-12-19 23:05:39 +010012575 if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
Damjan Marion7cd468a2016-12-19 23:05:39 +010012576 integ_alg >= IPSEC_INTEG_N_ALG)
12577 {
12578 clib_warning ("unsupported integ-alg: '%U'",
12579 format_ipsec_integ_alg, integ_alg);
12580 return -99;
12581 }
12582 }
12583 else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12584 ;
12585 else
12586 {
12587 clib_warning ("parse error '%U'", format_unformat_error, i);
12588 return -99;
12589 }
12590
12591 }
12592
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012593 M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012594
12595 mp->sad_id = ntohl (sad_id);
12596 mp->is_add = is_add;
12597 mp->protocol = protocol;
12598 mp->spi = ntohl (spi);
12599 mp->is_tunnel = is_tunnel;
12600 mp->is_tunnel_ipv6 = is_tunnel_ipv6;
12601 mp->crypto_algorithm = crypto_alg;
12602 mp->integrity_algorithm = integ_alg;
12603 mp->crypto_key_length = vec_len (ck);
12604 mp->integrity_key_length = vec_len (ik);
12605
12606 if (mp->crypto_key_length > sizeof (mp->crypto_key))
12607 mp->crypto_key_length = sizeof (mp->crypto_key);
12608
12609 if (mp->integrity_key_length > sizeof (mp->integrity_key))
12610 mp->integrity_key_length = sizeof (mp->integrity_key);
12611
12612 if (ck)
12613 clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12614 if (ik)
12615 clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12616
12617 if (is_tunnel)
12618 {
12619 if (is_tunnel_ipv6)
12620 {
12621 clib_memcpy (mp->tunnel_src_address, &tun_src6,
12622 sizeof (ip6_address_t));
12623 clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
12624 sizeof (ip6_address_t));
12625 }
12626 else
12627 {
12628 clib_memcpy (mp->tunnel_src_address, &tun_src4,
12629 sizeof (ip4_address_t));
12630 clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
12631 sizeof (ip4_address_t));
12632 }
12633 }
12634
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012635 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012636 W (ret);
12637 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012638}
12639
12640static int
12641api_ipsec_sa_set_key (vat_main_t * vam)
12642{
12643 unformat_input_t *i = vam->input;
12644 vl_api_ipsec_sa_set_key_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012645 u32 sa_id;
12646 u8 *ck = 0, *ik = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012647 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012648
12649 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12650 {
12651 if (unformat (i, "sa_id %d", &sa_id))
12652 ;
12653 else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12654 ;
12655 else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12656 ;
12657 else
12658 {
12659 clib_warning ("parse error '%U'", format_unformat_error, i);
12660 return -99;
12661 }
12662 }
12663
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012664 M (IPSEC_SA_SET_KEY, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012665
12666 mp->sa_id = ntohl (sa_id);
12667 mp->crypto_key_length = vec_len (ck);
12668 mp->integrity_key_length = vec_len (ik);
12669
12670 if (mp->crypto_key_length > sizeof (mp->crypto_key))
12671 mp->crypto_key_length = sizeof (mp->crypto_key);
12672
12673 if (mp->integrity_key_length > sizeof (mp->integrity_key))
12674 mp->integrity_key_length = sizeof (mp->integrity_key);
12675
12676 if (ck)
12677 clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12678 if (ik)
12679 clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12680
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012681 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012682 W (ret);
12683 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012684}
12685
12686static int
Matthew Smithb0972cb2017-05-02 16:20:41 -050012687api_ipsec_tunnel_if_add_del (vat_main_t * vam)
12688{
12689 unformat_input_t *i = vam->input;
12690 vl_api_ipsec_tunnel_if_add_del_t *mp;
12691 u32 local_spi = 0, remote_spi = 0;
12692 u32 crypto_alg = 0, integ_alg = 0;
12693 u8 *lck = NULL, *rck = NULL;
12694 u8 *lik = NULL, *rik = NULL;
12695 ip4_address_t local_ip = { {0} };
12696 ip4_address_t remote_ip = { {0} };
12697 u8 is_add = 1;
12698 u8 esn = 0;
12699 u8 anti_replay = 0;
12700 int ret;
12701
12702 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12703 {
12704 if (unformat (i, "del"))
12705 is_add = 0;
12706 else if (unformat (i, "esn"))
12707 esn = 1;
12708 else if (unformat (i, "anti_replay"))
12709 anti_replay = 1;
12710 else if (unformat (i, "local_spi %d", &local_spi))
12711 ;
12712 else if (unformat (i, "remote_spi %d", &remote_spi))
12713 ;
12714 else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
12715 ;
12716 else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
12717 ;
12718 else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
12719 ;
12720 else
12721 if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
12722 ;
12723 else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
12724 ;
12725 else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
12726 ;
12727 else
12728 if (unformat
12729 (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
12730 {
12731 if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
12732 crypto_alg >= IPSEC_CRYPTO_N_ALG)
12733 {
12734 errmsg ("unsupported crypto-alg: '%U'\n",
12735 format_ipsec_crypto_alg, crypto_alg);
12736 return -99;
12737 }
12738 }
12739 else
12740 if (unformat
12741 (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
12742 {
12743 if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
12744 integ_alg >= IPSEC_INTEG_N_ALG)
12745 {
12746 errmsg ("unsupported integ-alg: '%U'\n",
12747 format_ipsec_integ_alg, integ_alg);
12748 return -99;
12749 }
12750 }
12751 else
12752 {
12753 errmsg ("parse error '%U'\n", format_unformat_error, i);
12754 return -99;
12755 }
12756 }
12757
12758 M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
12759
12760 mp->is_add = is_add;
12761 mp->esn = esn;
12762 mp->anti_replay = anti_replay;
12763
12764 clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
12765 clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
12766
12767 mp->local_spi = htonl (local_spi);
12768 mp->remote_spi = htonl (remote_spi);
12769 mp->crypto_alg = (u8) crypto_alg;
12770
12771 mp->local_crypto_key_len = 0;
12772 if (lck)
12773 {
12774 mp->local_crypto_key_len = vec_len (lck);
12775 if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
12776 mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
12777 clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
12778 }
12779
12780 mp->remote_crypto_key_len = 0;
12781 if (rck)
12782 {
12783 mp->remote_crypto_key_len = vec_len (rck);
12784 if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
12785 mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
12786 clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
12787 }
12788
12789 mp->integ_alg = (u8) integ_alg;
12790
12791 mp->local_integ_key_len = 0;
12792 if (lik)
12793 {
12794 mp->local_integ_key_len = vec_len (lik);
12795 if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
12796 mp->local_integ_key_len = sizeof (mp->local_integ_key);
12797 clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
12798 }
12799
12800 mp->remote_integ_key_len = 0;
12801 if (rik)
12802 {
12803 mp->remote_integ_key_len = vec_len (rik);
12804 if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
12805 mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
12806 clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
12807 }
12808
12809 S (mp);
12810 W (ret);
12811 return ret;
12812}
12813
12814static int
Damjan Marion7cd468a2016-12-19 23:05:39 +010012815api_ikev2_profile_add_del (vat_main_t * vam)
12816{
12817 unformat_input_t *i = vam->input;
12818 vl_api_ikev2_profile_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012819 u8 is_add = 1;
12820 u8 *name = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012821 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012822
12823 const char *valid_chars = "a-zA-Z0-9_";
12824
12825 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12826 {
12827 if (unformat (i, "del"))
12828 is_add = 0;
12829 else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12830 vec_add1 (name, 0);
12831 else
12832 {
12833 errmsg ("parse error '%U'", format_unformat_error, i);
12834 return -99;
12835 }
12836 }
12837
12838 if (!vec_len (name))
12839 {
12840 errmsg ("profile name must be specified");
12841 return -99;
12842 }
12843
12844 if (vec_len (name) > 64)
12845 {
12846 errmsg ("profile name too long");
12847 return -99;
12848 }
12849
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012850 M (IKEV2_PROFILE_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012851
12852 clib_memcpy (mp->name, name, vec_len (name));
12853 mp->is_add = is_add;
12854 vec_free (name);
12855
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012856 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012857 W (ret);
12858 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012859}
12860
12861static int
12862api_ikev2_profile_set_auth (vat_main_t * vam)
12863{
12864 unformat_input_t *i = vam->input;
12865 vl_api_ikev2_profile_set_auth_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012866 u8 *name = 0;
12867 u8 *data = 0;
12868 u32 auth_method = 0;
12869 u8 is_hex = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012870 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012871
12872 const char *valid_chars = "a-zA-Z0-9_";
12873
12874 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12875 {
12876 if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12877 vec_add1 (name, 0);
12878 else if (unformat (i, "auth_method %U",
12879 unformat_ikev2_auth_method, &auth_method))
12880 ;
12881 else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
12882 is_hex = 1;
12883 else if (unformat (i, "auth_data %v", &data))
12884 ;
12885 else
12886 {
12887 errmsg ("parse error '%U'", format_unformat_error, i);
12888 return -99;
12889 }
12890 }
12891
12892 if (!vec_len (name))
12893 {
12894 errmsg ("profile name must be specified");
12895 return -99;
12896 }
12897
12898 if (vec_len (name) > 64)
12899 {
12900 errmsg ("profile name too long");
12901 return -99;
12902 }
12903
12904 if (!vec_len (data))
12905 {
12906 errmsg ("auth_data must be specified");
12907 return -99;
12908 }
12909
12910 if (!auth_method)
12911 {
12912 errmsg ("auth_method must be specified");
12913 return -99;
12914 }
12915
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012916 M (IKEV2_PROFILE_SET_AUTH, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012917
12918 mp->is_hex = is_hex;
12919 mp->auth_method = (u8) auth_method;
12920 mp->data_len = vec_len (data);
12921 clib_memcpy (mp->name, name, vec_len (name));
12922 clib_memcpy (mp->data, data, vec_len (data));
12923 vec_free (name);
12924 vec_free (data);
12925
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012926 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012927 W (ret);
12928 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012929}
12930
12931static int
12932api_ikev2_profile_set_id (vat_main_t * vam)
12933{
12934 unformat_input_t *i = vam->input;
12935 vl_api_ikev2_profile_set_id_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012936 u8 *name = 0;
12937 u8 *data = 0;
12938 u8 is_local = 0;
12939 u32 id_type = 0;
12940 ip4_address_t ip4;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012941 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012942
12943 const char *valid_chars = "a-zA-Z0-9_";
12944
12945 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12946 {
12947 if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12948 vec_add1 (name, 0);
12949 else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
12950 ;
12951 else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
12952 {
12953 data = vec_new (u8, 4);
12954 clib_memcpy (data, ip4.as_u8, 4);
12955 }
12956 else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
12957 ;
12958 else if (unformat (i, "id_data %v", &data))
12959 ;
12960 else if (unformat (i, "local"))
12961 is_local = 1;
12962 else if (unformat (i, "remote"))
12963 is_local = 0;
12964 else
12965 {
12966 errmsg ("parse error '%U'", format_unformat_error, i);
12967 return -99;
12968 }
12969 }
12970
12971 if (!vec_len (name))
12972 {
12973 errmsg ("profile name must be specified");
12974 return -99;
12975 }
12976
12977 if (vec_len (name) > 64)
12978 {
12979 errmsg ("profile name too long");
12980 return -99;
12981 }
12982
12983 if (!vec_len (data))
12984 {
12985 errmsg ("id_data must be specified");
12986 return -99;
12987 }
12988
12989 if (!id_type)
12990 {
12991 errmsg ("id_type must be specified");
12992 return -99;
12993 }
12994
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012995 M (IKEV2_PROFILE_SET_ID, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012996
12997 mp->is_local = is_local;
12998 mp->id_type = (u8) id_type;
12999 mp->data_len = vec_len (data);
13000 clib_memcpy (mp->name, name, vec_len (name));
13001 clib_memcpy (mp->data, data, vec_len (data));
13002 vec_free (name);
13003 vec_free (data);
13004
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013005 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013006 W (ret);
13007 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013008}
13009
13010static int
13011api_ikev2_profile_set_ts (vat_main_t * vam)
13012{
13013 unformat_input_t *i = vam->input;
13014 vl_api_ikev2_profile_set_ts_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013015 u8 *name = 0;
13016 u8 is_local = 0;
13017 u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
13018 ip4_address_t start_addr, end_addr;
13019
13020 const char *valid_chars = "a-zA-Z0-9_";
Jon Loeliger56c7b012017-02-01 12:31:41 -060013021 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013022
13023 start_addr.as_u32 = 0;
13024 end_addr.as_u32 = (u32) ~ 0;
13025
13026 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13027 {
13028 if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13029 vec_add1 (name, 0);
13030 else if (unformat (i, "protocol %d", &proto))
13031 ;
13032 else if (unformat (i, "start_port %d", &start_port))
13033 ;
13034 else if (unformat (i, "end_port %d", &end_port))
13035 ;
13036 else
13037 if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
13038 ;
13039 else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
13040 ;
13041 else if (unformat (i, "local"))
13042 is_local = 1;
13043 else if (unformat (i, "remote"))
13044 is_local = 0;
13045 else
13046 {
13047 errmsg ("parse error '%U'", format_unformat_error, i);
13048 return -99;
13049 }
13050 }
13051
13052 if (!vec_len (name))
13053 {
13054 errmsg ("profile name must be specified");
13055 return -99;
13056 }
13057
13058 if (vec_len (name) > 64)
13059 {
13060 errmsg ("profile name too long");
13061 return -99;
13062 }
13063
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013064 M (IKEV2_PROFILE_SET_TS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013065
13066 mp->is_local = is_local;
13067 mp->proto = (u8) proto;
13068 mp->start_port = (u16) start_port;
13069 mp->end_port = (u16) end_port;
13070 mp->start_addr = start_addr.as_u32;
13071 mp->end_addr = end_addr.as_u32;
13072 clib_memcpy (mp->name, name, vec_len (name));
13073 vec_free (name);
13074
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013075 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013076 W (ret);
13077 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013078}
13079
13080static int
13081api_ikev2_set_local_key (vat_main_t * vam)
13082{
13083 unformat_input_t *i = vam->input;
13084 vl_api_ikev2_set_local_key_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013085 u8 *file = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013086 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013087
13088 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13089 {
13090 if (unformat (i, "file %v", &file))
13091 vec_add1 (file, 0);
13092 else
13093 {
13094 errmsg ("parse error '%U'", format_unformat_error, i);
13095 return -99;
13096 }
13097 }
13098
13099 if (!vec_len (file))
13100 {
13101 errmsg ("RSA key file must be specified");
13102 return -99;
13103 }
13104
13105 if (vec_len (file) > 256)
13106 {
13107 errmsg ("file name too long");
13108 return -99;
13109 }
13110
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013111 M (IKEV2_SET_LOCAL_KEY, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013112
13113 clib_memcpy (mp->key_file, file, vec_len (file));
13114 vec_free (file);
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
Radu Nicolaucb33dc22017-02-16 16:49:46 +000013121static int
13122api_ikev2_set_responder (vat_main_t * vam)
13123{
13124 unformat_input_t *i = vam->input;
13125 vl_api_ikev2_set_responder_t *mp;
13126 int ret;
13127 u8 *name = 0;
13128 u32 sw_if_index = ~0;
13129 ip4_address_t address;
13130
13131 const char *valid_chars = "a-zA-Z0-9_";
13132
13133 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13134 {
13135 if (unformat
13136 (i, "%U interface %d address %U", unformat_token, valid_chars,
13137 &name, &sw_if_index, unformat_ip4_address, &address))
13138 vec_add1 (name, 0);
13139 else
13140 {
13141 errmsg ("parse error '%U'", format_unformat_error, i);
13142 return -99;
13143 }
13144 }
13145
13146 if (!vec_len (name))
13147 {
13148 errmsg ("profile name must be specified");
13149 return -99;
13150 }
13151
13152 if (vec_len (name) > 64)
13153 {
13154 errmsg ("profile name too long");
13155 return -99;
13156 }
13157
13158 M (IKEV2_SET_RESPONDER, mp);
13159
13160 clib_memcpy (mp->name, name, vec_len (name));
13161 vec_free (name);
13162
13163 mp->sw_if_index = sw_if_index;
13164 clib_memcpy (mp->address, &address, sizeof (address));
13165
13166 S (mp);
13167 W (ret);
13168 return ret;
13169}
13170
13171static int
13172api_ikev2_set_ike_transforms (vat_main_t * vam)
13173{
13174 unformat_input_t *i = vam->input;
13175 vl_api_ikev2_set_ike_transforms_t *mp;
13176 int ret;
13177 u8 *name = 0;
13178 u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
13179
13180 const char *valid_chars = "a-zA-Z0-9_";
13181
13182 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13183 {
13184 if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
13185 &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
13186 vec_add1 (name, 0);
13187 else
13188 {
13189 errmsg ("parse error '%U'", format_unformat_error, i);
13190 return -99;
13191 }
13192 }
13193
13194 if (!vec_len (name))
13195 {
13196 errmsg ("profile name must be specified");
13197 return -99;
13198 }
13199
13200 if (vec_len (name) > 64)
13201 {
13202 errmsg ("profile name too long");
13203 return -99;
13204 }
13205
13206 M (IKEV2_SET_IKE_TRANSFORMS, mp);
13207
13208 clib_memcpy (mp->name, name, vec_len (name));
13209 vec_free (name);
13210 mp->crypto_alg = crypto_alg;
13211 mp->crypto_key_size = crypto_key_size;
13212 mp->integ_alg = integ_alg;
13213 mp->dh_group = dh_group;
13214
13215 S (mp);
13216 W (ret);
13217 return ret;
13218}
13219
13220
13221static int
13222api_ikev2_set_esp_transforms (vat_main_t * vam)
13223{
13224 unformat_input_t *i = vam->input;
13225 vl_api_ikev2_set_esp_transforms_t *mp;
13226 int ret;
13227 u8 *name = 0;
13228 u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
13229
13230 const char *valid_chars = "a-zA-Z0-9_";
13231
13232 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13233 {
13234 if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
13235 &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
13236 vec_add1 (name, 0);
13237 else
13238 {
13239 errmsg ("parse error '%U'", format_unformat_error, i);
13240 return -99;
13241 }
13242 }
13243
13244 if (!vec_len (name))
13245 {
13246 errmsg ("profile name must be specified");
13247 return -99;
13248 }
13249
13250 if (vec_len (name) > 64)
13251 {
13252 errmsg ("profile name too long");
13253 return -99;
13254 }
13255
13256 M (IKEV2_SET_ESP_TRANSFORMS, mp);
13257
13258 clib_memcpy (mp->name, name, vec_len (name));
13259 vec_free (name);
13260 mp->crypto_alg = crypto_alg;
13261 mp->crypto_key_size = crypto_key_size;
13262 mp->integ_alg = integ_alg;
13263 mp->dh_group = dh_group;
13264
13265 S (mp);
13266 W (ret);
13267 return ret;
13268}
13269
13270static int
13271api_ikev2_set_sa_lifetime (vat_main_t * vam)
13272{
13273 unformat_input_t *i = vam->input;
13274 vl_api_ikev2_set_sa_lifetime_t *mp;
13275 int ret;
13276 u8 *name = 0;
13277 u64 lifetime, lifetime_maxdata;
13278 u32 lifetime_jitter, handover;
13279
13280 const char *valid_chars = "a-zA-Z0-9_";
13281
13282 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13283 {
13284 if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
13285 &lifetime, &lifetime_jitter, &handover,
13286 &lifetime_maxdata))
13287 vec_add1 (name, 0);
13288 else
13289 {
13290 errmsg ("parse error '%U'", format_unformat_error, i);
13291 return -99;
13292 }
13293 }
13294
13295 if (!vec_len (name))
13296 {
13297 errmsg ("profile name must be specified");
13298 return -99;
13299 }
13300
13301 if (vec_len (name) > 64)
13302 {
13303 errmsg ("profile name too long");
13304 return -99;
13305 }
13306
13307 M (IKEV2_SET_SA_LIFETIME, mp);
13308
13309 clib_memcpy (mp->name, name, vec_len (name));
13310 vec_free (name);
13311 mp->lifetime = lifetime;
13312 mp->lifetime_jitter = lifetime_jitter;
13313 mp->handover = handover;
13314 mp->lifetime_maxdata = lifetime_maxdata;
13315
13316 S (mp);
13317 W (ret);
13318 return ret;
13319}
13320
13321static int
13322api_ikev2_initiate_sa_init (vat_main_t * vam)
13323{
13324 unformat_input_t *i = vam->input;
13325 vl_api_ikev2_initiate_sa_init_t *mp;
13326 int ret;
13327 u8 *name = 0;
13328
13329 const char *valid_chars = "a-zA-Z0-9_";
13330
13331 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13332 {
13333 if (unformat (i, "%U", unformat_token, valid_chars, &name))
13334 vec_add1 (name, 0);
13335 else
13336 {
13337 errmsg ("parse error '%U'", format_unformat_error, i);
13338 return -99;
13339 }
13340 }
13341
13342 if (!vec_len (name))
13343 {
13344 errmsg ("profile name must be specified");
13345 return -99;
13346 }
13347
13348 if (vec_len (name) > 64)
13349 {
13350 errmsg ("profile name too long");
13351 return -99;
13352 }
13353
13354 M (IKEV2_INITIATE_SA_INIT, mp);
13355
13356 clib_memcpy (mp->name, name, vec_len (name));
13357 vec_free (name);
13358
13359 S (mp);
13360 W (ret);
13361 return ret;
13362}
13363
13364static int
13365api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
13366{
13367 unformat_input_t *i = vam->input;
13368 vl_api_ikev2_initiate_del_ike_sa_t *mp;
13369 int ret;
13370 u64 ispi;
13371
13372
13373 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13374 {
13375 if (unformat (i, "%lx", &ispi))
13376 ;
13377 else
13378 {
13379 errmsg ("parse error '%U'", format_unformat_error, i);
13380 return -99;
13381 }
13382 }
13383
13384 M (IKEV2_INITIATE_DEL_IKE_SA, mp);
13385
13386 mp->ispi = ispi;
13387
13388 S (mp);
13389 W (ret);
13390 return ret;
13391}
13392
13393static int
13394api_ikev2_initiate_del_child_sa (vat_main_t * vam)
13395{
13396 unformat_input_t *i = vam->input;
13397 vl_api_ikev2_initiate_del_child_sa_t *mp;
13398 int ret;
13399 u32 ispi;
13400
13401
13402 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13403 {
13404 if (unformat (i, "%x", &ispi))
13405 ;
13406 else
13407 {
13408 errmsg ("parse error '%U'", format_unformat_error, i);
13409 return -99;
13410 }
13411 }
13412
13413 M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
13414
13415 mp->ispi = ispi;
13416
13417 S (mp);
13418 W (ret);
13419 return ret;
13420}
13421
13422static int
13423api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
13424{
13425 unformat_input_t *i = vam->input;
13426 vl_api_ikev2_initiate_rekey_child_sa_t *mp;
13427 int ret;
13428 u32 ispi;
13429
13430
13431 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13432 {
13433 if (unformat (i, "%x", &ispi))
13434 ;
13435 else
13436 {
13437 errmsg ("parse error '%U'", format_unformat_error, i);
13438 return -99;
13439 }
13440 }
13441
13442 M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
13443
13444 mp->ispi = ispi;
13445
13446 S (mp);
13447 W (ret);
13448 return ret;
13449}
13450
Damjan Marion7cd468a2016-12-19 23:05:39 +010013451/*
13452 * MAP
13453 */
13454static int
13455api_map_add_domain (vat_main_t * vam)
13456{
13457 unformat_input_t *i = vam->input;
13458 vl_api_map_add_domain_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013459
13460 ip4_address_t ip4_prefix;
13461 ip6_address_t ip6_prefix;
13462 ip6_address_t ip6_src;
13463 u32 num_m_args = 0;
13464 u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
13465 0, psid_length = 0;
13466 u8 is_translation = 0;
13467 u32 mtu = 0;
13468 u32 ip6_src_len = 128;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013469 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013470
13471 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13472 {
13473 if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
13474 &ip4_prefix, &ip4_prefix_len))
13475 num_m_args++;
13476 else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
13477 &ip6_prefix, &ip6_prefix_len))
13478 num_m_args++;
13479 else
13480 if (unformat
13481 (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
13482 &ip6_src_len))
13483 num_m_args++;
13484 else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
13485 num_m_args++;
13486 else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
13487 num_m_args++;
13488 else if (unformat (i, "psid-offset %d", &psid_offset))
13489 num_m_args++;
13490 else if (unformat (i, "psid-len %d", &psid_length))
13491 num_m_args++;
13492 else if (unformat (i, "mtu %d", &mtu))
13493 num_m_args++;
13494 else if (unformat (i, "map-t"))
13495 is_translation = 1;
13496 else
13497 {
13498 clib_warning ("parse error '%U'", format_unformat_error, i);
13499 return -99;
13500 }
13501 }
13502
13503 if (num_m_args < 3)
13504 {
13505 errmsg ("mandatory argument(s) missing");
13506 return -99;
13507 }
13508
13509 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013510 M (MAP_ADD_DOMAIN, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013511
13512 clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
13513 mp->ip4_prefix_len = ip4_prefix_len;
13514
13515 clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
13516 mp->ip6_prefix_len = ip6_prefix_len;
13517
13518 clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
13519 mp->ip6_src_prefix_len = ip6_src_len;
13520
13521 mp->ea_bits_len = ea_bits_len;
13522 mp->psid_offset = psid_offset;
13523 mp->psid_length = psid_length;
13524 mp->is_translation = is_translation;
13525 mp->mtu = htons (mtu);
13526
13527 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013528 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013529
13530 /* Wait for a reply, return good/bad news */
Jon Loeliger56c7b012017-02-01 12:31:41 -060013531 W (ret);
13532 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013533}
13534
13535static int
13536api_map_del_domain (vat_main_t * vam)
13537{
13538 unformat_input_t *i = vam->input;
13539 vl_api_map_del_domain_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013540
13541 u32 num_m_args = 0;
13542 u32 index;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013543 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013544
13545 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13546 {
13547 if (unformat (i, "index %d", &index))
13548 num_m_args++;
13549 else
13550 {
13551 clib_warning ("parse error '%U'", format_unformat_error, i);
13552 return -99;
13553 }
13554 }
13555
13556 if (num_m_args != 1)
13557 {
13558 errmsg ("mandatory argument(s) missing");
13559 return -99;
13560 }
13561
13562 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013563 M (MAP_DEL_DOMAIN, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013564
13565 mp->index = ntohl (index);
13566
13567 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013568 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013569
13570 /* Wait for a reply, return good/bad news */
Jon Loeliger56c7b012017-02-01 12:31:41 -060013571 W (ret);
13572 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013573}
13574
13575static int
13576api_map_add_del_rule (vat_main_t * vam)
13577{
13578 unformat_input_t *i = vam->input;
13579 vl_api_map_add_del_rule_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013580 u8 is_add = 1;
13581 ip6_address_t ip6_dst;
13582 u32 num_m_args = 0, index, psid = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013583 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013584
13585 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13586 {
13587 if (unformat (i, "index %d", &index))
13588 num_m_args++;
13589 else if (unformat (i, "psid %d", &psid))
13590 num_m_args++;
13591 else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
13592 num_m_args++;
13593 else if (unformat (i, "del"))
13594 {
13595 is_add = 0;
13596 }
13597 else
13598 {
13599 clib_warning ("parse error '%U'", format_unformat_error, i);
13600 return -99;
13601 }
13602 }
13603
13604 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013605 M (MAP_ADD_DEL_RULE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013606
13607 mp->index = ntohl (index);
13608 mp->is_add = is_add;
13609 clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
13610 mp->psid = ntohs (psid);
13611
13612 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013613 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013614
13615 /* Wait for a reply, return good/bad news */
Jon Loeliger56c7b012017-02-01 12:31:41 -060013616 W (ret);
13617 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013618}
13619
13620static int
13621api_map_domain_dump (vat_main_t * vam)
13622{
13623 vl_api_map_domain_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060013624 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013625 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013626
13627 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013628 M (MAP_DOMAIN_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013629
13630 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013631 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013632
13633 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060013634 M (CONTROL_PING, mp_ping);
13635 S (mp_ping);
13636
Jon Loeliger56c7b012017-02-01 12:31:41 -060013637 W (ret);
13638 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013639}
13640
13641static int
13642api_map_rule_dump (vat_main_t * vam)
13643{
13644 unformat_input_t *i = vam->input;
13645 vl_api_map_rule_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060013646 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013647 u32 domain_index = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013648 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013649
13650 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13651 {
13652 if (unformat (i, "index %u", &domain_index))
13653 ;
13654 else
13655 break;
13656 }
13657
13658 if (domain_index == ~0)
13659 {
13660 clib_warning ("parse error: domain index expected");
13661 return -99;
13662 }
13663
13664 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013665 M (MAP_RULE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013666
13667 mp->domain_index = htonl (domain_index);
13668
13669 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013670 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013671
13672 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060013673 M (CONTROL_PING, mp_ping);
13674 S (mp_ping);
13675
Jon Loeliger56c7b012017-02-01 12:31:41 -060013676 W (ret);
13677 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013678}
13679
13680static void vl_api_map_add_domain_reply_t_handler
13681 (vl_api_map_add_domain_reply_t * mp)
13682{
13683 vat_main_t *vam = &vat_main;
13684 i32 retval = ntohl (mp->retval);
13685
13686 if (vam->async_mode)
13687 {
13688 vam->async_errors += (retval < 0);
13689 }
13690 else
13691 {
13692 vam->retval = retval;
13693 vam->result_ready = 1;
13694 }
13695}
13696
13697static void vl_api_map_add_domain_reply_t_handler_json
13698 (vl_api_map_add_domain_reply_t * mp)
13699{
13700 vat_main_t *vam = &vat_main;
13701 vat_json_node_t node;
13702
13703 vat_json_init_object (&node);
13704 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
13705 vat_json_object_add_uint (&node, "index", ntohl (mp->index));
13706
13707 vat_json_print (vam->ofp, &node);
13708 vat_json_free (&node);
13709
13710 vam->retval = ntohl (mp->retval);
13711 vam->result_ready = 1;
13712}
13713
13714static int
13715api_get_first_msg_id (vat_main_t * vam)
13716{
13717 vl_api_get_first_msg_id_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013718 unformat_input_t *i = vam->input;
13719 u8 *name;
13720 u8 name_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013721 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013722
13723 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13724 {
13725 if (unformat (i, "client %s", &name))
13726 name_set = 1;
13727 else
13728 break;
13729 }
13730
13731 if (name_set == 0)
13732 {
13733 errmsg ("missing client name");
13734 return -99;
13735 }
13736 vec_add1 (name, 0);
13737
13738 if (vec_len (name) > 63)
13739 {
13740 errmsg ("client name too long");
13741 return -99;
13742 }
13743
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013744 M (GET_FIRST_MSG_ID, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013745 clib_memcpy (mp->name, name, vec_len (name));
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013746 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013747 W (ret);
13748 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013749}
13750
13751static int
13752api_cop_interface_enable_disable (vat_main_t * vam)
13753{
13754 unformat_input_t *line_input = vam->input;
13755 vl_api_cop_interface_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013756 u32 sw_if_index = ~0;
13757 u8 enable_disable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013758 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013759
13760 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13761 {
13762 if (unformat (line_input, "disable"))
13763 enable_disable = 0;
13764 if (unformat (line_input, "enable"))
13765 enable_disable = 1;
13766 else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13767 vam, &sw_if_index))
13768 ;
13769 else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13770 ;
13771 else
13772 break;
13773 }
13774
13775 if (sw_if_index == ~0)
13776 {
13777 errmsg ("missing interface name or sw_if_index");
13778 return -99;
13779 }
13780
13781 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013782 M (COP_INTERFACE_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013783 mp->sw_if_index = ntohl (sw_if_index);
13784 mp->enable_disable = enable_disable;
13785
13786 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013787 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013788 /* Wait for the reply */
Jon Loeliger56c7b012017-02-01 12:31:41 -060013789 W (ret);
13790 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013791}
13792
13793static int
13794api_cop_whitelist_enable_disable (vat_main_t * vam)
13795{
13796 unformat_input_t *line_input = vam->input;
13797 vl_api_cop_whitelist_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013798 u32 sw_if_index = ~0;
13799 u8 ip4 = 0, ip6 = 0, default_cop = 0;
13800 u32 fib_id = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013801 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013802
13803 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13804 {
13805 if (unformat (line_input, "ip4"))
13806 ip4 = 1;
13807 else if (unformat (line_input, "ip6"))
13808 ip6 = 1;
13809 else if (unformat (line_input, "default"))
13810 default_cop = 1;
13811 else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13812 vam, &sw_if_index))
13813 ;
13814 else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13815 ;
13816 else if (unformat (line_input, "fib-id %d", &fib_id))
13817 ;
13818 else
13819 break;
13820 }
13821
13822 if (sw_if_index == ~0)
13823 {
13824 errmsg ("missing interface name or sw_if_index");
13825 return -99;
13826 }
13827
13828 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013829 M (COP_WHITELIST_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013830 mp->sw_if_index = ntohl (sw_if_index);
13831 mp->fib_id = ntohl (fib_id);
13832 mp->ip4 = ip4;
13833 mp->ip6 = ip6;
13834 mp->default_cop = default_cop;
13835
13836 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013837 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013838 /* Wait for the reply */
Jon Loeliger56c7b012017-02-01 12:31:41 -060013839 W (ret);
13840 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013841}
13842
13843static int
13844api_get_node_graph (vat_main_t * vam)
13845{
13846 vl_api_get_node_graph_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013847 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013848
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013849 M (GET_NODE_GRAPH, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013850
13851 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013852 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013853 /* Wait for the reply */
Jon Loeliger56c7b012017-02-01 12:31:41 -060013854 W (ret);
13855 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013856}
13857
13858/* *INDENT-OFF* */
13859/** Used for parsing LISP eids */
13860typedef CLIB_PACKED(struct{
13861 u8 addr[16]; /**< eid address */
13862 u32 len; /**< prefix length if IP */
13863 u8 type; /**< type of eid */
13864}) lisp_eid_vat_t;
13865/* *INDENT-ON* */
13866
13867static uword
13868unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
13869{
13870 lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
13871
13872 memset (a, 0, sizeof (a[0]));
13873
13874 if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
13875 {
13876 a->type = 0; /* ipv4 type */
13877 }
13878 else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
13879 {
13880 a->type = 1; /* ipv6 type */
13881 }
13882 else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
13883 {
13884 a->type = 2; /* mac type */
13885 }
13886 else
13887 {
13888 return 0;
13889 }
13890
13891 if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
13892 {
13893 return 0;
13894 }
13895
13896 return 1;
13897}
13898
13899static int
13900lisp_eid_size_vat (u8 type)
13901{
13902 switch (type)
13903 {
13904 case 0:
13905 return 4;
13906 case 1:
13907 return 16;
13908 case 2:
13909 return 6;
13910 }
13911 return 0;
13912}
13913
13914static void
13915lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
13916{
13917 clib_memcpy (dst, eid, lisp_eid_size_vat (type));
13918}
13919
Damjan Marion7cd468a2016-12-19 23:05:39 +010013920static int
Filip Tehlar694396d2017-02-17 14:29:11 +010013921api_one_add_del_locator_set (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010013922{
13923 unformat_input_t *input = vam->input;
Filip Tehlar694396d2017-02-17 14:29:11 +010013924 vl_api_one_add_del_locator_set_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013925 u8 is_add = 1;
13926 u8 *locator_set_name = NULL;
13927 u8 locator_set_name_set = 0;
Filip Tehlar05a057b2017-02-01 08:50:31 +010013928 vl_api_local_locator_t locator, *locators = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013929 u32 sw_if_index, priority, weight;
13930 u32 data_len = 0;
13931
Jon Loeliger56c7b012017-02-01 12:31:41 -060013932 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013933 /* Parse args required to build the message */
13934 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13935 {
13936 if (unformat (input, "del"))
13937 {
13938 is_add = 0;
13939 }
13940 else if (unformat (input, "locator-set %s", &locator_set_name))
13941 {
13942 locator_set_name_set = 1;
13943 }
13944 else if (unformat (input, "sw_if_index %u p %u w %u",
13945 &sw_if_index, &priority, &weight))
13946 {
13947 locator.sw_if_index = htonl (sw_if_index);
13948 locator.priority = priority;
13949 locator.weight = weight;
13950 vec_add1 (locators, locator);
13951 }
13952 else
13953 if (unformat
13954 (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
13955 &sw_if_index, &priority, &weight))
13956 {
13957 locator.sw_if_index = htonl (sw_if_index);
13958 locator.priority = priority;
13959 locator.weight = weight;
13960 vec_add1 (locators, locator);
13961 }
13962 else
13963 break;
13964 }
13965
13966 if (locator_set_name_set == 0)
13967 {
13968 errmsg ("missing locator-set name");
13969 vec_free (locators);
13970 return -99;
13971 }
13972
13973 if (vec_len (locator_set_name) > 64)
13974 {
13975 errmsg ("locator-set name too long");
13976 vec_free (locator_set_name);
13977 vec_free (locators);
13978 return -99;
13979 }
13980 vec_add1 (locator_set_name, 0);
13981
Filip Tehlar05a057b2017-02-01 08:50:31 +010013982 data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013983
13984 /* Construct the API message */
Filip Tehlar694396d2017-02-17 14:29:11 +010013985 M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013986
13987 mp->is_add = is_add;
13988 clib_memcpy (mp->locator_set_name, locator_set_name,
13989 vec_len (locator_set_name));
13990 vec_free (locator_set_name);
13991
13992 mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
13993 if (locators)
13994 clib_memcpy (mp->locators, locators, data_len);
13995 vec_free (locators);
13996
13997 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013998 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013999
14000 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014001 W (ret);
14002 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014003}
14004
Filip Tehlar694396d2017-02-17 14:29:11 +010014005#define api_lisp_add_del_locator_set api_one_add_del_locator_set
14006
Damjan Marion7cd468a2016-12-19 23:05:39 +010014007static int
Filip Tehlar694396d2017-02-17 14:29:11 +010014008api_one_add_del_locator (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010014009{
14010 unformat_input_t *input = vam->input;
Filip Tehlar694396d2017-02-17 14:29:11 +010014011 vl_api_one_add_del_locator_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014012 u32 tmp_if_index = ~0;
14013 u32 sw_if_index = ~0;
14014 u8 sw_if_index_set = 0;
14015 u8 sw_if_index_if_name_set = 0;
14016 u32 priority = ~0;
14017 u8 priority_set = 0;
14018 u32 weight = ~0;
14019 u8 weight_set = 0;
14020 u8 is_add = 1;
14021 u8 *locator_set_name = NULL;
14022 u8 locator_set_name_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014023 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014024
14025 /* Parse args required to build the message */
14026 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14027 {
14028 if (unformat (input, "del"))
14029 {
14030 is_add = 0;
14031 }
14032 else if (unformat (input, "locator-set %s", &locator_set_name))
14033 {
14034 locator_set_name_set = 1;
14035 }
14036 else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
14037 &tmp_if_index))
14038 {
14039 sw_if_index_if_name_set = 1;
14040 sw_if_index = tmp_if_index;
14041 }
14042 else if (unformat (input, "sw_if_index %d", &tmp_if_index))
14043 {
14044 sw_if_index_set = 1;
14045 sw_if_index = tmp_if_index;
14046 }
14047 else if (unformat (input, "p %d", &priority))
14048 {
14049 priority_set = 1;
14050 }
14051 else if (unformat (input, "w %d", &weight))
14052 {
14053 weight_set = 1;
14054 }
14055 else
14056 break;
14057 }
14058
14059 if (locator_set_name_set == 0)
14060 {
14061 errmsg ("missing locator-set name");
14062 return -99;
14063 }
14064
14065 if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
14066 {
14067 errmsg ("missing sw_if_index");
14068 vec_free (locator_set_name);
14069 return -99;
14070 }
14071
14072 if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
14073 {
14074 errmsg ("cannot use both params interface name and sw_if_index");
14075 vec_free (locator_set_name);
14076 return -99;
14077 }
14078
14079 if (priority_set == 0)
14080 {
14081 errmsg ("missing locator-set priority");
14082 vec_free (locator_set_name);
14083 return -99;
14084 }
14085
14086 if (weight_set == 0)
14087 {
14088 errmsg ("missing locator-set weight");
14089 vec_free (locator_set_name);
14090 return -99;
14091 }
14092
14093 if (vec_len (locator_set_name) > 64)
14094 {
14095 errmsg ("locator-set name too long");
14096 vec_free (locator_set_name);
14097 return -99;
14098 }
14099 vec_add1 (locator_set_name, 0);
14100
14101 /* Construct the API message */
Filip Tehlar694396d2017-02-17 14:29:11 +010014102 M (ONE_ADD_DEL_LOCATOR, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014103
14104 mp->is_add = is_add;
14105 mp->sw_if_index = ntohl (sw_if_index);
14106 mp->priority = priority;
14107 mp->weight = weight;
14108 clib_memcpy (mp->locator_set_name, locator_set_name,
14109 vec_len (locator_set_name));
14110 vec_free (locator_set_name);
14111
14112 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014113 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014114
14115 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014116 W (ret);
14117 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014118}
14119
Filip Tehlar694396d2017-02-17 14:29:11 +010014120#define api_lisp_add_del_locator api_one_add_del_locator
14121
Damjan Marion7cd468a2016-12-19 23:05:39 +010014122uword
14123unformat_hmac_key_id (unformat_input_t * input, va_list * args)
14124{
14125 u32 *key_id = va_arg (*args, u32 *);
14126 u8 *s = 0;
14127
14128 if (unformat (input, "%s", &s))
14129 {
14130 if (!strcmp ((char *) s, "sha1"))
14131 key_id[0] = HMAC_SHA_1_96;
14132 else if (!strcmp ((char *) s, "sha256"))
14133 key_id[0] = HMAC_SHA_256_128;
14134 else
14135 {
14136 clib_warning ("invalid key_id: '%s'", s);
14137 key_id[0] = HMAC_NO_KEY;
14138 }
14139 }
14140 else
14141 return 0;
14142
14143 vec_free (s);
14144 return 1;
14145}
14146
14147static int
Filip Tehlar694396d2017-02-17 14:29:11 +010014148api_one_add_del_local_eid (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010014149{
14150 unformat_input_t *input = vam->input;
Filip Tehlar694396d2017-02-17 14:29:11 +010014151 vl_api_one_add_del_local_eid_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014152 u8 is_add = 1;
14153 u8 eid_set = 0;
14154 lisp_eid_vat_t _eid, *eid = &_eid;
14155 u8 *locator_set_name = 0;
14156 u8 locator_set_name_set = 0;
14157 u32 vni = 0;
14158 u16 key_id = 0;
14159 u8 *key = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014160 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014161
14162 /* Parse args required to build the message */
14163 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14164 {
14165 if (unformat (input, "del"))
14166 {
14167 is_add = 0;
14168 }
14169 else if (unformat (input, "vni %d", &vni))
14170 {
14171 ;
14172 }
14173 else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14174 {
14175 eid_set = 1;
14176 }
14177 else if (unformat (input, "locator-set %s", &locator_set_name))
14178 {
14179 locator_set_name_set = 1;
14180 }
14181 else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
14182 ;
14183 else if (unformat (input, "secret-key %_%v%_", &key))
14184 ;
14185 else
14186 break;
14187 }
14188
14189 if (locator_set_name_set == 0)
14190 {
14191 errmsg ("missing locator-set name");
14192 return -99;
14193 }
14194
14195 if (0 == eid_set)
14196 {
14197 errmsg ("EID address not set!");
14198 vec_free (locator_set_name);
14199 return -99;
14200 }
14201
14202 if (key && (0 == key_id))
14203 {
14204 errmsg ("invalid key_id!");
14205 return -99;
14206 }
14207
14208 if (vec_len (key) > 64)
14209 {
14210 errmsg ("key too long");
14211 vec_free (key);
14212 return -99;
14213 }
14214
14215 if (vec_len (locator_set_name) > 64)
14216 {
14217 errmsg ("locator-set name too long");
14218 vec_free (locator_set_name);
14219 return -99;
14220 }
14221 vec_add1 (locator_set_name, 0);
14222
14223 /* Construct the API message */
Filip Tehlar694396d2017-02-17 14:29:11 +010014224 M (ONE_ADD_DEL_LOCAL_EID, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014225
14226 mp->is_add = is_add;
14227 lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14228 mp->eid_type = eid->type;
14229 mp->prefix_len = eid->len;
14230 mp->vni = clib_host_to_net_u32 (vni);
14231 mp->key_id = clib_host_to_net_u16 (key_id);
14232 clib_memcpy (mp->locator_set_name, locator_set_name,
14233 vec_len (locator_set_name));
14234 clib_memcpy (mp->key, key, vec_len (key));
14235
14236 vec_free (locator_set_name);
14237 vec_free (key);
14238
14239 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014240 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014241
14242 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014243 W (ret);
14244 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014245}
14246
Filip Tehlar694396d2017-02-17 14:29:11 +010014247#define api_lisp_add_del_local_eid api_one_add_del_local_eid
Damjan Marion7cd468a2016-12-19 23:05:39 +010014248
14249static int
14250api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
14251{
Filip Tehlarc3af7bf2017-01-13 14:13:09 +010014252 u32 dp_table = 0, vni = 0;;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014253 unformat_input_t *input = vam->input;
Filip Tehlar82786c42017-02-20 15:20:37 +010014254 vl_api_gpe_add_del_fwd_entry_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014255 u8 is_add = 1;
14256 lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
14257 lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
14258 u8 rmt_eid_set = 0, lcl_eid_set = 0;
Filip Tehlarc3af7bf2017-01-13 14:13:09 +010014259 u32 action = ~0, w;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014260 ip4_address_t rmt_rloc4, lcl_rloc4;
14261 ip6_address_t rmt_rloc6, lcl_rloc6;
Filip Tehlar82786c42017-02-20 15:20:37 +010014262 vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014263 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014264
14265 memset (&rloc, 0, sizeof (rloc));
14266
14267 /* Parse args required to build the message */
14268 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14269 {
14270 if (unformat (input, "del"))
Filip Tehlarc3af7bf2017-01-13 14:13:09 +010014271 is_add = 0;
14272 else if (unformat (input, "add"))
14273 is_add = 1;
14274 else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
Damjan Marion7cd468a2016-12-19 23:05:39 +010014275 {
14276 rmt_eid_set = 1;
14277 }
Filip Tehlarc3af7bf2017-01-13 14:13:09 +010014278 else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
Damjan Marion7cd468a2016-12-19 23:05:39 +010014279 {
14280 lcl_eid_set = 1;
14281 }
Filip Tehlarc3af7bf2017-01-13 14:13:09 +010014282 else if (unformat (input, "vrf %d", &dp_table))
14283 ;
14284 else if (unformat (input, "bd %d", &dp_table))
14285 ;
14286 else if (unformat (input, "vni %d", &vni))
14287 ;
14288 else if (unformat (input, "w %d", &w))
Damjan Marion7cd468a2016-12-19 23:05:39 +010014289 {
14290 if (!curr_rloc)
14291 {
14292 errmsg ("No RLOC configured for setting priority/weight!");
14293 return -99;
14294 }
Damjan Marion7cd468a2016-12-19 23:05:39 +010014295 curr_rloc->weight = w;
14296 }
14297 else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
14298 &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
14299 {
14300 rloc.is_ip4 = 1;
14301
14302 clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
Filip Tehlarc3af7bf2017-01-13 14:13:09 +010014303 rloc.weight = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014304 vec_add1 (lcl_locs, rloc);
14305
14306 clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
14307 vec_add1 (rmt_locs, rloc);
Filip Tehlarc3af7bf2017-01-13 14:13:09 +010014308 /* weight saved in rmt loc */
Damjan Marion7cd468a2016-12-19 23:05:39 +010014309 curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14310 }
14311 else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
14312 &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
14313 {
14314 rloc.is_ip4 = 0;
14315 clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
Filip Tehlarc3af7bf2017-01-13 14:13:09 +010014316 rloc.weight = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014317 vec_add1 (lcl_locs, rloc);
14318
14319 clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
14320 vec_add1 (rmt_locs, rloc);
Filip Tehlarc3af7bf2017-01-13 14:13:09 +010014321 /* weight saved in rmt loc */
Damjan Marion7cd468a2016-12-19 23:05:39 +010014322 curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14323 }
14324 else if (unformat (input, "action %d", &action))
14325 {
14326 ;
14327 }
14328 else
14329 {
14330 clib_warning ("parse error '%U'", format_unformat_error, input);
14331 return -99;
14332 }
14333 }
14334
14335 if (!rmt_eid_set)
14336 {
14337 errmsg ("remote eid addresses not set");
14338 return -99;
14339 }
14340
14341 if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
14342 {
14343 errmsg ("eid types don't match");
14344 return -99;
14345 }
14346
14347 if (0 == rmt_locs && (u32) ~ 0 == action)
14348 {
14349 errmsg ("action not set for negative mapping");
14350 return -99;
14351 }
14352
14353 /* Construct the API message */
Filip Tehlar82786c42017-02-20 15:20:37 +010014354 M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
14355 sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014356
14357 mp->is_add = is_add;
14358 lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
14359 lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
14360 mp->eid_type = rmt_eid->type;
Filip Tehlarc3af7bf2017-01-13 14:13:09 +010014361 mp->dp_table = clib_host_to_net_u32 (dp_table);
14362 mp->vni = clib_host_to_net_u32 (vni);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014363 mp->rmt_len = rmt_eid->len;
14364 mp->lcl_len = lcl_eid->len;
14365 mp->action = action;
14366
14367 if (0 != rmt_locs && 0 != lcl_locs)
14368 {
Filip Tehlarc3af7bf2017-01-13 14:13:09 +010014369 mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
14370 clib_memcpy (mp->locs, lcl_locs,
Filip Tehlar82786c42017-02-20 15:20:37 +010014371 (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
Filip Tehlarc3af7bf2017-01-13 14:13:09 +010014372
Filip Tehlar82786c42017-02-20 15:20:37 +010014373 u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
Filip Tehlarc3af7bf2017-01-13 14:13:09 +010014374 clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
Filip Tehlar82786c42017-02-20 15:20:37 +010014375 (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
Damjan Marion7cd468a2016-12-19 23:05:39 +010014376 }
14377 vec_free (lcl_locs);
14378 vec_free (rmt_locs);
14379
14380 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014381 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014382
14383 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014384 W (ret);
14385 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014386}
14387
14388static int
Filip Tehlar694396d2017-02-17 14:29:11 +010014389api_one_add_del_map_server (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010014390{
14391 unformat_input_t *input = vam->input;
Filip Tehlar694396d2017-02-17 14:29:11 +010014392 vl_api_one_add_del_map_server_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014393 u8 is_add = 1;
14394 u8 ipv4_set = 0;
14395 u8 ipv6_set = 0;
14396 ip4_address_t ipv4;
14397 ip6_address_t ipv6;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014398 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014399
14400 /* Parse args required to build the message */
14401 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14402 {
14403 if (unformat (input, "del"))
14404 {
14405 is_add = 0;
14406 }
14407 else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14408 {
14409 ipv4_set = 1;
14410 }
14411 else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14412 {
14413 ipv6_set = 1;
14414 }
14415 else
14416 break;
14417 }
14418
14419 if (ipv4_set && ipv6_set)
14420 {
14421 errmsg ("both eid v4 and v6 addresses set");
14422 return -99;
14423 }
14424
14425 if (!ipv4_set && !ipv6_set)
14426 {
14427 errmsg ("eid addresses not set");
14428 return -99;
14429 }
14430
14431 /* Construct the API message */
Filip Tehlar694396d2017-02-17 14:29:11 +010014432 M (ONE_ADD_DEL_MAP_SERVER, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014433
14434 mp->is_add = is_add;
14435 if (ipv6_set)
14436 {
14437 mp->is_ipv6 = 1;
14438 clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14439 }
14440 else
14441 {
14442 mp->is_ipv6 = 0;
14443 clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14444 }
14445
14446 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014447 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014448
14449 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014450 W (ret);
14451 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014452}
14453
Filip Tehlar694396d2017-02-17 14:29:11 +010014454#define api_lisp_add_del_map_server api_one_add_del_map_server
14455
Damjan Marion7cd468a2016-12-19 23:05:39 +010014456static int
Filip Tehlar694396d2017-02-17 14:29:11 +010014457api_one_add_del_map_resolver (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010014458{
14459 unformat_input_t *input = vam->input;
Filip Tehlar694396d2017-02-17 14:29:11 +010014460 vl_api_one_add_del_map_resolver_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014461 u8 is_add = 1;
14462 u8 ipv4_set = 0;
14463 u8 ipv6_set = 0;
14464 ip4_address_t ipv4;
14465 ip6_address_t ipv6;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014466 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014467
14468 /* Parse args required to build the message */
14469 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14470 {
14471 if (unformat (input, "del"))
14472 {
14473 is_add = 0;
14474 }
14475 else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14476 {
14477 ipv4_set = 1;
14478 }
14479 else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14480 {
14481 ipv6_set = 1;
14482 }
14483 else
14484 break;
14485 }
14486
14487 if (ipv4_set && ipv6_set)
14488 {
14489 errmsg ("both eid v4 and v6 addresses set");
14490 return -99;
14491 }
14492
14493 if (!ipv4_set && !ipv6_set)
14494 {
14495 errmsg ("eid addresses not set");
14496 return -99;
14497 }
14498
14499 /* Construct the API message */
Filip Tehlar694396d2017-02-17 14:29:11 +010014500 M (ONE_ADD_DEL_MAP_RESOLVER, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014501
14502 mp->is_add = is_add;
14503 if (ipv6_set)
14504 {
14505 mp->is_ipv6 = 1;
14506 clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14507 }
14508 else
14509 {
14510 mp->is_ipv6 = 0;
14511 clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14512 }
14513
14514 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014515 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014516
14517 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014518 W (ret);
14519 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014520}
14521
Filip Tehlar694396d2017-02-17 14:29:11 +010014522#define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
14523
Damjan Marion7cd468a2016-12-19 23:05:39 +010014524static int
14525api_lisp_gpe_enable_disable (vat_main_t * vam)
14526{
14527 unformat_input_t *input = vam->input;
Filip Tehlar82786c42017-02-20 15:20:37 +010014528 vl_api_gpe_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014529 u8 is_set = 0;
14530 u8 is_en = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014531 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014532
14533 /* Parse args required to build the message */
14534 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14535 {
14536 if (unformat (input, "enable"))
14537 {
14538 is_set = 1;
14539 is_en = 1;
14540 }
14541 else if (unformat (input, "disable"))
14542 {
14543 is_set = 1;
14544 is_en = 0;
14545 }
14546 else
14547 break;
14548 }
14549
14550 if (is_set == 0)
14551 {
14552 errmsg ("Value not set");
14553 return -99;
14554 }
14555
14556 /* Construct the API message */
Filip Tehlar82786c42017-02-20 15:20:37 +010014557 M (GPE_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014558
14559 mp->is_en = is_en;
14560
14561 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014562 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014563
14564 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014565 W (ret);
14566 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014567}
14568
14569static int
Filip Tehlar694396d2017-02-17 14:29:11 +010014570api_one_rloc_probe_enable_disable (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010014571{
14572 unformat_input_t *input = vam->input;
Filip Tehlar694396d2017-02-17 14:29:11 +010014573 vl_api_one_rloc_probe_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014574 u8 is_set = 0;
14575 u8 is_en = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014576 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014577
14578 /* Parse args required to build the message */
14579 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14580 {
14581 if (unformat (input, "enable"))
14582 {
14583 is_set = 1;
14584 is_en = 1;
14585 }
14586 else if (unformat (input, "disable"))
14587 is_set = 1;
14588 else
14589 break;
14590 }
14591
14592 if (!is_set)
14593 {
14594 errmsg ("Value not set");
14595 return -99;
14596 }
14597
14598 /* Construct the API message */
Filip Tehlar694396d2017-02-17 14:29:11 +010014599 M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014600
14601 mp->is_enabled = is_en;
14602
14603 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014604 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014605
14606 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014607 W (ret);
14608 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014609}
14610
Filip Tehlar694396d2017-02-17 14:29:11 +010014611#define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
14612
Damjan Marion7cd468a2016-12-19 23:05:39 +010014613static int
Filip Tehlar694396d2017-02-17 14:29:11 +010014614api_one_map_register_enable_disable (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010014615{
14616 unformat_input_t *input = vam->input;
Filip Tehlar694396d2017-02-17 14:29:11 +010014617 vl_api_one_map_register_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014618 u8 is_set = 0;
14619 u8 is_en = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014620 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014621
14622 /* Parse args required to build the message */
14623 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14624 {
14625 if (unformat (input, "enable"))
14626 {
14627 is_set = 1;
14628 is_en = 1;
14629 }
14630 else if (unformat (input, "disable"))
14631 is_set = 1;
14632 else
14633 break;
14634 }
14635
14636 if (!is_set)
14637 {
14638 errmsg ("Value not set");
14639 return -99;
14640 }
14641
14642 /* Construct the API message */
Filip Tehlar694396d2017-02-17 14:29:11 +010014643 M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014644
14645 mp->is_enabled = is_en;
14646
14647 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014648 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014649
14650 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014651 W (ret);
14652 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014653}
14654
Filip Tehlar694396d2017-02-17 14:29:11 +010014655#define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
14656
Damjan Marion7cd468a2016-12-19 23:05:39 +010014657static int
Filip Tehlar694396d2017-02-17 14:29:11 +010014658api_one_enable_disable (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010014659{
14660 unformat_input_t *input = vam->input;
Filip Tehlar694396d2017-02-17 14:29:11 +010014661 vl_api_one_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014662 u8 is_set = 0;
14663 u8 is_en = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014664 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014665
14666 /* Parse args required to build the message */
14667 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14668 {
14669 if (unformat (input, "enable"))
14670 {
14671 is_set = 1;
14672 is_en = 1;
14673 }
14674 else if (unformat (input, "disable"))
14675 {
14676 is_set = 1;
14677 }
14678 else
14679 break;
14680 }
14681
14682 if (!is_set)
14683 {
14684 errmsg ("Value not set");
14685 return -99;
14686 }
14687
14688 /* Construct the API message */
Filip Tehlar694396d2017-02-17 14:29:11 +010014689 M (ONE_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014690
14691 mp->is_en = is_en;
14692
14693 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014694 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014695
14696 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014697 W (ret);
14698 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014699}
14700
Filip Tehlar694396d2017-02-17 14:29:11 +010014701#define api_lisp_enable_disable api_one_enable_disable
14702
Damjan Marion7cd468a2016-12-19 23:05:39 +010014703static int
Filip Tehlar694396d2017-02-17 14:29:11 +010014704api_show_one_map_register_state (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010014705{
Filip Tehlar694396d2017-02-17 14:29:11 +010014706 vl_api_show_one_map_register_state_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014707 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014708
Filip Tehlar694396d2017-02-17 14:29:11 +010014709 M (SHOW_ONE_MAP_REGISTER_STATE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014710
14711 /* send */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014712 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014713
14714 /* wait for reply */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014715 W (ret);
14716 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014717}
14718
Filip Tehlar694396d2017-02-17 14:29:11 +010014719#define api_show_lisp_map_register_state api_show_one_map_register_state
14720
Damjan Marion7cd468a2016-12-19 23:05:39 +010014721static int
Filip Tehlar694396d2017-02-17 14:29:11 +010014722api_show_one_rloc_probe_state (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010014723{
Filip Tehlar694396d2017-02-17 14:29:11 +010014724 vl_api_show_one_rloc_probe_state_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014725 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014726
Filip Tehlar694396d2017-02-17 14:29:11 +010014727 M (SHOW_ONE_RLOC_PROBE_STATE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014728
14729 /* send */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014730 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014731
14732 /* wait for reply */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014733 W (ret);
14734 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014735}
14736
Filip Tehlar694396d2017-02-17 14:29:11 +010014737#define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
14738
Damjan Marion7cd468a2016-12-19 23:05:39 +010014739static int
Filip Tehlar4868ff62017-03-09 16:48:39 +010014740api_one_stats_enable_disable (vat_main_t * vam)
14741{
14742 vl_api_one_stats_enable_disable_t *mp;
14743 unformat_input_t *input = vam->input;
14744 u8 is_set = 0;
14745 u8 is_en = 0;
14746 int ret;
14747
14748 /* Parse args required to build the message */
14749 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14750 {
14751 if (unformat (input, "enable"))
14752 {
14753 is_set = 1;
14754 is_en = 1;
14755 }
14756 else if (unformat (input, "disable"))
14757 {
14758 is_set = 1;
14759 }
14760 else
14761 break;
14762 }
14763
14764 if (!is_set)
14765 {
14766 errmsg ("Value not set");
14767 return -99;
14768 }
14769
14770 M (ONE_STATS_ENABLE_DISABLE, mp);
14771 mp->is_en = is_en;
14772
14773 /* send */
14774 S (mp);
14775
14776 /* wait for reply */
14777 W (ret);
14778 return ret;
14779}
14780
14781static int
14782api_show_one_stats_enable_disable (vat_main_t * vam)
14783{
14784 vl_api_show_one_stats_enable_disable_t *mp;
14785 int ret;
14786
14787 M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
14788
14789 /* send */
14790 S (mp);
14791
14792 /* wait for reply */
14793 W (ret);
14794 return ret;
14795}
14796
14797static int
Filip Tehlar694396d2017-02-17 14:29:11 +010014798api_show_one_map_request_mode (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010014799{
Filip Tehlar694396d2017-02-17 14:29:11 +010014800 vl_api_show_one_map_request_mode_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014801 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014802
Filip Tehlar694396d2017-02-17 14:29:11 +010014803 M (SHOW_ONE_MAP_REQUEST_MODE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014804
14805 /* send */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014806 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014807
14808 /* wait for reply */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014809 W (ret);
14810 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014811}
14812
Filip Tehlar694396d2017-02-17 14:29:11 +010014813#define api_show_lisp_map_request_mode api_show_one_map_request_mode
14814
Damjan Marion7cd468a2016-12-19 23:05:39 +010014815static int
Filip Tehlar694396d2017-02-17 14:29:11 +010014816api_one_map_request_mode (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010014817{
Damjan Marion7cd468a2016-12-19 23:05:39 +010014818 unformat_input_t *input = vam->input;
Filip Tehlar694396d2017-02-17 14:29:11 +010014819 vl_api_one_map_request_mode_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014820 u8 mode = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014821 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014822
14823 /* Parse args required to build the message */
14824 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14825 {
14826 if (unformat (input, "dst-only"))
14827 mode = 0;
14828 else if (unformat (input, "src-dst"))
14829 mode = 1;
14830 else
14831 {
14832 errmsg ("parse error '%U'", format_unformat_error, input);
14833 return -99;
14834 }
14835 }
14836
Filip Tehlar694396d2017-02-17 14:29:11 +010014837 M (ONE_MAP_REQUEST_MODE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014838
14839 mp->mode = mode;
14840
14841 /* send */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014842 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014843
14844 /* wait for reply */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014845 W (ret);
14846 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014847}
14848
Filip Tehlar694396d2017-02-17 14:29:11 +010014849#define api_lisp_map_request_mode api_one_map_request_mode
14850
Damjan Marion7cd468a2016-12-19 23:05:39 +010014851/**
Filip Tehlar694396d2017-02-17 14:29:11 +010014852 * Enable/disable ONE proxy ITR.
Damjan Marion7cd468a2016-12-19 23:05:39 +010014853 *
14854 * @param vam vpp API test context
14855 * @return return code
14856 */
14857static int
Filip Tehlar694396d2017-02-17 14:29:11 +010014858api_one_pitr_set_locator_set (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010014859{
Damjan Marion7cd468a2016-12-19 23:05:39 +010014860 u8 ls_name_set = 0;
14861 unformat_input_t *input = vam->input;
Filip Tehlar694396d2017-02-17 14:29:11 +010014862 vl_api_one_pitr_set_locator_set_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014863 u8 is_add = 1;
14864 u8 *ls_name = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014865 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014866
14867 /* Parse args required to build the message */
14868 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14869 {
14870 if (unformat (input, "del"))
14871 is_add = 0;
14872 else if (unformat (input, "locator-set %s", &ls_name))
14873 ls_name_set = 1;
14874 else
14875 {
14876 errmsg ("parse error '%U'", format_unformat_error, input);
14877 return -99;
14878 }
14879 }
14880
14881 if (!ls_name_set)
14882 {
14883 errmsg ("locator-set name not set!");
14884 return -99;
14885 }
14886
Filip Tehlar694396d2017-02-17 14:29:11 +010014887 M (ONE_PITR_SET_LOCATOR_SET, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014888
14889 mp->is_add = is_add;
14890 clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
14891 vec_free (ls_name);
14892
14893 /* send */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014894 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014895
14896 /* wait for reply */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014897 W (ret);
14898 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014899}
14900
Filip Tehlar694396d2017-02-17 14:29:11 +010014901#define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
14902
Damjan Marion7cd468a2016-12-19 23:05:39 +010014903static int
Filip Tehlar694396d2017-02-17 14:29:11 +010014904api_show_one_pitr (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010014905{
Filip Tehlar694396d2017-02-17 14:29:11 +010014906 vl_api_show_one_pitr_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014907 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014908
14909 if (!vam->json_output)
14910 {
14911 print (vam->ofp, "%=20s", "lisp status:");
14912 }
14913
Filip Tehlar694396d2017-02-17 14:29:11 +010014914 M (SHOW_ONE_PITR, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014915 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014916 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014917
14918 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014919 W (ret);
14920 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014921}
14922
Filip Tehlar694396d2017-02-17 14:29:11 +010014923#define api_show_lisp_pitr api_show_one_pitr
14924
Filip Tehlar67a99f82017-03-10 13:18:02 +010014925static int
14926api_one_use_petr (vat_main_t * vam)
14927{
14928 unformat_input_t *input = vam->input;
14929 vl_api_one_use_petr_t *mp;
14930 u8 is_add = 0;
14931 ip_address_t ip;
14932 int ret;
14933
14934 memset (&ip, 0, sizeof (ip));
14935
14936 /* Parse args required to build the message */
14937 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14938 {
14939 if (unformat (input, "disable"))
14940 is_add = 0;
14941 else
14942 if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
14943 {
14944 is_add = 1;
14945 ip_addr_version (&ip) = IP4;
14946 }
14947 else
14948 if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
14949 {
14950 is_add = 1;
14951 ip_addr_version (&ip) = IP6;
14952 }
14953 else
14954 {
14955 errmsg ("parse error '%U'", format_unformat_error, input);
14956 return -99;
14957 }
14958 }
14959
14960 M (ONE_USE_PETR, mp);
14961
14962 mp->is_add = is_add;
14963 if (is_add)
14964 {
14965 mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
14966 if (mp->is_ip4)
14967 clib_memcpy (mp->address, &ip, 4);
14968 else
14969 clib_memcpy (mp->address, &ip, 16);
14970 }
14971
14972 /* send */
14973 S (mp);
14974
14975 /* wait for reply */
14976 W (ret);
14977 return ret;
14978}
14979
14980#define api_lisp_use_petr api_one_use_petr
14981
14982static int
14983api_show_one_use_petr (vat_main_t * vam)
14984{
14985 vl_api_show_one_use_petr_t *mp;
14986 int ret;
14987
14988 if (!vam->json_output)
14989 {
14990 print (vam->ofp, "%=20s", "Proxy-ETR status:");
14991 }
14992
14993 M (SHOW_ONE_USE_PETR, mp);
14994 /* send it... */
14995 S (mp);
14996
14997 /* Wait for a reply... */
14998 W (ret);
14999 return ret;
15000}
15001
15002#define api_show_lisp_use_petr api_show_one_use_petr
15003
Damjan Marion7cd468a2016-12-19 23:05:39 +010015004/**
15005 * Add/delete mapping between vni and vrf
15006 */
15007static int
Filip Tehlar694396d2017-02-17 14:29:11 +010015008api_one_eid_table_add_del_map (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010015009{
Damjan Marion7cd468a2016-12-19 23:05:39 +010015010 unformat_input_t *input = vam->input;
Filip Tehlar694396d2017-02-17 14:29:11 +010015011 vl_api_one_eid_table_add_del_map_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015012 u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
15013 u32 vni, vrf, bd_index;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015014 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015015
15016 /* Parse args required to build the message */
15017 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15018 {
15019 if (unformat (input, "del"))
15020 is_add = 0;
15021 else if (unformat (input, "vrf %d", &vrf))
15022 vrf_set = 1;
15023 else if (unformat (input, "bd_index %d", &bd_index))
15024 bd_index_set = 1;
15025 else if (unformat (input, "vni %d", &vni))
15026 vni_set = 1;
15027 else
15028 break;
15029 }
15030
15031 if (!vni_set || (!vrf_set && !bd_index_set))
15032 {
15033 errmsg ("missing arguments!");
15034 return -99;
15035 }
15036
15037 if (vrf_set && bd_index_set)
15038 {
15039 errmsg ("error: both vrf and bd entered!");
15040 return -99;
15041 }
15042
Filip Tehlar694396d2017-02-17 14:29:11 +010015043 M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015044
15045 mp->is_add = is_add;
15046 mp->vni = htonl (vni);
15047 mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
15048 mp->is_l2 = bd_index_set;
15049
15050 /* send */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015051 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015052
15053 /* wait for reply */
Jon Loeliger56c7b012017-02-01 12:31:41 -060015054 W (ret);
15055 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015056}
15057
Filip Tehlar694396d2017-02-17 14:29:11 +010015058#define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
15059
Damjan Marion7cd468a2016-12-19 23:05:39 +010015060uword
15061unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
15062{
15063 u32 *action = va_arg (*args, u32 *);
15064 u8 *s = 0;
15065
15066 if (unformat (input, "%s", &s))
15067 {
15068 if (!strcmp ((char *) s, "no-action"))
15069 action[0] = 0;
15070 else if (!strcmp ((char *) s, "natively-forward"))
15071 action[0] = 1;
15072 else if (!strcmp ((char *) s, "send-map-request"))
15073 action[0] = 2;
15074 else if (!strcmp ((char *) s, "drop"))
15075 action[0] = 3;
15076 else
15077 {
15078 clib_warning ("invalid action: '%s'", s);
15079 action[0] = 3;
15080 }
15081 }
15082 else
15083 return 0;
15084
15085 vec_free (s);
15086 return 1;
15087}
15088
15089/**
Filip Tehlar694396d2017-02-17 14:29:11 +010015090 * Add/del remote mapping to/from ONE control plane
Damjan Marion7cd468a2016-12-19 23:05:39 +010015091 *
15092 * @param vam vpp API test context
15093 * @return return code
15094 */
15095static int
Filip Tehlar694396d2017-02-17 14:29:11 +010015096api_one_add_del_remote_mapping (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010015097{
15098 unformat_input_t *input = vam->input;
Filip Tehlar694396d2017-02-17 14:29:11 +010015099 vl_api_one_add_del_remote_mapping_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015100 u32 vni = 0;
15101 lisp_eid_vat_t _eid, *eid = &_eid;
15102 lisp_eid_vat_t _seid, *seid = &_seid;
15103 u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
15104 u32 action = ~0, p, w, data_len;
15105 ip4_address_t rloc4;
15106 ip6_address_t rloc6;
Filip Tehlar05a057b2017-02-01 08:50:31 +010015107 vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015108 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015109
15110 memset (&rloc, 0, sizeof (rloc));
15111
15112 /* Parse args required to build the message */
15113 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15114 {
15115 if (unformat (input, "del-all"))
15116 {
15117 del_all = 1;
15118 }
15119 else if (unformat (input, "del"))
15120 {
15121 is_add = 0;
15122 }
15123 else if (unformat (input, "add"))
15124 {
15125 is_add = 1;
15126 }
15127 else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15128 {
15129 eid_set = 1;
15130 }
15131 else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
15132 {
15133 seid_set = 1;
15134 }
15135 else if (unformat (input, "vni %d", &vni))
15136 {
15137 ;
15138 }
15139 else if (unformat (input, "p %d w %d", &p, &w))
15140 {
15141 if (!curr_rloc)
15142 {
15143 errmsg ("No RLOC configured for setting priority/weight!");
15144 return -99;
15145 }
15146 curr_rloc->priority = p;
15147 curr_rloc->weight = w;
15148 }
15149 else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
15150 {
15151 rloc.is_ip4 = 1;
15152 clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
15153 vec_add1 (rlocs, rloc);
15154 curr_rloc = &rlocs[vec_len (rlocs) - 1];
15155 }
15156 else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
15157 {
15158 rloc.is_ip4 = 0;
15159 clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
15160 vec_add1 (rlocs, rloc);
15161 curr_rloc = &rlocs[vec_len (rlocs) - 1];
15162 }
15163 else if (unformat (input, "action %U",
15164 unformat_negative_mapping_action, &action))
15165 {
15166 ;
15167 }
15168 else
15169 {
15170 clib_warning ("parse error '%U'", format_unformat_error, input);
15171 return -99;
15172 }
15173 }
15174
15175 if (0 == eid_set)
15176 {
15177 errmsg ("missing params!");
15178 return -99;
15179 }
15180
15181 if (is_add && (~0 == action) && 0 == vec_len (rlocs))
15182 {
15183 errmsg ("no action set for negative map-reply!");
15184 return -99;
15185 }
15186
Filip Tehlar05a057b2017-02-01 08:50:31 +010015187 data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015188
Filip Tehlar694396d2017-02-17 14:29:11 +010015189 M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015190 mp->is_add = is_add;
15191 mp->vni = htonl (vni);
15192 mp->action = (u8) action;
15193 mp->is_src_dst = seid_set;
15194 mp->eid_len = eid->len;
15195 mp->seid_len = seid->len;
15196 mp->del_all = del_all;
15197 mp->eid_type = eid->type;
15198 lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15199 lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
15200
15201 mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
15202 clib_memcpy (mp->rlocs, rlocs, data_len);
15203 vec_free (rlocs);
15204
15205 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015206 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015207
15208 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060015209 W (ret);
15210 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015211}
15212
Filip Tehlar694396d2017-02-17 14:29:11 +010015213#define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
15214
Damjan Marion7cd468a2016-12-19 23:05:39 +010015215/**
Filip Tehlar694396d2017-02-17 14:29:11 +010015216 * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
Damjan Marion7cd468a2016-12-19 23:05:39 +010015217 * forwarding entries in data-plane accordingly.
15218 *
15219 * @param vam vpp API test context
15220 * @return return code
15221 */
15222static int
Filip Tehlar694396d2017-02-17 14:29:11 +010015223api_one_add_del_adjacency (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010015224{
15225 unformat_input_t *input = vam->input;
Filip Tehlar694396d2017-02-17 14:29:11 +010015226 vl_api_one_add_del_adjacency_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015227 u32 vni = 0;
15228 ip4_address_t leid4, reid4;
15229 ip6_address_t leid6, reid6;
15230 u8 reid_mac[6] = { 0 };
15231 u8 leid_mac[6] = { 0 };
15232 u8 reid_type, leid_type;
15233 u32 leid_len = 0, reid_len = 0, len;
15234 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015235 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015236
15237 leid_type = reid_type = (u8) ~ 0;
15238
15239 /* Parse args required to build the message */
15240 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15241 {
15242 if (unformat (input, "del"))
15243 {
15244 is_add = 0;
15245 }
15246 else if (unformat (input, "add"))
15247 {
15248 is_add = 1;
15249 }
15250 else if (unformat (input, "reid %U/%d", unformat_ip4_address,
15251 &reid4, &len))
15252 {
15253 reid_type = 0; /* ipv4 */
15254 reid_len = len;
15255 }
15256 else if (unformat (input, "reid %U/%d", unformat_ip6_address,
15257 &reid6, &len))
15258 {
15259 reid_type = 1; /* ipv6 */
15260 reid_len = len;
15261 }
15262 else if (unformat (input, "reid %U", unformat_ethernet_address,
15263 reid_mac))
15264 {
15265 reid_type = 2; /* mac */
15266 }
15267 else if (unformat (input, "leid %U/%d", unformat_ip4_address,
15268 &leid4, &len))
15269 {
15270 leid_type = 0; /* ipv4 */
15271 leid_len = len;
15272 }
15273 else if (unformat (input, "leid %U/%d", unformat_ip6_address,
15274 &leid6, &len))
15275 {
15276 leid_type = 1; /* ipv6 */
15277 leid_len = len;
15278 }
15279 else if (unformat (input, "leid %U", unformat_ethernet_address,
15280 leid_mac))
15281 {
15282 leid_type = 2; /* mac */
15283 }
15284 else if (unformat (input, "vni %d", &vni))
15285 {
15286 ;
15287 }
15288 else
15289 {
15290 errmsg ("parse error '%U'", format_unformat_error, input);
15291 return -99;
15292 }
15293 }
15294
15295 if ((u8) ~ 0 == reid_type)
15296 {
15297 errmsg ("missing params!");
15298 return -99;
15299 }
15300
15301 if (leid_type != reid_type)
15302 {
15303 errmsg ("remote and local EIDs are of different types!");
15304 return -99;
15305 }
15306
Filip Tehlar694396d2017-02-17 14:29:11 +010015307 M (ONE_ADD_DEL_ADJACENCY, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015308 mp->is_add = is_add;
15309 mp->vni = htonl (vni);
15310 mp->leid_len = leid_len;
15311 mp->reid_len = reid_len;
15312 mp->eid_type = reid_type;
15313
15314 switch (mp->eid_type)
15315 {
15316 case 0:
15317 clib_memcpy (mp->leid, &leid4, sizeof (leid4));
15318 clib_memcpy (mp->reid, &reid4, sizeof (reid4));
15319 break;
15320 case 1:
15321 clib_memcpy (mp->leid, &leid6, sizeof (leid6));
15322 clib_memcpy (mp->reid, &reid6, sizeof (reid6));
15323 break;
15324 case 2:
15325 clib_memcpy (mp->leid, leid_mac, 6);
15326 clib_memcpy (mp->reid, reid_mac, 6);
15327 break;
15328 default:
15329 errmsg ("unknown EID type %d!", mp->eid_type);
15330 return 0;
15331 }
15332
15333 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015334 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015335
15336 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060015337 W (ret);
15338 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015339}
15340
Filip Tehlar694396d2017-02-17 14:29:11 +010015341#define api_lisp_add_del_adjacency api_one_add_del_adjacency
15342
Filip Tehlar3e7b56932017-02-21 18:28:34 +010015343uword
15344unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
15345{
15346 u32 *mode = va_arg (*args, u32 *);
15347
15348 if (unformat (input, "lisp"))
15349 *mode = 0;
15350 else if (unformat (input, "vxlan"))
15351 *mode = 1;
15352 else
15353 return 0;
15354
15355 return 1;
15356}
15357
15358static int
15359api_gpe_get_encap_mode (vat_main_t * vam)
15360{
15361 vl_api_gpe_get_encap_mode_t *mp;
15362 int ret;
15363
15364 /* Construct the API message */
15365 M (GPE_GET_ENCAP_MODE, mp);
15366
15367 /* send it... */
15368 S (mp);
15369
15370 /* Wait for a reply... */
15371 W (ret);
15372 return ret;
15373}
15374
15375static int
15376api_gpe_set_encap_mode (vat_main_t * vam)
15377{
15378 unformat_input_t *input = vam->input;
15379 vl_api_gpe_set_encap_mode_t *mp;
15380 int ret;
15381 u32 mode = 0;
15382
15383 /* Parse args required to build the message */
15384 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15385 {
15386 if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
15387 ;
15388 else
15389 break;
15390 }
15391
15392 /* Construct the API message */
15393 M (GPE_SET_ENCAP_MODE, mp);
15394
15395 mp->mode = mode;
15396
15397 /* send it... */
15398 S (mp);
15399
15400 /* Wait for a reply... */
15401 W (ret);
15402 return ret;
15403}
15404
Damjan Marion7cd468a2016-12-19 23:05:39 +010015405static int
15406api_lisp_gpe_add_del_iface (vat_main_t * vam)
15407{
15408 unformat_input_t *input = vam->input;
Filip Tehlar82786c42017-02-20 15:20:37 +010015409 vl_api_gpe_add_del_iface_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015410 u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
15411 u32 dp_table = 0, vni = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015412 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015413
15414 /* Parse args required to build the message */
15415 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15416 {
15417 if (unformat (input, "up"))
15418 {
15419 action_set = 1;
15420 is_add = 1;
15421 }
15422 else if (unformat (input, "down"))
15423 {
15424 action_set = 1;
15425 is_add = 0;
15426 }
15427 else if (unformat (input, "table_id %d", &dp_table))
15428 {
15429 dp_table_set = 1;
15430 }
15431 else if (unformat (input, "bd_id %d", &dp_table))
15432 {
15433 dp_table_set = 1;
15434 is_l2 = 1;
15435 }
15436 else if (unformat (input, "vni %d", &vni))
15437 {
15438 vni_set = 1;
15439 }
15440 else
15441 break;
15442 }
15443
15444 if (action_set == 0)
15445 {
15446 errmsg ("Action not set");
15447 return -99;
15448 }
15449 if (dp_table_set == 0 || vni_set == 0)
15450 {
15451 errmsg ("vni and dp_table must be set");
15452 return -99;
15453 }
15454
15455 /* Construct the API message */
Filip Tehlar82786c42017-02-20 15:20:37 +010015456 M (GPE_ADD_DEL_IFACE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015457
15458 mp->is_add = is_add;
15459 mp->dp_table = dp_table;
15460 mp->is_l2 = is_l2;
15461 mp->vni = vni;
15462
15463 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015464 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015465
15466 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060015467 W (ret);
15468 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015469}
15470
15471/**
Filip Tehlar694396d2017-02-17 14:29:11 +010015472 * Add/del map request itr rlocs from ONE control plane and updates
Damjan Marion7cd468a2016-12-19 23:05:39 +010015473 *
15474 * @param vam vpp API test context
15475 * @return return code
15476 */
15477static int
Filip Tehlar694396d2017-02-17 14:29:11 +010015478api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010015479{
15480 unformat_input_t *input = vam->input;
Filip Tehlar694396d2017-02-17 14:29:11 +010015481 vl_api_one_add_del_map_request_itr_rlocs_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015482 u8 *locator_set_name = 0;
15483 u8 locator_set_name_set = 0;
15484 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015485 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015486
15487 /* Parse args required to build the message */
15488 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15489 {
15490 if (unformat (input, "del"))
15491 {
15492 is_add = 0;
15493 }
15494 else if (unformat (input, "%_%v%_", &locator_set_name))
15495 {
15496 locator_set_name_set = 1;
15497 }
15498 else
15499 {
15500 clib_warning ("parse error '%U'", format_unformat_error, input);
15501 return -99;
15502 }
15503 }
15504
15505 if (is_add && !locator_set_name_set)
15506 {
15507 errmsg ("itr-rloc is not set!");
15508 return -99;
15509 }
15510
15511 if (is_add && vec_len (locator_set_name) > 64)
15512 {
15513 errmsg ("itr-rloc locator-set name too long");
15514 vec_free (locator_set_name);
15515 return -99;
15516 }
15517
Filip Tehlar694396d2017-02-17 14:29:11 +010015518 M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015519 mp->is_add = is_add;
15520 if (is_add)
15521 {
15522 clib_memcpy (mp->locator_set_name, locator_set_name,
15523 vec_len (locator_set_name));
15524 }
15525 else
15526 {
15527 memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
15528 }
15529 vec_free (locator_set_name);
15530
15531 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015532 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015533
15534 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060015535 W (ret);
15536 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015537}
15538
Filip Tehlar694396d2017-02-17 14:29:11 +010015539#define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
15540
Damjan Marion7cd468a2016-12-19 23:05:39 +010015541static int
Filip Tehlar694396d2017-02-17 14:29:11 +010015542api_one_locator_dump (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010015543{
15544 unformat_input_t *input = vam->input;
Filip Tehlar694396d2017-02-17 14:29:11 +010015545 vl_api_one_locator_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060015546 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015547 u8 is_index_set = 0, is_name_set = 0;
15548 u8 *ls_name = 0;
15549 u32 ls_index = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015550 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015551
15552 /* Parse args required to build the message */
15553 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15554 {
15555 if (unformat (input, "ls_name %_%v%_", &ls_name))
15556 {
15557 is_name_set = 1;
15558 }
15559 else if (unformat (input, "ls_index %d", &ls_index))
15560 {
15561 is_index_set = 1;
15562 }
15563 else
15564 {
15565 errmsg ("parse error '%U'", format_unformat_error, input);
15566 return -99;
15567 }
15568 }
15569
15570 if (!is_index_set && !is_name_set)
15571 {
15572 errmsg ("error: expected one of index or name!");
15573 return -99;
15574 }
15575
15576 if (is_index_set && is_name_set)
15577 {
15578 errmsg ("error: only one param expected!");
15579 return -99;
15580 }
15581
15582 if (vec_len (ls_name) > 62)
15583 {
15584 errmsg ("error: locator set name too long!");
15585 return -99;
15586 }
15587
15588 if (!vam->json_output)
15589 {
15590 print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
15591 }
15592
Filip Tehlar694396d2017-02-17 14:29:11 +010015593 M (ONE_LOCATOR_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015594 mp->is_index_set = is_index_set;
15595
15596 if (is_index_set)
15597 mp->ls_index = clib_host_to_net_u32 (ls_index);
15598 else
15599 {
15600 vec_add1 (ls_name, 0);
15601 strncpy ((char *) mp->ls_name, (char *) ls_name,
15602 sizeof (mp->ls_name) - 1);
15603 }
15604
15605 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015606 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015607
15608 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060015609 M (CONTROL_PING, mp_ping);
15610 S (mp_ping);
15611
Damjan Marion7cd468a2016-12-19 23:05:39 +010015612 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060015613 W (ret);
15614 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015615}
15616
Filip Tehlar694396d2017-02-17 14:29:11 +010015617#define api_lisp_locator_dump api_one_locator_dump
15618
Damjan Marion7cd468a2016-12-19 23:05:39 +010015619static int
Filip Tehlar694396d2017-02-17 14:29:11 +010015620api_one_locator_set_dump (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010015621{
Filip Tehlar694396d2017-02-17 14:29:11 +010015622 vl_api_one_locator_set_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060015623 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015624 unformat_input_t *input = vam->input;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015625 u8 filter = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015626 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015627
15628 /* Parse args required to build the message */
15629 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15630 {
15631 if (unformat (input, "local"))
15632 {
15633 filter = 1;
15634 }
15635 else if (unformat (input, "remote"))
15636 {
15637 filter = 2;
15638 }
15639 else
15640 {
15641 errmsg ("parse error '%U'", format_unformat_error, input);
15642 return -99;
15643 }
15644 }
15645
15646 if (!vam->json_output)
15647 {
15648 print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
15649 }
15650
Filip Tehlar694396d2017-02-17 14:29:11 +010015651 M (ONE_LOCATOR_SET_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015652
15653 mp->filter = filter;
15654
15655 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015656 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015657
15658 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060015659 M (CONTROL_PING, mp_ping);
15660 S (mp_ping);
15661
Damjan Marion7cd468a2016-12-19 23:05:39 +010015662 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060015663 W (ret);
15664 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015665}
15666
Filip Tehlar694396d2017-02-17 14:29:11 +010015667#define api_lisp_locator_set_dump api_one_locator_set_dump
15668
Damjan Marion7cd468a2016-12-19 23:05:39 +010015669static int
Filip Tehlar694396d2017-02-17 14:29:11 +010015670api_one_eid_table_map_dump (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010015671{
15672 u8 is_l2 = 0;
15673 u8 mode_set = 0;
15674 unformat_input_t *input = vam->input;
Filip Tehlar694396d2017-02-17 14:29:11 +010015675 vl_api_one_eid_table_map_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060015676 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015677 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015678
15679 /* Parse args required to build the message */
15680 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15681 {
15682 if (unformat (input, "l2"))
15683 {
15684 is_l2 = 1;
15685 mode_set = 1;
15686 }
15687 else if (unformat (input, "l3"))
15688 {
15689 is_l2 = 0;
15690 mode_set = 1;
15691 }
15692 else
15693 {
15694 errmsg ("parse error '%U'", format_unformat_error, input);
15695 return -99;
15696 }
15697 }
15698
15699 if (!mode_set)
15700 {
15701 errmsg ("expected one of 'l2' or 'l3' parameter!");
15702 return -99;
15703 }
15704
15705 if (!vam->json_output)
15706 {
15707 print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
15708 }
15709
Filip Tehlar694396d2017-02-17 14:29:11 +010015710 M (ONE_EID_TABLE_MAP_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015711 mp->is_l2 = is_l2;
15712
15713 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015714 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015715
15716 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060015717 M (CONTROL_PING, mp_ping);
15718 S (mp_ping);
15719
Damjan Marion7cd468a2016-12-19 23:05:39 +010015720 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060015721 W (ret);
15722 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015723}
15724
Filip Tehlar694396d2017-02-17 14:29:11 +010015725#define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
15726
Damjan Marion7cd468a2016-12-19 23:05:39 +010015727static int
Filip Tehlar694396d2017-02-17 14:29:11 +010015728api_one_eid_table_vni_dump (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010015729{
Filip Tehlar694396d2017-02-17 14:29:11 +010015730 vl_api_one_eid_table_vni_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060015731 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015732 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015733
15734 if (!vam->json_output)
15735 {
15736 print (vam->ofp, "VNI");
15737 }
15738
Filip Tehlar694396d2017-02-17 14:29:11 +010015739 M (ONE_EID_TABLE_VNI_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015740
15741 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015742 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015743
15744 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060015745 M (CONTROL_PING, mp_ping);
15746 S (mp_ping);
15747
Damjan Marion7cd468a2016-12-19 23:05:39 +010015748 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060015749 W (ret);
15750 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015751}
15752
Filip Tehlar694396d2017-02-17 14:29:11 +010015753#define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
15754
Damjan Marion7cd468a2016-12-19 23:05:39 +010015755static int
Filip Tehlar694396d2017-02-17 14:29:11 +010015756api_one_eid_table_dump (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010015757{
15758 unformat_input_t *i = vam->input;
Filip Tehlar694396d2017-02-17 14:29:11 +010015759 vl_api_one_eid_table_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060015760 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015761 struct in_addr ip4;
15762 struct in6_addr ip6;
15763 u8 mac[6];
15764 u8 eid_type = ~0, eid_set = 0;
15765 u32 prefix_length = ~0, t, vni = 0;
15766 u8 filter = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015767 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015768
15769 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15770 {
15771 if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
15772 {
15773 eid_set = 1;
15774 eid_type = 0;
15775 prefix_length = t;
15776 }
15777 else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
15778 {
15779 eid_set = 1;
15780 eid_type = 1;
15781 prefix_length = t;
15782 }
15783 else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
15784 {
15785 eid_set = 1;
15786 eid_type = 2;
15787 }
15788 else if (unformat (i, "vni %d", &t))
15789 {
15790 vni = t;
15791 }
15792 else if (unformat (i, "local"))
15793 {
15794 filter = 1;
15795 }
15796 else if (unformat (i, "remote"))
15797 {
15798 filter = 2;
15799 }
15800 else
15801 {
15802 errmsg ("parse error '%U'", format_unformat_error, i);
15803 return -99;
15804 }
15805 }
15806
15807 if (!vam->json_output)
15808 {
15809 print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
15810 "type", "ls_index", "ttl", "authoritative", "key_id", "key");
15811 }
15812
Filip Tehlar694396d2017-02-17 14:29:11 +010015813 M (ONE_EID_TABLE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015814
15815 mp->filter = filter;
15816 if (eid_set)
15817 {
15818 mp->eid_set = 1;
15819 mp->vni = htonl (vni);
15820 mp->eid_type = eid_type;
15821 switch (eid_type)
15822 {
15823 case 0:
15824 mp->prefix_length = prefix_length;
15825 clib_memcpy (mp->eid, &ip4, sizeof (ip4));
15826 break;
15827 case 1:
15828 mp->prefix_length = prefix_length;
15829 clib_memcpy (mp->eid, &ip6, sizeof (ip6));
15830 break;
15831 case 2:
15832 clib_memcpy (mp->eid, mac, sizeof (mac));
15833 break;
15834 default:
15835 errmsg ("unknown EID type %d!", eid_type);
15836 return -99;
15837 }
15838 }
15839
15840 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015841 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015842
15843 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060015844 M (CONTROL_PING, mp_ping);
15845 S (mp_ping);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015846
15847 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060015848 W (ret);
15849 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015850}
15851
Filip Tehlar694396d2017-02-17 14:29:11 +010015852#define api_lisp_eid_table_dump api_one_eid_table_dump
15853
Damjan Marion7cd468a2016-12-19 23:05:39 +010015854static int
Filip Tehlar5fae99c2017-01-18 12:57:37 +010015855api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
15856{
15857 unformat_input_t *i = vam->input;
Filip Tehlar82786c42017-02-20 15:20:37 +010015858 vl_api_gpe_fwd_entries_get_t *mp;
Filip Tehlar5fae99c2017-01-18 12:57:37 +010015859 u8 vni_set = 0;
15860 u32 vni = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015861 int ret;
Filip Tehlar5fae99c2017-01-18 12:57:37 +010015862
15863 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15864 {
15865 if (unformat (i, "vni %d", &vni))
15866 {
15867 vni_set = 1;
15868 }
15869 else
15870 {
15871 errmsg ("parse error '%U'", format_unformat_error, i);
15872 return -99;
15873 }
15874 }
15875
15876 if (!vni_set)
15877 {
15878 errmsg ("vni not set!");
15879 return -99;
15880 }
15881
15882 if (!vam->json_output)
15883 {
15884 print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
15885 "leid", "reid");
15886 }
15887
Filip Tehlar82786c42017-02-20 15:20:37 +010015888 M (GPE_FWD_ENTRIES_GET, mp);
Filip Tehlar5fae99c2017-01-18 12:57:37 +010015889 mp->vni = clib_host_to_net_u32 (vni);
15890
15891 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015892 S (mp);
Filip Tehlar5fae99c2017-01-18 12:57:37 +010015893
15894 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060015895 W (ret);
15896 return ret;
Filip Tehlar5fae99c2017-01-18 12:57:37 +010015897}
15898
Filip Tehlar0eb874e2017-05-18 14:23:32 +020015899#define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
15900#define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
Filip Tehlar82786c42017-02-20 15:20:37 +010015901#define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
15902#define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
15903#define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
15904#define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
Filip Tehlar5fae99c2017-01-18 12:57:37 +010015905
15906static int
Filip Tehlar694396d2017-02-17 14:29:11 +010015907api_one_adjacencies_get (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010015908{
15909 unformat_input_t *i = vam->input;
Filip Tehlar694396d2017-02-17 14:29:11 +010015910 vl_api_one_adjacencies_get_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015911 u8 vni_set = 0;
15912 u32 vni = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015913 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015914
15915 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15916 {
15917 if (unformat (i, "vni %d", &vni))
15918 {
15919 vni_set = 1;
15920 }
15921 else
15922 {
15923 errmsg ("parse error '%U'", format_unformat_error, i);
15924 return -99;
15925 }
15926 }
15927
15928 if (!vni_set)
15929 {
15930 errmsg ("vni not set!");
15931 return -99;
15932 }
15933
15934 if (!vam->json_output)
15935 {
15936 print (vam->ofp, "%s %40s", "leid", "reid");
15937 }
15938
Filip Tehlar694396d2017-02-17 14:29:11 +010015939 M (ONE_ADJACENCIES_GET, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015940 mp->vni = clib_host_to_net_u32 (vni);
15941
15942 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015943 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015944
15945 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060015946 W (ret);
15947 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015948}
15949
Filip Tehlar694396d2017-02-17 14:29:11 +010015950#define api_lisp_adjacencies_get api_one_adjacencies_get
15951
Damjan Marion7cd468a2016-12-19 23:05:39 +010015952static int
Filip Tehlar0eb874e2017-05-18 14:23:32 +020015953api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
15954{
15955 vl_api_gpe_fwd_entry_vnis_get_t *mp;
15956 int ret;
15957
15958 if (!vam->json_output)
15959 {
15960 print (vam->ofp, "VNIs");
15961 }
15962
15963 M (GPE_FWD_ENTRY_VNIS_GET, mp);
15964
15965 /* send it... */
15966 S (mp);
15967
15968 /* Wait for a reply... */
15969 W (ret);
15970 return ret;
15971}
15972
15973static int
Filip Tehlar694396d2017-02-17 14:29:11 +010015974api_one_map_server_dump (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010015975{
Filip Tehlar694396d2017-02-17 14:29:11 +010015976 vl_api_one_map_server_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060015977 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015978 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015979
15980 if (!vam->json_output)
15981 {
15982 print (vam->ofp, "%=20s", "Map server");
15983 }
15984
Filip Tehlar694396d2017-02-17 14:29:11 +010015985 M (ONE_MAP_SERVER_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015986 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015987 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015988
15989 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060015990 M (CONTROL_PING, mp_ping);
15991 S (mp_ping);
15992
Damjan Marion7cd468a2016-12-19 23:05:39 +010015993 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060015994 W (ret);
15995 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015996}
15997
Filip Tehlar694396d2017-02-17 14:29:11 +010015998#define api_lisp_map_server_dump api_one_map_server_dump
15999
Damjan Marion7cd468a2016-12-19 23:05:39 +010016000static int
Filip Tehlar694396d2017-02-17 14:29:11 +010016001api_one_map_resolver_dump (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010016002{
Filip Tehlar694396d2017-02-17 14:29:11 +010016003 vl_api_one_map_resolver_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016004 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016005 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016006
16007 if (!vam->json_output)
16008 {
16009 print (vam->ofp, "%=20s", "Map resolver");
16010 }
16011
Filip Tehlar694396d2017-02-17 14:29:11 +010016012 M (ONE_MAP_RESOLVER_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016013 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016014 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016015
16016 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016017 M (CONTROL_PING, mp_ping);
16018 S (mp_ping);
16019
Damjan Marion7cd468a2016-12-19 23:05:39 +010016020 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060016021 W (ret);
16022 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016023}
16024
Filip Tehlar694396d2017-02-17 14:29:11 +010016025#define api_lisp_map_resolver_dump api_one_map_resolver_dump
16026
Damjan Marion7cd468a2016-12-19 23:05:39 +010016027static int
Filip Tehlar21511912017-04-07 10:41:42 +020016028api_one_stats_flush (vat_main_t * vam)
16029{
16030 vl_api_one_stats_flush_t *mp;
16031 int ret = 0;
16032
16033 M (ONE_STATS_FLUSH, mp);
16034 S (mp);
16035 W (ret);
16036 return ret;
16037}
16038
16039static int
Filip Tehlar4868ff62017-03-09 16:48:39 +010016040api_one_stats_dump (vat_main_t * vam)
16041{
16042 vl_api_one_stats_dump_t *mp;
16043 vl_api_control_ping_t *mp_ping;
16044 int ret;
16045
16046 M (ONE_STATS_DUMP, mp);
16047 /* send it... */
16048 S (mp);
16049
16050 /* Use a control ping for synchronization */
16051 M (CONTROL_PING, mp_ping);
16052 S (mp_ping);
16053
16054 /* Wait for a reply... */
16055 W (ret);
16056 return ret;
16057}
16058
16059static int
Filip Tehlar694396d2017-02-17 14:29:11 +010016060api_show_one_status (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010016061{
Filip Tehlar694396d2017-02-17 14:29:11 +010016062 vl_api_show_one_status_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016063 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016064
16065 if (!vam->json_output)
16066 {
Filip Tehlar694396d2017-02-17 14:29:11 +010016067 print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
Damjan Marion7cd468a2016-12-19 23:05:39 +010016068 }
16069
Filip Tehlar694396d2017-02-17 14:29:11 +010016070 M (SHOW_ONE_STATUS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016071 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016072 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016073 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060016074 W (ret);
16075 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016076}
16077
Filip Tehlar694396d2017-02-17 14:29:11 +010016078#define api_show_lisp_status api_show_one_status
16079
Damjan Marion7cd468a2016-12-19 23:05:39 +010016080static int
Filip Tehlar5fae99c2017-01-18 12:57:37 +010016081api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
16082{
Filip Tehlar82786c42017-02-20 15:20:37 +010016083 vl_api_gpe_fwd_entry_path_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016084 vl_api_control_ping_t *mp_ping;
Filip Tehlar5fae99c2017-01-18 12:57:37 +010016085 unformat_input_t *i = vam->input;
16086 u32 fwd_entry_index = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016087 int ret;
Filip Tehlar5fae99c2017-01-18 12:57:37 +010016088
16089 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16090 {
16091 if (unformat (i, "index %d", &fwd_entry_index))
16092 ;
16093 else
16094 break;
16095 }
16096
16097 if (~0 == fwd_entry_index)
16098 {
16099 errmsg ("no index specified!");
16100 return -99;
16101 }
16102
16103 if (!vam->json_output)
16104 {
16105 print (vam->ofp, "first line");
16106 }
16107
Filip Tehlar82786c42017-02-20 15:20:37 +010016108 M (GPE_FWD_ENTRY_PATH_DUMP, mp);
Filip Tehlar5fae99c2017-01-18 12:57:37 +010016109
16110 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016111 S (mp);
Filip Tehlar5fae99c2017-01-18 12:57:37 +010016112 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016113 M (CONTROL_PING, mp_ping);
16114 S (mp_ping);
16115
Filip Tehlar5fae99c2017-01-18 12:57:37 +010016116 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060016117 W (ret);
16118 return ret;
Filip Tehlar5fae99c2017-01-18 12:57:37 +010016119}
16120
16121static int
Filip Tehlar694396d2017-02-17 14:29:11 +010016122api_one_get_map_request_itr_rlocs (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010016123{
Filip Tehlar694396d2017-02-17 14:29:11 +010016124 vl_api_one_get_map_request_itr_rlocs_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016125 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016126
16127 if (!vam->json_output)
16128 {
16129 print (vam->ofp, "%=20s", "itr-rlocs:");
16130 }
16131
Filip Tehlar694396d2017-02-17 14:29:11 +010016132 M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016133 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016134 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016135 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060016136 W (ret);
16137 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016138}
16139
Filip Tehlar694396d2017-02-17 14:29:11 +010016140#define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
16141
Damjan Marion7cd468a2016-12-19 23:05:39 +010016142static int
16143api_af_packet_create (vat_main_t * vam)
16144{
16145 unformat_input_t *i = vam->input;
16146 vl_api_af_packet_create_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016147 u8 *host_if_name = 0;
16148 u8 hw_addr[6];
16149 u8 random_hw_addr = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016150 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016151
16152 memset (hw_addr, 0, sizeof (hw_addr));
16153
16154 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16155 {
16156 if (unformat (i, "name %s", &host_if_name))
16157 vec_add1 (host_if_name, 0);
16158 else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
16159 random_hw_addr = 0;
16160 else
16161 break;
16162 }
16163
16164 if (!vec_len (host_if_name))
16165 {
16166 errmsg ("host-interface name must be specified");
16167 return -99;
16168 }
16169
16170 if (vec_len (host_if_name) > 64)
16171 {
16172 errmsg ("host-interface name too long");
16173 return -99;
16174 }
16175
Jon Loeliger8a2aea32017-01-31 13:19:40 -060016176 M (AF_PACKET_CREATE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016177
16178 clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
16179 clib_memcpy (mp->hw_addr, hw_addr, 6);
16180 mp->use_random_hw_addr = random_hw_addr;
16181 vec_free (host_if_name);
16182
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016183 S (mp);
Dave Baracha1a093d2017-03-02 13:13:23 -050016184
16185 /* *INDENT-OFF* */
16186 W2 (ret,
16187 ({
16188 if (ret == 0)
16189 fprintf (vam->ofp ? vam->ofp : stderr,
16190 " new sw_if_index = %d\n", vam->sw_if_index);
16191 }));
16192 /* *INDENT-ON* */
Jon Loeliger56c7b012017-02-01 12:31:41 -060016193 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016194}
16195
16196static int
16197api_af_packet_delete (vat_main_t * vam)
16198{
16199 unformat_input_t *i = vam->input;
16200 vl_api_af_packet_delete_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016201 u8 *host_if_name = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016202 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016203
16204 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16205 {
16206 if (unformat (i, "name %s", &host_if_name))
16207 vec_add1 (host_if_name, 0);
16208 else
16209 break;
16210 }
16211
16212 if (!vec_len (host_if_name))
16213 {
16214 errmsg ("host-interface name must be specified");
16215 return -99;
16216 }
16217
16218 if (vec_len (host_if_name) > 64)
16219 {
16220 errmsg ("host-interface name too long");
16221 return -99;
16222 }
16223
Jon Loeliger8a2aea32017-01-31 13:19:40 -060016224 M (AF_PACKET_DELETE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016225
16226 clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
16227 vec_free (host_if_name);
16228
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016229 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060016230 W (ret);
16231 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016232}
16233
16234static int
16235api_policer_add_del (vat_main_t * vam)
16236{
16237 unformat_input_t *i = vam->input;
16238 vl_api_policer_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016239 u8 is_add = 1;
16240 u8 *name = 0;
16241 u32 cir = 0;
16242 u32 eir = 0;
16243 u64 cb = 0;
16244 u64 eb = 0;
16245 u8 rate_type = 0;
16246 u8 round_type = 0;
16247 u8 type = 0;
16248 u8 color_aware = 0;
16249 sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016250 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016251
16252 conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
16253 conform_action.dscp = 0;
16254 exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
16255 exceed_action.dscp = 0;
16256 violate_action.action_type = SSE2_QOS_ACTION_DROP;
16257 violate_action.dscp = 0;
16258
16259 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16260 {
16261 if (unformat (i, "del"))
16262 is_add = 0;
16263 else if (unformat (i, "name %s", &name))
16264 vec_add1 (name, 0);
16265 else if (unformat (i, "cir %u", &cir))
16266 ;
16267 else if (unformat (i, "eir %u", &eir))
16268 ;
16269 else if (unformat (i, "cb %u", &cb))
16270 ;
16271 else if (unformat (i, "eb %u", &eb))
16272 ;
16273 else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
16274 &rate_type))
16275 ;
16276 else if (unformat (i, "round_type %U", unformat_policer_round_type,
16277 &round_type))
16278 ;
16279 else if (unformat (i, "type %U", unformat_policer_type, &type))
16280 ;
16281 else if (unformat (i, "conform_action %U", unformat_policer_action_type,
16282 &conform_action))
16283 ;
16284 else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
16285 &exceed_action))
16286 ;
16287 else if (unformat (i, "violate_action %U", unformat_policer_action_type,
16288 &violate_action))
16289 ;
16290 else if (unformat (i, "color-aware"))
16291 color_aware = 1;
16292 else
16293 break;
16294 }
16295
16296 if (!vec_len (name))
16297 {
16298 errmsg ("policer name must be specified");
16299 return -99;
16300 }
16301
16302 if (vec_len (name) > 64)
16303 {
16304 errmsg ("policer name too long");
16305 return -99;
16306 }
16307
Jon Loeliger8a2aea32017-01-31 13:19:40 -060016308 M (POLICER_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016309
16310 clib_memcpy (mp->name, name, vec_len (name));
16311 vec_free (name);
16312 mp->is_add = is_add;
16313 mp->cir = cir;
16314 mp->eir = eir;
16315 mp->cb = cb;
16316 mp->eb = eb;
16317 mp->rate_type = rate_type;
16318 mp->round_type = round_type;
16319 mp->type = type;
16320 mp->conform_action_type = conform_action.action_type;
16321 mp->conform_dscp = conform_action.dscp;
16322 mp->exceed_action_type = exceed_action.action_type;
16323 mp->exceed_dscp = exceed_action.dscp;
16324 mp->violate_action_type = violate_action.action_type;
16325 mp->violate_dscp = violate_action.dscp;
16326 mp->color_aware = color_aware;
16327
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016328 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060016329 W (ret);
16330 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016331}
16332
16333static int
16334api_policer_dump (vat_main_t * vam)
16335{
16336 unformat_input_t *i = vam->input;
16337 vl_api_policer_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016338 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016339 u8 *match_name = 0;
16340 u8 match_name_valid = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016341 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016342
16343 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16344 {
16345 if (unformat (i, "name %s", &match_name))
16346 {
16347 vec_add1 (match_name, 0);
16348 match_name_valid = 1;
16349 }
16350 else
16351 break;
16352 }
16353
Jon Loeliger8a2aea32017-01-31 13:19:40 -060016354 M (POLICER_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016355 mp->match_name_valid = match_name_valid;
16356 clib_memcpy (mp->match_name, match_name, vec_len (match_name));
16357 vec_free (match_name);
16358 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016359 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016360
16361 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016362 M (CONTROL_PING, mp_ping);
16363 S (mp_ping);
16364
Damjan Marion7cd468a2016-12-19 23:05:39 +010016365 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060016366 W (ret);
16367 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016368}
16369
16370static int
16371api_policer_classify_set_interface (vat_main_t * vam)
16372{
16373 unformat_input_t *i = vam->input;
16374 vl_api_policer_classify_set_interface_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016375 u32 sw_if_index;
16376 int sw_if_index_set;
16377 u32 ip4_table_index = ~0;
16378 u32 ip6_table_index = ~0;
16379 u32 l2_table_index = ~0;
16380 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016381 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016382
16383 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16384 {
16385 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16386 sw_if_index_set = 1;
16387 else if (unformat (i, "sw_if_index %d", &sw_if_index))
16388 sw_if_index_set = 1;
16389 else if (unformat (i, "del"))
16390 is_add = 0;
16391 else if (unformat (i, "ip4-table %d", &ip4_table_index))
16392 ;
16393 else if (unformat (i, "ip6-table %d", &ip6_table_index))
16394 ;
16395 else if (unformat (i, "l2-table %d", &l2_table_index))
16396 ;
16397 else
16398 {
16399 clib_warning ("parse error '%U'", format_unformat_error, i);
16400 return -99;
16401 }
16402 }
16403
16404 if (sw_if_index_set == 0)
16405 {
16406 errmsg ("missing interface name or sw_if_index");
16407 return -99;
16408 }
16409
Jon Loeliger8a2aea32017-01-31 13:19:40 -060016410 M (POLICER_CLASSIFY_SET_INTERFACE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016411
16412 mp->sw_if_index = ntohl (sw_if_index);
16413 mp->ip4_table_index = ntohl (ip4_table_index);
16414 mp->ip6_table_index = ntohl (ip6_table_index);
16415 mp->l2_table_index = ntohl (l2_table_index);
16416 mp->is_add = is_add;
16417
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016418 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060016419 W (ret);
16420 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016421}
16422
16423static int
16424api_policer_classify_dump (vat_main_t * vam)
16425{
16426 unformat_input_t *i = vam->input;
16427 vl_api_policer_classify_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016428 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016429 u8 type = POLICER_CLASSIFY_N_TABLES;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016430 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016431
16432 if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
16433 ;
16434 else
16435 {
16436 errmsg ("classify table type must be specified");
16437 return -99;
16438 }
16439
16440 if (!vam->json_output)
16441 {
16442 print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
16443 }
16444
Jon Loeliger8a2aea32017-01-31 13:19:40 -060016445 M (POLICER_CLASSIFY_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016446 mp->type = type;
16447 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016448 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016449
16450 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016451 M (CONTROL_PING, mp_ping);
16452 S (mp_ping);
16453
Damjan Marion7cd468a2016-12-19 23:05:39 +010016454 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060016455 W (ret);
16456 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016457}
16458
16459static int
16460api_netmap_create (vat_main_t * vam)
16461{
16462 unformat_input_t *i = vam->input;
16463 vl_api_netmap_create_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016464 u8 *if_name = 0;
16465 u8 hw_addr[6];
16466 u8 random_hw_addr = 1;
16467 u8 is_pipe = 0;
16468 u8 is_master = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016469 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016470
16471 memset (hw_addr, 0, sizeof (hw_addr));
16472
16473 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16474 {
16475 if (unformat (i, "name %s", &if_name))
16476 vec_add1 (if_name, 0);
16477 else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
16478 random_hw_addr = 0;
16479 else if (unformat (i, "pipe"))
16480 is_pipe = 1;
16481 else if (unformat (i, "master"))
16482 is_master = 1;
16483 else if (unformat (i, "slave"))
16484 is_master = 0;
16485 else
16486 break;
16487 }
16488
16489 if (!vec_len (if_name))
16490 {
16491 errmsg ("interface name must be specified");
16492 return -99;
16493 }
16494
16495 if (vec_len (if_name) > 64)
16496 {
16497 errmsg ("interface name too long");
16498 return -99;
16499 }
16500
Jon Loeliger8a2aea32017-01-31 13:19:40 -060016501 M (NETMAP_CREATE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016502
16503 clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
16504 clib_memcpy (mp->hw_addr, hw_addr, 6);
16505 mp->use_random_hw_addr = random_hw_addr;
16506 mp->is_pipe = is_pipe;
16507 mp->is_master = is_master;
16508 vec_free (if_name);
16509
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016510 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060016511 W (ret);
16512 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016513}
16514
16515static int
16516api_netmap_delete (vat_main_t * vam)
16517{
16518 unformat_input_t *i = vam->input;
16519 vl_api_netmap_delete_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016520 u8 *if_name = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016521 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016522
16523 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16524 {
16525 if (unformat (i, "name %s", &if_name))
16526 vec_add1 (if_name, 0);
16527 else
16528 break;
16529 }
16530
16531 if (!vec_len (if_name))
16532 {
16533 errmsg ("interface name must be specified");
16534 return -99;
16535 }
16536
16537 if (vec_len (if_name) > 64)
16538 {
16539 errmsg ("interface name too long");
16540 return -99;
16541 }
16542
Jon Loeliger8a2aea32017-01-31 13:19:40 -060016543 M (NETMAP_DELETE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016544
16545 clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
16546 vec_free (if_name);
16547
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016548 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060016549 W (ret);
16550 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016551}
16552
Neale Ranns0f26c5a2017-03-01 15:12:11 -080016553static void
16554vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path2_t * fp)
16555{
16556 if (fp->afi == IP46_TYPE_IP6)
16557 print (vam->ofp,
16558 " weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16559 "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16560 ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16561 fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16562 format_ip6_address, fp->next_hop);
16563 else if (fp->afi == IP46_TYPE_IP4)
16564 print (vam->ofp,
16565 " weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16566 "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16567 ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16568 fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16569 format_ip4_address, fp->next_hop);
16570}
16571
16572static void
16573vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
16574 vl_api_fib_path2_t * fp)
16575{
16576 struct in_addr ip4;
16577 struct in6_addr ip6;
16578
16579 vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16580 vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16581 vat_json_object_add_uint (node, "is_local", fp->is_local);
16582 vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16583 vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16584 vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16585 vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16586 if (fp->afi == IP46_TYPE_IP4)
16587 {
16588 clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16589 vat_json_object_add_ip4 (node, "next_hop", ip4);
16590 }
16591 else if (fp->afi == IP46_TYPE_IP6)
16592 {
16593 clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16594 vat_json_object_add_ip6 (node, "next_hop", ip6);
16595 }
16596}
16597
16598static void
16599vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010016600{
16601 vat_main_t *vam = &vat_main;
Neale Ranns0f26c5a2017-03-01 15:12:11 -080016602 int count = ntohl (mp->mt_count);
16603 vl_api_fib_path2_t *fp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016604 i32 i;
16605
Neale Ranns0f26c5a2017-03-01 15:12:11 -080016606 print (vam->ofp, "[%d]: sw_if_index %d via:",
16607 ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
16608 fp = mp->mt_paths;
16609 for (i = 0; i < count; i++)
Damjan Marion7cd468a2016-12-19 23:05:39 +010016610 {
Neale Ranns0f26c5a2017-03-01 15:12:11 -080016611 vl_api_mpls_fib_path_print (vam, fp);
16612 fp++;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016613 }
Neale Ranns0f26c5a2017-03-01 15:12:11 -080016614
Damjan Marion7cd468a2016-12-19 23:05:39 +010016615 print (vam->ofp, "");
16616}
16617
Neale Ranns0f26c5a2017-03-01 15:12:11 -080016618#define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
16619#define vl_api_mpls_tunnel_details_t_print vl_noop_handler
16620
16621static void
16622vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010016623{
16624 vat_main_t *vam = &vat_main;
16625 vat_json_node_t *node = NULL;
Neale Ranns0f26c5a2017-03-01 15:12:11 -080016626 int count = ntohl (mp->mt_count);
16627 vl_api_fib_path2_t *fp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016628 i32 i;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016629
16630 if (VAT_JSON_ARRAY != vam->json_tree.type)
16631 {
16632 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16633 vat_json_init_array (&vam->json_tree);
16634 }
16635 node = vat_json_array_add (&vam->json_tree);
16636
16637 vat_json_init_object (node);
Neale Ranns0f26c5a2017-03-01 15:12:11 -080016638 vat_json_object_add_uint (node, "tunnel_index",
16639 ntohl (mp->mt_tunnel_index));
16640 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
16641
16642 vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
16643
16644 fp = mp->mt_paths;
16645 for (i = 0; i < count; i++)
Damjan Marion7cd468a2016-12-19 23:05:39 +010016646 {
Neale Ranns0f26c5a2017-03-01 15:12:11 -080016647 vl_api_mpls_fib_path_json_print (node, fp);
16648 fp++;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016649 }
16650}
16651
16652static int
16653api_mpls_tunnel_dump (vat_main_t * vam)
16654{
16655 vl_api_mpls_tunnel_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016656 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016657 i32 index = -1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016658 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016659
16660 /* Parse args required to build the message */
16661 while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
16662 {
16663 if (!unformat (vam->input, "tunnel_index %d", &index))
16664 {
16665 index = -1;
16666 break;
16667 }
16668 }
16669
16670 print (vam->ofp, " tunnel_index %d", index);
16671
Jon Loeliger8a2aea32017-01-31 13:19:40 -060016672 M (MPLS_TUNNEL_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016673 mp->tunnel_index = htonl (index);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016674 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016675
16676 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016677 M (CONTROL_PING, mp_ping);
16678 S (mp_ping);
16679
Jon Loeliger56c7b012017-02-01 12:31:41 -060016680 W (ret);
16681 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016682}
16683
16684#define vl_api_mpls_fib_details_t_endian vl_noop_handler
16685#define vl_api_mpls_fib_details_t_print vl_noop_handler
16686
Neale Ranns0f26c5a2017-03-01 15:12:11 -080016687
Damjan Marion7cd468a2016-12-19 23:05:39 +010016688static void
16689vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
16690{
16691 vat_main_t *vam = &vat_main;
16692 int count = ntohl (mp->count);
16693 vl_api_fib_path2_t *fp;
16694 int i;
16695
16696 print (vam->ofp,
16697 "table-id %d, label %u, ess_bit %u",
16698 ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
16699 fp = mp->path;
16700 for (i = 0; i < count; i++)
16701 {
Neale Ranns0f26c5a2017-03-01 15:12:11 -080016702 vl_api_mpls_fib_path_print (vam, fp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016703 fp++;
16704 }
16705}
16706
16707static void vl_api_mpls_fib_details_t_handler_json
16708 (vl_api_mpls_fib_details_t * mp)
16709{
16710 vat_main_t *vam = &vat_main;
16711 int count = ntohl (mp->count);
16712 vat_json_node_t *node = NULL;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016713 vl_api_fib_path2_t *fp;
16714 int i;
16715
16716 if (VAT_JSON_ARRAY != vam->json_tree.type)
16717 {
16718 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16719 vat_json_init_array (&vam->json_tree);
16720 }
16721 node = vat_json_array_add (&vam->json_tree);
16722
16723 vat_json_init_object (node);
16724 vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16725 vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
16726 vat_json_object_add_uint (node, "label", ntohl (mp->label));
16727 vat_json_object_add_uint (node, "path_count", count);
16728 fp = mp->path;
16729 for (i = 0; i < count; i++)
16730 {
Neale Ranns0f26c5a2017-03-01 15:12:11 -080016731 vl_api_mpls_fib_path_json_print (node, fp);
16732 fp++;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016733 }
16734}
16735
16736static int
16737api_mpls_fib_dump (vat_main_t * vam)
16738{
16739 vl_api_mpls_fib_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016740 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016741 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016742
Jon Loeliger8a2aea32017-01-31 13:19:40 -060016743 M (MPLS_FIB_DUMP, mp);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016744 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016745
16746 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016747 M (CONTROL_PING, mp_ping);
16748 S (mp_ping);
16749
Jon Loeliger56c7b012017-02-01 12:31:41 -060016750 W (ret);
16751 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016752}
16753
16754#define vl_api_ip_fib_details_t_endian vl_noop_handler
16755#define vl_api_ip_fib_details_t_print vl_noop_handler
16756
16757static void
16758vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
16759{
16760 vat_main_t *vam = &vat_main;
16761 int count = ntohl (mp->count);
16762 vl_api_fib_path_t *fp;
16763 int i;
16764
16765 print (vam->ofp,
16766 "table-id %d, prefix %U/%d",
16767 ntohl (mp->table_id), format_ip4_address, mp->address,
16768 mp->address_length);
16769 fp = mp->path;
16770 for (i = 0; i < count; i++)
16771 {
16772 if (fp->afi == IP46_TYPE_IP6)
16773 print (vam->ofp,
16774 " weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16775 "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16776 ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16777 fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16778 format_ip6_address, fp->next_hop);
16779 else if (fp->afi == IP46_TYPE_IP4)
16780 print (vam->ofp,
16781 " weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16782 "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16783 ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16784 fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16785 format_ip4_address, fp->next_hop);
16786 fp++;
16787 }
16788}
16789
16790static void vl_api_ip_fib_details_t_handler_json
16791 (vl_api_ip_fib_details_t * mp)
16792{
16793 vat_main_t *vam = &vat_main;
16794 int count = ntohl (mp->count);
16795 vat_json_node_t *node = NULL;
16796 struct in_addr ip4;
16797 struct in6_addr ip6;
16798 vl_api_fib_path_t *fp;
16799 int i;
16800
16801 if (VAT_JSON_ARRAY != vam->json_tree.type)
16802 {
16803 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16804 vat_json_init_array (&vam->json_tree);
16805 }
16806 node = vat_json_array_add (&vam->json_tree);
16807
16808 vat_json_init_object (node);
16809 vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16810 clib_memcpy (&ip4, &mp->address, sizeof (ip4));
16811 vat_json_object_add_ip4 (node, "prefix", ip4);
16812 vat_json_object_add_uint (node, "mask_length", mp->address_length);
16813 vat_json_object_add_uint (node, "path_count", count);
16814 fp = mp->path;
16815 for (i = 0; i < count; i++)
16816 {
16817 vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16818 vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16819 vat_json_object_add_uint (node, "is_local", fp->is_local);
16820 vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16821 vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16822 vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16823 vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16824 if (fp->afi == IP46_TYPE_IP4)
16825 {
16826 clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16827 vat_json_object_add_ip4 (node, "next_hop", ip4);
16828 }
16829 else if (fp->afi == IP46_TYPE_IP6)
16830 {
16831 clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16832 vat_json_object_add_ip6 (node, "next_hop", ip6);
16833 }
16834 }
16835}
16836
16837static int
16838api_ip_fib_dump (vat_main_t * vam)
16839{
16840 vl_api_ip_fib_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016841 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016842 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016843
Jon Loeliger8a2aea32017-01-31 13:19:40 -060016844 M (IP_FIB_DUMP, mp);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016845 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016846
16847 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016848 M (CONTROL_PING, mp_ping);
16849 S (mp_ping);
16850
Jon Loeliger56c7b012017-02-01 12:31:41 -060016851 W (ret);
16852 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016853}
16854
Neale Ranns5a8123b2017-01-26 01:18:23 -080016855static int
16856api_ip_mfib_dump (vat_main_t * vam)
16857{
16858 vl_api_ip_mfib_dump_t *mp;
16859 vl_api_control_ping_t *mp_ping;
16860 int ret;
16861
16862 M (IP_MFIB_DUMP, mp);
16863 S (mp);
16864
16865 /* Use a control ping for synchronization */
16866 M (CONTROL_PING, mp_ping);
16867 S (mp_ping);
16868
16869 W (ret);
16870 return ret;
16871}
16872
Damjan Marion7cd468a2016-12-19 23:05:39 +010016873static void vl_api_ip_neighbor_details_t_handler
16874 (vl_api_ip_neighbor_details_t * mp)
16875{
16876 vat_main_t *vam = &vat_main;
16877
16878 print (vam->ofp, "%c %U %U",
16879 (mp->is_static) ? 'S' : 'D',
16880 format_ethernet_address, &mp->mac_address,
16881 (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
16882 &mp->ip_address);
16883}
16884
16885static void vl_api_ip_neighbor_details_t_handler_json
16886 (vl_api_ip_neighbor_details_t * mp)
16887{
16888
16889 vat_main_t *vam = &vat_main;
16890 vat_json_node_t *node;
16891 struct in_addr ip4;
16892 struct in6_addr ip6;
16893
16894 if (VAT_JSON_ARRAY != vam->json_tree.type)
16895 {
16896 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16897 vat_json_init_array (&vam->json_tree);
16898 }
16899 node = vat_json_array_add (&vam->json_tree);
16900
16901 vat_json_init_object (node);
16902 vat_json_object_add_string_copy (node, "flag",
16903 (mp->is_static) ? (u8 *) "static" : (u8 *)
16904 "dynamic");
16905
16906 vat_json_object_add_string_copy (node, "link_layer",
16907 format (0, "%U", format_ethernet_address,
16908 &mp->mac_address));
16909
16910 if (mp->is_ipv6)
16911 {
16912 clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
16913 vat_json_object_add_ip6 (node, "ip_address", ip6);
16914 }
16915 else
16916 {
16917 clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
16918 vat_json_object_add_ip4 (node, "ip_address", ip4);
16919 }
16920}
16921
16922static int
16923api_ip_neighbor_dump (vat_main_t * vam)
16924{
16925 unformat_input_t *i = vam->input;
16926 vl_api_ip_neighbor_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016927 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016928 u8 is_ipv6 = 0;
16929 u32 sw_if_index = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016930 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016931
16932 /* Parse args required to build the message */
16933 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16934 {
16935 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16936 ;
16937 else if (unformat (i, "sw_if_index %d", &sw_if_index))
16938 ;
16939 else if (unformat (i, "ip6"))
16940 is_ipv6 = 1;
16941 else
16942 break;
16943 }
16944
16945 if (sw_if_index == ~0)
16946 {
16947 errmsg ("missing interface name or sw_if_index");
16948 return -99;
16949 }
16950
Jon Loeliger8a2aea32017-01-31 13:19:40 -060016951 M (IP_NEIGHBOR_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016952 mp->is_ipv6 = (u8) is_ipv6;
16953 mp->sw_if_index = ntohl (sw_if_index);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016954 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016955
16956 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016957 M (CONTROL_PING, mp_ping);
16958 S (mp_ping);
16959
Jon Loeliger56c7b012017-02-01 12:31:41 -060016960 W (ret);
16961 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016962}
16963
16964#define vl_api_ip6_fib_details_t_endian vl_noop_handler
16965#define vl_api_ip6_fib_details_t_print vl_noop_handler
16966
16967static void
16968vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
16969{
16970 vat_main_t *vam = &vat_main;
16971 int count = ntohl (mp->count);
16972 vl_api_fib_path_t *fp;
16973 int i;
16974
16975 print (vam->ofp,
16976 "table-id %d, prefix %U/%d",
16977 ntohl (mp->table_id), format_ip6_address, mp->address,
16978 mp->address_length);
16979 fp = mp->path;
16980 for (i = 0; i < count; i++)
16981 {
16982 if (fp->afi == IP46_TYPE_IP6)
16983 print (vam->ofp,
16984 " weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16985 "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16986 ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16987 fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16988 format_ip6_address, fp->next_hop);
16989 else if (fp->afi == IP46_TYPE_IP4)
16990 print (vam->ofp,
16991 " weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16992 "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16993 ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16994 fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16995 format_ip4_address, fp->next_hop);
16996 fp++;
16997 }
16998}
16999
17000static void vl_api_ip6_fib_details_t_handler_json
17001 (vl_api_ip6_fib_details_t * mp)
17002{
17003 vat_main_t *vam = &vat_main;
17004 int count = ntohl (mp->count);
17005 vat_json_node_t *node = NULL;
17006 struct in_addr ip4;
17007 struct in6_addr ip6;
17008 vl_api_fib_path_t *fp;
17009 int i;
17010
17011 if (VAT_JSON_ARRAY != vam->json_tree.type)
17012 {
17013 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17014 vat_json_init_array (&vam->json_tree);
17015 }
17016 node = vat_json_array_add (&vam->json_tree);
17017
17018 vat_json_init_object (node);
17019 vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
17020 clib_memcpy (&ip6, &mp->address, sizeof (ip6));
17021 vat_json_object_add_ip6 (node, "prefix", ip6);
17022 vat_json_object_add_uint (node, "mask_length", mp->address_length);
17023 vat_json_object_add_uint (node, "path_count", count);
17024 fp = mp->path;
17025 for (i = 0; i < count; i++)
17026 {
17027 vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17028 vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17029 vat_json_object_add_uint (node, "is_local", fp->is_local);
17030 vat_json_object_add_uint (node, "is_drop", fp->is_drop);
17031 vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
17032 vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
17033 vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
17034 if (fp->afi == IP46_TYPE_IP4)
17035 {
17036 clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
17037 vat_json_object_add_ip4 (node, "next_hop", ip4);
17038 }
17039 else if (fp->afi == IP46_TYPE_IP6)
17040 {
17041 clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
17042 vat_json_object_add_ip6 (node, "next_hop", ip6);
17043 }
17044 }
17045}
17046
17047static int
17048api_ip6_fib_dump (vat_main_t * vam)
17049{
17050 vl_api_ip6_fib_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060017051 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017052 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017053
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017054 M (IP6_FIB_DUMP, mp);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017055 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017056
17057 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060017058 M (CONTROL_PING, mp_ping);
17059 S (mp_ping);
17060
Jon Loeliger56c7b012017-02-01 12:31:41 -060017061 W (ret);
17062 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017063}
17064
Neale Ranns5a8123b2017-01-26 01:18:23 -080017065static int
17066api_ip6_mfib_dump (vat_main_t * vam)
17067{
17068 vl_api_ip6_mfib_dump_t *mp;
17069 vl_api_control_ping_t *mp_ping;
17070 int ret;
17071
17072 M (IP6_MFIB_DUMP, mp);
17073 S (mp);
17074
17075 /* Use a control ping for synchronization */
17076 M (CONTROL_PING, mp_ping);
17077 S (mp_ping);
17078
17079 W (ret);
17080 return ret;
17081}
17082
Damjan Marion7cd468a2016-12-19 23:05:39 +010017083int
17084api_classify_table_ids (vat_main_t * vam)
17085{
17086 vl_api_classify_table_ids_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017087 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017088
17089 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017090 M (CLASSIFY_TABLE_IDS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017091 mp->context = 0;
17092
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017093 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060017094 W (ret);
17095 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017096}
17097
17098int
17099api_classify_table_by_interface (vat_main_t * vam)
17100{
17101 unformat_input_t *input = vam->input;
17102 vl_api_classify_table_by_interface_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017103
17104 u32 sw_if_index = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017105 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017106 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17107 {
17108 if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17109 ;
17110 else if (unformat (input, "sw_if_index %d", &sw_if_index))
17111 ;
17112 else
17113 break;
17114 }
17115 if (sw_if_index == ~0)
17116 {
17117 errmsg ("missing interface name or sw_if_index");
17118 return -99;
17119 }
17120
17121 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017122 M (CLASSIFY_TABLE_BY_INTERFACE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017123 mp->context = 0;
17124 mp->sw_if_index = ntohl (sw_if_index);
17125
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017126 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060017127 W (ret);
17128 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017129}
17130
17131int
17132api_classify_table_info (vat_main_t * vam)
17133{
17134 unformat_input_t *input = vam->input;
17135 vl_api_classify_table_info_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017136
17137 u32 table_id = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017138 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017139 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17140 {
17141 if (unformat (input, "table_id %d", &table_id))
17142 ;
17143 else
17144 break;
17145 }
17146 if (table_id == ~0)
17147 {
17148 errmsg ("missing table id");
17149 return -99;
17150 }
17151
17152 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017153 M (CLASSIFY_TABLE_INFO, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017154 mp->context = 0;
17155 mp->table_id = ntohl (table_id);
17156
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017157 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060017158 W (ret);
17159 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017160}
17161
17162int
17163api_classify_session_dump (vat_main_t * vam)
17164{
17165 unformat_input_t *input = vam->input;
17166 vl_api_classify_session_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060017167 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017168
17169 u32 table_id = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017170 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017171 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17172 {
17173 if (unformat (input, "table_id %d", &table_id))
17174 ;
17175 else
17176 break;
17177 }
17178 if (table_id == ~0)
17179 {
17180 errmsg ("missing table id");
17181 return -99;
17182 }
17183
17184 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017185 M (CLASSIFY_SESSION_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017186 mp->context = 0;
17187 mp->table_id = ntohl (table_id);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017188 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017189
17190 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060017191 M (CONTROL_PING, mp_ping);
17192 S (mp_ping);
17193
Jon Loeliger56c7b012017-02-01 12:31:41 -060017194 W (ret);
17195 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017196}
17197
17198static void
17199vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
17200{
17201 vat_main_t *vam = &vat_main;
17202
17203 print (vam->ofp, "collector_address %U, collector_port %d, "
17204 "src_address %U, vrf_id %d, path_mtu %u, "
17205 "template_interval %u, udp_checksum %d",
17206 format_ip4_address, mp->collector_address,
17207 ntohs (mp->collector_port),
17208 format_ip4_address, mp->src_address,
17209 ntohl (mp->vrf_id), ntohl (mp->path_mtu),
17210 ntohl (mp->template_interval), mp->udp_checksum);
17211
17212 vam->retval = 0;
17213 vam->result_ready = 1;
17214}
17215
17216static void
17217 vl_api_ipfix_exporter_details_t_handler_json
17218 (vl_api_ipfix_exporter_details_t * mp)
17219{
17220 vat_main_t *vam = &vat_main;
17221 vat_json_node_t node;
17222 struct in_addr collector_address;
17223 struct in_addr src_address;
17224
17225 vat_json_init_object (&node);
17226 clib_memcpy (&collector_address, &mp->collector_address,
17227 sizeof (collector_address));
17228 vat_json_object_add_ip4 (&node, "collector_address", collector_address);
17229 vat_json_object_add_uint (&node, "collector_port",
17230 ntohs (mp->collector_port));
17231 clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
17232 vat_json_object_add_ip4 (&node, "src_address", src_address);
17233 vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
17234 vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
17235 vat_json_object_add_uint (&node, "template_interval",
17236 ntohl (mp->template_interval));
17237 vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
17238
17239 vat_json_print (vam->ofp, &node);
17240 vat_json_free (&node);
17241 vam->retval = 0;
17242 vam->result_ready = 1;
17243}
17244
17245int
17246api_ipfix_exporter_dump (vat_main_t * vam)
17247{
17248 vl_api_ipfix_exporter_dump_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017249 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017250
17251 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017252 M (IPFIX_EXPORTER_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017253 mp->context = 0;
17254
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017255 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060017256 W (ret);
17257 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017258}
17259
17260static int
17261api_ipfix_classify_stream_dump (vat_main_t * vam)
17262{
17263 vl_api_ipfix_classify_stream_dump_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017264 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017265
17266 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017267 M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017268 mp->context = 0;
17269
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017270 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060017271 W (ret);
17272 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017273 /* NOTREACHED */
17274 return 0;
17275}
17276
17277static void
17278 vl_api_ipfix_classify_stream_details_t_handler
17279 (vl_api_ipfix_classify_stream_details_t * mp)
17280{
17281 vat_main_t *vam = &vat_main;
17282 print (vam->ofp, "domain_id %d, src_port %d",
17283 ntohl (mp->domain_id), ntohs (mp->src_port));
17284 vam->retval = 0;
17285 vam->result_ready = 1;
17286}
17287
17288static void
17289 vl_api_ipfix_classify_stream_details_t_handler_json
17290 (vl_api_ipfix_classify_stream_details_t * mp)
17291{
17292 vat_main_t *vam = &vat_main;
17293 vat_json_node_t node;
17294
17295 vat_json_init_object (&node);
17296 vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
17297 vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
17298
17299 vat_json_print (vam->ofp, &node);
17300 vat_json_free (&node);
17301 vam->retval = 0;
17302 vam->result_ready = 1;
17303}
17304
17305static int
17306api_ipfix_classify_table_dump (vat_main_t * vam)
17307{
17308 vl_api_ipfix_classify_table_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060017309 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017310 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017311
17312 if (!vam->json_output)
17313 {
17314 print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
17315 "transport_protocol");
17316 }
17317
17318 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017319 M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017320
17321 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017322 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017323
17324 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060017325 M (CONTROL_PING, mp_ping);
17326 S (mp_ping);
17327
Jon Loeliger56c7b012017-02-01 12:31:41 -060017328 W (ret);
17329 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017330}
17331
17332static void
17333 vl_api_ipfix_classify_table_details_t_handler
17334 (vl_api_ipfix_classify_table_details_t * mp)
17335{
17336 vat_main_t *vam = &vat_main;
17337 print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
17338 mp->transport_protocol);
17339}
17340
17341static void
17342 vl_api_ipfix_classify_table_details_t_handler_json
17343 (vl_api_ipfix_classify_table_details_t * mp)
17344{
17345 vat_json_node_t *node = NULL;
17346 vat_main_t *vam = &vat_main;
17347
17348 if (VAT_JSON_ARRAY != vam->json_tree.type)
17349 {
17350 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17351 vat_json_init_array (&vam->json_tree);
17352 }
17353
17354 node = vat_json_array_add (&vam->json_tree);
17355 vat_json_init_object (node);
17356
17357 vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
17358 vat_json_object_add_uint (node, "ip_version", mp->ip_version);
17359 vat_json_object_add_uint (node, "transport_protocol",
17360 mp->transport_protocol);
17361}
17362
17363static int
17364api_sw_interface_span_enable_disable (vat_main_t * vam)
17365{
17366 unformat_input_t *i = vam->input;
17367 vl_api_sw_interface_span_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017368 u32 src_sw_if_index = ~0;
17369 u32 dst_sw_if_index = ~0;
17370 u8 state = 3;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017371 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017372
17373 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17374 {
17375 if (unformat
17376 (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
17377 ;
17378 else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
17379 ;
17380 else
17381 if (unformat
17382 (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
17383 ;
17384 else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
17385 ;
17386 else if (unformat (i, "disable"))
17387 state = 0;
17388 else if (unformat (i, "rx"))
17389 state = 1;
17390 else if (unformat (i, "tx"))
17391 state = 2;
17392 else if (unformat (i, "both"))
17393 state = 3;
17394 else
17395 break;
17396 }
17397
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017398 M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017399
17400 mp->sw_if_index_from = htonl (src_sw_if_index);
17401 mp->sw_if_index_to = htonl (dst_sw_if_index);
17402 mp->state = state;
17403
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017404 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060017405 W (ret);
17406 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017407}
17408
17409static void
17410vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
17411 * mp)
17412{
17413 vat_main_t *vam = &vat_main;
17414 u8 *sw_if_from_name = 0;
17415 u8 *sw_if_to_name = 0;
17416 u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
17417 u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
17418 char *states[] = { "none", "rx", "tx", "both" };
17419 hash_pair_t *p;
17420
17421 /* *INDENT-OFF* */
17422 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
17423 ({
17424 if ((u32) p->value[0] == sw_if_index_from)
17425 {
17426 sw_if_from_name = (u8 *)(p->key);
17427 if (sw_if_to_name)
17428 break;
17429 }
17430 if ((u32) p->value[0] == sw_if_index_to)
17431 {
17432 sw_if_to_name = (u8 *)(p->key);
17433 if (sw_if_from_name)
17434 break;
17435 }
17436 }));
17437 /* *INDENT-ON* */
17438 print (vam->ofp, "%20s => %20s (%s)",
17439 sw_if_from_name, sw_if_to_name, states[mp->state]);
17440}
17441
17442static void
17443 vl_api_sw_interface_span_details_t_handler_json
17444 (vl_api_sw_interface_span_details_t * mp)
17445{
17446 vat_main_t *vam = &vat_main;
17447 vat_json_node_t *node = NULL;
17448 u8 *sw_if_from_name = 0;
17449 u8 *sw_if_to_name = 0;
17450 u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
17451 u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
17452 hash_pair_t *p;
17453
17454 /* *INDENT-OFF* */
17455 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
17456 ({
17457 if ((u32) p->value[0] == sw_if_index_from)
17458 {
17459 sw_if_from_name = (u8 *)(p->key);
17460 if (sw_if_to_name)
17461 break;
17462 }
17463 if ((u32) p->value[0] == sw_if_index_to)
17464 {
17465 sw_if_to_name = (u8 *)(p->key);
17466 if (sw_if_from_name)
17467 break;
17468 }
17469 }));
17470 /* *INDENT-ON* */
17471
17472 if (VAT_JSON_ARRAY != vam->json_tree.type)
17473 {
17474 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17475 vat_json_init_array (&vam->json_tree);
17476 }
17477 node = vat_json_array_add (&vam->json_tree);
17478
17479 vat_json_init_object (node);
17480 vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
17481 vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
17482 vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
Neale Ranns05b2bf22017-01-30 06:44:58 -080017483 if (0 != sw_if_to_name)
17484 {
17485 vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
17486 }
Damjan Marion7cd468a2016-12-19 23:05:39 +010017487 vat_json_object_add_uint (node, "state", mp->state);
17488}
17489
17490static int
17491api_sw_interface_span_dump (vat_main_t * vam)
17492{
17493 vl_api_sw_interface_span_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060017494 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017495 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017496
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017497 M (SW_INTERFACE_SPAN_DUMP, mp);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017498 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017499
17500 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060017501 M (CONTROL_PING, mp_ping);
17502 S (mp_ping);
17503
Jon Loeliger56c7b012017-02-01 12:31:41 -060017504 W (ret);
17505 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017506}
17507
17508int
17509api_pg_create_interface (vat_main_t * vam)
17510{
17511 unformat_input_t *input = vam->input;
17512 vl_api_pg_create_interface_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017513
17514 u32 if_id = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017515 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017516 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17517 {
17518 if (unformat (input, "if_id %d", &if_id))
17519 ;
17520 else
17521 break;
17522 }
17523 if (if_id == ~0)
17524 {
17525 errmsg ("missing pg interface index");
17526 return -99;
17527 }
17528
17529 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017530 M (PG_CREATE_INTERFACE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017531 mp->context = 0;
17532 mp->interface_id = ntohl (if_id);
17533
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017534 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060017535 W (ret);
17536 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017537}
17538
17539int
17540api_pg_capture (vat_main_t * vam)
17541{
17542 unformat_input_t *input = vam->input;
17543 vl_api_pg_capture_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017544
17545 u32 if_id = ~0;
17546 u8 enable = 1;
17547 u32 count = 1;
17548 u8 pcap_file_set = 0;
17549 u8 *pcap_file = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017550 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017551 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17552 {
17553 if (unformat (input, "if_id %d", &if_id))
17554 ;
17555 else if (unformat (input, "pcap %s", &pcap_file))
17556 pcap_file_set = 1;
17557 else if (unformat (input, "count %d", &count))
17558 ;
17559 else if (unformat (input, "disable"))
17560 enable = 0;
17561 else
17562 break;
17563 }
17564 if (if_id == ~0)
17565 {
17566 errmsg ("missing pg interface index");
17567 return -99;
17568 }
17569 if (pcap_file_set > 0)
17570 {
17571 if (vec_len (pcap_file) > 255)
17572 {
17573 errmsg ("pcap file name is too long");
17574 return -99;
17575 }
17576 }
17577
17578 u32 name_len = vec_len (pcap_file);
17579 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017580 M (PG_CAPTURE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017581 mp->context = 0;
17582 mp->interface_id = ntohl (if_id);
17583 mp->is_enabled = enable;
17584 mp->count = ntohl (count);
17585 mp->pcap_name_length = ntohl (name_len);
17586 if (pcap_file_set != 0)
17587 {
17588 clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
17589 }
17590 vec_free (pcap_file);
17591
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017592 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060017593 W (ret);
17594 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017595}
17596
17597int
17598api_pg_enable_disable (vat_main_t * vam)
17599{
17600 unformat_input_t *input = vam->input;
17601 vl_api_pg_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017602
17603 u8 enable = 1;
17604 u8 stream_name_set = 0;
17605 u8 *stream_name = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017606 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017607 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17608 {
17609 if (unformat (input, "stream %s", &stream_name))
17610 stream_name_set = 1;
17611 else if (unformat (input, "disable"))
17612 enable = 0;
17613 else
17614 break;
17615 }
17616
17617 if (stream_name_set > 0)
17618 {
17619 if (vec_len (stream_name) > 255)
17620 {
17621 errmsg ("stream name too long");
17622 return -99;
17623 }
17624 }
17625
17626 u32 name_len = vec_len (stream_name);
17627 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017628 M (PG_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017629 mp->context = 0;
17630 mp->is_enabled = enable;
17631 if (stream_name_set != 0)
17632 {
17633 mp->stream_name_length = ntohl (name_len);
17634 clib_memcpy (mp->stream_name, stream_name, name_len);
17635 }
17636 vec_free (stream_name);
17637
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017638 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060017639 W (ret);
17640 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017641}
17642
17643int
17644api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
17645{
17646 unformat_input_t *input = vam->input;
17647 vl_api_ip_source_and_port_range_check_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017648
17649 u16 *low_ports = 0;
17650 u16 *high_ports = 0;
17651 u16 this_low;
17652 u16 this_hi;
17653 ip4_address_t ip4_addr;
17654 ip6_address_t ip6_addr;
17655 u32 length;
17656 u32 tmp, tmp2;
17657 u8 prefix_set = 0;
17658 u32 vrf_id = ~0;
17659 u8 is_add = 1;
17660 u8 is_ipv6 = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017661 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017662
17663 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17664 {
17665 if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
17666 {
17667 prefix_set = 1;
17668 }
17669 else
17670 if (unformat
17671 (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
17672 {
17673 prefix_set = 1;
17674 is_ipv6 = 1;
17675 }
17676 else if (unformat (input, "vrf %d", &vrf_id))
17677 ;
17678 else if (unformat (input, "del"))
17679 is_add = 0;
17680 else if (unformat (input, "port %d", &tmp))
17681 {
17682 if (tmp == 0 || tmp > 65535)
17683 {
17684 errmsg ("port %d out of range", tmp);
17685 return -99;
17686 }
17687 this_low = tmp;
17688 this_hi = this_low + 1;
17689 vec_add1 (low_ports, this_low);
17690 vec_add1 (high_ports, this_hi);
17691 }
17692 else if (unformat (input, "range %d - %d", &tmp, &tmp2))
17693 {
17694 if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
17695 {
17696 errmsg ("incorrect range parameters");
17697 return -99;
17698 }
17699 this_low = tmp;
17700 /* Note: in debug CLI +1 is added to high before
17701 passing to real fn that does "the work"
17702 (ip_source_and_port_range_check_add_del).
17703 This fn is a wrapper around the binary API fn a
17704 control plane will call, which expects this increment
17705 to have occurred. Hence letting the binary API control
17706 plane fn do the increment for consistency between VAT
17707 and other control planes.
17708 */
17709 this_hi = tmp2;
17710 vec_add1 (low_ports, this_low);
17711 vec_add1 (high_ports, this_hi);
17712 }
17713 else
17714 break;
17715 }
17716
17717 if (prefix_set == 0)
17718 {
17719 errmsg ("<address>/<mask> not specified");
17720 return -99;
17721 }
17722
17723 if (vrf_id == ~0)
17724 {
17725 errmsg ("VRF ID required, not specified");
17726 return -99;
17727 }
17728
17729 if (vrf_id == 0)
17730 {
17731 errmsg
17732 ("VRF ID should not be default. Should be distinct VRF for this purpose.");
17733 return -99;
17734 }
17735
17736 if (vec_len (low_ports) == 0)
17737 {
17738 errmsg ("At least one port or port range required");
17739 return -99;
17740 }
17741
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017742 M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017743
17744 mp->is_add = is_add;
17745
17746 if (is_ipv6)
17747 {
17748 mp->is_ipv6 = 1;
17749 clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
17750 }
17751 else
17752 {
17753 mp->is_ipv6 = 0;
17754 clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
17755 }
17756
17757 mp->mask_length = length;
17758 mp->number_of_ranges = vec_len (low_ports);
17759
17760 clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
17761 vec_free (low_ports);
17762
17763 clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
17764 vec_free (high_ports);
17765
17766 mp->vrf_id = ntohl (vrf_id);
17767
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017768 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060017769 W (ret);
17770 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017771}
17772
17773int
17774api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
17775{
17776 unformat_input_t *input = vam->input;
17777 vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017778 u32 sw_if_index = ~0;
17779 int vrf_set = 0;
17780 u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
17781 u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
17782 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017783 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017784
17785 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17786 {
17787 if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17788 ;
17789 else if (unformat (input, "sw_if_index %d", &sw_if_index))
17790 ;
17791 else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
17792 vrf_set = 1;
17793 else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
17794 vrf_set = 1;
17795 else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
17796 vrf_set = 1;
17797 else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
17798 vrf_set = 1;
17799 else if (unformat (input, "del"))
17800 is_add = 0;
17801 else
17802 break;
17803 }
17804
17805 if (sw_if_index == ~0)
17806 {
17807 errmsg ("Interface required but not specified");
17808 return -99;
17809 }
17810
17811 if (vrf_set == 0)
17812 {
17813 errmsg ("VRF ID required but not specified");
17814 return -99;
17815 }
17816
17817 if (tcp_out_vrf_id == 0
17818 || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
17819 {
17820 errmsg
17821 ("VRF ID should not be default. Should be distinct VRF for this purpose.");
17822 return -99;
17823 }
17824
17825 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017826 M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017827
17828 mp->sw_if_index = ntohl (sw_if_index);
17829 mp->is_add = is_add;
17830 mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
17831 mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
17832 mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
17833 mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
17834
17835 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017836 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017837
17838 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060017839 W (ret);
17840 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017841}
17842
17843static int
17844api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
17845{
17846 unformat_input_t *i = vam->input;
17847 vl_api_ipsec_gre_add_del_tunnel_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017848 u32 local_sa_id = 0;
17849 u32 remote_sa_id = 0;
17850 ip4_address_t src_address;
17851 ip4_address_t dst_address;
17852 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017853 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017854
17855 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17856 {
17857 if (unformat (i, "local_sa %d", &local_sa_id))
17858 ;
17859 else if (unformat (i, "remote_sa %d", &remote_sa_id))
17860 ;
17861 else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
17862 ;
17863 else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
17864 ;
17865 else if (unformat (i, "del"))
17866 is_add = 0;
17867 else
17868 {
17869 clib_warning ("parse error '%U'", format_unformat_error, i);
17870 return -99;
17871 }
17872 }
17873
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017874 M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017875
17876 mp->local_sa_id = ntohl (local_sa_id);
17877 mp->remote_sa_id = ntohl (remote_sa_id);
17878 clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
17879 clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
17880 mp->is_add = is_add;
17881
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017882 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060017883 W (ret);
17884 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017885}
17886
17887static int
17888api_punt (vat_main_t * vam)
17889{
17890 unformat_input_t *i = vam->input;
17891 vl_api_punt_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017892 u32 ipv = ~0;
17893 u32 protocol = ~0;
17894 u32 port = ~0;
17895 int is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017896 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017897
17898 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17899 {
17900 if (unformat (i, "ip %d", &ipv))
17901 ;
17902 else if (unformat (i, "protocol %d", &protocol))
17903 ;
17904 else if (unformat (i, "port %d", &port))
17905 ;
17906 else if (unformat (i, "del"))
17907 is_add = 0;
17908 else
17909 {
17910 clib_warning ("parse error '%U'", format_unformat_error, i);
17911 return -99;
17912 }
17913 }
17914
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017915 M (PUNT, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017916
17917 mp->is_add = (u8) is_add;
17918 mp->ipv = (u8) ipv;
17919 mp->l4_protocol = (u8) protocol;
17920 mp->l4_port = htons ((u16) port);
17921
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017922 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060017923 W (ret);
17924 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017925}
17926
17927static void vl_api_ipsec_gre_tunnel_details_t_handler
17928 (vl_api_ipsec_gre_tunnel_details_t * mp)
17929{
17930 vat_main_t *vam = &vat_main;
17931
17932 print (vam->ofp, "%11d%15U%15U%14d%14d",
17933 ntohl (mp->sw_if_index),
17934 format_ip4_address, &mp->src_address,
17935 format_ip4_address, &mp->dst_address,
17936 ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
17937}
17938
17939static void vl_api_ipsec_gre_tunnel_details_t_handler_json
17940 (vl_api_ipsec_gre_tunnel_details_t * mp)
17941{
17942 vat_main_t *vam = &vat_main;
17943 vat_json_node_t *node = NULL;
17944 struct in_addr ip4;
17945
17946 if (VAT_JSON_ARRAY != vam->json_tree.type)
17947 {
17948 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17949 vat_json_init_array (&vam->json_tree);
17950 }
17951 node = vat_json_array_add (&vam->json_tree);
17952
17953 vat_json_init_object (node);
17954 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17955 clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
17956 vat_json_object_add_ip4 (node, "src_address", ip4);
17957 clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
17958 vat_json_object_add_ip4 (node, "dst_address", ip4);
17959 vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
17960 vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
17961}
17962
17963static int
17964api_ipsec_gre_tunnel_dump (vat_main_t * vam)
17965{
17966 unformat_input_t *i = vam->input;
17967 vl_api_ipsec_gre_tunnel_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060017968 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017969 u32 sw_if_index;
17970 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017971 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017972
17973 /* Parse args required to build the message */
17974 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17975 {
17976 if (unformat (i, "sw_if_index %d", &sw_if_index))
17977 sw_if_index_set = 1;
17978 else
17979 break;
17980 }
17981
17982 if (sw_if_index_set == 0)
17983 {
17984 sw_if_index = ~0;
17985 }
17986
17987 if (!vam->json_output)
17988 {
17989 print (vam->ofp, "%11s%15s%15s%14s%14s",
17990 "sw_if_index", "src_address", "dst_address",
17991 "local_sa_id", "remote_sa_id");
17992 }
17993
17994 /* Get list of gre-tunnel interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017995 M (IPSEC_GRE_TUNNEL_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017996
17997 mp->sw_if_index = htonl (sw_if_index);
17998
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017999 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010018000
18001 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060018002 M (CONTROL_PING, mp_ping);
18003 S (mp_ping);
18004
Jon Loeliger56c7b012017-02-01 12:31:41 -060018005 W (ret);
18006 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010018007}
18008
18009static int
18010api_delete_subif (vat_main_t * vam)
18011{
18012 unformat_input_t *i = vam->input;
18013 vl_api_delete_subif_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010018014 u32 sw_if_index = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060018015 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010018016
18017 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18018 {
18019 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18020 ;
18021 if (unformat (i, "sw_if_index %d", &sw_if_index))
18022 ;
18023 else
18024 break;
18025 }
18026
18027 if (sw_if_index == ~0)
18028 {
18029 errmsg ("missing sw_if_index");
18030 return -99;
18031 }
18032
18033 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060018034 M (DELETE_SUBIF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010018035 mp->sw_if_index = ntohl (sw_if_index);
18036
Jon Loeliger7bc770c2017-01-31 14:03:33 -060018037 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060018038 W (ret);
18039 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010018040}
18041
18042#define foreach_pbb_vtr_op \
18043_("disable", L2_VTR_DISABLED) \
18044_("pop", L2_VTR_POP_2) \
18045_("push", L2_VTR_PUSH_2)
18046
18047static int
18048api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
18049{
18050 unformat_input_t *i = vam->input;
18051 vl_api_l2_interface_pbb_tag_rewrite_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010018052 u32 sw_if_index = ~0, vtr_op = ~0;
18053 u16 outer_tag = ~0;
18054 u8 dmac[6], smac[6];
18055 u8 dmac_set = 0, smac_set = 0;
18056 u16 vlanid = 0;
18057 u32 sid = ~0;
18058 u32 tmp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060018059 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010018060
18061 /* Shut up coverity */
18062 memset (dmac, 0, sizeof (dmac));
18063 memset (smac, 0, sizeof (smac));
18064
18065 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18066 {
18067 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18068 ;
18069 else if (unformat (i, "sw_if_index %d", &sw_if_index))
18070 ;
18071 else if (unformat (i, "vtr_op %d", &vtr_op))
18072 ;
18073#define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
18074 foreach_pbb_vtr_op
18075#undef _
18076 else if (unformat (i, "translate_pbb_stag"))
18077 {
18078 if (unformat (i, "%d", &tmp))
18079 {
18080 vtr_op = L2_VTR_TRANSLATE_2_1;
18081 outer_tag = tmp;
18082 }
18083 else
18084 {
18085 errmsg
18086 ("translate_pbb_stag operation requires outer tag definition");
18087 return -99;
18088 }
18089 }
18090 else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
18091 dmac_set++;
18092 else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
18093 smac_set++;
18094 else if (unformat (i, "sid %d", &sid))
18095 ;
18096 else if (unformat (i, "vlanid %d", &tmp))
18097 vlanid = tmp;
18098 else
18099 {
18100 clib_warning ("parse error '%U'", format_unformat_error, i);
18101 return -99;
18102 }
18103 }
18104
18105 if ((sw_if_index == ~0) || (vtr_op == ~0))
18106 {
18107 errmsg ("missing sw_if_index or vtr operation");
18108 return -99;
18109 }
18110 if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
18111 && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
18112 {
18113 errmsg
18114 ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
18115 return -99;
18116 }
18117
Jon Loeliger8a2aea32017-01-31 13:19:40 -060018118 M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010018119 mp->sw_if_index = ntohl (sw_if_index);
18120 mp->vtr_op = ntohl (vtr_op);
18121 mp->outer_tag = ntohs (outer_tag);
18122 clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
18123 clib_memcpy (mp->b_smac, smac, sizeof (smac));
18124 mp->b_vlanid = ntohs (vlanid);
18125 mp->i_sid = ntohl (sid);
18126
Jon Loeliger7bc770c2017-01-31 14:03:33 -060018127 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060018128 W (ret);
18129 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010018130}
18131
18132static int
18133api_flow_classify_set_interface (vat_main_t * vam)
18134{
18135 unformat_input_t *i = vam->input;
18136 vl_api_flow_classify_set_interface_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010018137 u32 sw_if_index;
18138 int sw_if_index_set;
18139 u32 ip4_table_index = ~0;
18140 u32 ip6_table_index = ~0;
18141 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060018142 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010018143
18144 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18145 {
18146 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18147 sw_if_index_set = 1;
18148 else if (unformat (i, "sw_if_index %d", &sw_if_index))
18149 sw_if_index_set = 1;
18150 else if (unformat (i, "del"))
18151 is_add = 0;
18152 else if (unformat (i, "ip4-table %d", &ip4_table_index))
18153 ;
18154 else if (unformat (i, "ip6-table %d", &ip6_table_index))
18155 ;
18156 else
18157 {
18158 clib_warning ("parse error '%U'", format_unformat_error, i);
18159 return -99;
18160 }
18161 }
18162
18163 if (sw_if_index_set == 0)
18164 {
18165 errmsg ("missing interface name or sw_if_index");
18166 return -99;
18167 }
18168
Jon Loeliger8a2aea32017-01-31 13:19:40 -060018169 M (FLOW_CLASSIFY_SET_INTERFACE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010018170
18171 mp->sw_if_index = ntohl (sw_if_index);
18172 mp->ip4_table_index = ntohl (ip4_table_index);
18173 mp->ip6_table_index = ntohl (ip6_table_index);
18174 mp->is_add = is_add;
18175
Jon Loeliger7bc770c2017-01-31 14:03:33 -060018176 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060018177 W (ret);
18178 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010018179}
18180
18181static int
18182api_flow_classify_dump (vat_main_t * vam)
18183{
18184 unformat_input_t *i = vam->input;
18185 vl_api_flow_classify_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060018186 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010018187 u8 type = FLOW_CLASSIFY_N_TABLES;
Jon Loeliger56c7b012017-02-01 12:31:41 -060018188 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010018189
18190 if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
18191 ;
18192 else
18193 {
18194 errmsg ("classify table type must be specified");
18195 return -99;
18196 }
18197
18198 if (!vam->json_output)
18199 {
18200 print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18201 }
18202
Jon Loeliger8a2aea32017-01-31 13:19:40 -060018203 M (FLOW_CLASSIFY_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010018204 mp->type = type;
18205 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060018206 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010018207
18208 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060018209 M (CONTROL_PING, mp_ping);
18210 S (mp_ping);
18211
Damjan Marion7cd468a2016-12-19 23:05:39 +010018212 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060018213 W (ret);
18214 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010018215}
18216
18217static int
18218api_feature_enable_disable (vat_main_t * vam)
18219{
18220 unformat_input_t *i = vam->input;
18221 vl_api_feature_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010018222 u8 *arc_name = 0;
18223 u8 *feature_name = 0;
18224 u32 sw_if_index = ~0;
18225 u8 enable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060018226 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010018227
18228 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18229 {
18230 if (unformat (i, "arc_name %s", &arc_name))
18231 ;
18232 else if (unformat (i, "feature_name %s", &feature_name))
18233 ;
18234 else
18235 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18236 ;
18237 else if (unformat (i, "sw_if_index %d", &sw_if_index))
18238 ;
18239 else if (unformat (i, "disable"))
18240 enable = 0;
18241 else
18242 break;
18243 }
18244
18245 if (arc_name == 0)
18246 {
18247 errmsg ("missing arc name");
18248 return -99;
18249 }
18250 if (vec_len (arc_name) > 63)
18251 {
18252 errmsg ("arc name too long");
18253 }
18254
18255 if (feature_name == 0)
18256 {
18257 errmsg ("missing feature name");
18258 return -99;
18259 }
18260 if (vec_len (feature_name) > 63)
18261 {
18262 errmsg ("feature name too long");
18263 }
18264
18265 if (sw_if_index == ~0)
18266 {
18267 errmsg ("missing interface name or sw_if_index");
18268 return -99;
18269 }
18270
18271 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060018272 M (FEATURE_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010018273 mp->sw_if_index = ntohl (sw_if_index);
18274 mp->enable = enable;
18275 clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
18276 clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
18277 vec_free (arc_name);
18278 vec_free (feature_name);
18279
Jon Loeliger7bc770c2017-01-31 14:03:33 -060018280 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060018281 W (ret);
18282 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010018283}
18284
18285static int
18286api_sw_interface_tag_add_del (vat_main_t * vam)
18287{
18288 unformat_input_t *i = vam->input;
18289 vl_api_sw_interface_tag_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010018290 u32 sw_if_index = ~0;
18291 u8 *tag = 0;
18292 u8 enable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060018293 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010018294
18295 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18296 {
18297 if (unformat (i, "tag %s", &tag))
18298 ;
18299 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18300 ;
18301 else if (unformat (i, "sw_if_index %d", &sw_if_index))
18302 ;
18303 else if (unformat (i, "del"))
18304 enable = 0;
18305 else
18306 break;
18307 }
18308
18309 if (sw_if_index == ~0)
18310 {
18311 errmsg ("missing interface name or sw_if_index");
18312 return -99;
18313 }
18314
18315 if (enable && (tag == 0))
18316 {
18317 errmsg ("no tag specified");
18318 return -99;
18319 }
18320
18321 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060018322 M (SW_INTERFACE_TAG_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010018323 mp->sw_if_index = ntohl (sw_if_index);
18324 mp->is_add = enable;
18325 if (enable)
18326 strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
18327 vec_free (tag);
18328
Jon Loeliger7bc770c2017-01-31 14:03:33 -060018329 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060018330 W (ret);
18331 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010018332}
18333
18334static void vl_api_l2_xconnect_details_t_handler
18335 (vl_api_l2_xconnect_details_t * mp)
18336{
18337 vat_main_t *vam = &vat_main;
18338
18339 print (vam->ofp, "%15d%15d",
18340 ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
18341}
18342
18343static void vl_api_l2_xconnect_details_t_handler_json
18344 (vl_api_l2_xconnect_details_t * mp)
18345{
18346 vat_main_t *vam = &vat_main;
18347 vat_json_node_t *node = NULL;
18348
18349 if (VAT_JSON_ARRAY != vam->json_tree.type)
18350 {
18351 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18352 vat_json_init_array (&vam->json_tree);
18353 }
18354 node = vat_json_array_add (&vam->json_tree);
18355
18356 vat_json_init_object (node);
18357 vat_json_object_add_uint (node, "rx_sw_if_index",
18358 ntohl (mp->rx_sw_if_index));
18359 vat_json_object_add_uint (node, "tx_sw_if_index",
18360 ntohl (mp->tx_sw_if_index));
18361}
18362
18363static int
18364api_l2_xconnect_dump (vat_main_t * vam)
18365{
18366 vl_api_l2_xconnect_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060018367 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060018368 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010018369
18370 if (!vam->json_output)
18371 {
18372 print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
18373 }
18374
Jon Loeliger8a2aea32017-01-31 13:19:40 -060018375 M (L2_XCONNECT_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010018376
Jon Loeliger7bc770c2017-01-31 14:03:33 -060018377 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010018378
18379 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060018380 M (CONTROL_PING, mp_ping);
18381 S (mp_ping);
18382
Jon Loeliger56c7b012017-02-01 12:31:41 -060018383 W (ret);
18384 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010018385}
18386
18387static int
18388api_sw_interface_set_mtu (vat_main_t * vam)
18389{
18390 unformat_input_t *i = vam->input;
18391 vl_api_sw_interface_set_mtu_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010018392 u32 sw_if_index = ~0;
18393 u32 mtu = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060018394 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010018395
18396 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18397 {
18398 if (unformat (i, "mtu %d", &mtu))
18399 ;
18400 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18401 ;
18402 else if (unformat (i, "sw_if_index %d", &sw_if_index))
18403 ;
18404 else
18405 break;
18406 }
18407
18408 if (sw_if_index == ~0)
18409 {
18410 errmsg ("missing interface name or sw_if_index");
18411 return -99;
18412 }
18413
18414 if (mtu == 0)
18415 {
18416 errmsg ("no mtu specified");
18417 return -99;
18418 }
18419
18420 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060018421 M (SW_INTERFACE_SET_MTU, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010018422 mp->sw_if_index = ntohl (sw_if_index);
18423 mp->mtu = ntohs ((u16) mtu);
18424
Jon Loeliger7bc770c2017-01-31 14:03:33 -060018425 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060018426 W (ret);
18427 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010018428}
18429
18430
18431static int
18432q_or_quit (vat_main_t * vam)
18433{
Dave Barachdef19da2017-02-22 17:29:20 -050018434#if VPP_API_TEST_BUILTIN == 0
Damjan Marion7cd468a2016-12-19 23:05:39 +010018435 longjmp (vam->jump_buf, 1);
Dave Barachdef19da2017-02-22 17:29:20 -050018436#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +010018437 return 0; /* not so much */
18438}
18439
18440static int
18441q (vat_main_t * vam)
18442{
18443 return q_or_quit (vam);
18444}
18445
18446static int
18447quit (vat_main_t * vam)
18448{
18449 return q_or_quit (vam);
18450}
18451
18452static int
18453comment (vat_main_t * vam)
18454{
18455 return 0;
18456}
18457
18458static int
18459cmd_cmp (void *a1, void *a2)
18460{
18461 u8 **c1 = a1;
18462 u8 **c2 = a2;
18463
18464 return strcmp ((char *) (c1[0]), (char *) (c2[0]));
18465}
18466
18467static int
18468help (vat_main_t * vam)
18469{
18470 u8 **cmds = 0;
18471 u8 *name = 0;
18472 hash_pair_t *p;
18473 unformat_input_t *i = vam->input;
18474 int j;
18475
18476 if (unformat (i, "%s", &name))
18477 {
18478 uword *hs;
18479
18480 vec_add1 (name, 0);
18481
18482 hs = hash_get_mem (vam->help_by_name, name);
18483 if (hs)
18484 print (vam->ofp, "usage: %s %s", name, hs[0]);
18485 else
18486 print (vam->ofp, "No such msg / command '%s'", name);
18487 vec_free (name);
18488 return 0;
18489 }
18490
18491 print (vam->ofp, "Help is available for the following:");
18492
18493 /* *INDENT-OFF* */
18494 hash_foreach_pair (p, vam->function_by_name,
18495 ({
18496 vec_add1 (cmds, (u8 *)(p->key));
18497 }));
18498 /* *INDENT-ON* */
18499
18500 vec_sort_with_function (cmds, cmd_cmp);
18501
18502 for (j = 0; j < vec_len (cmds); j++)
18503 print (vam->ofp, "%s", cmds[j]);
18504
18505 vec_free (cmds);
18506 return 0;
18507}
18508
18509static int
18510set (vat_main_t * vam)
18511{
18512 u8 *name = 0, *value = 0;
18513 unformat_input_t *i = vam->input;
18514
18515 if (unformat (i, "%s", &name))
18516 {
18517 /* The input buffer is a vector, not a string. */
18518 value = vec_dup (i->buffer);
18519 vec_delete (value, i->index, 0);
18520 /* Almost certainly has a trailing newline */
18521 if (value[vec_len (value) - 1] == '\n')
18522 value[vec_len (value) - 1] = 0;
18523 /* Make sure it's a proper string, one way or the other */
18524 vec_add1 (value, 0);
18525 (void) clib_macro_set_value (&vam->macro_main,
18526 (char *) name, (char *) value);
18527 }
18528 else
18529 errmsg ("usage: set <name> <value>");
18530
18531 vec_free (name);
18532 vec_free (value);
18533 return 0;
18534}
18535
18536static int
18537unset (vat_main_t * vam)
18538{
18539 u8 *name = 0;
18540
18541 if (unformat (vam->input, "%s", &name))
18542 if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
18543 errmsg ("unset: %s wasn't set", name);
18544 vec_free (name);
18545 return 0;
18546}
18547
18548typedef struct
18549{
18550 u8 *name;
18551 u8 *value;
18552} macro_sort_t;
18553
18554
18555static int
18556macro_sort_cmp (void *a1, void *a2)
18557{
18558 macro_sort_t *s1 = a1;
18559 macro_sort_t *s2 = a2;
18560
18561 return strcmp ((char *) (s1->name), (char *) (s2->name));
18562}
18563
18564static int
18565dump_macro_table (vat_main_t * vam)
18566{
18567 macro_sort_t *sort_me = 0, *sm;
18568 int i;
18569 hash_pair_t *p;
18570
18571 /* *INDENT-OFF* */
18572 hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
18573 ({
18574 vec_add2 (sort_me, sm, 1);
18575 sm->name = (u8 *)(p->key);
18576 sm->value = (u8 *) (p->value[0]);
18577 }));
18578 /* *INDENT-ON* */
18579
18580 vec_sort_with_function (sort_me, macro_sort_cmp);
18581
18582 if (vec_len (sort_me))
18583 print (vam->ofp, "%-15s%s", "Name", "Value");
18584 else
18585 print (vam->ofp, "The macro table is empty...");
18586
18587 for (i = 0; i < vec_len (sort_me); i++)
18588 print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
18589 return 0;
18590}
18591
18592static int
18593dump_node_table (vat_main_t * vam)
18594{
18595 int i, j;
18596 vlib_node_t *node, *next_node;
18597
18598 if (vec_len (vam->graph_nodes) == 0)
18599 {
18600 print (vam->ofp, "Node table empty, issue get_node_graph...");
18601 return 0;
18602 }
18603
18604 for (i = 0; i < vec_len (vam->graph_nodes); i++)
18605 {
18606 node = vam->graph_nodes[i];
18607 print (vam->ofp, "[%d] %s", i, node->name);
18608 for (j = 0; j < vec_len (node->next_nodes); j++)
18609 {
18610 if (node->next_nodes[j] != ~0)
18611 {
18612 next_node = vam->graph_nodes[node->next_nodes[j]];
18613 print (vam->ofp, " [%d] %s", j, next_node->name);
18614 }
18615 }
18616 }
18617 return 0;
18618}
18619
18620static int
18621value_sort_cmp (void *a1, void *a2)
18622{
18623 name_sort_t *n1 = a1;
18624 name_sort_t *n2 = a2;
18625
18626 if (n1->value < n2->value)
18627 return -1;
18628 if (n1->value > n2->value)
18629 return 1;
18630 return 0;
18631}
18632
18633
18634static int
18635dump_msg_api_table (vat_main_t * vam)
18636{
18637 api_main_t *am = &api_main;
18638 name_sort_t *nses = 0, *ns;
18639 hash_pair_t *hp;
18640 int i;
18641
18642 /* *INDENT-OFF* */
18643 hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
18644 ({
18645 vec_add2 (nses, ns, 1);
18646 ns->name = (u8 *)(hp->key);
18647 ns->value = (u32) hp->value[0];
18648 }));
18649 /* *INDENT-ON* */
18650
18651 vec_sort_with_function (nses, value_sort_cmp);
18652
18653 for (i = 0; i < vec_len (nses); i++)
18654 print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
18655 vec_free (nses);
18656 return 0;
18657}
18658
18659static int
18660get_msg_id (vat_main_t * vam)
18661{
18662 u8 *name_and_crc;
18663 u32 message_index;
18664
18665 if (unformat (vam->input, "%s", &name_and_crc))
18666 {
18667 message_index = vl_api_get_msg_index (name_and_crc);
18668 if (message_index == ~0)
18669 {
18670 print (vam->ofp, " '%s' not found", name_and_crc);
18671 return 0;
18672 }
18673 print (vam->ofp, " '%s' has message index %d",
18674 name_and_crc, message_index);
18675 return 0;
18676 }
18677 errmsg ("name_and_crc required...");
18678 return 0;
18679}
18680
18681static int
18682search_node_table (vat_main_t * vam)
18683{
18684 unformat_input_t *line_input = vam->input;
18685 u8 *node_to_find;
18686 int j;
18687 vlib_node_t *node, *next_node;
18688 uword *p;
18689
18690 if (vam->graph_node_index_by_name == 0)
18691 {
18692 print (vam->ofp, "Node table empty, issue get_node_graph...");
18693 return 0;
18694 }
18695
18696 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
18697 {
18698 if (unformat (line_input, "%s", &node_to_find))
18699 {
18700 vec_add1 (node_to_find, 0);
18701 p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
18702 if (p == 0)
18703 {
18704 print (vam->ofp, "%s not found...", node_to_find);
18705 goto out;
18706 }
18707 node = vam->graph_nodes[p[0]];
18708 print (vam->ofp, "[%d] %s", p[0], node->name);
18709 for (j = 0; j < vec_len (node->next_nodes); j++)
18710 {
18711 if (node->next_nodes[j] != ~0)
18712 {
18713 next_node = vam->graph_nodes[node->next_nodes[j]];
18714 print (vam->ofp, " [%d] %s", j, next_node->name);
18715 }
18716 }
18717 }
18718
18719 else
18720 {
18721 clib_warning ("parse error '%U'", format_unformat_error,
18722 line_input);
18723 return -99;
18724 }
18725
18726 out:
18727 vec_free (node_to_find);
18728
18729 }
18730
18731 return 0;
18732}
18733
18734
18735static int
18736script (vat_main_t * vam)
18737{
18738#if (VPP_API_TEST_BUILTIN==0)
18739 u8 *s = 0;
18740 char *save_current_file;
18741 unformat_input_t save_input;
18742 jmp_buf save_jump_buf;
18743 u32 save_line_number;
18744
18745 FILE *new_fp, *save_ifp;
18746
18747 if (unformat (vam->input, "%s", &s))
18748 {
18749 new_fp = fopen ((char *) s, "r");
18750 if (new_fp == 0)
18751 {
18752 errmsg ("Couldn't open script file %s", s);
18753 vec_free (s);
18754 return -99;
18755 }
18756 }
18757 else
18758 {
18759 errmsg ("Missing script name");
18760 return -99;
18761 }
18762
18763 clib_memcpy (&save_input, &vam->input, sizeof (save_input));
18764 clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
18765 save_ifp = vam->ifp;
18766 save_line_number = vam->input_line_number;
18767 save_current_file = (char *) vam->current_file;
18768
18769 vam->input_line_number = 0;
18770 vam->ifp = new_fp;
18771 vam->current_file = s;
18772 do_one_file (vam);
18773
18774 clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
18775 clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
18776 vam->ifp = save_ifp;
18777 vam->input_line_number = save_line_number;
18778 vam->current_file = (u8 *) save_current_file;
18779 vec_free (s);
18780
18781 return 0;
18782#else
18783 clib_warning ("use the exec command...");
18784 return -99;
18785#endif
18786}
18787
18788static int
18789echo (vat_main_t * vam)
18790{
18791 print (vam->ofp, "%v", vam->input->buffer);
18792 return 0;
18793}
18794
18795/* List of API message constructors, CLI names map to api_xxx */
18796#define foreach_vpe_api_msg \
Jon Loeligerc83c3b72017-02-23 13:57:35 -060018797_(create_loopback,"[mac <mac-addr>] [instance <instance>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010018798_(sw_interface_dump,"") \
18799_(sw_interface_set_flags, \
18800 "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
18801_(sw_interface_add_del_address, \
18802 "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
18803_(sw_interface_set_table, \
18804 "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]") \
18805_(sw_interface_set_mpls_enable, \
18806 "<intfc> | sw_if_index [disable | dis]") \
18807_(sw_interface_set_vpath, \
18808 "<intfc> | sw_if_index <id> enable | disable") \
18809_(sw_interface_set_vxlan_bypass, \
John Lo2b81eb82017-01-30 13:12:10 -050018810 "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010018811_(sw_interface_set_l2_xconnect, \
18812 "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
18813 "enable | disable") \
18814_(sw_interface_set_l2_bridge, \
Eyal Barif24991c2017-04-05 05:33:21 +030018815 "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n" \
Damjan Marion7cd468a2016-12-19 23:05:39 +010018816 "[shg <split-horizon-group>] [bvi]\n" \
18817 "enable | disable") \
Eyal Barif24991c2017-04-05 05:33:21 +030018818_(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010018819_(bridge_domain_add_del, \
Eyal Barifead6702017-04-04 04:46:32 +030018820 "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] [del]\n") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010018821_(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n") \
18822_(l2fib_add_del, \
18823 "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 +030018824_(l2fib_flush_bd, "bd_id <bridge-domain-id>") \
18825_(l2fib_flush_int, "<intfc> | sw_if_index <id>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010018826_(l2_flags, \
18827 "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n") \
18828_(bridge_flags, \
18829 "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
18830_(tap_connect, \
18831 "tapname <name> mac <mac-addr> | random-mac [tag <string>]") \
18832_(tap_modify, \
18833 "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
18834_(tap_delete, \
18835 "<vpp-if-name> | sw_if_index <id>") \
18836_(sw_interface_tap_dump, "") \
18837_(ip_add_del_route, \
18838 "<addr>/<mask> via <addr> [table-id <n>]\n" \
18839 "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n" \
18840 "[weight <n>] [drop] [local] [classify <n>] [del]\n" \
18841 "[multipath] [count <n>]") \
Neale Ranns32e1c012016-11-22 17:07:28 +000018842_(ip_mroute_add_del, \
18843 "<src> <grp>/<mask> [table-id <n>]\n" \
18844 "[<intfc> | sw_if_index <id>] [local] [del]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010018845_(mpls_route_add_del, \
18846 "<label> <eos> via <addr> [table-id <n>]\n" \
18847 "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n" \
18848 "[weight <n>] [drop] [local] [classify <n>] [del]\n" \
18849 "[multipath] [count <n>]") \
18850_(mpls_ip_bind_unbind, \
18851 "<label> <addr/len>") \
18852_(mpls_tunnel_add_del, \
18853 " via <addr> [table-id <n>]\n" \
18854 "sw_if_index <id>] [l2] [del]") \
18855_(proxy_arp_add_del, \
18856 "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]") \
18857_(proxy_arp_intfc_enable_disable, \
18858 "<intfc> | sw_if_index <id> enable | disable") \
18859_(sw_interface_set_unnumbered, \
18860 "<intfc> | sw_if_index <id> unnum_if_index <id> [del]") \
18861_(ip_neighbor_add_del, \
18862 "(<intfc> | sw_if_index <id>) dst <ip46-address> " \
18863 "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]") \
18864_(reset_vrf, "vrf <id> [ipv6]") \
18865_(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>") \
18866_(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n" \
18867 "[outer_vlan_id <n>][inner_vlan_id <n>]\n" \
18868 "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n" \
18869 "[outer_vlan_id_any][inner_vlan_id_any]") \
18870_(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]") \
18871_(reset_fib, "vrf <n> [ipv6]") \
18872_(dhcp_proxy_config, \
18873 "svr <v46-address> src <v46-address>\n" \
Neale Ranns20a175a2017-02-14 07:28:41 -080018874 "rx_vrf_id <nn> server_vrf_id <nn> [del]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010018875_(dhcp_proxy_set_vss, \
18876 "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]") \
Neale Ranns20a175a2017-02-14 07:28:41 -080018877_(dhcp_proxy_dump, "ip6") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010018878_(dhcp_client_config, \
18879 "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
18880_(set_ip_flow_hash, \
18881 "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]") \
18882_(sw_interface_ip6_enable_disable, \
18883 "<intfc> | sw_if_index <id> enable | disable") \
18884_(sw_interface_ip6_set_link_local_address, \
18885 "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>") \
Neale Ranns3f844d02017-02-18 00:03:54 -080018886_(ip6nd_proxy_add_del, \
18887 "<intfc> | sw_if_index <id> <ip6-address>") \
18888_(ip6nd_proxy_dump, "") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010018889_(sw_interface_ip6nd_ra_prefix, \
18890 "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n" \
18891 "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n" \
18892 "[nolink] [isno]") \
18893_(sw_interface_ip6nd_ra_config, \
18894 "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n" \
18895 "[life <n>] [count <n>] [interval <n>] [suppress]\n" \
18896 "[managed] [other] [ll] [send] [cease] [isno] [def]") \
18897_(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]") \
18898_(l2_patch_add_del, \
18899 "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
18900 "enable | disable") \
Pablo Camarillofb380952016-12-07 18:34:18 +010018901_(sr_localsid_add_del, \
18902 "(del) address <addr> next_hop <addr> behavior <beh>\n" \
18903 "fib-table <num> (end.psp) sw_if_index <num>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010018904_(classify_add_del_table, \
18905 "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n" \
18906 " [del] [del-chain] mask <mask-value>\n" \
18907 " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n" \
18908 " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]") \
18909_(classify_add_del_session, \
18910 "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n" \
18911 " table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n" \
18912 " [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n" \
18913 " [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]") \
18914_(classify_set_interface_ip_table, \
18915 "<intfc> | sw_if_index <nn> table <nn>") \
18916_(classify_set_interface_l2_tables, \
18917 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
18918 " [other-table <nn>]") \
18919_(get_node_index, "node <node-name") \
18920_(add_node_next, "node <node-name> next <next-node-name>") \
18921_(l2tpv3_create_tunnel, \
18922 "client_address <ip6-addr> our_address <ip6-addr>\n" \
18923 "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
18924 "[remote_cookie <nn>]\n[l2-sublayer-preset]\n") \
18925_(l2tpv3_set_tunnel_cookies, \
18926 "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n" \
18927 "[new_remote_cookie <nn>]\n") \
18928_(l2tpv3_interface_enable_disable, \
18929 "<intfc> | sw_if_index <nn> enable | disable") \
18930_(l2tpv3_set_lookup_key, \
18931 "lookup_v6_src | lookup_v6_dst | lookup_session_id") \
18932_(sw_if_l2tpv3_tunnel_dump, "") \
18933_(vxlan_add_del_tunnel, \
18934 "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n" \
18935 "{ <intfc> | mcast_sw_if_index <nn> } }\n" \
18936 "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]") \
18937_(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]") \
18938_(gre_add_del_tunnel, \
Ciara Loftus7eac9162016-09-30 15:47:03 +010018939 "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [teb] [del]\n") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010018940_(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]") \
18941_(l2_fib_clear_table, "") \
18942_(l2_interface_efp_filter, "sw_if_index <nn> enable | disable") \
18943_(l2_interface_vlan_tag_rewrite, \
18944 "<intfc> | sw_if_index <nn> \n" \
18945 "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n" \
18946 "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>") \
18947_(create_vhost_user_if, \
18948 "socket <filename> [server] [renumber <dev_instance>] " \
Stevenf3b53642017-05-01 14:03:02 -070018949 "[mac <mac_address>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010018950_(modify_vhost_user_if, \
18951 "<intfc> | sw_if_index <nn> socket <filename>\n" \
Stevenf3b53642017-05-01 14:03:02 -070018952 "[server] [renumber <dev_instance>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010018953_(delete_vhost_user_if, "<intfc> | sw_if_index <nn>") \
18954_(sw_interface_vhost_user_dump, "") \
18955_(show_version, "") \
18956_(vxlan_gpe_add_del_tunnel, \
18957 "local <addr> remote <addr> vni <nn>\n" \
18958 "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]" \
18959 "[next-ethernet] [next-nsh]\n") \
18960_(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]") \
18961_(l2_fib_table_dump, "bd_id <bridge-domain-id>") \
18962_(interface_name_renumber, \
18963 "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>") \
18964_(input_acl_set_interface, \
18965 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
18966 " [l2-table <nn>] [del]") \
18967_(want_ip4_arp_events, "address <ip4-address> [del]") \
18968_(want_ip6_nd_events, "address <ip6-address> [del]") \
18969_(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)") \
18970_(ip_dump, "ipv4 | ipv6") \
18971_(ipsec_spd_add_del, "spd_id <n> [del]") \
18972_(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n" \
18973 " spid_id <n> ") \
18974_(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n" \
18975 " crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n" \
18976 " integ_alg <alg> integ_key <hex>") \
18977_(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n" \
18978 " (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n" \
18979 " laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
18980 " [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
18981_(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>") \
Matthew Smithb0972cb2017-05-02 16:20:41 -050018982_(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n" \
18983 " crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
18984 " integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n" \
18985 " local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010018986_(ikev2_profile_add_del, "name <profile_name> [del]") \
18987_(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n" \
18988 "(auth_data 0x<data> | auth_data <data>)") \
18989_(ikev2_profile_set_id, "name <profile_name> id_type <type>\n" \
18990 "(id_data 0x<data> | id_data <data>) (local|remote)") \
18991_(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n" \
18992 "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
18993 "(local|remote)") \
18994_(ikev2_set_local_key, "file <absolute_file_path>") \
Radu Nicolaucb33dc22017-02-16 16:49:46 +000018995_(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
18996_(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
18997_(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
18998_(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
18999_(ikev2_initiate_sa_init, "<profile_name>") \
19000_(ikev2_initiate_del_ike_sa, "<ispi>") \
19001_(ikev2_initiate_del_child_sa, "<ispi>") \
19002_(ikev2_initiate_rekey_child_sa, "<ispi>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010019003_(delete_loopback,"sw_if_index <nn>") \
19004_(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
19005_(map_add_domain, \
19006 "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> " \
19007 "ip6-src <ip6addr> " \
19008 "ea-bits-len <n> psid-offset <n> psid-len <n>") \
19009_(map_del_domain, "index <n>") \
19010_(map_add_del_rule, \
19011 "index <n> psid <n> dst <ip6addr> [del]") \
19012_(map_domain_dump, "") \
19013_(map_rule_dump, "index <map-domain>") \
19014_(want_interface_events, "enable|disable") \
19015_(want_stats,"enable|disable") \
19016_(get_first_msg_id, "client <name>") \
19017_(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
19018_(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n" \
19019 "fib-id <nn> [ip4][ip6][default]") \
19020_(get_node_graph, " ") \
19021_(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>") \
19022_(ioam_enable, "[trace] [pow] [ppc <encap|decap>]") \
19023_(ioam_disable, "") \
Filip Tehlar694396d2017-02-17 14:29:11 +010019024_(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
19025 " sw_if_index <sw_if_index> p <priority> " \
19026 "w <weight>] [del]") \
19027_(one_add_del_locator, "locator-set <locator_name> " \
19028 "iface <intf> | sw_if_index <sw_if_index> " \
19029 "p <priority> w <weight> [del]") \
19030_(one_add_del_local_eid,"vni <vni> eid " \
19031 "<ipv4|ipv6>/<prefix> | <L2 address> " \
19032 "locator-set <locator_name> [del]" \
19033 "[key-id sha1|sha256 secret-key <secret-key>]")\
19034_(one_add_del_map_resolver, "<ip4|6-addr> [del]") \
19035_(one_add_del_map_server, "<ip4|6-addr> [del]") \
19036_(one_enable_disable, "enable|disable") \
19037_(one_map_register_enable_disable, "enable|disable") \
19038_(one_rloc_probe_enable_disable, "enable|disable") \
19039_(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> " \
19040 "[seid <seid>] " \
19041 "rloc <locator> p <prio> " \
19042 "w <weight> [rloc <loc> ... ] " \
19043 "action <action> [del-all]") \
19044_(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid " \
19045 "<local-eid>") \
19046_(one_pitr_set_locator_set, "locator-set <loc-set-name> | del") \
Filip Tehlar67a99f82017-03-10 13:18:02 +010019047_(one_use_petr, "ip-address> | disable") \
Filip Tehlar694396d2017-02-17 14:29:11 +010019048_(one_map_request_mode, "src-dst|dst-only") \
19049_(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]") \
19050_(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>") \
19051_(one_locator_set_dump, "[local | remote]") \
19052_(one_locator_dump, "ls_index <index> | ls_name <name>") \
19053_(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] " \
19054 "[local] | [remote]") \
Filip Tehlar4868ff62017-03-09 16:48:39 +010019055_(one_stats_enable_disable, "enable|disalbe") \
19056_(show_one_stats_enable_disable, "") \
Filip Tehlar694396d2017-02-17 14:29:11 +010019057_(one_eid_table_vni_dump, "") \
19058_(one_eid_table_map_dump, "l2|l3") \
19059_(one_map_resolver_dump, "") \
19060_(one_map_server_dump, "") \
19061_(one_adjacencies_get, "vni <vni>") \
19062_(show_one_rloc_probe_state, "") \
19063_(show_one_map_register_state, "") \
19064_(show_one_status, "") \
Filip Tehlar4868ff62017-03-09 16:48:39 +010019065_(one_stats_dump, "") \
Filip Tehlar21511912017-04-07 10:41:42 +020019066_(one_stats_flush, "") \
Filip Tehlar694396d2017-02-17 14:29:11 +010019067_(one_get_map_request_itr_rlocs, "") \
19068_(show_one_pitr, "") \
Filip Tehlar67a99f82017-03-10 13:18:02 +010019069_(show_one_use_petr, "") \
Filip Tehlar694396d2017-02-17 14:29:11 +010019070_(show_one_map_request_mode, "") \
19071_(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
Damjan Marion7cd468a2016-12-19 23:05:39 +010019072 " sw_if_index <sw_if_index> p <priority> " \
19073 "w <weight>] [del]") \
19074_(lisp_add_del_locator, "locator-set <locator_name> " \
19075 "iface <intf> | sw_if_index <sw_if_index> " \
19076 "p <priority> w <weight> [del]") \
19077_(lisp_add_del_local_eid,"vni <vni> eid " \
19078 "<ipv4|ipv6>/<prefix> | <L2 address> " \
19079 "locator-set <locator_name> [del]" \
19080 "[key-id sha1|sha256 secret-key <secret-key>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010019081_(lisp_add_del_map_resolver, "<ip4|6-addr> [del]") \
19082_(lisp_add_del_map_server, "<ip4|6-addr> [del]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010019083_(lisp_enable_disable, "enable|disable") \
19084_(lisp_map_register_enable_disable, "enable|disable") \
19085_(lisp_rloc_probe_enable_disable, "enable|disable") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010019086_(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> " \
19087 "[seid <seid>] " \
19088 "rloc <locator> p <prio> " \
19089 "w <weight> [rloc <loc> ... ] " \
19090 "action <action> [del-all]") \
19091_(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid " \
19092 "<local-eid>") \
19093_(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del") \
Filip Tehlar67a99f82017-03-10 13:18:02 +010019094_(lisp_use_petr, "<ip-address> | disable") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010019095_(lisp_map_request_mode, "src-dst|dst-only") \
19096_(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]") \
19097_(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>") \
19098_(lisp_locator_set_dump, "[local | remote]") \
19099_(lisp_locator_dump, "ls_index <index> | ls_name <name>") \
19100_(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] " \
19101 "[local] | [remote]") \
19102_(lisp_eid_table_vni_dump, "") \
19103_(lisp_eid_table_map_dump, "l2|l3") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010019104_(lisp_map_resolver_dump, "") \
19105_(lisp_map_server_dump, "") \
19106_(lisp_adjacencies_get, "vni <vni>") \
Filip Tehlar0eb874e2017-05-18 14:23:32 +020019107_(gpe_fwd_entry_vnis_get, "") \
Filip Tehlar5fae99c2017-01-18 12:57:37 +010019108_(lisp_gpe_fwd_entries_get, "vni <vni>") \
19109_(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>") \
Filip Tehlar3e7b56932017-02-21 18:28:34 +010019110_(gpe_set_encap_mode, "lisp|vxlan") \
19111_(gpe_get_encap_mode, "") \
Filip Tehlar82786c42017-02-20 15:20:37 +010019112_(lisp_gpe_add_del_iface, "up|down") \
19113_(lisp_gpe_enable_disable, "enable|disable") \
19114_(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>" \
19115 "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010019116_(show_lisp_rloc_probe_state, "") \
19117_(show_lisp_map_register_state, "") \
19118_(show_lisp_status, "") \
19119_(lisp_get_map_request_itr_rlocs, "") \
19120_(show_lisp_pitr, "") \
Filip Tehlar67a99f82017-03-10 13:18:02 +010019121_(show_lisp_use_petr, "") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010019122_(show_lisp_map_request_mode, "") \
19123_(af_packet_create, "name <host interface name> [hw_addr <mac>]") \
19124_(af_packet_delete, "name <host interface name>") \
19125_(policer_add_del, "name <policer name> <params> [del]") \
19126_(policer_dump, "[name <policer name>]") \
19127_(policer_classify_set_interface, \
19128 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
19129 " [l2-table <nn>] [del]") \
19130_(policer_classify_dump, "type [ip4|ip6|l2]") \
19131_(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] " \
19132 "[master|slave]") \
19133_(netmap_delete, "name <interface name>") \
19134_(mpls_tunnel_dump, "tunnel_index <tunnel-id>") \
19135_(mpls_fib_dump, "") \
19136_(classify_table_ids, "") \
19137_(classify_table_by_interface, "sw_if_index <sw_if_index>") \
19138_(classify_table_info, "table_id <nn>") \
19139_(classify_session_dump, "table_id <nn>") \
19140_(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] " \
19141 "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] " \
19142 "[template_interval <nn>] [udp_checksum]") \
19143_(ipfix_exporter_dump, "") \
19144_(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
19145_(ipfix_classify_stream_dump, "") \
19146_(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
19147_(ipfix_classify_table_dump, "") \
19148_(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
19149_(sw_interface_span_dump, "") \
19150_(get_next_index, "node-name <node-name> next-node-name <node-name>") \
19151_(pg_create_interface, "if_id <nn>") \
19152_(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]") \
19153_(pg_enable_disable, "[stream <id>] disable") \
19154_(ip_source_and_port_range_check_add_del, \
19155 "<ip-addr>/<mask> range <nn>-<nn> vrf <id>") \
19156_(ip_source_and_port_range_check_interface_add_del, \
19157 "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]" \
19158 "[udp-in-vrf <id>] [udp-out-vrf <id>]") \
19159_(ipsec_gre_add_del_tunnel, \
19160 "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]") \
19161_(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]") \
19162_(delete_subif,"<intfc> | sw_if_index <nn>") \
19163_(l2_interface_pbb_tag_rewrite, \
19164 "<intfc> | sw_if_index <nn> \n" \
19165 "[disable | push | pop | translate_pbb_stag <outer_tag>] \n" \
19166 "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]") \
19167_(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]") \
19168_(flow_classify_set_interface, \
19169 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
19170_(flow_classify_dump, "type [ip4|ip6]") \
19171_(ip_fib_dump, "") \
Neale Ranns5a8123b2017-01-26 01:18:23 -080019172_(ip_mfib_dump, "") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010019173_(ip6_fib_dump, "") \
Neale Ranns5a8123b2017-01-26 01:18:23 -080019174_(ip6_mfib_dump, "") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010019175_(feature_enable_disable, "arc_name <arc_name> " \
19176 "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]") \
19177_(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>" \
19178"[disable]") \
19179_(l2_xconnect_dump, "") \
19180_(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>") \
19181_(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>") \
19182_(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")
19183
19184/* List of command functions, CLI names map directly to functions */
19185#define foreach_cli_function \
19186_(comment, "usage: comment <ignore-rest-of-line>") \
19187_(dump_interface_table, "usage: dump_interface_table") \
19188_(dump_sub_interface_table, "usage: dump_sub_interface_table") \
19189_(dump_ipv4_table, "usage: dump_ipv4_table") \
19190_(dump_ipv6_table, "usage: dump_ipv6_table") \
19191_(dump_stats_table, "usage: dump_stats_table") \
19192_(dump_macro_table, "usage: dump_macro_table ") \
19193_(dump_node_table, "usage: dump_node_table") \
19194_(dump_msg_api_table, "usage: dump_msg_api_table") \
19195_(get_msg_id, "usage: get_msg_id name_and_crc") \
19196_(echo, "usage: echo <message>") \
19197_(exec, "usage: exec <vpe-debug-CLI-command>") \
19198_(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>") \
19199_(help, "usage: help") \
19200_(q, "usage: quit") \
19201_(quit, "usage: quit") \
19202_(search_node_table, "usage: search_node_table <name>...") \
19203_(set, "usage: set <variable-name> <value>") \
19204_(script, "usage: script <file-name>") \
19205_(unset, "usage: unset <variable-name>")
19206
19207#define _(N,n) \
19208 static void vl_api_##n##_t_handler_uni \
19209 (vl_api_##n##_t * mp) \
19210 { \
19211 vat_main_t * vam = &vat_main; \
19212 if (vam->json_output) { \
19213 vl_api_##n##_t_handler_json(mp); \
19214 } else { \
19215 vl_api_##n##_t_handler(mp); \
19216 } \
19217 }
19218foreach_vpe_api_reply_msg;
Dave Baracha1a093d2017-03-02 13:13:23 -050019219#if VPP_API_TEST_BUILTIN == 0
19220foreach_standalone_reply_msg;
19221#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +010019222#undef _
19223
19224void
19225vat_api_hookup (vat_main_t * vam)
19226{
19227#define _(N,n) \
19228 vl_msg_api_set_handlers(VL_API_##N, #n, \
19229 vl_api_##n##_t_handler_uni, \
19230 vl_noop_handler, \
19231 vl_api_##n##_t_endian, \
19232 vl_api_##n##_t_print, \
19233 sizeof(vl_api_##n##_t), 1);
19234 foreach_vpe_api_reply_msg;
Dave Baracha1a093d2017-03-02 13:13:23 -050019235#if VPP_API_TEST_BUILTIN == 0
19236 foreach_standalone_reply_msg;
19237#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +010019238#undef _
19239
19240#if (VPP_API_TEST_BUILTIN==0)
19241 vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
Damjan Marion7cd468a2016-12-19 23:05:39 +010019242
19243 vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
19244
19245 vam->function_by_name = hash_create_string (0, sizeof (uword));
19246
19247 vam->help_by_name = hash_create_string (0, sizeof (uword));
Dave Barach45e4f362017-03-07 12:52:31 -050019248#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +010019249
19250 /* API messages we can send */
19251#define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
19252 foreach_vpe_api_msg;
19253#undef _
19254
19255 /* Help strings */
19256#define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
19257 foreach_vpe_api_msg;
19258#undef _
Damjan Marion7cd468a2016-12-19 23:05:39 +010019259
19260 /* CLI functions */
19261#define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
19262 foreach_cli_function;
19263#undef _
19264
19265 /* Help strings */
19266#define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
19267 foreach_cli_function;
19268#undef _
19269}
19270
Dave Baracha1a093d2017-03-02 13:13:23 -050019271#if VPP_API_TEST_BUILTIN
19272static clib_error_t *
19273vat_api_hookup_shim (vlib_main_t * vm)
19274{
19275 vat_api_hookup (&vat_main);
19276 return 0;
19277}
19278
19279VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
19280#endif
19281
Damjan Marion7cd468a2016-12-19 23:05:39 +010019282/*
19283 * fd.io coding-style-patch-verification: ON
19284 *
19285 * Local Variables:
19286 * eval: (c-set-style "gnu")
19287 * End:
19288 */