blob: aac59bb8bc022ff51f999a5e9aa23bdca68b9c4c [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
Steven7312cc72017-03-15 21:18:55 -0700406#define VHOST_USER_POLLING_MODE 0
407#define VHOST_USER_INTERRUPT_MODE 1
408#define VHOST_USER_ADAPTIVE_MODE 2
409
410static u8 *
411api_format_vhost_user_operation_mode (u8 * s, va_list * va)
412{
413 int operation_mode = va_arg (*va, int);
414
415 switch (operation_mode)
416 {
417 case VHOST_USER_POLLING_MODE:
418 s = format (s, "%-9s", "polling");
419 break;
420 case VHOST_USER_INTERRUPT_MODE:
421 s = format (s, "%-9s", "interrupt");
422 break;
423 default:
424 s = format (s, "%-9s", "invalid");
425 }
426 return s;
427}
428
429static uword
430api_unformat_vhost_user_operation_mode (unformat_input_t * input,
431 va_list * args)
432{
433 u8 *operation_mode = va_arg (*args, u8 *);
434 uword rc = 1;
435
436 if (unformat (input, "interrupt"))
437 *operation_mode = VHOST_USER_INTERRUPT_MODE;
438 else if (unformat (input, "polling"))
439 *operation_mode = VHOST_USER_POLLING_MODE;
440 else
441 rc = 0;
442
443 return rc;
444}
445
Damjan Marion7cd468a2016-12-19 23:05:39 +0100446static uword
447unformat_policer_rate_type (unformat_input_t * input, va_list * args)
448{
449 u8 *r = va_arg (*args, u8 *);
450
451 if (unformat (input, "kbps"))
452 *r = SSE2_QOS_RATE_KBPS;
453 else if (unformat (input, "pps"))
454 *r = SSE2_QOS_RATE_PPS;
455 else
456 return 0;
457 return 1;
458}
459
460static uword
461unformat_policer_round_type (unformat_input_t * input, va_list * args)
462{
463 u8 *r = va_arg (*args, u8 *);
464
465 if (unformat (input, "closest"))
466 *r = SSE2_QOS_ROUND_TO_CLOSEST;
467 else if (unformat (input, "up"))
468 *r = SSE2_QOS_ROUND_TO_UP;
469 else if (unformat (input, "down"))
470 *r = SSE2_QOS_ROUND_TO_DOWN;
471 else
472 return 0;
473 return 1;
474}
475
476static uword
477unformat_policer_type (unformat_input_t * input, va_list * args)
478{
479 u8 *r = va_arg (*args, u8 *);
480
481 if (unformat (input, "1r2c"))
482 *r = SSE2_QOS_POLICER_TYPE_1R2C;
483 else if (unformat (input, "1r3c"))
484 *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
485 else if (unformat (input, "2r3c-2698"))
486 *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
487 else if (unformat (input, "2r3c-4115"))
488 *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
489 else if (unformat (input, "2r3c-mef5cf1"))
490 *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
491 else
492 return 0;
493 return 1;
494}
495
496static uword
497unformat_dscp (unformat_input_t * input, va_list * va)
498{
499 u8 *r = va_arg (*va, u8 *);
500
501 if (0);
502#define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
503 foreach_vnet_dscp
504#undef _
505 else
506 return 0;
507 return 1;
508}
509
510static uword
511unformat_policer_action_type (unformat_input_t * input, va_list * va)
512{
513 sse2_qos_pol_action_params_st *a
514 = va_arg (*va, sse2_qos_pol_action_params_st *);
515
516 if (unformat (input, "drop"))
517 a->action_type = SSE2_QOS_ACTION_DROP;
518 else if (unformat (input, "transmit"))
519 a->action_type = SSE2_QOS_ACTION_TRANSMIT;
520 else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
521 a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
522 else
523 return 0;
524 return 1;
525}
526
527static uword
528unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
529{
530 u32 *r = va_arg (*va, u32 *);
531 u32 tid;
532
533 if (unformat (input, "ip4"))
534 tid = POLICER_CLASSIFY_TABLE_IP4;
535 else if (unformat (input, "ip6"))
536 tid = POLICER_CLASSIFY_TABLE_IP6;
537 else if (unformat (input, "l2"))
538 tid = POLICER_CLASSIFY_TABLE_L2;
539 else
540 return 0;
541
542 *r = tid;
543 return 1;
544}
545
546static uword
547unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
548{
549 u32 *r = va_arg (*va, u32 *);
550 u32 tid;
551
552 if (unformat (input, "ip4"))
553 tid = FLOW_CLASSIFY_TABLE_IP4;
554 else if (unformat (input, "ip6"))
555 tid = FLOW_CLASSIFY_TABLE_IP6;
556 else
557 return 0;
558
559 *r = tid;
560 return 1;
561}
562
Neale Ranns32e1c012016-11-22 17:07:28 +0000563static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
564static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
565static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
566static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
567
Dave Barach4a3f69c2017-02-22 12:44:56 -0500568#if (VPP_API_TEST_BUILTIN==0)
Neale Ranns32e1c012016-11-22 17:07:28 +0000569uword
570unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
571{
572 mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
573 mfib_itf_attribute_t attr;
574
575 old = *iflags;
576 FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
577 {
578 if (unformat (input, mfib_itf_flag_long_names[attr]))
579 *iflags |= (1 << attr);
580 }
581 FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
582 {
583 if (unformat (input, mfib_itf_flag_names[attr]))
584 *iflags |= (1 << attr);
585 }
586
587 return (old == *iflags ? 0 : 1);
588}
589
590uword
591unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
592{
593 mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
594 mfib_entry_attribute_t attr;
595
596 old = *eflags;
597 FOR_EACH_MFIB_ATTRIBUTE (attr)
598 {
599 if (unformat (input, mfib_flag_long_names[attr]))
600 *eflags |= (1 << attr);
601 }
602 FOR_EACH_MFIB_ATTRIBUTE (attr)
603 {
604 if (unformat (input, mfib_flag_names[attr]))
605 *eflags |= (1 << attr);
606 }
607
608 return (old == *eflags ? 0 : 1);
609}
610
Damjan Marion7cd468a2016-12-19 23:05:39 +0100611u8 *
612format_ip4_address (u8 * s, va_list * args)
613{
614 u8 *a = va_arg (*args, u8 *);
615 return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
616}
617
618u8 *
619format_ip6_address (u8 * s, va_list * args)
620{
621 ip6_address_t *a = va_arg (*args, ip6_address_t *);
622 u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
623
624 i_max_n_zero = ARRAY_LEN (a->as_u16);
625 max_n_zeros = 0;
626 i_first_zero = i_max_n_zero;
627 n_zeros = 0;
628 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
629 {
630 u32 is_zero = a->as_u16[i] == 0;
631 if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
632 {
633 i_first_zero = i;
634 n_zeros = 0;
635 }
636 n_zeros += is_zero;
637 if ((!is_zero && n_zeros > max_n_zeros)
638 || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
639 {
640 i_max_n_zero = i_first_zero;
641 max_n_zeros = n_zeros;
642 i_first_zero = ARRAY_LEN (a->as_u16);
643 n_zeros = 0;
644 }
645 }
646
647 last_double_colon = 0;
648 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
649 {
650 if (i == i_max_n_zero && max_n_zeros > 1)
651 {
652 s = format (s, "::");
653 i += max_n_zeros - 1;
654 last_double_colon = 1;
655 }
656 else
657 {
658 s = format (s, "%s%x",
659 (last_double_colon || i == 0) ? "" : ":",
660 clib_net_to_host_u16 (a->as_u16[i]));
661 last_double_colon = 0;
662 }
663 }
664
665 return s;
666}
667
668/* Format an IP46 address. */
669u8 *
670format_ip46_address (u8 * s, va_list * args)
671{
672 ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
673 ip46_type_t type = va_arg (*args, ip46_type_t);
674 int is_ip4 = 1;
675
676 switch (type)
677 {
678 case IP46_TYPE_ANY:
679 is_ip4 = ip46_address_is_ip4 (ip46);
680 break;
681 case IP46_TYPE_IP4:
682 is_ip4 = 1;
683 break;
684 case IP46_TYPE_IP6:
685 is_ip4 = 0;
686 break;
687 }
688
689 return is_ip4 ?
690 format (s, "%U", format_ip4_address, &ip46->ip4) :
691 format (s, "%U", format_ip6_address, &ip46->ip6);
692}
693
694u8 *
695format_ethernet_address (u8 * s, va_list * args)
696{
697 u8 *a = va_arg (*args, u8 *);
698
699 return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
700 a[0], a[1], a[2], a[3], a[4], a[5]);
701}
702#endif
703
704static void
705increment_v4_address (ip4_address_t * a)
706{
707 u32 v;
708
709 v = ntohl (a->as_u32) + 1;
710 a->as_u32 = ntohl (v);
711}
712
713static void
714increment_v6_address (ip6_address_t * a)
715{
716 u64 v0, v1;
717
718 v0 = clib_net_to_host_u64 (a->as_u64[0]);
719 v1 = clib_net_to_host_u64 (a->as_u64[1]);
720
721 v1 += 1;
722 if (v1 == 0)
723 v0 += 1;
724 a->as_u64[0] = clib_net_to_host_u64 (v0);
725 a->as_u64[1] = clib_net_to_host_u64 (v1);
726}
727
728static void
729increment_mac_address (u64 * mac)
730{
731 u64 tmp = *mac;
732
733 tmp = clib_net_to_host_u64 (tmp);
734 tmp += 1 << 16; /* skip unused (least significant) octets */
735 tmp = clib_host_to_net_u64 (tmp);
736 *mac = tmp;
737}
738
739static void vl_api_create_loopback_reply_t_handler
740 (vl_api_create_loopback_reply_t * mp)
741{
742 vat_main_t *vam = &vat_main;
743 i32 retval = ntohl (mp->retval);
744
745 vam->retval = retval;
746 vam->regenerate_interface_table = 1;
747 vam->sw_if_index = ntohl (mp->sw_if_index);
748 vam->result_ready = 1;
749}
750
751static void vl_api_create_loopback_reply_t_handler_json
752 (vl_api_create_loopback_reply_t * mp)
753{
754 vat_main_t *vam = &vat_main;
755 vat_json_node_t node;
756
757 vat_json_init_object (&node);
758 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
759 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
760
761 vat_json_print (vam->ofp, &node);
762 vat_json_free (&node);
763 vam->retval = ntohl (mp->retval);
764 vam->result_ready = 1;
765}
766
Jon Loeligerc83c3b72017-02-23 13:57:35 -0600767static void vl_api_create_loopback_instance_reply_t_handler
768 (vl_api_create_loopback_instance_reply_t * mp)
769{
770 vat_main_t *vam = &vat_main;
771 i32 retval = ntohl (mp->retval);
772
773 vam->retval = retval;
774 vam->regenerate_interface_table = 1;
775 vam->sw_if_index = ntohl (mp->sw_if_index);
776 vam->result_ready = 1;
777}
778
779static void vl_api_create_loopback_instance_reply_t_handler_json
780 (vl_api_create_loopback_instance_reply_t * mp)
781{
782 vat_main_t *vam = &vat_main;
783 vat_json_node_t node;
784
785 vat_json_init_object (&node);
786 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
787 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
788
789 vat_json_print (vam->ofp, &node);
790 vat_json_free (&node);
791 vam->retval = ntohl (mp->retval);
792 vam->result_ready = 1;
793}
794
Damjan Marion7cd468a2016-12-19 23:05:39 +0100795static void vl_api_af_packet_create_reply_t_handler
796 (vl_api_af_packet_create_reply_t * mp)
797{
798 vat_main_t *vam = &vat_main;
799 i32 retval = ntohl (mp->retval);
800
801 vam->retval = retval;
802 vam->regenerate_interface_table = 1;
803 vam->sw_if_index = ntohl (mp->sw_if_index);
804 vam->result_ready = 1;
805}
806
807static void vl_api_af_packet_create_reply_t_handler_json
808 (vl_api_af_packet_create_reply_t * mp)
809{
810 vat_main_t *vam = &vat_main;
811 vat_json_node_t node;
812
813 vat_json_init_object (&node);
814 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
815 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
816
817 vat_json_print (vam->ofp, &node);
818 vat_json_free (&node);
819
820 vam->retval = ntohl (mp->retval);
821 vam->result_ready = 1;
822}
823
824static void vl_api_create_vlan_subif_reply_t_handler
825 (vl_api_create_vlan_subif_reply_t * mp)
826{
827 vat_main_t *vam = &vat_main;
828 i32 retval = ntohl (mp->retval);
829
830 vam->retval = retval;
831 vam->regenerate_interface_table = 1;
832 vam->sw_if_index = ntohl (mp->sw_if_index);
833 vam->result_ready = 1;
834}
835
836static void vl_api_create_vlan_subif_reply_t_handler_json
837 (vl_api_create_vlan_subif_reply_t * mp)
838{
839 vat_main_t *vam = &vat_main;
840 vat_json_node_t node;
841
842 vat_json_init_object (&node);
843 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
844 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
845
846 vat_json_print (vam->ofp, &node);
847 vat_json_free (&node);
848
849 vam->retval = ntohl (mp->retval);
850 vam->result_ready = 1;
851}
852
853static void vl_api_create_subif_reply_t_handler
854 (vl_api_create_subif_reply_t * mp)
855{
856 vat_main_t *vam = &vat_main;
857 i32 retval = ntohl (mp->retval);
858
859 vam->retval = retval;
860 vam->regenerate_interface_table = 1;
861 vam->sw_if_index = ntohl (mp->sw_if_index);
862 vam->result_ready = 1;
863}
864
865static void vl_api_create_subif_reply_t_handler_json
866 (vl_api_create_subif_reply_t * mp)
867{
868 vat_main_t *vam = &vat_main;
869 vat_json_node_t node;
870
871 vat_json_init_object (&node);
872 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
873 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
874
875 vat_json_print (vam->ofp, &node);
876 vat_json_free (&node);
877
878 vam->retval = ntohl (mp->retval);
879 vam->result_ready = 1;
880}
881
882static void vl_api_interface_name_renumber_reply_t_handler
883 (vl_api_interface_name_renumber_reply_t * mp)
884{
885 vat_main_t *vam = &vat_main;
886 i32 retval = ntohl (mp->retval);
887
888 vam->retval = retval;
889 vam->regenerate_interface_table = 1;
890 vam->result_ready = 1;
891}
892
893static void vl_api_interface_name_renumber_reply_t_handler_json
894 (vl_api_interface_name_renumber_reply_t * mp)
895{
896 vat_main_t *vam = &vat_main;
897 vat_json_node_t node;
898
899 vat_json_init_object (&node);
900 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
901
902 vat_json_print (vam->ofp, &node);
903 vat_json_free (&node);
904
905 vam->retval = ntohl (mp->retval);
906 vam->result_ready = 1;
907}
908
909/*
910 * Special-case: build the interface table, maintain
911 * the next loopback sw_if_index vbl.
912 */
913static void vl_api_sw_interface_details_t_handler
914 (vl_api_sw_interface_details_t * mp)
915{
916 vat_main_t *vam = &vat_main;
917 u8 *s = format (0, "%s%c", mp->interface_name, 0);
918
919 hash_set_mem (vam->sw_if_index_by_interface_name, s,
920 ntohl (mp->sw_if_index));
921
922 /* In sub interface case, fill the sub interface table entry */
923 if (mp->sw_if_index != mp->sup_sw_if_index)
924 {
925 sw_interface_subif_t *sub = NULL;
926
927 vec_add2 (vam->sw_if_subif_table, sub, 1);
928
929 vec_validate (sub->interface_name, strlen ((char *) s) + 1);
930 strncpy ((char *) sub->interface_name, (char *) s,
931 vec_len (sub->interface_name));
932 sub->sw_if_index = ntohl (mp->sw_if_index);
933 sub->sub_id = ntohl (mp->sub_id);
934
935 sub->sub_dot1ad = mp->sub_dot1ad;
936 sub->sub_number_of_tags = mp->sub_number_of_tags;
937 sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
938 sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
939 sub->sub_exact_match = mp->sub_exact_match;
940 sub->sub_default = mp->sub_default;
941 sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
942 sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
943
944 /* vlan tag rewrite */
945 sub->vtr_op = ntohl (mp->vtr_op);
946 sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
947 sub->vtr_tag1 = ntohl (mp->vtr_tag1);
948 sub->vtr_tag2 = ntohl (mp->vtr_tag2);
949 }
950}
951
952static void vl_api_sw_interface_details_t_handler_json
953 (vl_api_sw_interface_details_t * mp)
954{
955 vat_main_t *vam = &vat_main;
956 vat_json_node_t *node = NULL;
957
958 if (VAT_JSON_ARRAY != vam->json_tree.type)
959 {
960 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
961 vat_json_init_array (&vam->json_tree);
962 }
963 node = vat_json_array_add (&vam->json_tree);
964
965 vat_json_init_object (node);
966 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
967 vat_json_object_add_uint (node, "sup_sw_if_index",
968 ntohl (mp->sup_sw_if_index));
969 vat_json_object_add_uint (node, "l2_address_length",
970 ntohl (mp->l2_address_length));
971 vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
972 sizeof (mp->l2_address));
973 vat_json_object_add_string_copy (node, "interface_name",
974 mp->interface_name);
975 vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
976 vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
977 vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
978 vat_json_object_add_uint (node, "link_speed", mp->link_speed);
979 vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
980 vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
981 vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
982 vat_json_object_add_uint (node, "sub_number_of_tags",
983 mp->sub_number_of_tags);
984 vat_json_object_add_uint (node, "sub_outer_vlan_id",
985 ntohs (mp->sub_outer_vlan_id));
986 vat_json_object_add_uint (node, "sub_inner_vlan_id",
987 ntohs (mp->sub_inner_vlan_id));
988 vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
989 vat_json_object_add_uint (node, "sub_default", mp->sub_default);
990 vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
991 mp->sub_outer_vlan_id_any);
992 vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
993 mp->sub_inner_vlan_id_any);
994 vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
995 vat_json_object_add_uint (node, "vtr_push_dot1q",
996 ntohl (mp->vtr_push_dot1q));
997 vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
998 vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
Pavel Kotucek65e84572017-01-16 17:01:56 +0100999 if (mp->sub_dot1ah)
1000 {
1001 vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1002 format (0, "%U",
1003 format_ethernet_address,
1004 &mp->b_dmac));
1005 vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1006 format (0, "%U",
1007 format_ethernet_address,
1008 &mp->b_smac));
1009 vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1010 vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1011 }
Damjan Marion7cd468a2016-12-19 23:05:39 +01001012}
1013
Dave Baracha1a093d2017-03-02 13:13:23 -05001014#if VPP_API_TEST_BUILTIN == 0
Damjan Marion7cd468a2016-12-19 23:05:39 +01001015static void vl_api_sw_interface_set_flags_t_handler
1016 (vl_api_sw_interface_set_flags_t * mp)
1017{
1018 vat_main_t *vam = &vat_main;
1019 if (vam->interface_event_display)
1020 errmsg ("interface flags: sw_if_index %d %s %s",
1021 ntohl (mp->sw_if_index),
1022 mp->admin_up_down ? "admin-up" : "admin-down",
1023 mp->link_up_down ? "link-up" : "link-down");
1024}
Dave Baracha1a093d2017-03-02 13:13:23 -05001025#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +01001026
1027static void vl_api_sw_interface_set_flags_t_handler_json
1028 (vl_api_sw_interface_set_flags_t * mp)
1029{
1030 /* JSON output not supported */
1031}
1032
1033static void
1034vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1035{
1036 vat_main_t *vam = &vat_main;
1037 i32 retval = ntohl (mp->retval);
1038
1039 vam->retval = retval;
Damjan Marion7bee80c2017-04-26 15:32:12 +02001040 vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001041 vam->result_ready = 1;
1042}
1043
1044static void
1045vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1046{
1047 vat_main_t *vam = &vat_main;
1048 vat_json_node_t node;
1049 api_main_t *am = &api_main;
1050 void *oldheap;
1051 u8 *reply;
1052
1053 vat_json_init_object (&node);
1054 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1055 vat_json_object_add_uint (&node, "reply_in_shmem",
1056 ntohl (mp->reply_in_shmem));
1057 /* Toss the shared-memory original... */
1058 pthread_mutex_lock (&am->vlib_rp->mutex);
1059 oldheap = svm_push_data_heap (am->vlib_rp);
1060
Damjan Marion7bee80c2017-04-26 15:32:12 +02001061 reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001062 vec_free (reply);
1063
1064 svm_pop_heap (oldheap);
1065 pthread_mutex_unlock (&am->vlib_rp->mutex);
1066
1067 vat_json_print (vam->ofp, &node);
1068 vat_json_free (&node);
1069
1070 vam->retval = ntohl (mp->retval);
1071 vam->result_ready = 1;
1072}
1073
1074static void
1075vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1076{
1077 vat_main_t *vam = &vat_main;
1078 i32 retval = ntohl (mp->retval);
1079
1080 vam->retval = retval;
1081 vam->cmd_reply = mp->reply;
1082 vam->result_ready = 1;
1083}
1084
1085static void
1086vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1087{
1088 vat_main_t *vam = &vat_main;
1089 vat_json_node_t node;
1090
1091 vat_json_init_object (&node);
1092 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1093 vat_json_object_add_string_copy (&node, "reply", mp->reply);
1094
1095 vat_json_print (vam->ofp, &node);
1096 vat_json_free (&node);
1097
1098 vam->retval = ntohl (mp->retval);
1099 vam->result_ready = 1;
1100}
1101
1102static void vl_api_classify_add_del_table_reply_t_handler
1103 (vl_api_classify_add_del_table_reply_t * mp)
1104{
1105 vat_main_t *vam = &vat_main;
1106 i32 retval = ntohl (mp->retval);
1107 if (vam->async_mode)
1108 {
1109 vam->async_errors += (retval < 0);
1110 }
1111 else
1112 {
1113 vam->retval = retval;
1114 if (retval == 0 &&
1115 ((mp->new_table_index != 0xFFFFFFFF) ||
1116 (mp->skip_n_vectors != 0xFFFFFFFF) ||
1117 (mp->match_n_vectors != 0xFFFFFFFF)))
1118 /*
1119 * Note: this is just barely thread-safe, depends on
1120 * the main thread spinning waiting for an answer...
1121 */
1122 errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1123 ntohl (mp->new_table_index),
1124 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1125 vam->result_ready = 1;
1126 }
1127}
1128
1129static void vl_api_classify_add_del_table_reply_t_handler_json
1130 (vl_api_classify_add_del_table_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, "new_table_index",
1138 ntohl (mp->new_table_index));
1139 vat_json_object_add_uint (&node, "skip_n_vectors",
1140 ntohl (mp->skip_n_vectors));
1141 vat_json_object_add_uint (&node, "match_n_vectors",
1142 ntohl (mp->match_n_vectors));
1143
1144 vat_json_print (vam->ofp, &node);
1145 vat_json_free (&node);
1146
1147 vam->retval = ntohl (mp->retval);
1148 vam->result_ready = 1;
1149}
1150
1151static void vl_api_get_node_index_reply_t_handler
1152 (vl_api_get_node_index_reply_t * mp)
1153{
1154 vat_main_t *vam = &vat_main;
1155 i32 retval = ntohl (mp->retval);
1156 if (vam->async_mode)
1157 {
1158 vam->async_errors += (retval < 0);
1159 }
1160 else
1161 {
1162 vam->retval = retval;
1163 if (retval == 0)
1164 errmsg ("node index %d", ntohl (mp->node_index));
1165 vam->result_ready = 1;
1166 }
1167}
1168
1169static void vl_api_get_node_index_reply_t_handler_json
1170 (vl_api_get_node_index_reply_t * mp)
1171{
1172 vat_main_t *vam = &vat_main;
1173 vat_json_node_t node;
1174
1175 vat_json_init_object (&node);
1176 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1177 vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1178
1179 vat_json_print (vam->ofp, &node);
1180 vat_json_free (&node);
1181
1182 vam->retval = ntohl (mp->retval);
1183 vam->result_ready = 1;
1184}
1185
1186static void vl_api_get_next_index_reply_t_handler
1187 (vl_api_get_next_index_reply_t * mp)
1188{
1189 vat_main_t *vam = &vat_main;
1190 i32 retval = ntohl (mp->retval);
1191 if (vam->async_mode)
1192 {
1193 vam->async_errors += (retval < 0);
1194 }
1195 else
1196 {
1197 vam->retval = retval;
1198 if (retval == 0)
1199 errmsg ("next node index %d", ntohl (mp->next_index));
1200 vam->result_ready = 1;
1201 }
1202}
1203
1204static void vl_api_get_next_index_reply_t_handler_json
1205 (vl_api_get_next_index_reply_t * mp)
1206{
1207 vat_main_t *vam = &vat_main;
1208 vat_json_node_t node;
1209
1210 vat_json_init_object (&node);
1211 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1212 vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1213
1214 vat_json_print (vam->ofp, &node);
1215 vat_json_free (&node);
1216
1217 vam->retval = ntohl (mp->retval);
1218 vam->result_ready = 1;
1219}
1220
1221static void vl_api_add_node_next_reply_t_handler
1222 (vl_api_add_node_next_reply_t * mp)
1223{
1224 vat_main_t *vam = &vat_main;
1225 i32 retval = ntohl (mp->retval);
1226 if (vam->async_mode)
1227 {
1228 vam->async_errors += (retval < 0);
1229 }
1230 else
1231 {
1232 vam->retval = retval;
1233 if (retval == 0)
1234 errmsg ("next index %d", ntohl (mp->next_index));
1235 vam->result_ready = 1;
1236 }
1237}
1238
1239static void vl_api_add_node_next_reply_t_handler_json
1240 (vl_api_add_node_next_reply_t * mp)
1241{
1242 vat_main_t *vam = &vat_main;
1243 vat_json_node_t node;
1244
1245 vat_json_init_object (&node);
1246 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1247 vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1248
1249 vat_json_print (vam->ofp, &node);
1250 vat_json_free (&node);
1251
1252 vam->retval = ntohl (mp->retval);
1253 vam->result_ready = 1;
1254}
1255
1256static void vl_api_show_version_reply_t_handler
1257 (vl_api_show_version_reply_t * mp)
1258{
1259 vat_main_t *vam = &vat_main;
1260 i32 retval = ntohl (mp->retval);
1261
1262 if (retval >= 0)
1263 {
1264 errmsg (" program: %s", mp->program);
1265 errmsg (" version: %s", mp->version);
1266 errmsg (" build date: %s", mp->build_date);
1267 errmsg ("build directory: %s", mp->build_directory);
1268 }
1269 vam->retval = retval;
1270 vam->result_ready = 1;
1271}
1272
1273static void vl_api_show_version_reply_t_handler_json
1274 (vl_api_show_version_reply_t * mp)
1275{
1276 vat_main_t *vam = &vat_main;
1277 vat_json_node_t node;
1278
1279 vat_json_init_object (&node);
1280 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1281 vat_json_object_add_string_copy (&node, "program", mp->program);
1282 vat_json_object_add_string_copy (&node, "version", mp->version);
1283 vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1284 vat_json_object_add_string_copy (&node, "build_directory",
1285 mp->build_directory);
1286
1287 vat_json_print (vam->ofp, &node);
1288 vat_json_free (&node);
1289
1290 vam->retval = ntohl (mp->retval);
1291 vam->result_ready = 1;
1292}
1293
1294static void
1295vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1296{
Wojciech Dec09a38a62017-03-07 19:30:39 +01001297 u32 sw_if_index = ntohl (mp->sw_if_index);
John Lo20e1f2a2017-03-29 13:35:43 -04001298 errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
Damjan Marion7cd468a2016-12-19 23:05:39 +01001299 mp->mac_ip ? "mac/ip binding" : "address resolution",
John Lo20e1f2a2017-03-29 13:35:43 -04001300 ntohl (mp->pid), format_ip4_address, &mp->address,
Wojciech Dec09a38a62017-03-07 19:30:39 +01001301 format_ethernet_address, mp->new_mac, sw_if_index);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001302}
1303
1304static void
1305vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1306{
1307 /* JSON output not supported */
1308}
1309
1310static void
1311vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1312{
Wojciech Dec09a38a62017-03-07 19:30:39 +01001313 u32 sw_if_index = ntohl (mp->sw_if_index);
John Lo20e1f2a2017-03-29 13:35:43 -04001314 errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
Damjan Marion7cd468a2016-12-19 23:05:39 +01001315 mp->mac_ip ? "mac/ip binding" : "address resolution",
John Lo20e1f2a2017-03-29 13:35:43 -04001316 ntohl (mp->pid), format_ip6_address, mp->address,
Wojciech Dec09a38a62017-03-07 19:30:39 +01001317 format_ethernet_address, mp->new_mac, sw_if_index);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001318}
1319
1320static void
1321vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1322{
1323 /* JSON output not supported */
1324}
1325
Ole Troan01384fe2017-05-12 11:55:35 +02001326#define vl_api_bridge_domain_details_t_endian vl_noop_handler
1327#define vl_api_bridge_domain_details_t_print vl_noop_handler
1328
Damjan Marion7cd468a2016-12-19 23:05:39 +01001329/*
1330 * Special-case: build the bridge domain table, maintain
1331 * the next bd id vbl.
1332 */
1333static void vl_api_bridge_domain_details_t_handler
1334 (vl_api_bridge_domain_details_t * mp)
1335{
1336 vat_main_t *vam = &vat_main;
1337 u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
Ole Troan01384fe2017-05-12 11:55:35 +02001338 int i;
Damjan Marion7cd468a2016-12-19 23:05:39 +01001339
1340 print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1341 " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1342
1343 print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1344 ntohl (mp->bd_id), mp->learn, mp->forward,
1345 mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1346
1347 if (n_sw_ifs)
Ole Troan01384fe2017-05-12 11:55:35 +02001348 {
1349 vl_api_bridge_domain_sw_if_t *sw_ifs;
1350 print (vam->ofp, "\n\n%s %s %s", "sw_if_index", "SHG",
1351 "Interface Name");
1352
1353 sw_ifs = mp->sw_if_details;
1354 for (i = 0; i < n_sw_ifs; i++)
1355 {
1356 u8 *sw_if_name = 0;
1357 u32 sw_if_index;
1358 hash_pair_t *p;
1359
1360 sw_if_index = ntohl (sw_ifs->sw_if_index);
1361
1362 /* *INDENT-OFF* */
1363 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1364 ({
1365 if ((u32) p->value[0] == sw_if_index)
1366 {
1367 sw_if_name = (u8 *)(p->key);
1368 break;
1369 }
1370 }));
1371 /* *INDENT-ON* */
1372 print (vam->ofp, "%7d %3d %s", sw_if_index,
1373 sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1374 "sw_if_index not found!");
1375
1376 sw_ifs++;
1377 }
1378 }
Damjan Marion7cd468a2016-12-19 23:05:39 +01001379}
1380
1381static void vl_api_bridge_domain_details_t_handler_json
1382 (vl_api_bridge_domain_details_t * mp)
1383{
1384 vat_main_t *vam = &vat_main;
1385 vat_json_node_t *node, *array = NULL;
Ole Troan01384fe2017-05-12 11:55:35 +02001386 u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001387
1388 if (VAT_JSON_ARRAY != vam->json_tree.type)
1389 {
1390 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1391 vat_json_init_array (&vam->json_tree);
1392 }
1393 node = vat_json_array_add (&vam->json_tree);
1394
1395 vat_json_init_object (node);
1396 vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1397 vat_json_object_add_uint (node, "flood", mp->flood);
1398 vat_json_object_add_uint (node, "forward", mp->forward);
1399 vat_json_object_add_uint (node, "learn", mp->learn);
1400 vat_json_object_add_uint (node, "bvi_sw_if_index",
1401 ntohl (mp->bvi_sw_if_index));
Ole Troan01384fe2017-05-12 11:55:35 +02001402 vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001403 array = vat_json_object_add (node, "sw_if");
1404 vat_json_init_array (array);
Damjan Marion7cd468a2016-12-19 23:05:39 +01001405
Damjan Marion7cd468a2016-12-19 23:05:39 +01001406
Damjan Marion7cd468a2016-12-19 23:05:39 +01001407
Ole Troan01384fe2017-05-12 11:55:35 +02001408 if (n_sw_ifs)
1409 {
1410 vl_api_bridge_domain_sw_if_t *sw_ifs;
1411 int i;
Damjan Marion7cd468a2016-12-19 23:05:39 +01001412
Ole Troan01384fe2017-05-12 11:55:35 +02001413 sw_ifs = mp->sw_if_details;
1414 for (i = 0; i < n_sw_ifs; i++)
1415 {
1416 node = vat_json_array_add (array);
1417 vat_json_init_object (node);
1418 vat_json_object_add_uint (node, "sw_if_index",
1419 ntohl (sw_ifs->sw_if_index));
1420 vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1421 sw_ifs++;
1422 }
1423 }
Damjan Marion7cd468a2016-12-19 23:05:39 +01001424}
1425
1426static void vl_api_control_ping_reply_t_handler
1427 (vl_api_control_ping_reply_t * mp)
1428{
1429 vat_main_t *vam = &vat_main;
1430 i32 retval = ntohl (mp->retval);
1431 if (vam->async_mode)
1432 {
1433 vam->async_errors += (retval < 0);
1434 }
1435 else
1436 {
1437 vam->retval = retval;
1438 vam->result_ready = 1;
1439 }
1440}
1441
1442static void vl_api_control_ping_reply_t_handler_json
1443 (vl_api_control_ping_reply_t * mp)
1444{
1445 vat_main_t *vam = &vat_main;
1446 i32 retval = ntohl (mp->retval);
1447
1448 if (VAT_JSON_NONE != vam->json_tree.type)
1449 {
1450 vat_json_print (vam->ofp, &vam->json_tree);
1451 vat_json_free (&vam->json_tree);
1452 vam->json_tree.type = VAT_JSON_NONE;
1453 }
1454 else
1455 {
1456 /* just print [] */
1457 vat_json_init_array (&vam->json_tree);
1458 vat_json_print (vam->ofp, &vam->json_tree);
1459 vam->json_tree.type = VAT_JSON_NONE;
1460 }
1461
1462 vam->retval = retval;
1463 vam->result_ready = 1;
1464}
1465
1466static void
Eyal Barifead6702017-04-04 04:46:32 +03001467 vl_api_bridge_domain_set_mac_age_reply_t_handler
1468 (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1469{
1470 vat_main_t *vam = &vat_main;
1471 i32 retval = ntohl (mp->retval);
1472 if (vam->async_mode)
1473 {
1474 vam->async_errors += (retval < 0);
1475 }
1476 else
1477 {
1478 vam->retval = retval;
1479 vam->result_ready = 1;
1480 }
1481}
1482
1483static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1484 (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1485{
1486 vat_main_t *vam = &vat_main;
1487 vat_json_node_t node;
1488
1489 vat_json_init_object (&node);
1490 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1491
1492 vat_json_print (vam->ofp, &node);
1493 vat_json_free (&node);
1494
1495 vam->retval = ntohl (mp->retval);
1496 vam->result_ready = 1;
1497}
1498
1499static void
Damjan Marion7cd468a2016-12-19 23:05:39 +01001500vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1501{
1502 vat_main_t *vam = &vat_main;
1503 i32 retval = ntohl (mp->retval);
1504 if (vam->async_mode)
1505 {
1506 vam->async_errors += (retval < 0);
1507 }
1508 else
1509 {
1510 vam->retval = retval;
1511 vam->result_ready = 1;
1512 }
1513}
1514
1515static void vl_api_l2_flags_reply_t_handler_json
1516 (vl_api_l2_flags_reply_t * mp)
1517{
1518 vat_main_t *vam = &vat_main;
1519 vat_json_node_t node;
1520
1521 vat_json_init_object (&node);
1522 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1523 vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1524 ntohl (mp->resulting_feature_bitmap));
1525
1526 vat_json_print (vam->ofp, &node);
1527 vat_json_free (&node);
1528
1529 vam->retval = ntohl (mp->retval);
1530 vam->result_ready = 1;
1531}
1532
1533static void vl_api_bridge_flags_reply_t_handler
1534 (vl_api_bridge_flags_reply_t * mp)
1535{
1536 vat_main_t *vam = &vat_main;
1537 i32 retval = ntohl (mp->retval);
1538 if (vam->async_mode)
1539 {
1540 vam->async_errors += (retval < 0);
1541 }
1542 else
1543 {
1544 vam->retval = retval;
1545 vam->result_ready = 1;
1546 }
1547}
1548
1549static void vl_api_bridge_flags_reply_t_handler_json
1550 (vl_api_bridge_flags_reply_t * mp)
1551{
1552 vat_main_t *vam = &vat_main;
1553 vat_json_node_t node;
1554
1555 vat_json_init_object (&node);
1556 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1557 vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1558 ntohl (mp->resulting_feature_bitmap));
1559
1560 vat_json_print (vam->ofp, &node);
1561 vat_json_free (&node);
1562
1563 vam->retval = ntohl (mp->retval);
1564 vam->result_ready = 1;
1565}
1566
1567static void vl_api_tap_connect_reply_t_handler
1568 (vl_api_tap_connect_reply_t * mp)
1569{
1570 vat_main_t *vam = &vat_main;
1571 i32 retval = ntohl (mp->retval);
1572 if (vam->async_mode)
1573 {
1574 vam->async_errors += (retval < 0);
1575 }
1576 else
1577 {
1578 vam->retval = retval;
1579 vam->sw_if_index = ntohl (mp->sw_if_index);
1580 vam->result_ready = 1;
1581 }
1582
1583}
1584
1585static void vl_api_tap_connect_reply_t_handler_json
1586 (vl_api_tap_connect_reply_t * mp)
1587{
1588 vat_main_t *vam = &vat_main;
1589 vat_json_node_t node;
1590
1591 vat_json_init_object (&node);
1592 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1593 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1594
1595 vat_json_print (vam->ofp, &node);
1596 vat_json_free (&node);
1597
1598 vam->retval = ntohl (mp->retval);
1599 vam->result_ready = 1;
1600
1601}
1602
1603static void
1604vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1605{
1606 vat_main_t *vam = &vat_main;
1607 i32 retval = ntohl (mp->retval);
1608 if (vam->async_mode)
1609 {
1610 vam->async_errors += (retval < 0);
1611 }
1612 else
1613 {
1614 vam->retval = retval;
1615 vam->sw_if_index = ntohl (mp->sw_if_index);
1616 vam->result_ready = 1;
1617 }
1618}
1619
1620static void vl_api_tap_modify_reply_t_handler_json
1621 (vl_api_tap_modify_reply_t * mp)
1622{
1623 vat_main_t *vam = &vat_main;
1624 vat_json_node_t node;
1625
1626 vat_json_init_object (&node);
1627 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1628 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1629
1630 vat_json_print (vam->ofp, &node);
1631 vat_json_free (&node);
1632
1633 vam->retval = ntohl (mp->retval);
1634 vam->result_ready = 1;
1635}
1636
1637static void
1638vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1639{
1640 vat_main_t *vam = &vat_main;
1641 i32 retval = ntohl (mp->retval);
1642 if (vam->async_mode)
1643 {
1644 vam->async_errors += (retval < 0);
1645 }
1646 else
1647 {
1648 vam->retval = retval;
1649 vam->result_ready = 1;
1650 }
1651}
1652
1653static void vl_api_tap_delete_reply_t_handler_json
1654 (vl_api_tap_delete_reply_t * mp)
1655{
1656 vat_main_t *vam = &vat_main;
1657 vat_json_node_t node;
1658
1659 vat_json_init_object (&node);
1660 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1661
1662 vat_json_print (vam->ofp, &node);
1663 vat_json_free (&node);
1664
1665 vam->retval = ntohl (mp->retval);
1666 vam->result_ready = 1;
1667}
1668
1669static void vl_api_mpls_tunnel_add_del_reply_t_handler
1670 (vl_api_mpls_tunnel_add_del_reply_t * mp)
1671{
1672 vat_main_t *vam = &vat_main;
1673 i32 retval = ntohl (mp->retval);
1674 if (vam->async_mode)
1675 {
1676 vam->async_errors += (retval < 0);
1677 }
1678 else
1679 {
1680 vam->retval = retval;
1681 vam->result_ready = 1;
1682 }
1683}
1684
1685static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1686 (vl_api_mpls_tunnel_add_del_reply_t * mp)
1687{
1688 vat_main_t *vam = &vat_main;
1689 vat_json_node_t node;
1690
1691 vat_json_init_object (&node);
1692 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1693 vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1694 ntohl (mp->sw_if_index));
1695
1696 vat_json_print (vam->ofp, &node);
1697 vat_json_free (&node);
1698
1699 vam->retval = ntohl (mp->retval);
1700 vam->result_ready = 1;
1701}
1702
1703static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1704 (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1705{
1706 vat_main_t *vam = &vat_main;
1707 i32 retval = ntohl (mp->retval);
1708 if (vam->async_mode)
1709 {
1710 vam->async_errors += (retval < 0);
1711 }
1712 else
1713 {
1714 vam->retval = retval;
1715 vam->sw_if_index = ntohl (mp->sw_if_index);
1716 vam->result_ready = 1;
1717 }
1718}
1719
1720static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1721 (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1722{
1723 vat_main_t *vam = &vat_main;
1724 vat_json_node_t node;
1725
1726 vat_json_init_object (&node);
1727 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1728 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1729
1730 vat_json_print (vam->ofp, &node);
1731 vat_json_free (&node);
1732
1733 vam->retval = ntohl (mp->retval);
1734 vam->result_ready = 1;
1735}
1736
1737
Filip Tehlar694396d2017-02-17 14:29:11 +01001738static void vl_api_one_add_del_locator_set_reply_t_handler
1739 (vl_api_one_add_del_locator_set_reply_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01001740{
1741 vat_main_t *vam = &vat_main;
1742 i32 retval = ntohl (mp->retval);
1743 if (vam->async_mode)
1744 {
1745 vam->async_errors += (retval < 0);
1746 }
1747 else
1748 {
1749 vam->retval = retval;
1750 vam->result_ready = 1;
1751 }
1752}
1753
Filip Tehlar694396d2017-02-17 14:29:11 +01001754static void vl_api_one_add_del_locator_set_reply_t_handler_json
1755 (vl_api_one_add_del_locator_set_reply_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01001756{
1757 vat_main_t *vam = &vat_main;
1758 vat_json_node_t node;
1759
1760 vat_json_init_object (&node);
1761 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1762 vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1763
1764 vat_json_print (vam->ofp, &node);
1765 vat_json_free (&node);
1766
1767 vam->retval = ntohl (mp->retval);
1768 vam->result_ready = 1;
1769}
1770
1771static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1772 (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1773{
1774 vat_main_t *vam = &vat_main;
1775 i32 retval = ntohl (mp->retval);
1776 if (vam->async_mode)
1777 {
1778 vam->async_errors += (retval < 0);
1779 }
1780 else
1781 {
1782 vam->retval = retval;
1783 vam->sw_if_index = ntohl (mp->sw_if_index);
1784 vam->result_ready = 1;
1785 }
1786}
1787
1788static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1789 (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1790{
1791 vat_main_t *vam = &vat_main;
1792 vat_json_node_t node;
1793
1794 vat_json_init_object (&node);
1795 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1796 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1797
1798 vat_json_print (vam->ofp, &node);
1799 vat_json_free (&node);
1800
1801 vam->retval = ntohl (mp->retval);
1802 vam->result_ready = 1;
1803}
1804
1805static void vl_api_gre_add_del_tunnel_reply_t_handler
1806 (vl_api_gre_add_del_tunnel_reply_t * mp)
1807{
1808 vat_main_t *vam = &vat_main;
1809 i32 retval = ntohl (mp->retval);
1810 if (vam->async_mode)
1811 {
1812 vam->async_errors += (retval < 0);
1813 }
1814 else
1815 {
1816 vam->retval = retval;
1817 vam->sw_if_index = ntohl (mp->sw_if_index);
1818 vam->result_ready = 1;
1819 }
1820}
1821
1822static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1823 (vl_api_gre_add_del_tunnel_reply_t * mp)
1824{
1825 vat_main_t *vam = &vat_main;
1826 vat_json_node_t node;
1827
1828 vat_json_init_object (&node);
1829 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1830 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1831
1832 vat_json_print (vam->ofp, &node);
1833 vat_json_free (&node);
1834
1835 vam->retval = ntohl (mp->retval);
1836 vam->result_ready = 1;
1837}
1838
1839static void vl_api_create_vhost_user_if_reply_t_handler
1840 (vl_api_create_vhost_user_if_reply_t * mp)
1841{
1842 vat_main_t *vam = &vat_main;
1843 i32 retval = ntohl (mp->retval);
1844 if (vam->async_mode)
1845 {
1846 vam->async_errors += (retval < 0);
1847 }
1848 else
1849 {
1850 vam->retval = retval;
1851 vam->sw_if_index = ntohl (mp->sw_if_index);
1852 vam->result_ready = 1;
1853 }
1854}
1855
1856static void vl_api_create_vhost_user_if_reply_t_handler_json
1857 (vl_api_create_vhost_user_if_reply_t * mp)
1858{
1859 vat_main_t *vam = &vat_main;
1860 vat_json_node_t node;
1861
1862 vat_json_init_object (&node);
1863 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1864 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1865
1866 vat_json_print (vam->ofp, &node);
1867 vat_json_free (&node);
1868
1869 vam->retval = ntohl (mp->retval);
1870 vam->result_ready = 1;
1871}
1872
1873static void vl_api_ip_address_details_t_handler
1874 (vl_api_ip_address_details_t * mp)
1875{
1876 vat_main_t *vam = &vat_main;
1877 static ip_address_details_t empty_ip_address_details = { {0} };
1878 ip_address_details_t *address = NULL;
1879 ip_details_t *current_ip_details = NULL;
1880 ip_details_t *details = NULL;
1881
1882 details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1883
1884 if (!details || vam->current_sw_if_index >= vec_len (details)
1885 || !details[vam->current_sw_if_index].present)
1886 {
1887 errmsg ("ip address details arrived but not stored");
1888 errmsg ("ip_dump should be called first");
1889 return;
1890 }
1891
1892 current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1893
1894#define addresses (current_ip_details->addr)
1895
1896 vec_validate_init_empty (addresses, vec_len (addresses),
1897 empty_ip_address_details);
1898
1899 address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1900
1901 clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1902 address->prefix_length = mp->prefix_length;
1903#undef addresses
1904}
1905
1906static void vl_api_ip_address_details_t_handler_json
1907 (vl_api_ip_address_details_t * mp)
1908{
1909 vat_main_t *vam = &vat_main;
1910 vat_json_node_t *node = NULL;
1911 struct in6_addr ip6;
1912 struct in_addr ip4;
1913
1914 if (VAT_JSON_ARRAY != vam->json_tree.type)
1915 {
1916 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1917 vat_json_init_array (&vam->json_tree);
1918 }
1919 node = vat_json_array_add (&vam->json_tree);
1920
1921 vat_json_init_object (node);
1922 if (vam->is_ipv6)
1923 {
1924 clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1925 vat_json_object_add_ip6 (node, "ip", ip6);
1926 }
1927 else
1928 {
1929 clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1930 vat_json_object_add_ip4 (node, "ip", ip4);
1931 }
1932 vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1933}
1934
1935static void
1936vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1937{
1938 vat_main_t *vam = &vat_main;
1939 static ip_details_t empty_ip_details = { 0 };
1940 ip_details_t *ip = NULL;
1941 u32 sw_if_index = ~0;
1942
1943 sw_if_index = ntohl (mp->sw_if_index);
1944
1945 vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1946 sw_if_index, empty_ip_details);
1947
1948 ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1949 sw_if_index);
1950
1951 ip->present = 1;
1952}
1953
1954static void
1955vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1956{
1957 vat_main_t *vam = &vat_main;
1958
1959 if (VAT_JSON_ARRAY != vam->json_tree.type)
1960 {
1961 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1962 vat_json_init_array (&vam->json_tree);
1963 }
1964 vat_json_array_add_uint (&vam->json_tree,
1965 clib_net_to_host_u32 (mp->sw_if_index));
1966}
1967
1968static void vl_api_map_domain_details_t_handler_json
1969 (vl_api_map_domain_details_t * mp)
1970{
1971 vat_json_node_t *node = NULL;
1972 vat_main_t *vam = &vat_main;
1973 struct in6_addr ip6;
1974 struct in_addr ip4;
1975
1976 if (VAT_JSON_ARRAY != vam->json_tree.type)
1977 {
1978 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1979 vat_json_init_array (&vam->json_tree);
1980 }
1981
1982 node = vat_json_array_add (&vam->json_tree);
1983 vat_json_init_object (node);
1984
1985 vat_json_object_add_uint (node, "domain_index",
1986 clib_net_to_host_u32 (mp->domain_index));
1987 clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1988 vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1989 clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1990 vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1991 clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1992 vat_json_object_add_ip6 (node, "ip6_src", ip6);
1993 vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1994 vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1995 vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1996 vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1997 vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1998 vat_json_object_add_int (node, "psid_length", mp->psid_length);
1999 vat_json_object_add_uint (node, "flags", mp->flags);
2000 vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
2001 vat_json_object_add_int (node, "is_translation", mp->is_translation);
2002}
2003
2004static void vl_api_map_domain_details_t_handler
2005 (vl_api_map_domain_details_t * mp)
2006{
2007 vat_main_t *vam = &vat_main;
2008
2009 if (mp->is_translation)
2010 {
2011 print (vam->ofp,
2012 "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
2013 format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2014 format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2015 format_ip6_address, mp->ip6_src, mp->ip6_src_len,
2016 clib_net_to_host_u32 (mp->domain_index));
2017 }
2018 else
2019 {
2020 print (vam->ofp,
2021 "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
2022 format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2023 format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2024 format_ip6_address, mp->ip6_src,
2025 clib_net_to_host_u32 (mp->domain_index));
2026 }
2027 print (vam->ofp, " ea-len %d psid-offset %d psid-len %d mtu %d %s",
2028 mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
2029 mp->is_translation ? "map-t" : "");
2030}
2031
2032static void vl_api_map_rule_details_t_handler_json
2033 (vl_api_map_rule_details_t * mp)
2034{
2035 struct in6_addr ip6;
2036 vat_json_node_t *node = NULL;
2037 vat_main_t *vam = &vat_main;
2038
2039 if (VAT_JSON_ARRAY != vam->json_tree.type)
2040 {
2041 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2042 vat_json_init_array (&vam->json_tree);
2043 }
2044
2045 node = vat_json_array_add (&vam->json_tree);
2046 vat_json_init_object (node);
2047
2048 vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
2049 clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
2050 vat_json_object_add_ip6 (node, "ip6_dst", ip6);
2051}
2052
2053static void
2054vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
2055{
2056 vat_main_t *vam = &vat_main;
2057 print (vam->ofp, " %d (psid) %U (ip6-dst)",
2058 clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
2059}
2060
2061static void
2062vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2063{
2064 errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2065 "router_addr %U host_mac %U",
John Lo20e1f2a2017-03-29 13:35:43 -04002066 ntohl (mp->pid), mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
Damjan Marion7cd468a2016-12-19 23:05:39 +01002067 format_ip4_address, &mp->host_address,
2068 format_ip4_address, &mp->router_address,
2069 format_ethernet_address, mp->host_mac);
2070}
2071
2072static void vl_api_dhcp_compl_event_t_handler_json
2073 (vl_api_dhcp_compl_event_t * mp)
2074{
2075 /* JSON output not supported */
2076}
2077
2078static void
2079set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2080 u32 counter)
2081{
2082 vat_main_t *vam = &vat_main;
2083 static u64 default_counter = 0;
2084
2085 vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2086 NULL);
2087 vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2088 sw_if_index, default_counter);
2089 vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2090}
2091
2092static void
2093set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2094 interface_counter_t counter)
2095{
2096 vat_main_t *vam = &vat_main;
2097 static interface_counter_t default_counter = { 0, };
2098
2099 vec_validate_init_empty (vam->combined_interface_counters,
2100 vnet_counter_type, NULL);
2101 vec_validate_init_empty (vam->combined_interface_counters
2102 [vnet_counter_type], sw_if_index, default_counter);
2103 vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2104}
2105
Aloys Augustinee551982017-02-17 14:55:29 +01002106static void vl_api_vnet_interface_simple_counters_t_handler
2107 (vl_api_vnet_interface_simple_counters_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002108{
2109 /* not supported */
2110}
2111
Aloys Augustinee551982017-02-17 14:55:29 +01002112static void vl_api_vnet_interface_combined_counters_t_handler
2113 (vl_api_vnet_interface_combined_counters_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002114{
Aloys Augustinee551982017-02-17 14:55:29 +01002115 /* not supported */
2116}
2117
2118static void vl_api_vnet_interface_simple_counters_t_handler_json
2119 (vl_api_vnet_interface_simple_counters_t * mp)
2120{
Damjan Marion7cd468a2016-12-19 23:05:39 +01002121 u64 *v_packets;
2122 u64 packets;
2123 u32 count;
2124 u32 first_sw_if_index;
2125 int i;
2126
2127 count = ntohl (mp->count);
2128 first_sw_if_index = ntohl (mp->first_sw_if_index);
2129
Aloys Augustinee551982017-02-17 14:55:29 +01002130 v_packets = (u64 *) & mp->data;
2131 for (i = 0; i < count; i++)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002132 {
Aloys Augustinee551982017-02-17 14:55:29 +01002133 packets = clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2134 set_simple_interface_counter (mp->vnet_counter_type,
2135 first_sw_if_index + i, packets);
2136 v_packets++;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002137 }
Aloys Augustinee551982017-02-17 14:55:29 +01002138}
2139
2140static void vl_api_vnet_interface_combined_counters_t_handler_json
2141 (vl_api_vnet_interface_combined_counters_t * mp)
2142{
2143 interface_counter_t counter;
2144 vlib_counter_t *v;
2145 u32 first_sw_if_index;
2146 int i;
2147 u32 count;
2148
2149 count = ntohl (mp->count);
2150 first_sw_if_index = ntohl (mp->first_sw_if_index);
2151
2152 v = (vlib_counter_t *) & mp->data;
2153 for (i = 0; i < count; i++)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002154 {
Aloys Augustinee551982017-02-17 14:55:29 +01002155 counter.packets =
2156 clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2157 counter.bytes =
2158 clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2159 set_combined_interface_counter (mp->vnet_counter_type,
2160 first_sw_if_index + i, counter);
2161 v++;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002162 }
2163}
2164
2165static u32
2166ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2167{
2168 vat_main_t *vam = &vat_main;
2169 u32 i;
2170
2171 for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2172 {
2173 if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2174 {
2175 return i;
2176 }
2177 }
2178 return ~0;
2179}
2180
2181static u32
2182ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2183{
2184 vat_main_t *vam = &vat_main;
2185 u32 i;
2186
2187 for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2188 {
2189 if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2190 {
2191 return i;
2192 }
2193 }
2194 return ~0;
2195}
2196
2197static void vl_api_vnet_ip4_fib_counters_t_handler
2198 (vl_api_vnet_ip4_fib_counters_t * mp)
2199{
2200 /* not supported */
2201}
2202
2203static void vl_api_vnet_ip4_fib_counters_t_handler_json
2204 (vl_api_vnet_ip4_fib_counters_t * mp)
2205{
2206 vat_main_t *vam = &vat_main;
2207 vl_api_ip4_fib_counter_t *v;
2208 ip4_fib_counter_t *counter;
2209 struct in_addr ip4;
2210 u32 vrf_id;
2211 u32 vrf_index;
2212 u32 count;
2213 int i;
2214
2215 vrf_id = ntohl (mp->vrf_id);
2216 vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2217 if (~0 == vrf_index)
2218 {
2219 vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2220 vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2221 vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2222 vec_validate (vam->ip4_fib_counters, vrf_index);
2223 vam->ip4_fib_counters[vrf_index] = NULL;
2224 }
2225
2226 vec_free (vam->ip4_fib_counters[vrf_index]);
2227 v = (vl_api_ip4_fib_counter_t *) & mp->c;
2228 count = ntohl (mp->count);
2229 for (i = 0; i < count; i++)
2230 {
2231 vec_validate (vam->ip4_fib_counters[vrf_index], i);
2232 counter = &vam->ip4_fib_counters[vrf_index][i];
2233 clib_memcpy (&ip4, &v->address, sizeof (ip4));
2234 counter->address = ip4;
2235 counter->address_length = v->address_length;
2236 counter->packets = clib_net_to_host_u64 (v->packets);
2237 counter->bytes = clib_net_to_host_u64 (v->bytes);
2238 v++;
2239 }
2240}
2241
Neale Ranns044183f2017-01-24 01:34:25 -08002242static void vl_api_vnet_ip4_nbr_counters_t_handler
2243 (vl_api_vnet_ip4_nbr_counters_t * mp)
2244{
2245 /* not supported */
2246}
2247
2248static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2249 (vl_api_vnet_ip4_nbr_counters_t * mp)
2250{
2251 vat_main_t *vam = &vat_main;
2252 vl_api_ip4_nbr_counter_t *v;
2253 ip4_nbr_counter_t *counter;
2254 u32 sw_if_index;
2255 u32 count;
2256 int i;
2257
2258 sw_if_index = ntohl (mp->sw_if_index);
2259 count = ntohl (mp->count);
2260 vec_validate (vam->ip4_nbr_counters, sw_if_index);
2261
2262 if (mp->begin)
2263 vec_free (vam->ip4_nbr_counters[sw_if_index]);
2264
2265 v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2266 for (i = 0; i < count; i++)
2267 {
2268 vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2269 counter = &vam->ip4_nbr_counters[sw_if_index][i];
2270 counter->address.s_addr = v->address;
2271 counter->packets = clib_net_to_host_u64 (v->packets);
2272 counter->bytes = clib_net_to_host_u64 (v->bytes);
2273 counter->linkt = v->link_type;
2274 v++;
2275 }
2276}
2277
Damjan Marion7cd468a2016-12-19 23:05:39 +01002278static void vl_api_vnet_ip6_fib_counters_t_handler
2279 (vl_api_vnet_ip6_fib_counters_t * mp)
2280{
2281 /* not supported */
2282}
2283
2284static void vl_api_vnet_ip6_fib_counters_t_handler_json
2285 (vl_api_vnet_ip6_fib_counters_t * mp)
2286{
2287 vat_main_t *vam = &vat_main;
2288 vl_api_ip6_fib_counter_t *v;
2289 ip6_fib_counter_t *counter;
2290 struct in6_addr ip6;
2291 u32 vrf_id;
2292 u32 vrf_index;
2293 u32 count;
2294 int i;
2295
2296 vrf_id = ntohl (mp->vrf_id);
2297 vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2298 if (~0 == vrf_index)
2299 {
2300 vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2301 vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2302 vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2303 vec_validate (vam->ip6_fib_counters, vrf_index);
2304 vam->ip6_fib_counters[vrf_index] = NULL;
2305 }
2306
2307 vec_free (vam->ip6_fib_counters[vrf_index]);
2308 v = (vl_api_ip6_fib_counter_t *) & mp->c;
2309 count = ntohl (mp->count);
2310 for (i = 0; i < count; i++)
2311 {
2312 vec_validate (vam->ip6_fib_counters[vrf_index], i);
2313 counter = &vam->ip6_fib_counters[vrf_index][i];
2314 clib_memcpy (&ip6, &v->address, sizeof (ip6));
2315 counter->address = ip6;
2316 counter->address_length = v->address_length;
2317 counter->packets = clib_net_to_host_u64 (v->packets);
2318 counter->bytes = clib_net_to_host_u64 (v->bytes);
2319 v++;
2320 }
2321}
2322
Neale Ranns044183f2017-01-24 01:34:25 -08002323static void vl_api_vnet_ip6_nbr_counters_t_handler
2324 (vl_api_vnet_ip6_nbr_counters_t * mp)
2325{
2326 /* not supported */
2327}
2328
2329static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2330 (vl_api_vnet_ip6_nbr_counters_t * mp)
2331{
2332 vat_main_t *vam = &vat_main;
2333 vl_api_ip6_nbr_counter_t *v;
2334 ip6_nbr_counter_t *counter;
2335 struct in6_addr ip6;
2336 u32 sw_if_index;
2337 u32 count;
2338 int i;
2339
2340 sw_if_index = ntohl (mp->sw_if_index);
2341 count = ntohl (mp->count);
2342 vec_validate (vam->ip6_nbr_counters, sw_if_index);
2343
2344 if (mp->begin)
2345 vec_free (vam->ip6_nbr_counters[sw_if_index]);
2346
2347 v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2348 for (i = 0; i < count; i++)
2349 {
2350 vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2351 counter = &vam->ip6_nbr_counters[sw_if_index][i];
2352 clib_memcpy (&ip6, &v->address, sizeof (ip6));
2353 counter->address = ip6;
2354 counter->packets = clib_net_to_host_u64 (v->packets);
2355 counter->bytes = clib_net_to_host_u64 (v->bytes);
2356 v++;
2357 }
2358}
2359
Damjan Marion7cd468a2016-12-19 23:05:39 +01002360static void vl_api_get_first_msg_id_reply_t_handler
2361 (vl_api_get_first_msg_id_reply_t * mp)
2362{
2363 vat_main_t *vam = &vat_main;
2364 i32 retval = ntohl (mp->retval);
2365
2366 if (vam->async_mode)
2367 {
2368 vam->async_errors += (retval < 0);
2369 }
2370 else
2371 {
2372 vam->retval = retval;
2373 vam->result_ready = 1;
2374 }
2375 if (retval >= 0)
2376 {
2377 errmsg ("first message id %d", ntohs (mp->first_msg_id));
2378 }
2379}
2380
2381static void vl_api_get_first_msg_id_reply_t_handler_json
2382 (vl_api_get_first_msg_id_reply_t * mp)
2383{
2384 vat_main_t *vam = &vat_main;
2385 vat_json_node_t node;
2386
2387 vat_json_init_object (&node);
2388 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2389 vat_json_object_add_uint (&node, "first_msg_id",
2390 (uint) ntohs (mp->first_msg_id));
2391
2392 vat_json_print (vam->ofp, &node);
2393 vat_json_free (&node);
2394
2395 vam->retval = ntohl (mp->retval);
2396 vam->result_ready = 1;
2397}
2398
2399static void vl_api_get_node_graph_reply_t_handler
2400 (vl_api_get_node_graph_reply_t * mp)
2401{
2402 vat_main_t *vam = &vat_main;
2403 api_main_t *am = &api_main;
2404 i32 retval = ntohl (mp->retval);
2405 u8 *pvt_copy, *reply;
2406 void *oldheap;
2407 vlib_node_t *node;
2408 int i;
2409
2410 if (vam->async_mode)
2411 {
2412 vam->async_errors += (retval < 0);
2413 }
2414 else
2415 {
2416 vam->retval = retval;
2417 vam->result_ready = 1;
2418 }
2419
2420 /* "Should never happen..." */
2421 if (retval != 0)
2422 return;
2423
Damjan Marion7bee80c2017-04-26 15:32:12 +02002424 reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002425 pvt_copy = vec_dup (reply);
2426
2427 /* Toss the shared-memory original... */
2428 pthread_mutex_lock (&am->vlib_rp->mutex);
2429 oldheap = svm_push_data_heap (am->vlib_rp);
2430
2431 vec_free (reply);
2432
2433 svm_pop_heap (oldheap);
2434 pthread_mutex_unlock (&am->vlib_rp->mutex);
2435
2436 if (vam->graph_nodes)
2437 {
2438 hash_free (vam->graph_node_index_by_name);
2439
2440 for (i = 0; i < vec_len (vam->graph_nodes); i++)
2441 {
2442 node = vam->graph_nodes[i];
2443 vec_free (node->name);
2444 vec_free (node->next_nodes);
2445 vec_free (node);
2446 }
2447 vec_free (vam->graph_nodes);
2448 }
2449
2450 vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2451 vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2452 vec_free (pvt_copy);
2453
2454 for (i = 0; i < vec_len (vam->graph_nodes); i++)
2455 {
2456 node = vam->graph_nodes[i];
2457 hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2458 }
2459}
2460
2461static void vl_api_get_node_graph_reply_t_handler_json
2462 (vl_api_get_node_graph_reply_t * mp)
2463{
2464 vat_main_t *vam = &vat_main;
2465 api_main_t *am = &api_main;
2466 void *oldheap;
2467 vat_json_node_t node;
2468 u8 *reply;
2469
2470 /* $$$$ make this real? */
2471 vat_json_init_object (&node);
2472 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2473 vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2474
Damjan Marion7bee80c2017-04-26 15:32:12 +02002475 reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
Damjan Marion7cd468a2016-12-19 23:05:39 +01002476
2477 /* Toss the shared-memory original... */
2478 pthread_mutex_lock (&am->vlib_rp->mutex);
2479 oldheap = svm_push_data_heap (am->vlib_rp);
2480
2481 vec_free (reply);
2482
2483 svm_pop_heap (oldheap);
2484 pthread_mutex_unlock (&am->vlib_rp->mutex);
2485
2486 vat_json_print (vam->ofp, &node);
2487 vat_json_free (&node);
2488
2489 vam->retval = ntohl (mp->retval);
2490 vam->result_ready = 1;
2491}
2492
2493static void
Filip Tehlar694396d2017-02-17 14:29:11 +01002494vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002495{
2496 vat_main_t *vam = &vat_main;
2497 u8 *s = 0;
2498
2499 if (mp->local)
2500 {
2501 s = format (s, "%=16d%=16d%=16d",
2502 ntohl (mp->sw_if_index), mp->priority, mp->weight);
2503 }
2504 else
2505 {
2506 s = format (s, "%=16U%=16d%=16d",
2507 mp->is_ipv6 ? format_ip6_address :
2508 format_ip4_address,
2509 mp->ip_address, mp->priority, mp->weight);
2510 }
2511
2512 print (vam->ofp, "%v", s);
2513 vec_free (s);
2514}
2515
2516static void
Filip Tehlar694396d2017-02-17 14:29:11 +01002517vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002518{
2519 vat_main_t *vam = &vat_main;
2520 vat_json_node_t *node = NULL;
2521 struct in6_addr ip6;
2522 struct in_addr ip4;
2523
2524 if (VAT_JSON_ARRAY != vam->json_tree.type)
2525 {
2526 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2527 vat_json_init_array (&vam->json_tree);
2528 }
2529 node = vat_json_array_add (&vam->json_tree);
2530 vat_json_init_object (node);
2531
2532 vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2533 vat_json_object_add_uint (node, "priority", mp->priority);
2534 vat_json_object_add_uint (node, "weight", mp->weight);
2535
2536 if (mp->local)
2537 vat_json_object_add_uint (node, "sw_if_index",
2538 clib_net_to_host_u32 (mp->sw_if_index));
2539 else
2540 {
2541 if (mp->is_ipv6)
2542 {
2543 clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2544 vat_json_object_add_ip6 (node, "address", ip6);
2545 }
2546 else
2547 {
2548 clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2549 vat_json_object_add_ip4 (node, "address", ip4);
2550 }
2551 }
2552}
2553
2554static void
Filip Tehlar694396d2017-02-17 14:29:11 +01002555vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2556 mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002557{
2558 vat_main_t *vam = &vat_main;
2559 u8 *ls_name = 0;
2560
2561 ls_name = format (0, "%s", mp->ls_name);
2562
2563 print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2564 ls_name);
2565 vec_free (ls_name);
2566}
2567
2568static void
Filip Tehlar694396d2017-02-17 14:29:11 +01002569 vl_api_one_locator_set_details_t_handler_json
2570 (vl_api_one_locator_set_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002571{
2572 vat_main_t *vam = &vat_main;
2573 vat_json_node_t *node = 0;
2574 u8 *ls_name = 0;
2575
2576 ls_name = format (0, "%s", mp->ls_name);
2577 vec_add1 (ls_name, 0);
2578
2579 if (VAT_JSON_ARRAY != vam->json_tree.type)
2580 {
2581 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2582 vat_json_init_array (&vam->json_tree);
2583 }
2584 node = vat_json_array_add (&vam->json_tree);
2585
2586 vat_json_init_object (node);
2587 vat_json_object_add_string_copy (node, "ls_name", ls_name);
2588 vat_json_object_add_uint (node, "ls_index",
2589 clib_net_to_host_u32 (mp->ls_index));
2590 vec_free (ls_name);
2591}
2592
2593static u8 *
2594format_lisp_flat_eid (u8 * s, va_list * args)
2595{
2596 u32 type = va_arg (*args, u32);
2597 u8 *eid = va_arg (*args, u8 *);
2598 u32 eid_len = va_arg (*args, u32);
2599
2600 switch (type)
2601 {
2602 case 0:
2603 return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2604 case 1:
2605 return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2606 case 2:
2607 return format (s, "%U", format_ethernet_address, eid);
2608 }
2609 return 0;
2610}
2611
2612static u8 *
2613format_lisp_eid_vat (u8 * s, va_list * args)
2614{
2615 u32 type = va_arg (*args, u32);
2616 u8 *eid = va_arg (*args, u8 *);
2617 u32 eid_len = va_arg (*args, u32);
2618 u8 *seid = va_arg (*args, u8 *);
2619 u32 seid_len = va_arg (*args, u32);
2620 u32 is_src_dst = va_arg (*args, u32);
2621
2622 if (is_src_dst)
2623 s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2624
2625 s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2626
2627 return s;
2628}
2629
2630static void
Filip Tehlar694396d2017-02-17 14:29:11 +01002631vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002632{
2633 vat_main_t *vam = &vat_main;
2634 u8 *s = 0, *eid = 0;
2635
2636 if (~0 == mp->locator_set_index)
2637 s = format (0, "action: %d", mp->action);
2638 else
2639 s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2640
2641 eid = format (0, "%U", format_lisp_eid_vat,
2642 mp->eid_type,
2643 mp->eid,
2644 mp->eid_prefix_len,
2645 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2646 vec_add1 (eid, 0);
2647
2648 print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2649 clib_net_to_host_u32 (mp->vni),
2650 eid,
2651 mp->is_local ? "local" : "remote",
2652 s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2653 clib_net_to_host_u16 (mp->key_id), mp->key);
2654
2655 vec_free (s);
2656 vec_free (eid);
2657}
2658
2659static void
Filip Tehlar694396d2017-02-17 14:29:11 +01002660vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
2661 * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002662{
2663 vat_main_t *vam = &vat_main;
2664 vat_json_node_t *node = 0;
2665 u8 *eid = 0;
2666
2667 if (VAT_JSON_ARRAY != vam->json_tree.type)
2668 {
2669 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2670 vat_json_init_array (&vam->json_tree);
2671 }
2672 node = vat_json_array_add (&vam->json_tree);
2673
2674 vat_json_init_object (node);
2675 if (~0 == mp->locator_set_index)
2676 vat_json_object_add_uint (node, "action", mp->action);
2677 else
2678 vat_json_object_add_uint (node, "locator_set_index",
2679 clib_net_to_host_u32 (mp->locator_set_index));
2680
2681 vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2682 eid = format (0, "%U", format_lisp_eid_vat,
2683 mp->eid_type,
2684 mp->eid,
2685 mp->eid_prefix_len,
2686 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2687 vec_add1 (eid, 0);
2688 vat_json_object_add_string_copy (node, "eid", eid);
2689 vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2690 vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2691 vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2692
2693 if (mp->key_id)
2694 {
2695 vat_json_object_add_uint (node, "key_id",
2696 clib_net_to_host_u16 (mp->key_id));
2697 vat_json_object_add_string_copy (node, "key", mp->key);
2698 }
2699 vec_free (eid);
2700}
2701
2702static void
Filip Tehlar4868ff62017-03-09 16:48:39 +01002703vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
2704{
2705 vat_main_t *vam = &vat_main;
2706 u8 *seid = 0, *deid = 0;
2707 u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
2708
2709 deid = format (0, "%U", format_lisp_eid_vat,
2710 mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
2711
2712 seid = format (0, "%U", format_lisp_eid_vat,
2713 mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
2714
2715 vec_add1 (deid, 0);
2716 vec_add1 (seid, 0);
2717
2718 if (mp->is_ip4)
2719 format_ip_address_fcn = format_ip4_address;
2720 else
2721 format_ip_address_fcn = format_ip6_address;
2722
2723
2724 print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
2725 clib_net_to_host_u32 (mp->vni),
2726 seid, deid,
2727 format_ip_address_fcn, mp->lloc,
2728 format_ip_address_fcn, mp->rloc,
2729 clib_net_to_host_u32 (mp->pkt_count),
2730 clib_net_to_host_u32 (mp->bytes));
2731
2732 vec_free (deid);
2733 vec_free (seid);
2734}
2735
2736static void
2737vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
2738{
2739 struct in6_addr ip6;
2740 struct in_addr ip4;
2741 vat_main_t *vam = &vat_main;
2742 vat_json_node_t *node = 0;
2743 u8 *deid = 0, *seid = 0;
2744
2745 if (VAT_JSON_ARRAY != vam->json_tree.type)
2746 {
2747 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2748 vat_json_init_array (&vam->json_tree);
2749 }
2750 node = vat_json_array_add (&vam->json_tree);
2751
2752 vat_json_init_object (node);
2753 deid = format (0, "%U", format_lisp_eid_vat,
2754 mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
2755
2756 seid = format (0, "%U", format_lisp_eid_vat,
2757 mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
2758
2759 vec_add1 (deid, 0);
2760 vec_add1 (seid, 0);
2761
2762 vat_json_object_add_string_copy (node, "seid", seid);
2763 vat_json_object_add_string_copy (node, "deid", deid);
2764 vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2765
2766 if (mp->is_ip4)
2767 {
2768 clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
2769 vat_json_object_add_ip4 (node, "lloc", ip4);
2770 clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
2771 vat_json_object_add_ip4 (node, "rloc", ip4);
2772 }
2773 else
2774 {
2775 clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
2776 vat_json_object_add_ip6 (node, "lloc", ip6);
2777 clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
2778 vat_json_object_add_ip6 (node, "rloc", ip6);
2779 }
2780 vat_json_object_add_uint (node, "pkt_count",
2781 clib_net_to_host_u32 (mp->pkt_count));
2782 vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
2783
2784 vec_free (deid);
2785 vec_free (seid);
2786}
2787
2788static void
Filip Tehlar694396d2017-02-17 14:29:11 +01002789 vl_api_one_eid_table_map_details_t_handler
2790 (vl_api_one_eid_table_map_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002791{
2792 vat_main_t *vam = &vat_main;
2793
2794 u8 *line = format (0, "%=10d%=10d",
2795 clib_net_to_host_u32 (mp->vni),
2796 clib_net_to_host_u32 (mp->dp_table));
2797 print (vam->ofp, "%v", line);
2798 vec_free (line);
2799}
2800
2801static void
Filip Tehlar694396d2017-02-17 14:29:11 +01002802 vl_api_one_eid_table_map_details_t_handler_json
2803 (vl_api_one_eid_table_map_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002804{
2805 vat_main_t *vam = &vat_main;
2806 vat_json_node_t *node = NULL;
2807
2808 if (VAT_JSON_ARRAY != vam->json_tree.type)
2809 {
2810 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2811 vat_json_init_array (&vam->json_tree);
2812 }
2813 node = vat_json_array_add (&vam->json_tree);
2814 vat_json_init_object (node);
2815 vat_json_object_add_uint (node, "dp_table",
2816 clib_net_to_host_u32 (mp->dp_table));
2817 vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2818}
2819
2820static void
Filip Tehlar694396d2017-02-17 14:29:11 +01002821 vl_api_one_eid_table_vni_details_t_handler
2822 (vl_api_one_eid_table_vni_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002823{
2824 vat_main_t *vam = &vat_main;
2825
2826 u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2827 print (vam->ofp, "%v", line);
2828 vec_free (line);
2829}
2830
2831static void
Filip Tehlar694396d2017-02-17 14:29:11 +01002832 vl_api_one_eid_table_vni_details_t_handler_json
2833 (vl_api_one_eid_table_vni_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002834{
2835 vat_main_t *vam = &vat_main;
2836 vat_json_node_t *node = NULL;
2837
2838 if (VAT_JSON_ARRAY != vam->json_tree.type)
2839 {
2840 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2841 vat_json_init_array (&vam->json_tree);
2842 }
2843 node = vat_json_array_add (&vam->json_tree);
2844 vat_json_init_object (node);
2845 vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2846}
2847
Damjan Marion7cd468a2016-12-19 23:05:39 +01002848static void
Filip Tehlar694396d2017-02-17 14:29:11 +01002849 vl_api_show_one_map_register_state_reply_t_handler
2850 (vl_api_show_one_map_register_state_reply_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002851{
2852 vat_main_t *vam = &vat_main;
2853 int retval = clib_net_to_host_u32 (mp->retval);
2854
2855 print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2856
2857 vam->retval = retval;
2858 vam->result_ready = 1;
2859}
2860
2861static void
Filip Tehlar694396d2017-02-17 14:29:11 +01002862 vl_api_show_one_map_register_state_reply_t_handler_json
2863 (vl_api_show_one_map_register_state_reply_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002864{
2865 vat_main_t *vam = &vat_main;
2866 vat_json_node_t _node, *node = &_node;
2867 int retval = clib_net_to_host_u32 (mp->retval);
2868
2869 u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2870
2871 vat_json_init_object (node);
2872 vat_json_object_add_string_copy (node, "state", s);
2873
2874 vat_json_print (vam->ofp, node);
2875 vat_json_free (node);
2876
2877 vam->retval = retval;
2878 vam->result_ready = 1;
2879 vec_free (s);
2880}
2881
2882static void
Filip Tehlar694396d2017-02-17 14:29:11 +01002883 vl_api_show_one_rloc_probe_state_reply_t_handler
2884 (vl_api_show_one_rloc_probe_state_reply_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002885{
2886 vat_main_t *vam = &vat_main;
2887 int retval = clib_net_to_host_u32 (mp->retval);
2888
2889 if (retval)
2890 goto end;
2891
2892 print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2893end:
2894 vam->retval = retval;
2895 vam->result_ready = 1;
2896}
2897
2898static void
Filip Tehlar694396d2017-02-17 14:29:11 +01002899 vl_api_show_one_rloc_probe_state_reply_t_handler_json
2900 (vl_api_show_one_rloc_probe_state_reply_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002901{
2902 vat_main_t *vam = &vat_main;
2903 vat_json_node_t _node, *node = &_node;
2904 int retval = clib_net_to_host_u32 (mp->retval);
2905
2906 u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2907 vat_json_init_object (node);
2908 vat_json_object_add_string_copy (node, "state", s);
2909
2910 vat_json_print (vam->ofp, node);
2911 vat_json_free (node);
2912
2913 vam->retval = retval;
2914 vam->result_ready = 1;
2915 vec_free (s);
2916}
2917
2918static void
Filip Tehlar4868ff62017-03-09 16:48:39 +01002919 vl_api_show_one_stats_enable_disable_reply_t_handler
2920 (vl_api_show_one_stats_enable_disable_reply_t * mp)
2921{
2922 vat_main_t *vam = &vat_main;
2923 int retval = clib_net_to_host_u32 (mp->retval);
2924
2925 if (retval)
2926 goto end;
2927
2928 print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
2929end:
2930 vam->retval = retval;
2931 vam->result_ready = 1;
2932}
2933
2934static void
2935 vl_api_show_one_stats_enable_disable_reply_t_handler_json
2936 (vl_api_show_one_stats_enable_disable_reply_t * mp)
2937{
2938 vat_main_t *vam = &vat_main;
2939 vat_json_node_t _node, *node = &_node;
2940 int retval = clib_net_to_host_u32 (mp->retval);
2941
2942 u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
2943 vat_json_init_object (node);
2944 vat_json_object_add_string_copy (node, "state", s);
2945
2946 vat_json_print (vam->ofp, node);
2947 vat_json_free (node);
2948
2949 vam->retval = retval;
2950 vam->result_ready = 1;
2951 vec_free (s);
2952}
2953
2954static void
Filip Tehlar82786c42017-02-20 15:20:37 +01002955api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
Filip Tehlar5fae99c2017-01-18 12:57:37 +01002956{
2957 e->dp_table = clib_net_to_host_u32 (e->dp_table);
2958 e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
Filip Tehlar0eb874e2017-05-18 14:23:32 +02002959 e->vni = clib_net_to_host_u32 (e->vni);
Filip Tehlar5fae99c2017-01-18 12:57:37 +01002960}
2961
2962static void
Filip Tehlar82786c42017-02-20 15:20:37 +01002963 gpe_fwd_entries_get_reply_t_net_to_host
2964 (vl_api_gpe_fwd_entries_get_reply_t * mp)
Filip Tehlar5fae99c2017-01-18 12:57:37 +01002965{
2966 u32 i;
2967
2968 mp->count = clib_net_to_host_u32 (mp->count);
2969 for (i = 0; i < mp->count; i++)
2970 {
Filip Tehlar82786c42017-02-20 15:20:37 +01002971 api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
Filip Tehlar5fae99c2017-01-18 12:57:37 +01002972 }
2973}
2974
Filip Tehlar3e7b56932017-02-21 18:28:34 +01002975static u8 *
2976format_gpe_encap_mode (u8 * s, va_list * args)
2977{
2978 u32 mode = va_arg (*args, u32);
2979
2980 switch (mode)
2981 {
2982 case 0:
2983 return format (s, "lisp");
2984 case 1:
2985 return format (s, "vxlan");
2986 }
2987 return 0;
2988}
2989
2990static void
2991 vl_api_gpe_get_encap_mode_reply_t_handler
2992 (vl_api_gpe_get_encap_mode_reply_t * mp)
2993{
2994 vat_main_t *vam = &vat_main;
2995
2996 print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
2997 vam->retval = ntohl (mp->retval);
2998 vam->result_ready = 1;
2999}
3000
3001static void
3002 vl_api_gpe_get_encap_mode_reply_t_handler_json
3003 (vl_api_gpe_get_encap_mode_reply_t * mp)
3004{
3005 vat_main_t *vam = &vat_main;
3006 vat_json_node_t node;
3007
3008 u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3009 vec_add1 (encap_mode, 0);
3010
3011 vat_json_init_object (&node);
3012 vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3013
3014 vec_free (encap_mode);
3015 vat_json_print (vam->ofp, &node);
3016 vat_json_free (&node);
3017
3018 vam->retval = ntohl (mp->retval);
3019 vam->result_ready = 1;
3020}
3021
Filip Tehlar5fae99c2017-01-18 12:57:37 +01003022static void
Filip Tehlar82786c42017-02-20 15:20:37 +01003023 vl_api_gpe_fwd_entry_path_details_t_handler
3024 (vl_api_gpe_fwd_entry_path_details_t * mp)
Filip Tehlar5fae99c2017-01-18 12:57:37 +01003025{
3026 vat_main_t *vam = &vat_main;
3027 u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3028
3029 if (mp->lcl_loc.is_ip4)
3030 format_ip_address_fcn = format_ip4_address;
3031 else
3032 format_ip_address_fcn = format_ip6_address;
3033
3034 print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3035 format_ip_address_fcn, &mp->lcl_loc,
3036 format_ip_address_fcn, &mp->rmt_loc);
3037}
3038
3039static void
Filip Tehlar82786c42017-02-20 15:20:37 +01003040lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
Filip Tehlar5fae99c2017-01-18 12:57:37 +01003041{
3042 struct in6_addr ip6;
3043 struct in_addr ip4;
3044
3045 if (loc->is_ip4)
3046 {
3047 clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3048 vat_json_object_add_ip4 (n, "address", ip4);
3049 }
3050 else
3051 {
3052 clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3053 vat_json_object_add_ip6 (n, "address", ip6);
3054 }
3055 vat_json_object_add_uint (n, "weight", loc->weight);
3056}
3057
3058static void
Filip Tehlar82786c42017-02-20 15:20:37 +01003059 vl_api_gpe_fwd_entry_path_details_t_handler_json
3060 (vl_api_gpe_fwd_entry_path_details_t * mp)
Filip Tehlar5fae99c2017-01-18 12:57:37 +01003061{
3062 vat_main_t *vam = &vat_main;
3063 vat_json_node_t *node = NULL;
3064 vat_json_node_t *loc_node;
3065
3066 if (VAT_JSON_ARRAY != vam->json_tree.type)
3067 {
3068 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3069 vat_json_init_array (&vam->json_tree);
3070 }
3071 node = vat_json_array_add (&vam->json_tree);
3072 vat_json_init_object (node);
3073
3074 loc_node = vat_json_object_add (node, "local_locator");
3075 vat_json_init_object (loc_node);
3076 lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3077
3078 loc_node = vat_json_object_add (node, "remote_locator");
3079 vat_json_init_object (loc_node);
3080 lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3081}
3082
3083static void
Filip Tehlar82786c42017-02-20 15:20:37 +01003084 vl_api_gpe_fwd_entries_get_reply_t_handler
3085 (vl_api_gpe_fwd_entries_get_reply_t * mp)
Filip Tehlar5fae99c2017-01-18 12:57:37 +01003086{
3087 vat_main_t *vam = &vat_main;
3088 u32 i;
3089 int retval = clib_net_to_host_u32 (mp->retval);
Filip Tehlar82786c42017-02-20 15:20:37 +01003090 vl_api_gpe_fwd_entry_t *e;
Filip Tehlar5fae99c2017-01-18 12:57:37 +01003091
3092 if (retval)
3093 goto end;
3094
Filip Tehlar82786c42017-02-20 15:20:37 +01003095 gpe_fwd_entries_get_reply_t_net_to_host (mp);
Filip Tehlar5fae99c2017-01-18 12:57:37 +01003096
3097 for (i = 0; i < mp->count; i++)
3098 {
3099 e = &mp->entries[i];
3100 print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3101 format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3102 format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3103 }
3104
3105end:
3106 vam->retval = retval;
3107 vam->result_ready = 1;
3108}
3109
3110static void
Filip Tehlar82786c42017-02-20 15:20:37 +01003111 vl_api_gpe_fwd_entries_get_reply_t_handler_json
3112 (vl_api_gpe_fwd_entries_get_reply_t * mp)
Filip Tehlar5fae99c2017-01-18 12:57:37 +01003113{
3114 u8 *s = 0;
3115 vat_main_t *vam = &vat_main;
3116 vat_json_node_t *e = 0, root;
3117 u32 i;
3118 int retval = clib_net_to_host_u32 (mp->retval);
Filip Tehlar82786c42017-02-20 15:20:37 +01003119 vl_api_gpe_fwd_entry_t *fwd;
Filip Tehlar5fae99c2017-01-18 12:57:37 +01003120
3121 if (retval)
3122 goto end;
3123
Filip Tehlar82786c42017-02-20 15:20:37 +01003124 gpe_fwd_entries_get_reply_t_net_to_host (mp);
Filip Tehlar5fae99c2017-01-18 12:57:37 +01003125 vat_json_init_array (&root);
3126
3127 for (i = 0; i < mp->count; i++)
3128 {
3129 e = vat_json_array_add (&root);
3130 fwd = &mp->entries[i];
3131
3132 vat_json_init_object (e);
3133 vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3134 vat_json_object_add_int (e, "dp_table", fwd->dp_table);
Filip Tehlar0eb874e2017-05-18 14:23:32 +02003135 vat_json_object_add_int (e, "vni", fwd->vni);
3136 vat_json_object_add_int (e, "action", fwd->action);
Filip Tehlar5fae99c2017-01-18 12:57:37 +01003137
3138 s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3139 fwd->leid_prefix_len);
3140 vec_add1 (s, 0);
3141 vat_json_object_add_string_copy (e, "leid", s);
3142 vec_free (s);
3143
3144 s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3145 fwd->reid_prefix_len);
3146 vec_add1 (s, 0);
3147 vat_json_object_add_string_copy (e, "reid", s);
3148 vec_free (s);
3149 }
3150
3151 vat_json_print (vam->ofp, &root);
3152 vat_json_free (&root);
3153
3154end:
3155 vam->retval = retval;
3156 vam->result_ready = 1;
3157}
3158
3159static void
Filip Tehlar0eb874e2017-05-18 14:23:32 +02003160 vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3161 (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3162{
3163 vat_main_t *vam = &vat_main;
3164 u32 i, n;
3165 int retval = clib_net_to_host_u32 (mp->retval);
3166
3167 if (retval)
3168 goto end;
3169
3170 n = clib_net_to_host_u32 (mp->count);
3171
3172 for (i = 0; i < n; i++)
3173 print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3174
3175end:
3176 vam->retval = retval;
3177 vam->result_ready = 1;
3178}
3179
3180static void
3181 vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3182 (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3183{
3184 vat_main_t *vam = &vat_main;
3185 vat_json_node_t root;
3186 u32 i, n;
3187 int retval = clib_net_to_host_u32 (mp->retval);
3188
3189 if (retval)
3190 goto end;
3191
3192 n = clib_net_to_host_u32 (mp->count);
3193 vat_json_init_array (&root);
3194
3195 for (i = 0; i < n; i++)
3196 vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3197
3198 vat_json_print (vam->ofp, &root);
3199 vat_json_free (&root);
3200
3201end:
3202 vam->retval = retval;
3203 vam->result_ready = 1;
3204}
3205
3206static void
Filip Tehlar694396d2017-02-17 14:29:11 +01003207 vl_api_one_adjacencies_get_reply_t_handler
3208 (vl_api_one_adjacencies_get_reply_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01003209{
3210 vat_main_t *vam = &vat_main;
3211 u32 i, n;
3212 int retval = clib_net_to_host_u32 (mp->retval);
Filip Tehlar694396d2017-02-17 14:29:11 +01003213 vl_api_one_adjacency_t *a;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003214
3215 if (retval)
3216 goto end;
3217
3218 n = clib_net_to_host_u32 (mp->count);
3219
3220 for (i = 0; i < n; i++)
3221 {
3222 a = &mp->adjacencies[i];
3223 print (vam->ofp, "%U %40U",
3224 format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3225 format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3226 }
3227
3228end:
3229 vam->retval = retval;
3230 vam->result_ready = 1;
3231}
3232
3233static void
Filip Tehlar694396d2017-02-17 14:29:11 +01003234 vl_api_one_adjacencies_get_reply_t_handler_json
3235 (vl_api_one_adjacencies_get_reply_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01003236{
3237 u8 *s = 0;
3238 vat_main_t *vam = &vat_main;
3239 vat_json_node_t *e = 0, root;
3240 u32 i, n;
3241 int retval = clib_net_to_host_u32 (mp->retval);
Filip Tehlar694396d2017-02-17 14:29:11 +01003242 vl_api_one_adjacency_t *a;
Damjan Marion7cd468a2016-12-19 23:05:39 +01003243
3244 if (retval)
3245 goto end;
3246
3247 n = clib_net_to_host_u32 (mp->count);
3248 vat_json_init_array (&root);
3249
3250 for (i = 0; i < n; i++)
3251 {
3252 e = vat_json_array_add (&root);
3253 a = &mp->adjacencies[i];
3254
3255 vat_json_init_object (e);
3256 s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
3257 a->leid_prefix_len);
3258 vec_add1 (s, 0);
3259 vat_json_object_add_string_copy (e, "leid", s);
3260 vec_free (s);
3261
3262 s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
3263 a->reid_prefix_len);
3264 vec_add1 (s, 0);
3265 vat_json_object_add_string_copy (e, "reid", s);
3266 vec_free (s);
3267 }
3268
3269 vat_json_print (vam->ofp, &root);
3270 vat_json_free (&root);
3271
3272end:
3273 vam->retval = retval;
3274 vam->result_ready = 1;
3275}
3276
3277static void
Filip Tehlar694396d2017-02-17 14:29:11 +01003278vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * 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_server_details_t_handler_json
3289 (vl_api_one_map_server_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-server", ip6);
3308 }
3309 else
3310 {
3311 clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3312 vat_json_object_add_ip4 (node, "map-server", ip4);
3313 }
3314}
3315
3316static void
Filip Tehlar694396d2017-02-17 14:29:11 +01003317vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
3318 * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01003319{
3320 vat_main_t *vam = &vat_main;
3321
3322 print (vam->ofp, "%=20U",
3323 mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3324 mp->ip_address);
3325}
3326
3327static void
Filip Tehlar694396d2017-02-17 14:29:11 +01003328 vl_api_one_map_resolver_details_t_handler_json
3329 (vl_api_one_map_resolver_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01003330{
3331 vat_main_t *vam = &vat_main;
3332 vat_json_node_t *node = NULL;
3333 struct in6_addr ip6;
3334 struct in_addr ip4;
3335
3336 if (VAT_JSON_ARRAY != vam->json_tree.type)
3337 {
3338 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3339 vat_json_init_array (&vam->json_tree);
3340 }
3341 node = vat_json_array_add (&vam->json_tree);
3342
3343 vat_json_init_object (node);
3344 if (mp->is_ipv6)
3345 {
3346 clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3347 vat_json_object_add_ip6 (node, "map resolver", ip6);
3348 }
3349 else
3350 {
3351 clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3352 vat_json_object_add_ip4 (node, "map resolver", ip4);
3353 }
3354}
3355
3356static void
Filip Tehlar694396d2017-02-17 14:29:11 +01003357vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01003358{
3359 vat_main_t *vam = &vat_main;
3360 i32 retval = ntohl (mp->retval);
3361
3362 if (0 <= retval)
3363 {
3364 print (vam->ofp, "feature: %s\ngpe: %s",
3365 mp->feature_status ? "enabled" : "disabled",
3366 mp->gpe_status ? "enabled" : "disabled");
3367 }
3368
3369 vam->retval = retval;
3370 vam->result_ready = 1;
3371}
3372
3373static void
Filip Tehlar694396d2017-02-17 14:29:11 +01003374 vl_api_show_one_status_reply_t_handler_json
3375 (vl_api_show_one_status_reply_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01003376{
3377 vat_main_t *vam = &vat_main;
3378 vat_json_node_t node;
3379 u8 *gpe_status = NULL;
3380 u8 *feature_status = NULL;
3381
3382 gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
3383 feature_status = format (0, "%s",
3384 mp->feature_status ? "enabled" : "disabled");
3385 vec_add1 (gpe_status, 0);
3386 vec_add1 (feature_status, 0);
3387
3388 vat_json_init_object (&node);
3389 vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
3390 vat_json_object_add_string_copy (&node, "feature_status", feature_status);
3391
3392 vec_free (gpe_status);
3393 vec_free (feature_status);
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 void
Filip Tehlar694396d2017-02-17 14:29:11 +01003403 vl_api_one_get_map_request_itr_rlocs_reply_t_handler
3404 (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01003405{
3406 vat_main_t *vam = &vat_main;
3407 i32 retval = ntohl (mp->retval);
3408
3409 if (retval >= 0)
3410 {
3411 print (vam->ofp, "%=20s", mp->locator_set_name);
3412 }
3413
3414 vam->retval = retval;
3415 vam->result_ready = 1;
3416}
3417
3418static void
Filip Tehlar694396d2017-02-17 14:29:11 +01003419 vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
3420 (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01003421{
3422 vat_main_t *vam = &vat_main;
3423 vat_json_node_t *node = NULL;
3424
3425 if (VAT_JSON_ARRAY != vam->json_tree.type)
3426 {
3427 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3428 vat_json_init_array (&vam->json_tree);
3429 }
3430 node = vat_json_array_add (&vam->json_tree);
3431
3432 vat_json_init_object (node);
3433 vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
3434
3435 vat_json_print (vam->ofp, node);
3436 vat_json_free (node);
3437
3438 vam->retval = ntohl (mp->retval);
3439 vam->result_ready = 1;
3440}
3441
3442static u8 *
3443format_lisp_map_request_mode (u8 * s, va_list * args)
3444{
3445 u32 mode = va_arg (*args, u32);
3446
3447 switch (mode)
3448 {
3449 case 0:
3450 return format (0, "dst-only");
3451 case 1:
3452 return format (0, "src-dst");
3453 }
3454 return 0;
3455}
3456
3457static void
Filip Tehlar694396d2017-02-17 14:29:11 +01003458 vl_api_show_one_map_request_mode_reply_t_handler
3459 (vl_api_show_one_map_request_mode_reply_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01003460{
3461 vat_main_t *vam = &vat_main;
3462 i32 retval = ntohl (mp->retval);
3463
3464 if (0 <= retval)
3465 {
3466 u32 mode = mp->mode;
3467 print (vam->ofp, "map_request_mode: %U",
3468 format_lisp_map_request_mode, mode);
3469 }
3470
3471 vam->retval = retval;
3472 vam->result_ready = 1;
3473}
3474
3475static void
Filip Tehlar694396d2017-02-17 14:29:11 +01003476 vl_api_show_one_map_request_mode_reply_t_handler_json
3477 (vl_api_show_one_map_request_mode_reply_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01003478{
3479 vat_main_t *vam = &vat_main;
3480 vat_json_node_t node;
3481 u8 *s = 0;
3482 u32 mode;
3483
3484 mode = mp->mode;
3485 s = format (0, "%U", format_lisp_map_request_mode, mode);
3486 vec_add1 (s, 0);
3487
3488 vat_json_init_object (&node);
3489 vat_json_object_add_string_copy (&node, "map_request_mode", s);
3490 vat_json_print (vam->ofp, &node);
3491 vat_json_free (&node);
3492
3493 vec_free (s);
3494 vam->retval = ntohl (mp->retval);
3495 vam->result_ready = 1;
3496}
3497
3498static void
Filip Tehlar67a99f82017-03-10 13:18:02 +01003499 vl_api_show_one_use_petr_reply_t_handler
3500 (vl_api_show_one_use_petr_reply_t * mp)
3501{
3502 vat_main_t *vam = &vat_main;
3503 i32 retval = ntohl (mp->retval);
3504
3505 if (0 <= retval)
3506 {
3507 print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
3508 if (mp->status)
3509 {
3510 print (vam->ofp, "Proxy-ETR address; %U",
3511 mp->is_ip4 ? format_ip4_address : format_ip6_address,
3512 mp->address);
3513 }
3514 }
3515
3516 vam->retval = retval;
3517 vam->result_ready = 1;
3518}
3519
3520static void
3521 vl_api_show_one_use_petr_reply_t_handler_json
3522 (vl_api_show_one_use_petr_reply_t * mp)
3523{
3524 vat_main_t *vam = &vat_main;
3525 vat_json_node_t node;
3526 u8 *status = 0;
3527 struct in_addr ip4;
3528 struct in6_addr ip6;
3529
3530 status = format (0, "%s", mp->status ? "enabled" : "disabled");
3531 vec_add1 (status, 0);
3532
3533 vat_json_init_object (&node);
3534 vat_json_object_add_string_copy (&node, "status", status);
3535 if (mp->status)
3536 {
3537 if (mp->is_ip4)
3538 {
3539 clib_memcpy (&ip6, mp->address, sizeof (ip6));
3540 vat_json_object_add_ip6 (&node, "address", ip6);
3541 }
3542 else
3543 {
3544 clib_memcpy (&ip4, mp->address, sizeof (ip4));
3545 vat_json_object_add_ip4 (&node, "address", ip4);
3546 }
3547 }
3548
3549 vec_free (status);
3550
3551 vat_json_print (vam->ofp, &node);
3552 vat_json_free (&node);
3553
3554 vam->retval = ntohl (mp->retval);
3555 vam->result_ready = 1;
3556}
3557
3558static void
Filip Tehlar694396d2017-02-17 14:29:11 +01003559vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01003560{
3561 vat_main_t *vam = &vat_main;
3562 i32 retval = ntohl (mp->retval);
3563
3564 if (0 <= retval)
3565 {
3566 print (vam->ofp, "%-20s%-16s",
3567 mp->status ? "enabled" : "disabled",
3568 mp->status ? (char *) mp->locator_set_name : "");
3569 }
3570
3571 vam->retval = retval;
3572 vam->result_ready = 1;
3573}
3574
3575static void
Filip Tehlar694396d2017-02-17 14:29:11 +01003576vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01003577{
3578 vat_main_t *vam = &vat_main;
3579 vat_json_node_t node;
3580 u8 *status = 0;
3581
3582 status = format (0, "%s", mp->status ? "enabled" : "disabled");
3583 vec_add1 (status, 0);
3584
3585 vat_json_init_object (&node);
3586 vat_json_object_add_string_copy (&node, "status", status);
3587 if (mp->status)
3588 {
3589 vat_json_object_add_string_copy (&node, "locator_set",
3590 mp->locator_set_name);
3591 }
3592
3593 vec_free (status);
3594
3595 vat_json_print (vam->ofp, &node);
3596 vat_json_free (&node);
3597
3598 vam->retval = ntohl (mp->retval);
3599 vam->result_ready = 1;
3600}
3601
3602static u8 *
3603format_policer_type (u8 * s, va_list * va)
3604{
3605 u32 i = va_arg (*va, u32);
3606
3607 if (i == SSE2_QOS_POLICER_TYPE_1R2C)
3608 s = format (s, "1r2c");
3609 else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
3610 s = format (s, "1r3c");
3611 else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
3612 s = format (s, "2r3c-2698");
3613 else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
3614 s = format (s, "2r3c-4115");
3615 else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
3616 s = format (s, "2r3c-mef5cf1");
3617 else
3618 s = format (s, "ILLEGAL");
3619 return s;
3620}
3621
3622static u8 *
3623format_policer_rate_type (u8 * s, va_list * va)
3624{
3625 u32 i = va_arg (*va, u32);
3626
3627 if (i == SSE2_QOS_RATE_KBPS)
3628 s = format (s, "kbps");
3629 else if (i == SSE2_QOS_RATE_PPS)
3630 s = format (s, "pps");
3631 else
3632 s = format (s, "ILLEGAL");
3633 return s;
3634}
3635
3636static u8 *
3637format_policer_round_type (u8 * s, va_list * va)
3638{
3639 u32 i = va_arg (*va, u32);
3640
3641 if (i == SSE2_QOS_ROUND_TO_CLOSEST)
3642 s = format (s, "closest");
3643 else if (i == SSE2_QOS_ROUND_TO_UP)
3644 s = format (s, "up");
3645 else if (i == SSE2_QOS_ROUND_TO_DOWN)
3646 s = format (s, "down");
3647 else
3648 s = format (s, "ILLEGAL");
3649 return s;
3650}
3651
3652static u8 *
3653format_policer_action_type (u8 * s, va_list * va)
3654{
3655 u32 i = va_arg (*va, u32);
3656
3657 if (i == SSE2_QOS_ACTION_DROP)
3658 s = format (s, "drop");
3659 else if (i == SSE2_QOS_ACTION_TRANSMIT)
3660 s = format (s, "transmit");
3661 else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3662 s = format (s, "mark-and-transmit");
3663 else
3664 s = format (s, "ILLEGAL");
3665 return s;
3666}
3667
3668static u8 *
3669format_dscp (u8 * s, va_list * va)
3670{
3671 u32 i = va_arg (*va, u32);
3672 char *t = 0;
3673
3674 switch (i)
3675 {
3676#define _(v,f,str) case VNET_DSCP_##f: t = str; break;
3677 foreach_vnet_dscp
3678#undef _
3679 default:
3680 return format (s, "ILLEGAL");
3681 }
3682 s = format (s, "%s", t);
3683 return s;
3684}
3685
3686static void
3687vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
3688{
3689 vat_main_t *vam = &vat_main;
3690 u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
3691
3692 if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3693 conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3694 else
3695 conform_dscp_str = format (0, "");
3696
3697 if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3698 exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3699 else
3700 exceed_dscp_str = format (0, "");
3701
3702 if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3703 violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3704 else
3705 violate_dscp_str = format (0, "");
3706
3707 print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
3708 "rate type %U, round type %U, %s rate, %s color-aware, "
3709 "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
3710 "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
3711 "conform action %U%s, exceed action %U%s, violate action %U%s",
3712 mp->name,
3713 format_policer_type, mp->type,
3714 ntohl (mp->cir),
3715 ntohl (mp->eir),
3716 clib_net_to_host_u64 (mp->cb),
3717 clib_net_to_host_u64 (mp->eb),
3718 format_policer_rate_type, mp->rate_type,
3719 format_policer_round_type, mp->round_type,
3720 mp->single_rate ? "single" : "dual",
3721 mp->color_aware ? "is" : "not",
3722 ntohl (mp->cir_tokens_per_period),
3723 ntohl (mp->pir_tokens_per_period),
3724 ntohl (mp->scale),
3725 ntohl (mp->current_limit),
3726 ntohl (mp->current_bucket),
3727 ntohl (mp->extended_limit),
3728 ntohl (mp->extended_bucket),
3729 clib_net_to_host_u64 (mp->last_update_time),
3730 format_policer_action_type, mp->conform_action_type,
3731 conform_dscp_str,
3732 format_policer_action_type, mp->exceed_action_type,
3733 exceed_dscp_str,
3734 format_policer_action_type, mp->violate_action_type,
3735 violate_dscp_str);
3736
3737 vec_free (conform_dscp_str);
3738 vec_free (exceed_dscp_str);
3739 vec_free (violate_dscp_str);
3740}
3741
3742static void vl_api_policer_details_t_handler_json
3743 (vl_api_policer_details_t * mp)
3744{
3745 vat_main_t *vam = &vat_main;
3746 vat_json_node_t *node;
3747 u8 *rate_type_str, *round_type_str, *type_str;
3748 u8 *conform_action_str, *exceed_action_str, *violate_action_str;
3749
3750 rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
3751 round_type_str =
3752 format (0, "%U", format_policer_round_type, mp->round_type);
3753 type_str = format (0, "%U", format_policer_type, mp->type);
3754 conform_action_str = format (0, "%U", format_policer_action_type,
3755 mp->conform_action_type);
3756 exceed_action_str = format (0, "%U", format_policer_action_type,
3757 mp->exceed_action_type);
3758 violate_action_str = format (0, "%U", format_policer_action_type,
3759 mp->violate_action_type);
3760
3761 if (VAT_JSON_ARRAY != vam->json_tree.type)
3762 {
3763 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3764 vat_json_init_array (&vam->json_tree);
3765 }
3766 node = vat_json_array_add (&vam->json_tree);
3767
3768 vat_json_init_object (node);
3769 vat_json_object_add_string_copy (node, "name", mp->name);
3770 vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3771 vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
Marek Gradzki59ed4902017-03-21 11:51:54 +01003772 vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
3773 vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
Damjan Marion7cd468a2016-12-19 23:05:39 +01003774 vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3775 vat_json_object_add_string_copy (node, "round_type", round_type_str);
3776 vat_json_object_add_string_copy (node, "type", type_str);
3777 vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3778 vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3779 vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3780 vat_json_object_add_uint (node, "cir_tokens_per_period",
3781 ntohl (mp->cir_tokens_per_period));
3782 vat_json_object_add_uint (node, "eir_tokens_per_period",
3783 ntohl (mp->pir_tokens_per_period));
3784 vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3785 vat_json_object_add_uint (node, "current_bucket",
3786 ntohl (mp->current_bucket));
3787 vat_json_object_add_uint (node, "extended_limit",
3788 ntohl (mp->extended_limit));
3789 vat_json_object_add_uint (node, "extended_bucket",
3790 ntohl (mp->extended_bucket));
3791 vat_json_object_add_uint (node, "last_update_time",
3792 ntohl (mp->last_update_time));
3793 vat_json_object_add_string_copy (node, "conform_action",
3794 conform_action_str);
3795 if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3796 {
3797 u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3798 vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3799 vec_free (dscp_str);
3800 }
3801 vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3802 if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3803 {
3804 u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3805 vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3806 vec_free (dscp_str);
3807 }
3808 vat_json_object_add_string_copy (node, "violate_action",
3809 violate_action_str);
3810 if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3811 {
3812 u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3813 vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3814 vec_free (dscp_str);
3815 }
3816
3817 vec_free (rate_type_str);
3818 vec_free (round_type_str);
3819 vec_free (type_str);
3820 vec_free (conform_action_str);
3821 vec_free (exceed_action_str);
3822 vec_free (violate_action_str);
3823}
3824
3825static void
3826vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3827 mp)
3828{
3829 vat_main_t *vam = &vat_main;
3830 int i, count = ntohl (mp->count);
3831
3832 if (count > 0)
3833 print (vam->ofp, "classify table ids (%d) : ", count);
3834 for (i = 0; i < count; i++)
3835 {
3836 print (vam->ofp, "%d", ntohl (mp->ids[i]));
3837 print (vam->ofp, (i < count - 1) ? "," : "");
3838 }
3839 vam->retval = ntohl (mp->retval);
3840 vam->result_ready = 1;
3841}
3842
3843static void
3844 vl_api_classify_table_ids_reply_t_handler_json
3845 (vl_api_classify_table_ids_reply_t * mp)
3846{
3847 vat_main_t *vam = &vat_main;
3848 int i, count = ntohl (mp->count);
3849
3850 if (count > 0)
3851 {
3852 vat_json_node_t node;
3853
3854 vat_json_init_object (&node);
3855 for (i = 0; i < count; i++)
3856 {
3857 vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3858 }
3859 vat_json_print (vam->ofp, &node);
3860 vat_json_free (&node);
3861 }
3862 vam->retval = ntohl (mp->retval);
3863 vam->result_ready = 1;
3864}
3865
3866static void
3867 vl_api_classify_table_by_interface_reply_t_handler
3868 (vl_api_classify_table_by_interface_reply_t * mp)
3869{
3870 vat_main_t *vam = &vat_main;
3871 u32 table_id;
3872
3873 table_id = ntohl (mp->l2_table_id);
3874 if (table_id != ~0)
3875 print (vam->ofp, "l2 table id : %d", table_id);
3876 else
3877 print (vam->ofp, "l2 table id : No input ACL tables configured");
3878 table_id = ntohl (mp->ip4_table_id);
3879 if (table_id != ~0)
3880 print (vam->ofp, "ip4 table id : %d", table_id);
3881 else
3882 print (vam->ofp, "ip4 table id : No input ACL tables configured");
3883 table_id = ntohl (mp->ip6_table_id);
3884 if (table_id != ~0)
3885 print (vam->ofp, "ip6 table id : %d", table_id);
3886 else
3887 print (vam->ofp, "ip6 table id : No input ACL tables configured");
3888 vam->retval = ntohl (mp->retval);
3889 vam->result_ready = 1;
3890}
3891
3892static void
3893 vl_api_classify_table_by_interface_reply_t_handler_json
3894 (vl_api_classify_table_by_interface_reply_t * mp)
3895{
3896 vat_main_t *vam = &vat_main;
3897 vat_json_node_t node;
3898
3899 vat_json_init_object (&node);
3900
3901 vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3902 vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3903 vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
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
3912static void vl_api_policer_add_del_reply_t_handler
3913 (vl_api_policer_add_del_reply_t * mp)
3914{
3915 vat_main_t *vam = &vat_main;
3916 i32 retval = ntohl (mp->retval);
3917 if (vam->async_mode)
3918 {
3919 vam->async_errors += (retval < 0);
3920 }
3921 else
3922 {
3923 vam->retval = retval;
3924 vam->result_ready = 1;
3925 if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3926 /*
3927 * Note: this is just barely thread-safe, depends on
3928 * the main thread spinning waiting for an answer...
3929 */
3930 errmsg ("policer index %d", ntohl (mp->policer_index));
3931 }
3932}
3933
3934static void vl_api_policer_add_del_reply_t_handler_json
3935 (vl_api_policer_add_del_reply_t * mp)
3936{
3937 vat_main_t *vam = &vat_main;
3938 vat_json_node_t node;
3939
3940 vat_json_init_object (&node);
3941 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3942 vat_json_object_add_uint (&node, "policer_index",
3943 ntohl (mp->policer_index));
3944
3945 vat_json_print (vam->ofp, &node);
3946 vat_json_free (&node);
3947
3948 vam->retval = ntohl (mp->retval);
3949 vam->result_ready = 1;
3950}
3951
3952/* Format hex dump. */
3953u8 *
3954format_hex_bytes (u8 * s, va_list * va)
3955{
3956 u8 *bytes = va_arg (*va, u8 *);
3957 int n_bytes = va_arg (*va, int);
3958 uword i;
3959
3960 /* Print short or long form depending on byte count. */
3961 uword short_form = n_bytes <= 32;
3962 uword indent = format_get_indent (s);
3963
3964 if (n_bytes == 0)
3965 return s;
3966
3967 for (i = 0; i < n_bytes; i++)
3968 {
3969 if (!short_form && (i % 32) == 0)
3970 s = format (s, "%08x: ", i);
3971 s = format (s, "%02x", bytes[i]);
3972 if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3973 s = format (s, "\n%U", format_white_space, indent);
3974 }
3975
3976 return s;
3977}
3978
3979static void
3980vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3981 * mp)
3982{
3983 vat_main_t *vam = &vat_main;
3984 i32 retval = ntohl (mp->retval);
3985 if (retval == 0)
3986 {
3987 print (vam->ofp, "classify table info :");
3988 print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
3989 ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3990 ntohl (mp->miss_next_index));
3991 print (vam->ofp, "nbuckets: %d skip: %d match: %d",
3992 ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3993 ntohl (mp->match_n_vectors));
3994 print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
3995 ntohl (mp->mask_length));
3996 }
3997 vam->retval = retval;
3998 vam->result_ready = 1;
3999}
4000
4001static void
4002 vl_api_classify_table_info_reply_t_handler_json
4003 (vl_api_classify_table_info_reply_t * mp)
4004{
4005 vat_main_t *vam = &vat_main;
4006 vat_json_node_t node;
4007
4008 i32 retval = ntohl (mp->retval);
4009 if (retval == 0)
4010 {
4011 vat_json_init_object (&node);
4012
4013 vat_json_object_add_int (&node, "sessions",
4014 ntohl (mp->active_sessions));
4015 vat_json_object_add_int (&node, "nexttbl",
4016 ntohl (mp->next_table_index));
4017 vat_json_object_add_int (&node, "nextnode",
4018 ntohl (mp->miss_next_index));
4019 vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4020 vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4021 vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4022 u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4023 ntohl (mp->mask_length), 0);
4024 vat_json_object_add_string_copy (&node, "mask", s);
4025
4026 vat_json_print (vam->ofp, &node);
4027 vat_json_free (&node);
4028 }
4029 vam->retval = ntohl (mp->retval);
4030 vam->result_ready = 1;
4031}
4032
4033static void
4034vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4035 mp)
4036{
4037 vat_main_t *vam = &vat_main;
4038
4039 print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4040 ntohl (mp->hit_next_index), ntohl (mp->advance),
4041 ntohl (mp->opaque_index));
4042 print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4043 ntohl (mp->match_length));
4044}
4045
4046static void
4047 vl_api_classify_session_details_t_handler_json
4048 (vl_api_classify_session_details_t * mp)
4049{
4050 vat_main_t *vam = &vat_main;
4051 vat_json_node_t *node = NULL;
4052
4053 if (VAT_JSON_ARRAY != vam->json_tree.type)
4054 {
4055 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4056 vat_json_init_array (&vam->json_tree);
4057 }
4058 node = vat_json_array_add (&vam->json_tree);
4059
4060 vat_json_init_object (node);
4061 vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4062 vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4063 vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4064 u8 *s =
4065 format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4066 0);
4067 vat_json_object_add_string_copy (node, "match", s);
4068}
4069
4070static void vl_api_pg_create_interface_reply_t_handler
4071 (vl_api_pg_create_interface_reply_t * mp)
4072{
4073 vat_main_t *vam = &vat_main;
4074
4075 vam->retval = ntohl (mp->retval);
4076 vam->result_ready = 1;
4077}
4078
4079static void vl_api_pg_create_interface_reply_t_handler_json
4080 (vl_api_pg_create_interface_reply_t * mp)
4081{
4082 vat_main_t *vam = &vat_main;
4083 vat_json_node_t node;
4084
4085 i32 retval = ntohl (mp->retval);
4086 if (retval == 0)
4087 {
4088 vat_json_init_object (&node);
4089
4090 vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4091
4092 vat_json_print (vam->ofp, &node);
4093 vat_json_free (&node);
4094 }
4095 vam->retval = ntohl (mp->retval);
4096 vam->result_ready = 1;
4097}
4098
4099static void vl_api_policer_classify_details_t_handler
4100 (vl_api_policer_classify_details_t * mp)
4101{
4102 vat_main_t *vam = &vat_main;
4103
4104 print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4105 ntohl (mp->table_index));
4106}
4107
4108static void vl_api_policer_classify_details_t_handler_json
4109 (vl_api_policer_classify_details_t * mp)
4110{
4111 vat_main_t *vam = &vat_main;
4112 vat_json_node_t *node;
4113
4114 if (VAT_JSON_ARRAY != vam->json_tree.type)
4115 {
4116 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4117 vat_json_init_array (&vam->json_tree);
4118 }
4119 node = vat_json_array_add (&vam->json_tree);
4120
4121 vat_json_init_object (node);
4122 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4123 vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4124}
4125
4126static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
4127 (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4128{
4129 vat_main_t *vam = &vat_main;
4130 i32 retval = ntohl (mp->retval);
4131 if (vam->async_mode)
4132 {
4133 vam->async_errors += (retval < 0);
4134 }
4135 else
4136 {
4137 vam->retval = retval;
4138 vam->sw_if_index = ntohl (mp->sw_if_index);
4139 vam->result_ready = 1;
4140 }
4141}
4142
4143static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
4144 (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4145{
4146 vat_main_t *vam = &vat_main;
4147 vat_json_node_t node;
4148
4149 vat_json_init_object (&node);
4150 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4151 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
4152
4153 vat_json_print (vam->ofp, &node);
4154 vat_json_free (&node);
4155
4156 vam->retval = ntohl (mp->retval);
4157 vam->result_ready = 1;
4158}
4159
4160static void vl_api_flow_classify_details_t_handler
4161 (vl_api_flow_classify_details_t * mp)
4162{
4163 vat_main_t *vam = &vat_main;
4164
4165 print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4166 ntohl (mp->table_index));
4167}
4168
4169static void vl_api_flow_classify_details_t_handler_json
4170 (vl_api_flow_classify_details_t * mp)
4171{
4172 vat_main_t *vam = &vat_main;
4173 vat_json_node_t *node;
4174
4175 if (VAT_JSON_ARRAY != vam->json_tree.type)
4176 {
4177 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4178 vat_json_init_array (&vam->json_tree);
4179 }
4180 node = vat_json_array_add (&vam->json_tree);
4181
4182 vat_json_init_object (node);
4183 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4184 vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4185}
4186
Aloys Augustinee551982017-02-17 14:55:29 +01004187#define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
4188#define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
4189#define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
4190#define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
Damjan Marion7cd468a2016-12-19 23:05:39 +01004191#define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
4192#define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
4193#define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
4194#define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
Neale Ranns044183f2017-01-24 01:34:25 -08004195#define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
4196#define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
4197#define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
4198#define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
Filip Tehlar694396d2017-02-17 14:29:11 +01004199#define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
4200#define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
Damjan Marion7cd468a2016-12-19 23:05:39 +01004201
4202/*
4203 * Generate boilerplate reply handlers, which
4204 * dig the return value out of the xxx_reply_t API message,
4205 * stick it into vam->retval, and set vam->result_ready
4206 *
4207 * Could also do this by pointing N message decode slots at
4208 * a single function, but that could break in subtle ways.
4209 */
4210
4211#define foreach_standard_reply_retval_handler \
4212_(sw_interface_set_flags_reply) \
4213_(sw_interface_add_del_address_reply) \
4214_(sw_interface_set_table_reply) \
4215_(sw_interface_set_mpls_enable_reply) \
4216_(sw_interface_set_vpath_reply) \
4217_(sw_interface_set_vxlan_bypass_reply) \
4218_(sw_interface_set_l2_bridge_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01004219_(bridge_domain_add_del_reply) \
4220_(sw_interface_set_l2_xconnect_reply) \
4221_(l2fib_add_del_reply) \
Eyal Barif24991c2017-04-05 05:33:21 +03004222_(l2fib_flush_int_reply) \
4223_(l2fib_flush_bd_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01004224_(ip_add_del_route_reply) \
Neale Ranns32e1c012016-11-22 17:07:28 +00004225_(ip_mroute_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01004226_(mpls_route_add_del_reply) \
4227_(mpls_ip_bind_unbind_reply) \
4228_(proxy_arp_add_del_reply) \
4229_(proxy_arp_intfc_enable_disable_reply) \
4230_(sw_interface_set_unnumbered_reply) \
4231_(ip_neighbor_add_del_reply) \
4232_(reset_vrf_reply) \
4233_(oam_add_del_reply) \
4234_(reset_fib_reply) \
4235_(dhcp_proxy_config_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01004236_(dhcp_proxy_set_vss_reply) \
4237_(dhcp_client_config_reply) \
4238_(set_ip_flow_hash_reply) \
4239_(sw_interface_ip6_enable_disable_reply) \
4240_(sw_interface_ip6_set_link_local_address_reply) \
Neale Ranns3f844d02017-02-18 00:03:54 -08004241_(ip6nd_proxy_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01004242_(sw_interface_ip6nd_ra_prefix_reply) \
4243_(sw_interface_ip6nd_ra_config_reply) \
4244_(set_arp_neighbor_limit_reply) \
4245_(l2_patch_add_del_reply) \
Pablo Camarillofb380952016-12-07 18:34:18 +01004246_(sr_policy_add_reply) \
4247_(sr_policy_mod_reply) \
4248_(sr_policy_del_reply) \
4249_(sr_localsid_add_del_reply) \
4250_(sr_steering_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01004251_(classify_add_del_session_reply) \
4252_(classify_set_interface_ip_table_reply) \
4253_(classify_set_interface_l2_tables_reply) \
4254_(l2tpv3_set_tunnel_cookies_reply) \
4255_(l2tpv3_interface_enable_disable_reply) \
4256_(l2tpv3_set_lookup_key_reply) \
4257_(l2_fib_clear_table_reply) \
4258_(l2_interface_efp_filter_reply) \
4259_(l2_interface_vlan_tag_rewrite_reply) \
4260_(modify_vhost_user_if_reply) \
4261_(delete_vhost_user_if_reply) \
4262_(want_ip4_arp_events_reply) \
4263_(want_ip6_nd_events_reply) \
4264_(input_acl_set_interface_reply) \
4265_(ipsec_spd_add_del_reply) \
4266_(ipsec_interface_add_del_spd_reply) \
4267_(ipsec_spd_add_del_entry_reply) \
4268_(ipsec_sad_add_del_entry_reply) \
4269_(ipsec_sa_set_key_reply) \
Matthew Smithb0972cb2017-05-02 16:20:41 -05004270_(ipsec_tunnel_if_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01004271_(ikev2_profile_add_del_reply) \
4272_(ikev2_profile_set_auth_reply) \
4273_(ikev2_profile_set_id_reply) \
4274_(ikev2_profile_set_ts_reply) \
4275_(ikev2_set_local_key_reply) \
Radu Nicolaucb33dc22017-02-16 16:49:46 +00004276_(ikev2_set_responder_reply) \
4277_(ikev2_set_ike_transforms_reply) \
4278_(ikev2_set_esp_transforms_reply) \
4279_(ikev2_set_sa_lifetime_reply) \
4280_(ikev2_initiate_sa_init_reply) \
4281_(ikev2_initiate_del_ike_sa_reply) \
4282_(ikev2_initiate_del_child_sa_reply) \
4283_(ikev2_initiate_rekey_child_sa_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01004284_(delete_loopback_reply) \
4285_(bd_ip_mac_add_del_reply) \
4286_(map_del_domain_reply) \
4287_(map_add_del_rule_reply) \
4288_(want_interface_events_reply) \
4289_(want_stats_reply) \
4290_(cop_interface_enable_disable_reply) \
4291_(cop_whitelist_enable_disable_reply) \
4292_(sw_interface_clear_stats_reply) \
4293_(ioam_enable_reply) \
4294_(ioam_disable_reply) \
Filip Tehlar694396d2017-02-17 14:29:11 +01004295_(one_add_del_locator_reply) \
4296_(one_add_del_local_eid_reply) \
4297_(one_add_del_remote_mapping_reply) \
4298_(one_add_del_adjacency_reply) \
4299_(one_add_del_map_resolver_reply) \
4300_(one_add_del_map_server_reply) \
4301_(one_enable_disable_reply) \
4302_(one_rloc_probe_enable_disable_reply) \
4303_(one_map_register_enable_disable_reply) \
4304_(one_pitr_set_locator_set_reply) \
4305_(one_map_request_mode_reply) \
4306_(one_add_del_map_request_itr_rlocs_reply) \
4307_(one_eid_table_add_del_map_reply) \
Filip Tehlar67a99f82017-03-10 13:18:02 +01004308_(one_use_petr_reply) \
Filip Tehlar4868ff62017-03-09 16:48:39 +01004309_(one_stats_enable_disable_reply) \
Filip Tehlar21511912017-04-07 10:41:42 +02004310_(one_stats_flush_reply) \
Filip Tehlar82786c42017-02-20 15:20:37 +01004311_(gpe_add_del_fwd_entry_reply) \
Filip Tehlar82786c42017-02-20 15:20:37 +01004312_(gpe_enable_disable_reply) \
Filip Tehlar3e7b56932017-02-21 18:28:34 +01004313_(gpe_set_encap_mode_reply) \
Filip Tehlar82786c42017-02-20 15:20:37 +01004314_(gpe_add_del_iface_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01004315_(vxlan_gpe_add_del_tunnel_reply) \
4316_(af_packet_delete_reply) \
4317_(policer_classify_set_interface_reply) \
4318_(netmap_create_reply) \
4319_(netmap_delete_reply) \
4320_(set_ipfix_exporter_reply) \
4321_(set_ipfix_classify_stream_reply) \
4322_(ipfix_classify_table_add_del_reply) \
4323_(flow_classify_set_interface_reply) \
4324_(sw_interface_span_enable_disable_reply) \
4325_(pg_capture_reply) \
4326_(pg_enable_disable_reply) \
4327_(ip_source_and_port_range_check_add_del_reply) \
4328_(ip_source_and_port_range_check_interface_add_del_reply)\
4329_(delete_subif_reply) \
4330_(l2_interface_pbb_tag_rewrite_reply) \
4331_(punt_reply) \
4332_(feature_enable_disable_reply) \
4333_(sw_interface_tag_add_del_reply) \
4334_(sw_interface_set_mtu_reply)
4335
4336#define _(n) \
4337 static void vl_api_##n##_t_handler \
4338 (vl_api_##n##_t * mp) \
4339 { \
4340 vat_main_t * vam = &vat_main; \
4341 i32 retval = ntohl(mp->retval); \
4342 if (vam->async_mode) { \
4343 vam->async_errors += (retval < 0); \
4344 } else { \
4345 vam->retval = retval; \
4346 vam->result_ready = 1; \
4347 } \
4348 }
4349foreach_standard_reply_retval_handler;
4350#undef _
4351
4352#define _(n) \
4353 static void vl_api_##n##_t_handler_json \
4354 (vl_api_##n##_t * mp) \
4355 { \
4356 vat_main_t * vam = &vat_main; \
4357 vat_json_node_t node; \
4358 vat_json_init_object(&node); \
4359 vat_json_object_add_int(&node, "retval", ntohl(mp->retval)); \
4360 vat_json_print(vam->ofp, &node); \
4361 vam->retval = ntohl(mp->retval); \
4362 vam->result_ready = 1; \
4363 }
4364foreach_standard_reply_retval_handler;
4365#undef _
4366
4367/*
4368 * Table of message reply handlers, must include boilerplate handlers
4369 * we just generated
4370 */
4371
4372#define foreach_vpe_api_reply_msg \
4373_(CREATE_LOOPBACK_REPLY, create_loopback_reply) \
Jon Loeligerc83c3b72017-02-23 13:57:35 -06004374_(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01004375_(SW_INTERFACE_DETAILS, sw_interface_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01004376_(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply) \
4377_(CONTROL_PING_REPLY, control_ping_reply) \
4378_(CLI_REPLY, cli_reply) \
4379_(CLI_INBAND_REPLY, cli_inband_reply) \
4380_(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY, \
4381 sw_interface_add_del_address_reply) \
4382_(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply) \
4383_(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
4384_(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply) \
4385_(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
4386_(SW_INTERFACE_SET_L2_XCONNECT_REPLY, \
4387 sw_interface_set_l2_xconnect_reply) \
4388_(SW_INTERFACE_SET_L2_BRIDGE_REPLY, \
4389 sw_interface_set_l2_bridge_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01004390_(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply) \
4391_(BRIDGE_DOMAIN_DETAILS, bridge_domain_details) \
Eyal Barifead6702017-04-04 04:46:32 +03004392_(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01004393_(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply) \
Eyal Barif24991c2017-04-05 05:33:21 +03004394_(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply) \
4395_(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01004396_(L2_FLAGS_REPLY, l2_flags_reply) \
4397_(BRIDGE_FLAGS_REPLY, bridge_flags_reply) \
4398_(TAP_CONNECT_REPLY, tap_connect_reply) \
4399_(TAP_MODIFY_REPLY, tap_modify_reply) \
4400_(TAP_DELETE_REPLY, tap_delete_reply) \
4401_(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details) \
4402_(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply) \
Neale Ranns32e1c012016-11-22 17:07:28 +00004403_(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01004404_(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply) \
4405_(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply) \
4406_(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply) \
4407_(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY, \
4408 proxy_arp_intfc_enable_disable_reply) \
4409_(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply) \
4410_(SW_INTERFACE_SET_UNNUMBERED_REPLY, \
4411 sw_interface_set_unnumbered_reply) \
4412_(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply) \
4413_(RESET_VRF_REPLY, reset_vrf_reply) \
4414_(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply) \
4415_(CREATE_SUBIF_REPLY, create_subif_reply) \
4416_(OAM_ADD_DEL_REPLY, oam_add_del_reply) \
4417_(RESET_FIB_REPLY, reset_fib_reply) \
4418_(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01004419_(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply) \
Neale Ranns20a175a2017-02-14 07:28:41 -08004420_(DHCP_PROXY_DETAILS, dhcp_proxy_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01004421_(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply) \
4422_(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply) \
4423_(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY, \
4424 sw_interface_ip6_enable_disable_reply) \
4425_(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY, \
4426 sw_interface_ip6_set_link_local_address_reply) \
Neale Ranns3f844d02017-02-18 00:03:54 -08004427_(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply) \
4428_(IP6ND_PROXY_DETAILS, ip6nd_proxy_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01004429_(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY, \
4430 sw_interface_ip6nd_ra_prefix_reply) \
4431_(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY, \
4432 sw_interface_ip6nd_ra_config_reply) \
4433_(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply) \
4434_(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply) \
Pablo Camarillofb380952016-12-07 18:34:18 +01004435_(SR_POLICY_ADD_REPLY, sr_policy_add_reply) \
4436_(SR_POLICY_MOD_REPLY, sr_policy_mod_reply) \
4437_(SR_POLICY_DEL_REPLY, sr_policy_del_reply) \
4438_(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply) \
4439_(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01004440_(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply) \
4441_(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply) \
4442_(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY, \
4443classify_set_interface_ip_table_reply) \
4444_(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY, \
4445 classify_set_interface_l2_tables_reply) \
4446_(GET_NODE_INDEX_REPLY, get_node_index_reply) \
4447_(ADD_NODE_NEXT_REPLY, add_node_next_reply) \
4448_(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply) \
4449_(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply) \
4450_(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY, \
4451 l2tpv3_interface_enable_disable_reply) \
4452_(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply) \
4453_(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details) \
4454_(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply) \
4455_(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details) \
4456_(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply) \
4457_(GRE_TUNNEL_DETAILS, gre_tunnel_details) \
4458_(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply) \
4459_(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply) \
4460_(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
4461_(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details) \
4462_(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply) \
4463_(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply) \
4464_(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply) \
4465_(SHOW_VERSION_REPLY, show_version_reply) \
Ole Troan01384fe2017-05-12 11:55:35 +02004466_(L2_FIB_TABLE_DETAILS, l2_fib_table_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01004467_(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply) \
4468_(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details) \
4469_(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply) \
4470_(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply) \
4471_(IP4_ARP_EVENT, ip4_arp_event) \
4472_(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply) \
4473_(IP6_ND_EVENT, ip6_nd_event) \
4474_(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply) \
4475_(IP_ADDRESS_DETAILS, ip_address_details) \
4476_(IP_DETAILS, ip_details) \
4477_(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply) \
4478_(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
4479_(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply) \
4480_(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply) \
4481_(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply) \
Matthew Smithb0972cb2017-05-02 16:20:41 -05004482_(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01004483_(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply) \
4484_(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply) \
4485_(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply) \
4486_(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply) \
4487_(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply) \
Radu Nicolaucb33dc22017-02-16 16:49:46 +00004488_(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply) \
4489_(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply) \
4490_(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply) \
4491_(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply) \
4492_(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply) \
4493_(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply) \
4494_(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
4495_(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01004496_(DELETE_LOOPBACK_REPLY, delete_loopback_reply) \
4497_(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply) \
4498_(DHCP_COMPL_EVENT, dhcp_compl_event) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01004499_(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply) \
4500_(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply) \
4501_(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply) \
4502_(MAP_DOMAIN_DETAILS, map_domain_details) \
4503_(MAP_RULE_DETAILS, map_rule_details) \
4504_(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply) \
4505_(WANT_STATS_REPLY, want_stats_reply) \
4506_(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply) \
4507_(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
4508_(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
4509_(GET_NODE_GRAPH_REPLY, get_node_graph_reply) \
4510_(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply) \
4511_(IOAM_ENABLE_REPLY, ioam_enable_reply) \
4512_(IOAM_DISABLE_REPLY, ioam_disable_reply) \
Filip Tehlar694396d2017-02-17 14:29:11 +01004513_(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply) \
4514_(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply) \
4515_(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply) \
4516_(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply) \
4517_(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply) \
4518_(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply) \
4519_(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply) \
4520_(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply) \
4521_(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY, \
4522 one_map_register_enable_disable_reply) \
4523_(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY, \
4524 one_rloc_probe_enable_disable_reply) \
4525_(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply) \
Filip Tehlar67a99f82017-03-10 13:18:02 +01004526_(ONE_USE_PETR_REPLY, one_use_petr_reply) \
Filip Tehlar694396d2017-02-17 14:29:11 +01004527_(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply) \
4528_(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply) \
4529_(ONE_LOCATOR_SET_DETAILS, one_locator_set_details) \
4530_(ONE_LOCATOR_DETAILS, one_locator_details) \
4531_(ONE_EID_TABLE_DETAILS, one_eid_table_details) \
4532_(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details) \
4533_(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details) \
4534_(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details) \
4535_(ONE_MAP_SERVER_DETAILS, one_map_server_details) \
4536_(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply) \
Filip Tehlar4868ff62017-03-09 16:48:39 +01004537_(ONE_STATS_DETAILS, one_stats_details) \
Filip Tehlar21511912017-04-07 10:41:42 +02004538_(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply) \
Filip Tehlar4868ff62017-03-09 16:48:39 +01004539_(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply) \
4540_(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY, \
4541 show_one_stats_enable_disable_reply) \
Filip Tehlar3e7b56932017-02-21 18:28:34 +01004542_(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply) \
4543_(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply) \
Filip Tehlar82786c42017-02-20 15:20:37 +01004544_(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply) \
Filip Tehlar694396d2017-02-17 14:29:11 +01004545_(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply) \
4546_(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply) \
Filip Tehlar0eb874e2017-05-18 14:23:32 +02004547_(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply) \
Filip Tehlar82786c42017-02-20 15:20:37 +01004548_(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply) \
4549_(GPE_FWD_ENTRY_PATH_DETAILS, \
4550 gpe_fwd_entry_path_details) \
Filip Tehlar694396d2017-02-17 14:29:11 +01004551_(SHOW_ONE_STATUS_REPLY, show_one_status_reply) \
4552_(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY, \
4553 one_add_del_map_request_itr_rlocs_reply) \
4554_(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY, \
4555 one_get_map_request_itr_rlocs_reply) \
4556_(SHOW_ONE_PITR_REPLY, show_one_pitr_reply) \
Filip Tehlar67a99f82017-03-10 13:18:02 +01004557_(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply) \
Filip Tehlar694396d2017-02-17 14:29:11 +01004558_(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply) \
4559_(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply) \
4560_(SHOW_ONE_MAP_REGISTER_STATE_REPLY, \
4561 show_one_map_register_state_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01004562_(AF_PACKET_CREATE_REPLY, af_packet_create_reply) \
4563_(AF_PACKET_DELETE_REPLY, af_packet_delete_reply) \
4564_(POLICER_ADD_DEL_REPLY, policer_add_del_reply) \
4565_(POLICER_DETAILS, policer_details) \
4566_(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
4567_(POLICER_CLASSIFY_DETAILS, policer_classify_details) \
4568_(NETMAP_CREATE_REPLY, netmap_create_reply) \
4569_(NETMAP_DELETE_REPLY, netmap_delete_reply) \
4570_(MPLS_TUNNEL_DETAILS, mpls_tunnel_details) \
4571_(MPLS_FIB_DETAILS, mpls_fib_details) \
4572_(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply) \
4573_(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
4574_(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply) \
4575_(CLASSIFY_SESSION_DETAILS, classify_session_details) \
4576_(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply) \
4577_(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details) \
4578_(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply) \
4579_(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details) \
4580_(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
4581_(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details) \
4582_(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
4583_(FLOW_CLASSIFY_DETAILS, flow_classify_details) \
4584_(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
4585_(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details) \
4586_(GET_NEXT_INDEX_REPLY, get_next_index_reply) \
4587_(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply) \
4588_(PG_CAPTURE_REPLY, pg_capture_reply) \
4589_(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply) \
4590_(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY, \
4591 ip_source_and_port_range_check_add_del_reply) \
4592_(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY, \
4593 ip_source_and_port_range_check_interface_add_del_reply) \
4594_(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply) \
4595_(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details) \
4596_(DELETE_SUBIF_REPLY, delete_subif_reply) \
4597_(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
4598_(PUNT_REPLY, punt_reply) \
4599_(IP_FIB_DETAILS, ip_fib_details) \
4600_(IP6_FIB_DETAILS, ip6_fib_details) \
4601_(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply) \
4602_(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply) \
4603_(L2_XCONNECT_DETAILS, l2_xconnect_details) \
4604_(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply) \
4605_(IP_NEIGHBOR_DETAILS, ip_neighbor_details) \
4606_(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)
4607
Dave Baracha1a093d2017-03-02 13:13:23 -05004608#define foreach_standalone_reply_msg \
4609_(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags) \
Aloys Augustinee551982017-02-17 14:55:29 +01004610_(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters) \
4611_(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters) \
Dave Baracha1a093d2017-03-02 13:13:23 -05004612_(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters) \
4613_(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters) \
4614_(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters) \
4615_(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)
4616
Damjan Marion7cd468a2016-12-19 23:05:39 +01004617typedef struct
4618{
4619 u8 *name;
4620 u32 value;
4621} name_sort_t;
4622
4623
4624#define STR_VTR_OP_CASE(op) \
4625 case L2_VTR_ ## op: \
4626 return "" # op;
4627
4628static const char *
4629str_vtr_op (u32 vtr_op)
4630{
4631 switch (vtr_op)
4632 {
4633 STR_VTR_OP_CASE (DISABLED);
4634 STR_VTR_OP_CASE (PUSH_1);
4635 STR_VTR_OP_CASE (PUSH_2);
4636 STR_VTR_OP_CASE (POP_1);
4637 STR_VTR_OP_CASE (POP_2);
4638 STR_VTR_OP_CASE (TRANSLATE_1_1);
4639 STR_VTR_OP_CASE (TRANSLATE_1_2);
4640 STR_VTR_OP_CASE (TRANSLATE_2_1);
4641 STR_VTR_OP_CASE (TRANSLATE_2_2);
4642 }
4643
4644 return "UNKNOWN";
4645}
4646
4647static int
4648dump_sub_interface_table (vat_main_t * vam)
4649{
4650 const sw_interface_subif_t *sub = NULL;
4651
4652 if (vam->json_output)
4653 {
4654 clib_warning
4655 ("JSON output supported only for VPE API calls and dump_stats_table");
4656 return -99;
4657 }
4658
4659 print (vam->ofp,
4660 "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
4661 "Interface", "sw_if_index",
4662 "sub id", "dot1ad", "tags", "outer id",
4663 "inner id", "exact", "default", "outer any", "inner any");
4664
4665 vec_foreach (sub, vam->sw_if_subif_table)
4666 {
4667 print (vam->ofp,
4668 "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
4669 sub->interface_name,
4670 sub->sw_if_index,
4671 sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
4672 sub->sub_number_of_tags, sub->sub_outer_vlan_id,
4673 sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
4674 sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
4675 if (sub->vtr_op != L2_VTR_DISABLED)
4676 {
4677 print (vam->ofp,
4678 " vlan-tag-rewrite - op: %-14s [ dot1q: %d "
4679 "tag1: %d tag2: %d ]",
4680 str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
4681 sub->vtr_tag1, sub->vtr_tag2);
4682 }
4683 }
4684
4685 return 0;
4686}
4687
4688static int
4689name_sort_cmp (void *a1, void *a2)
4690{
4691 name_sort_t *n1 = a1;
4692 name_sort_t *n2 = a2;
4693
4694 return strcmp ((char *) n1->name, (char *) n2->name);
4695}
4696
4697static int
4698dump_interface_table (vat_main_t * vam)
4699{
4700 hash_pair_t *p;
4701 name_sort_t *nses = 0, *ns;
4702
4703 if (vam->json_output)
4704 {
4705 clib_warning
4706 ("JSON output supported only for VPE API calls and dump_stats_table");
4707 return -99;
4708 }
4709
4710 /* *INDENT-OFF* */
4711 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4712 ({
4713 vec_add2 (nses, ns, 1);
4714 ns->name = (u8 *)(p->key);
4715 ns->value = (u32) p->value[0];
4716 }));
4717 /* *INDENT-ON* */
4718
4719 vec_sort_with_function (nses, name_sort_cmp);
4720
4721 print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
4722 vec_foreach (ns, nses)
4723 {
4724 print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
4725 }
4726 vec_free (nses);
4727 return 0;
4728}
4729
4730static int
4731dump_ip_table (vat_main_t * vam, int is_ipv6)
4732{
4733 const ip_details_t *det = NULL;
4734 const ip_address_details_t *address = NULL;
4735 u32 i = ~0;
4736
4737 print (vam->ofp, "%-12s", "sw_if_index");
4738
4739 vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
4740 {
4741 i++;
4742 if (!det->present)
4743 {
4744 continue;
4745 }
4746 print (vam->ofp, "%-12d", i);
4747 print (vam->ofp, " %-30s%-13s", "Address", "Prefix length");
4748 if (!det->addr)
4749 {
4750 continue;
4751 }
4752 vec_foreach (address, det->addr)
4753 {
4754 print (vam->ofp,
4755 " %-30U%-13d",
4756 is_ipv6 ? format_ip6_address : format_ip4_address,
4757 address->ip, address->prefix_length);
4758 }
4759 }
4760
4761 return 0;
4762}
4763
4764static int
4765dump_ipv4_table (vat_main_t * vam)
4766{
4767 if (vam->json_output)
4768 {
4769 clib_warning
4770 ("JSON output supported only for VPE API calls and dump_stats_table");
4771 return -99;
4772 }
4773
4774 return dump_ip_table (vam, 0);
4775}
4776
4777static int
4778dump_ipv6_table (vat_main_t * vam)
4779{
4780 if (vam->json_output)
4781 {
4782 clib_warning
4783 ("JSON output supported only for VPE API calls and dump_stats_table");
4784 return -99;
4785 }
4786
4787 return dump_ip_table (vam, 1);
4788}
4789
4790static char *
4791counter_type_to_str (u8 counter_type, u8 is_combined)
4792{
4793 if (!is_combined)
4794 {
4795 switch (counter_type)
4796 {
4797 case VNET_INTERFACE_COUNTER_DROP:
4798 return "drop";
4799 case VNET_INTERFACE_COUNTER_PUNT:
4800 return "punt";
4801 case VNET_INTERFACE_COUNTER_IP4:
4802 return "ip4";
4803 case VNET_INTERFACE_COUNTER_IP6:
4804 return "ip6";
4805 case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4806 return "rx-no-buf";
4807 case VNET_INTERFACE_COUNTER_RX_MISS:
4808 return "rx-miss";
4809 case VNET_INTERFACE_COUNTER_RX_ERROR:
4810 return "rx-error";
4811 case VNET_INTERFACE_COUNTER_TX_ERROR:
4812 return "tx-error";
4813 default:
4814 return "INVALID-COUNTER-TYPE";
4815 }
4816 }
4817 else
4818 {
4819 switch (counter_type)
4820 {
4821 case VNET_INTERFACE_COUNTER_RX:
4822 return "rx";
4823 case VNET_INTERFACE_COUNTER_TX:
4824 return "tx";
4825 default:
4826 return "INVALID-COUNTER-TYPE";
4827 }
4828 }
4829}
4830
4831static int
4832dump_stats_table (vat_main_t * vam)
4833{
4834 vat_json_node_t node;
4835 vat_json_node_t *msg_array;
4836 vat_json_node_t *msg;
4837 vat_json_node_t *counter_array;
4838 vat_json_node_t *counter;
4839 interface_counter_t c;
4840 u64 packets;
4841 ip4_fib_counter_t *c4;
4842 ip6_fib_counter_t *c6;
Neale Ranns044183f2017-01-24 01:34:25 -08004843 ip4_nbr_counter_t *n4;
4844 ip6_nbr_counter_t *n6;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004845 int i, j;
4846
4847 if (!vam->json_output)
4848 {
4849 clib_warning ("dump_stats_table supported only in JSON format");
4850 return -99;
4851 }
4852
4853 vat_json_init_object (&node);
4854
4855 /* interface counters */
4856 msg_array = vat_json_object_add (&node, "interface_counters");
4857 vat_json_init_array (msg_array);
4858 for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4859 {
4860 msg = vat_json_array_add (msg_array);
4861 vat_json_init_object (msg);
4862 vat_json_object_add_string_copy (msg, "vnet_counter_type",
4863 (u8 *) counter_type_to_str (i, 0));
4864 vat_json_object_add_int (msg, "is_combined", 0);
4865 counter_array = vat_json_object_add (msg, "data");
4866 vat_json_init_array (counter_array);
4867 for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4868 {
4869 packets = vam->simple_interface_counters[i][j];
4870 vat_json_array_add_uint (counter_array, packets);
4871 }
4872 }
4873 for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4874 {
4875 msg = vat_json_array_add (msg_array);
4876 vat_json_init_object (msg);
4877 vat_json_object_add_string_copy (msg, "vnet_counter_type",
4878 (u8 *) counter_type_to_str (i, 1));
4879 vat_json_object_add_int (msg, "is_combined", 1);
4880 counter_array = vat_json_object_add (msg, "data");
4881 vat_json_init_array (counter_array);
4882 for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4883 {
4884 c = vam->combined_interface_counters[i][j];
4885 counter = vat_json_array_add (counter_array);
4886 vat_json_init_object (counter);
4887 vat_json_object_add_uint (counter, "packets", c.packets);
4888 vat_json_object_add_uint (counter, "bytes", c.bytes);
4889 }
4890 }
4891
4892 /* ip4 fib counters */
4893 msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4894 vat_json_init_array (msg_array);
4895 for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4896 {
4897 msg = vat_json_array_add (msg_array);
4898 vat_json_init_object (msg);
4899 vat_json_object_add_uint (msg, "vrf_id",
4900 vam->ip4_fib_counters_vrf_id_by_index[i]);
4901 counter_array = vat_json_object_add (msg, "c");
4902 vat_json_init_array (counter_array);
4903 for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4904 {
4905 counter = vat_json_array_add (counter_array);
4906 vat_json_init_object (counter);
4907 c4 = &vam->ip4_fib_counters[i][j];
4908 vat_json_object_add_ip4 (counter, "address", c4->address);
4909 vat_json_object_add_uint (counter, "address_length",
4910 c4->address_length);
4911 vat_json_object_add_uint (counter, "packets", c4->packets);
4912 vat_json_object_add_uint (counter, "bytes", c4->bytes);
4913 }
4914 }
4915
4916 /* ip6 fib counters */
4917 msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4918 vat_json_init_array (msg_array);
4919 for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4920 {
4921 msg = vat_json_array_add (msg_array);
4922 vat_json_init_object (msg);
4923 vat_json_object_add_uint (msg, "vrf_id",
4924 vam->ip6_fib_counters_vrf_id_by_index[i]);
4925 counter_array = vat_json_object_add (msg, "c");
4926 vat_json_init_array (counter_array);
4927 for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4928 {
4929 counter = vat_json_array_add (counter_array);
4930 vat_json_init_object (counter);
4931 c6 = &vam->ip6_fib_counters[i][j];
4932 vat_json_object_add_ip6 (counter, "address", c6->address);
4933 vat_json_object_add_uint (counter, "address_length",
4934 c6->address_length);
4935 vat_json_object_add_uint (counter, "packets", c6->packets);
4936 vat_json_object_add_uint (counter, "bytes", c6->bytes);
4937 }
4938 }
4939
Neale Ranns044183f2017-01-24 01:34:25 -08004940 /* ip4 nbr counters */
4941 msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
4942 vat_json_init_array (msg_array);
4943 for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
4944 {
4945 msg = vat_json_array_add (msg_array);
4946 vat_json_init_object (msg);
4947 vat_json_object_add_uint (msg, "sw_if_index", i);
4948 counter_array = vat_json_object_add (msg, "c");
4949 vat_json_init_array (counter_array);
4950 for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
4951 {
4952 counter = vat_json_array_add (counter_array);
4953 vat_json_init_object (counter);
4954 n4 = &vam->ip4_nbr_counters[i][j];
4955 vat_json_object_add_ip4 (counter, "address", n4->address);
4956 vat_json_object_add_uint (counter, "link-type", n4->linkt);
4957 vat_json_object_add_uint (counter, "packets", n4->packets);
4958 vat_json_object_add_uint (counter, "bytes", n4->bytes);
4959 }
4960 }
4961
4962 /* ip6 nbr counters */
4963 msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
4964 vat_json_init_array (msg_array);
4965 for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
4966 {
4967 msg = vat_json_array_add (msg_array);
4968 vat_json_init_object (msg);
4969 vat_json_object_add_uint (msg, "sw_if_index", i);
4970 counter_array = vat_json_object_add (msg, "c");
4971 vat_json_init_array (counter_array);
4972 for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
4973 {
4974 counter = vat_json_array_add (counter_array);
4975 vat_json_init_object (counter);
4976 n6 = &vam->ip6_nbr_counters[i][j];
4977 vat_json_object_add_ip6 (counter, "address", n6->address);
4978 vat_json_object_add_uint (counter, "packets", n6->packets);
4979 vat_json_object_add_uint (counter, "bytes", n6->bytes);
4980 }
4981 }
4982
Damjan Marion7cd468a2016-12-19 23:05:39 +01004983 vat_json_print (vam->ofp, &node);
4984 vat_json_free (&node);
4985
4986 return 0;
4987}
4988
4989int
4990exec (vat_main_t * vam)
4991{
4992 api_main_t *am = &api_main;
Ole Troan01384fe2017-05-12 11:55:35 +02004993 vl_api_cli_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004994 f64 timeout;
4995 void *oldheap;
4996 u8 *cmd = 0;
4997 unformat_input_t *i = vam->input;
4998
4999 if (vec_len (i->buffer) == 0)
5000 return -1;
5001
5002 if (vam->exec_mode == 0 && unformat (i, "mode"))
5003 {
5004 vam->exec_mode = 1;
5005 return 0;
5006 }
5007 if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5008 {
5009 vam->exec_mode = 0;
5010 return 0;
5011 }
5012
5013
Ole Troan01384fe2017-05-12 11:55:35 +02005014 M (CLI, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005015
5016 /*
5017 * Copy cmd into shared memory.
5018 * In order for the CLI command to work, it
5019 * must be a vector ending in \n, not a C-string ending
5020 * in \n\0.
5021 */
5022 pthread_mutex_lock (&am->vlib_rp->mutex);
5023 oldheap = svm_push_data_heap (am->vlib_rp);
5024
5025 vec_validate (cmd, vec_len (vam->input->buffer) - 1);
5026 clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
5027
5028 svm_pop_heap (oldheap);
5029 pthread_mutex_unlock (&am->vlib_rp->mutex);
5030
Damjan Marion7bee80c2017-04-26 15:32:12 +02005031 mp->cmd_in_shmem = pointer_to_uword (cmd);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005032 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005033 timeout = vat_time_now (vam) + 10.0;
5034
5035 while (vat_time_now (vam) < timeout)
5036 {
5037 if (vam->result_ready == 1)
5038 {
5039 u8 *free_me;
5040 if (vam->shmem_result != NULL)
5041 print (vam->ofp, "%s", vam->shmem_result);
5042 pthread_mutex_lock (&am->vlib_rp->mutex);
5043 oldheap = svm_push_data_heap (am->vlib_rp);
5044
5045 free_me = (u8 *) vam->shmem_result;
5046 vec_free (free_me);
5047
5048 svm_pop_heap (oldheap);
5049 pthread_mutex_unlock (&am->vlib_rp->mutex);
5050 return 0;
5051 }
5052 }
5053 return -99;
5054}
5055
5056/*
5057 * Future replacement of exec() that passes CLI buffers directly in
5058 * the API messages instead of an additional shared memory area.
5059 */
5060static int
5061exec_inband (vat_main_t * vam)
5062{
5063 vl_api_cli_inband_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005064 unformat_input_t *i = vam->input;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005065 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005066
5067 if (vec_len (i->buffer) == 0)
5068 return -1;
5069
5070 if (vam->exec_mode == 0 && unformat (i, "mode"))
5071 {
5072 vam->exec_mode = 1;
5073 return 0;
5074 }
5075 if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5076 {
5077 vam->exec_mode = 0;
5078 return 0;
5079 }
5080
5081 /*
5082 * In order for the CLI command to work, it
5083 * must be a vector ending in \n, not a C-string ending
5084 * in \n\0.
5085 */
5086 u32 len = vec_len (vam->input->buffer);
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005087 M2 (CLI_INBAND, mp, len);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005088 clib_memcpy (mp->cmd, vam->input->buffer, len);
5089 mp->length = htonl (len);
5090
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005091 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06005092 W2 (ret, print (vam->ofp, "%s", vam->cmd_reply));
5093 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005094}
5095
5096static int
5097api_create_loopback (vat_main_t * vam)
5098{
5099 unformat_input_t *i = vam->input;
5100 vl_api_create_loopback_t *mp;
Jon Loeligerc83c3b72017-02-23 13:57:35 -06005101 vl_api_create_loopback_instance_t *mp_lbi;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005102 u8 mac_address[6];
5103 u8 mac_set = 0;
Jon Loeligerc83c3b72017-02-23 13:57:35 -06005104 u8 is_specified = 0;
5105 u32 user_instance = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005106 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005107
5108 memset (mac_address, 0, sizeof (mac_address));
5109
5110 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5111 {
5112 if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5113 mac_set = 1;
Jon Loeligerc83c3b72017-02-23 13:57:35 -06005114 if (unformat (i, "instance %d", &user_instance))
5115 is_specified = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005116 else
5117 break;
5118 }
5119
Jon Loeligerc83c3b72017-02-23 13:57:35 -06005120 if (is_specified)
5121 {
5122 M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5123 mp_lbi->is_specified = is_specified;
5124 if (is_specified)
5125 mp_lbi->user_instance = htonl (user_instance);
5126 if (mac_set)
5127 clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5128 S (mp_lbi);
5129 }
5130 else
5131 {
5132 /* Construct the API message */
5133 M (CREATE_LOOPBACK, mp);
5134 if (mac_set)
5135 clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5136 S (mp);
5137 }
Damjan Marion7cd468a2016-12-19 23:05:39 +01005138
Jon Loeliger56c7b012017-02-01 12:31:41 -06005139 W (ret);
5140 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005141}
5142
5143static int
5144api_delete_loopback (vat_main_t * vam)
5145{
5146 unformat_input_t *i = vam->input;
5147 vl_api_delete_loopback_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005148 u32 sw_if_index = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005149 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005150
5151 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5152 {
5153 if (unformat (i, "sw_if_index %d", &sw_if_index))
5154 ;
5155 else
5156 break;
5157 }
5158
5159 if (sw_if_index == ~0)
5160 {
5161 errmsg ("missing sw_if_index");
5162 return -99;
5163 }
5164
5165 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005166 M (DELETE_LOOPBACK, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005167 mp->sw_if_index = ntohl (sw_if_index);
5168
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005169 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06005170 W (ret);
5171 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005172}
5173
5174static int
5175api_want_stats (vat_main_t * vam)
5176{
5177 unformat_input_t *i = vam->input;
5178 vl_api_want_stats_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005179 int enable = -1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005180 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005181
5182 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5183 {
5184 if (unformat (i, "enable"))
5185 enable = 1;
5186 else if (unformat (i, "disable"))
5187 enable = 0;
5188 else
5189 break;
5190 }
5191
5192 if (enable == -1)
5193 {
5194 errmsg ("missing enable|disable");
5195 return -99;
5196 }
5197
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005198 M (WANT_STATS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005199 mp->enable_disable = enable;
5200
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005201 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06005202 W (ret);
5203 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005204}
5205
5206static int
5207api_want_interface_events (vat_main_t * vam)
5208{
5209 unformat_input_t *i = vam->input;
5210 vl_api_want_interface_events_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005211 int enable = -1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005212 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005213
5214 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5215 {
5216 if (unformat (i, "enable"))
5217 enable = 1;
5218 else if (unformat (i, "disable"))
5219 enable = 0;
5220 else
5221 break;
5222 }
5223
5224 if (enable == -1)
5225 {
5226 errmsg ("missing enable|disable");
5227 return -99;
5228 }
5229
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005230 M (WANT_INTERFACE_EVENTS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005231 mp->enable_disable = enable;
5232
5233 vam->interface_event_display = enable;
5234
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005235 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06005236 W (ret);
5237 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005238}
5239
5240
5241/* Note: non-static, called once to set up the initial intfc table */
5242int
5243api_sw_interface_dump (vat_main_t * vam)
5244{
5245 vl_api_sw_interface_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -06005246 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005247 hash_pair_t *p;
5248 name_sort_t *nses = 0, *ns;
5249 sw_interface_subif_t *sub = NULL;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005250 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005251
5252 /* Toss the old name table */
5253 /* *INDENT-OFF* */
5254 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5255 ({
5256 vec_add2 (nses, ns, 1);
5257 ns->name = (u8 *)(p->key);
5258 ns->value = (u32) p->value[0];
5259 }));
5260 /* *INDENT-ON* */
5261
5262 hash_free (vam->sw_if_index_by_interface_name);
5263
5264 vec_foreach (ns, nses) vec_free (ns->name);
5265
5266 vec_free (nses);
5267
5268 vec_foreach (sub, vam->sw_if_subif_table)
5269 {
5270 vec_free (sub->interface_name);
5271 }
5272 vec_free (vam->sw_if_subif_table);
5273
5274 /* recreate the interface name hash table */
5275 vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5276
5277 /* Get list of ethernets */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005278 M (SW_INTERFACE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005279 mp->name_filter_valid = 1;
5280 strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005281 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005282
5283 /* and local / loopback interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005284 M (SW_INTERFACE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005285 mp->name_filter_valid = 1;
5286 strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005287 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005288
5289 /* and packet-generator interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005290 M (SW_INTERFACE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005291 mp->name_filter_valid = 1;
5292 strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005293 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005294
5295 /* and vxlan-gpe tunnel interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005296 M (SW_INTERFACE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005297 mp->name_filter_valid = 1;
5298 strncpy ((char *) mp->name_filter, "vxlan_gpe",
5299 sizeof (mp->name_filter) - 1);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005300 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005301
5302 /* and vxlan tunnel interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005303 M (SW_INTERFACE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005304 mp->name_filter_valid = 1;
5305 strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005306 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005307
5308 /* and host (af_packet) interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005309 M (SW_INTERFACE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005310 mp->name_filter_valid = 1;
5311 strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005312 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005313
5314 /* and l2tpv3 tunnel interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005315 M (SW_INTERFACE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005316 mp->name_filter_valid = 1;
5317 strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
5318 sizeof (mp->name_filter) - 1);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005319 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005320
5321 /* and GRE tunnel interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005322 M (SW_INTERFACE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005323 mp->name_filter_valid = 1;
5324 strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005325 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005326
5327 /* and LISP-GPE interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005328 M (SW_INTERFACE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005329 mp->name_filter_valid = 1;
5330 strncpy ((char *) mp->name_filter, "lisp_gpe",
5331 sizeof (mp->name_filter) - 1);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005332 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005333
5334 /* and IPSEC tunnel interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005335 M (SW_INTERFACE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005336 mp->name_filter_valid = 1;
5337 strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005338 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005339
5340 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -06005341 M (CONTROL_PING, mp_ping);
5342 S (mp_ping);
5343
Jon Loeliger56c7b012017-02-01 12:31:41 -06005344 W (ret);
5345 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005346}
5347
5348static int
5349api_sw_interface_set_flags (vat_main_t * vam)
5350{
5351 unformat_input_t *i = vam->input;
5352 vl_api_sw_interface_set_flags_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005353 u32 sw_if_index;
5354 u8 sw_if_index_set = 0;
5355 u8 admin_up = 0, link_up = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005356 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005357
5358 /* Parse args required to build the message */
5359 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5360 {
5361 if (unformat (i, "admin-up"))
5362 admin_up = 1;
5363 else if (unformat (i, "admin-down"))
5364 admin_up = 0;
5365 else if (unformat (i, "link-up"))
5366 link_up = 1;
5367 else if (unformat (i, "link-down"))
5368 link_up = 0;
5369 else
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 if (sw_if_index_set == 0)
5379 {
5380 errmsg ("missing interface name or sw_if_index");
5381 return -99;
5382 }
5383
5384 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005385 M (SW_INTERFACE_SET_FLAGS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005386 mp->sw_if_index = ntohl (sw_if_index);
5387 mp->admin_up_down = admin_up;
5388 mp->link_up_down = link_up;
5389
5390 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005391 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005392
5393 /* Wait for a reply, return the good/bad news... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06005394 W (ret);
5395 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005396}
5397
5398static int
5399api_sw_interface_clear_stats (vat_main_t * vam)
5400{
5401 unformat_input_t *i = vam->input;
5402 vl_api_sw_interface_clear_stats_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005403 u32 sw_if_index;
5404 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005405 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005406
5407 /* Parse args required to build the message */
5408 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5409 {
5410 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5411 sw_if_index_set = 1;
5412 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5413 sw_if_index_set = 1;
5414 else
5415 break;
5416 }
5417
5418 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005419 M (SW_INTERFACE_CLEAR_STATS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005420
5421 if (sw_if_index_set == 1)
5422 mp->sw_if_index = ntohl (sw_if_index);
5423 else
5424 mp->sw_if_index = ~0;
5425
5426 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005427 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005428
5429 /* Wait for a reply, return the good/bad news... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06005430 W (ret);
5431 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005432}
5433
Damjan Marion7cd468a2016-12-19 23:05:39 +01005434static int
5435api_sw_interface_add_del_address (vat_main_t * vam)
5436{
5437 unformat_input_t *i = vam->input;
5438 vl_api_sw_interface_add_del_address_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005439 u32 sw_if_index;
5440 u8 sw_if_index_set = 0;
5441 u8 is_add = 1, del_all = 0;
5442 u32 address_length = 0;
5443 u8 v4_address_set = 0;
5444 u8 v6_address_set = 0;
5445 ip4_address_t v4address;
5446 ip6_address_t v6address;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005447 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005448
5449 /* Parse args required to build the message */
5450 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5451 {
5452 if (unformat (i, "del-all"))
5453 del_all = 1;
5454 else if (unformat (i, "del"))
5455 is_add = 0;
5456 else
5457 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5458 sw_if_index_set = 1;
5459 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5460 sw_if_index_set = 1;
5461 else if (unformat (i, "%U/%d",
5462 unformat_ip4_address, &v4address, &address_length))
5463 v4_address_set = 1;
5464 else if (unformat (i, "%U/%d",
5465 unformat_ip6_address, &v6address, &address_length))
5466 v6_address_set = 1;
5467 else
5468 break;
5469 }
5470
5471 if (sw_if_index_set == 0)
5472 {
5473 errmsg ("missing interface name or sw_if_index");
5474 return -99;
5475 }
5476 if (v4_address_set && v6_address_set)
5477 {
5478 errmsg ("both v4 and v6 addresses set");
5479 return -99;
5480 }
5481 if (!v4_address_set && !v6_address_set && !del_all)
5482 {
5483 errmsg ("no addresses set");
5484 return -99;
5485 }
5486
5487 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005488 M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005489
5490 mp->sw_if_index = ntohl (sw_if_index);
5491 mp->is_add = is_add;
5492 mp->del_all = del_all;
5493 if (v6_address_set)
5494 {
5495 mp->is_ipv6 = 1;
5496 clib_memcpy (mp->address, &v6address, sizeof (v6address));
5497 }
5498 else
5499 {
5500 clib_memcpy (mp->address, &v4address, sizeof (v4address));
5501 }
5502 mp->address_length = address_length;
5503
5504 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005505 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005506
5507 /* Wait for a reply, return good/bad news */
Jon Loeliger56c7b012017-02-01 12:31:41 -06005508 W (ret);
5509 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005510}
5511
5512static int
5513api_sw_interface_set_mpls_enable (vat_main_t * vam)
5514{
5515 unformat_input_t *i = vam->input;
5516 vl_api_sw_interface_set_mpls_enable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005517 u32 sw_if_index;
5518 u8 sw_if_index_set = 0;
5519 u8 enable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005520 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005521
5522 /* Parse args required to build the message */
5523 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5524 {
5525 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5526 sw_if_index_set = 1;
5527 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5528 sw_if_index_set = 1;
5529 else if (unformat (i, "disable"))
5530 enable = 0;
5531 else if (unformat (i, "dis"))
5532 enable = 0;
5533 else
5534 break;
5535 }
5536
5537 if (sw_if_index_set == 0)
5538 {
5539 errmsg ("missing interface name or sw_if_index");
5540 return -99;
5541 }
5542
5543 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005544 M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005545
5546 mp->sw_if_index = ntohl (sw_if_index);
5547 mp->enable = enable;
5548
5549 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005550 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005551
5552 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06005553 W (ret);
5554 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005555}
5556
5557static int
5558api_sw_interface_set_table (vat_main_t * vam)
5559{
5560 unformat_input_t *i = vam->input;
5561 vl_api_sw_interface_set_table_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005562 u32 sw_if_index, vrf_id = 0;
5563 u8 sw_if_index_set = 0;
5564 u8 is_ipv6 = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005565 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005566
5567 /* Parse args required to build the message */
5568 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5569 {
5570 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5571 sw_if_index_set = 1;
5572 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5573 sw_if_index_set = 1;
5574 else if (unformat (i, "vrf %d", &vrf_id))
5575 ;
5576 else if (unformat (i, "ipv6"))
5577 is_ipv6 = 1;
5578 else
5579 break;
5580 }
5581
5582 if (sw_if_index_set == 0)
5583 {
5584 errmsg ("missing interface name or sw_if_index");
5585 return -99;
5586 }
5587
5588 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005589 M (SW_INTERFACE_SET_TABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005590
5591 mp->sw_if_index = ntohl (sw_if_index);
5592 mp->is_ipv6 = is_ipv6;
5593 mp->vrf_id = ntohl (vrf_id);
5594
5595 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005596 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005597
5598 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06005599 W (ret);
5600 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005601}
5602
5603static void vl_api_sw_interface_get_table_reply_t_handler
5604 (vl_api_sw_interface_get_table_reply_t * mp)
5605{
5606 vat_main_t *vam = &vat_main;
5607
5608 print (vam->ofp, "%d", ntohl (mp->vrf_id));
5609
5610 vam->retval = ntohl (mp->retval);
5611 vam->result_ready = 1;
5612
5613}
5614
5615static void vl_api_sw_interface_get_table_reply_t_handler_json
5616 (vl_api_sw_interface_get_table_reply_t * mp)
5617{
5618 vat_main_t *vam = &vat_main;
5619 vat_json_node_t node;
5620
5621 vat_json_init_object (&node);
5622 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5623 vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
5624
5625 vat_json_print (vam->ofp, &node);
5626 vat_json_free (&node);
5627
5628 vam->retval = ntohl (mp->retval);
5629 vam->result_ready = 1;
5630}
5631
5632static int
5633api_sw_interface_get_table (vat_main_t * vam)
5634{
5635 unformat_input_t *i = vam->input;
5636 vl_api_sw_interface_get_table_t *mp;
5637 u32 sw_if_index;
5638 u8 sw_if_index_set = 0;
5639 u8 is_ipv6 = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005640 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005641
5642 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5643 {
5644 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5645 sw_if_index_set = 1;
5646 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5647 sw_if_index_set = 1;
5648 else if (unformat (i, "ipv6"))
5649 is_ipv6 = 1;
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
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005660 M (SW_INTERFACE_GET_TABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005661 mp->sw_if_index = htonl (sw_if_index);
5662 mp->is_ipv6 = is_ipv6;
5663
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005664 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06005665 W (ret);
5666 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005667}
5668
5669static int
5670api_sw_interface_set_vpath (vat_main_t * vam)
5671{
5672 unformat_input_t *i = vam->input;
5673 vl_api_sw_interface_set_vpath_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005674 u32 sw_if_index = 0;
5675 u8 sw_if_index_set = 0;
5676 u8 is_enable = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005677 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005678
5679 /* Parse args required to build the message */
5680 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5681 {
5682 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5683 sw_if_index_set = 1;
5684 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5685 sw_if_index_set = 1;
5686 else if (unformat (i, "enable"))
5687 is_enable = 1;
5688 else if (unformat (i, "disable"))
5689 is_enable = 0;
5690 else
5691 break;
5692 }
5693
5694 if (sw_if_index_set == 0)
5695 {
5696 errmsg ("missing interface name or sw_if_index");
5697 return -99;
5698 }
5699
5700 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005701 M (SW_INTERFACE_SET_VPATH, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005702
5703 mp->sw_if_index = ntohl (sw_if_index);
5704 mp->enable = is_enable;
5705
5706 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005707 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005708
5709 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06005710 W (ret);
5711 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005712}
5713
5714static int
5715api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
5716{
5717 unformat_input_t *i = vam->input;
5718 vl_api_sw_interface_set_vxlan_bypass_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005719 u32 sw_if_index = 0;
5720 u8 sw_if_index_set = 0;
John Lo2b81eb82017-01-30 13:12:10 -05005721 u8 is_enable = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005722 u8 is_ipv6 = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005723 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005724
5725 /* Parse args required to build the message */
5726 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5727 {
5728 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5729 sw_if_index_set = 1;
5730 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5731 sw_if_index_set = 1;
5732 else if (unformat (i, "enable"))
5733 is_enable = 1;
5734 else if (unformat (i, "disable"))
5735 is_enable = 0;
5736 else if (unformat (i, "ip4"))
5737 is_ipv6 = 0;
5738 else if (unformat (i, "ip6"))
5739 is_ipv6 = 1;
5740 else
5741 break;
5742 }
5743
5744 if (sw_if_index_set == 0)
5745 {
5746 errmsg ("missing interface name or sw_if_index");
5747 return -99;
5748 }
5749
5750 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005751 M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005752
5753 mp->sw_if_index = ntohl (sw_if_index);
5754 mp->enable = is_enable;
5755 mp->is_ipv6 = is_ipv6;
5756
5757 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005758 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005759
5760 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06005761 W (ret);
5762 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005763}
5764
5765static int
5766api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5767{
5768 unformat_input_t *i = vam->input;
5769 vl_api_sw_interface_set_l2_xconnect_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005770 u32 rx_sw_if_index;
5771 u8 rx_sw_if_index_set = 0;
5772 u32 tx_sw_if_index;
5773 u8 tx_sw_if_index_set = 0;
5774 u8 enable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005775 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005776
5777 /* Parse args required to build the message */
5778 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5779 {
5780 if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5781 rx_sw_if_index_set = 1;
5782 else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5783 tx_sw_if_index_set = 1;
5784 else if (unformat (i, "rx"))
5785 {
5786 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5787 {
5788 if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5789 &rx_sw_if_index))
5790 rx_sw_if_index_set = 1;
5791 }
5792 else
5793 break;
5794 }
5795 else if (unformat (i, "tx"))
5796 {
5797 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5798 {
5799 if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5800 &tx_sw_if_index))
5801 tx_sw_if_index_set = 1;
5802 }
5803 else
5804 break;
5805 }
5806 else if (unformat (i, "enable"))
5807 enable = 1;
5808 else if (unformat (i, "disable"))
5809 enable = 0;
5810 else
5811 break;
5812 }
5813
5814 if (rx_sw_if_index_set == 0)
5815 {
5816 errmsg ("missing rx interface name or rx_sw_if_index");
5817 return -99;
5818 }
5819
5820 if (enable && (tx_sw_if_index_set == 0))
5821 {
5822 errmsg ("missing tx interface name or tx_sw_if_index");
5823 return -99;
5824 }
5825
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005826 M (SW_INTERFACE_SET_L2_XCONNECT, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005827
5828 mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5829 mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5830 mp->enable = enable;
5831
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005832 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06005833 W (ret);
5834 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005835}
5836
5837static int
5838api_sw_interface_set_l2_bridge (vat_main_t * vam)
5839{
5840 unformat_input_t *i = vam->input;
5841 vl_api_sw_interface_set_l2_bridge_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005842 u32 rx_sw_if_index;
5843 u8 rx_sw_if_index_set = 0;
5844 u32 bd_id;
5845 u8 bd_id_set = 0;
5846 u8 bvi = 0;
5847 u32 shg = 0;
5848 u8 enable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005849 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005850
5851 /* Parse args required to build the message */
5852 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5853 {
5854 if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5855 rx_sw_if_index_set = 1;
5856 else if (unformat (i, "bd_id %d", &bd_id))
5857 bd_id_set = 1;
5858 else
5859 if (unformat
5860 (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
5861 rx_sw_if_index_set = 1;
5862 else if (unformat (i, "shg %d", &shg))
5863 ;
5864 else if (unformat (i, "bvi"))
5865 bvi = 1;
5866 else if (unformat (i, "enable"))
5867 enable = 1;
5868 else if (unformat (i, "disable"))
5869 enable = 0;
5870 else
5871 break;
5872 }
5873
5874 if (rx_sw_if_index_set == 0)
5875 {
5876 errmsg ("missing rx interface name or sw_if_index");
5877 return -99;
5878 }
5879
5880 if (enable && (bd_id_set == 0))
5881 {
5882 errmsg ("missing bridge domain");
5883 return -99;
5884 }
5885
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005886 M (SW_INTERFACE_SET_L2_BRIDGE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005887
5888 mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5889 mp->bd_id = ntohl (bd_id);
5890 mp->shg = (u8) shg;
5891 mp->bvi = bvi;
5892 mp->enable = enable;
5893
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005894 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06005895 W (ret);
5896 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005897}
5898
5899static int
5900api_bridge_domain_dump (vat_main_t * vam)
5901{
5902 unformat_input_t *i = vam->input;
5903 vl_api_bridge_domain_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -06005904 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005905 u32 bd_id = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005906 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005907
5908 /* Parse args required to build the message */
5909 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5910 {
5911 if (unformat (i, "bd_id %d", &bd_id))
5912 ;
5913 else
5914 break;
5915 }
5916
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005917 M (BRIDGE_DOMAIN_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005918 mp->bd_id = ntohl (bd_id);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005919 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005920
5921 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -06005922 M (CONTROL_PING, mp_ping);
5923 S (mp_ping);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005924
Jon Loeliger56c7b012017-02-01 12:31:41 -06005925 W (ret);
5926 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005927}
5928
5929static int
5930api_bridge_domain_add_del (vat_main_t * vam)
5931{
5932 unformat_input_t *i = vam->input;
5933 vl_api_bridge_domain_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005934 u32 bd_id = ~0;
5935 u8 is_add = 1;
5936 u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5937 u32 mac_age = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005938 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005939
5940 /* Parse args required to build the message */
5941 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5942 {
5943 if (unformat (i, "bd_id %d", &bd_id))
5944 ;
5945 else if (unformat (i, "flood %d", &flood))
5946 ;
5947 else if (unformat (i, "uu-flood %d", &uu_flood))
5948 ;
5949 else if (unformat (i, "forward %d", &forward))
5950 ;
5951 else if (unformat (i, "learn %d", &learn))
5952 ;
5953 else if (unformat (i, "arp-term %d", &arp_term))
5954 ;
5955 else if (unformat (i, "mac-age %d", &mac_age))
5956 ;
5957 else if (unformat (i, "del"))
5958 {
5959 is_add = 0;
5960 flood = uu_flood = forward = learn = 0;
5961 }
5962 else
5963 break;
5964 }
5965
5966 if (bd_id == ~0)
5967 {
5968 errmsg ("missing bridge domain");
5969 return -99;
5970 }
5971
5972 if (mac_age > 255)
5973 {
5974 errmsg ("mac age must be less than 256 ");
5975 return -99;
5976 }
5977
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005978 M (BRIDGE_DOMAIN_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005979
5980 mp->bd_id = ntohl (bd_id);
5981 mp->flood = flood;
5982 mp->uu_flood = uu_flood;
5983 mp->forward = forward;
5984 mp->learn = learn;
5985 mp->arp_term = arp_term;
5986 mp->is_add = is_add;
5987 mp->mac_age = (u8) mac_age;
5988
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005989 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06005990 W (ret);
5991 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005992}
5993
5994static int
Eyal Barif24991c2017-04-05 05:33:21 +03005995api_l2fib_flush_bd (vat_main_t * vam)
5996{
5997 unformat_input_t *i = vam->input;
5998 vl_api_l2fib_flush_bd_t *mp;
5999 u32 bd_id = ~0;
6000 int ret;
6001
6002 /* Parse args required to build the message */
6003 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6004 {
6005 if (unformat (i, "bd_id %d", &bd_id));
6006 else
6007 break;
6008 }
6009
6010 if (bd_id == ~0)
6011 {
6012 errmsg ("missing bridge domain");
6013 return -99;
6014 }
6015
6016 M (L2FIB_FLUSH_BD, mp);
6017
6018 mp->bd_id = htonl (bd_id);
6019
6020 S (mp);
6021 W (ret);
6022 return ret;
6023}
6024
6025static int
6026api_l2fib_flush_int (vat_main_t * vam)
6027{
6028 unformat_input_t *i = vam->input;
6029 vl_api_l2fib_flush_int_t *mp;
6030 u32 sw_if_index = ~0;
6031 int ret;
6032
6033 /* Parse args required to build the message */
6034 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6035 {
6036 if (unformat (i, "sw_if_index %d", &sw_if_index));
6037 else
6038 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6039 else
6040 break;
6041 }
6042
6043 if (sw_if_index == ~0)
6044 {
6045 errmsg ("missing interface name or sw_if_index");
6046 return -99;
6047 }
6048
6049 M (L2FIB_FLUSH_INT, mp);
6050
6051 mp->sw_if_index = ntohl (sw_if_index);
6052
6053 S (mp);
6054 W (ret);
6055 return ret;
6056}
6057
6058static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01006059api_l2fib_add_del (vat_main_t * vam)
6060{
6061 unformat_input_t *i = vam->input;
6062 vl_api_l2fib_add_del_t *mp;
6063 f64 timeout;
6064 u64 mac = 0;
6065 u8 mac_set = 0;
6066 u32 bd_id;
6067 u8 bd_id_set = 0;
6068 u32 sw_if_index = ~0;
6069 u8 sw_if_index_set = 0;
6070 u8 is_add = 1;
6071 u8 static_mac = 0;
6072 u8 filter_mac = 0;
6073 u8 bvi_mac = 0;
6074 int count = 1;
6075 f64 before = 0;
6076 int j;
6077
6078 /* Parse args required to build the message */
6079 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6080 {
6081 if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
6082 mac_set = 1;
6083 else if (unformat (i, "bd_id %d", &bd_id))
6084 bd_id_set = 1;
6085 else if (unformat (i, "sw_if_index %d", &sw_if_index))
6086 sw_if_index_set = 1;
6087 else if (unformat (i, "sw_if"))
6088 {
6089 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6090 {
6091 if (unformat
6092 (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6093 sw_if_index_set = 1;
6094 }
6095 else
6096 break;
6097 }
6098 else if (unformat (i, "static"))
6099 static_mac = 1;
6100 else if (unformat (i, "filter"))
6101 {
6102 filter_mac = 1;
6103 static_mac = 1;
6104 }
6105 else if (unformat (i, "bvi"))
6106 {
6107 bvi_mac = 1;
6108 static_mac = 1;
6109 }
6110 else if (unformat (i, "del"))
6111 is_add = 0;
6112 else if (unformat (i, "count %d", &count))
6113 ;
6114 else
6115 break;
6116 }
6117
6118 if (mac_set == 0)
6119 {
6120 errmsg ("missing mac address");
6121 return -99;
6122 }
6123
6124 if (bd_id_set == 0)
6125 {
6126 errmsg ("missing bridge domain");
6127 return -99;
6128 }
6129
6130 if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6131 {
6132 errmsg ("missing interface name or sw_if_index");
6133 return -99;
6134 }
6135
6136 if (count > 1)
6137 {
6138 /* Turn on async mode */
6139 vam->async_mode = 1;
6140 vam->async_errors = 0;
6141 before = vat_time_now (vam);
6142 }
6143
6144 for (j = 0; j < count; j++)
6145 {
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006146 M (L2FIB_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006147
6148 mp->mac = mac;
6149 mp->bd_id = ntohl (bd_id);
6150 mp->is_add = is_add;
6151
6152 if (is_add)
6153 {
6154 mp->sw_if_index = ntohl (sw_if_index);
6155 mp->static_mac = static_mac;
6156 mp->filter_mac = filter_mac;
6157 mp->bvi_mac = bvi_mac;
6158 }
6159 increment_mac_address (&mac);
6160 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006161 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006162 }
6163
6164 if (count > 1)
6165 {
Jon Loeliger2d23eca2017-02-01 13:09:58 -06006166 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006167 f64 after;
6168
6169 /* Shut off async mode */
6170 vam->async_mode = 0;
6171
Jon Loeliger2d23eca2017-02-01 13:09:58 -06006172 M (CONTROL_PING, mp_ping);
6173 S (mp_ping);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006174
6175 timeout = vat_time_now (vam) + 1.0;
6176 while (vat_time_now (vam) < timeout)
6177 if (vam->result_ready == 1)
6178 goto out;
6179 vam->retval = -99;
6180
6181 out:
6182 if (vam->retval == -99)
6183 errmsg ("timeout");
6184
6185 if (vam->async_errors > 0)
6186 {
6187 errmsg ("%d asynchronous errors", vam->async_errors);
6188 vam->retval = -98;
6189 }
6190 vam->async_errors = 0;
6191 after = vat_time_now (vam);
6192
6193 print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6194 count, after - before, count / (after - before));
6195 }
6196 else
6197 {
Jon Loeliger56c7b012017-02-01 12:31:41 -06006198 int ret;
6199
Damjan Marion7cd468a2016-12-19 23:05:39 +01006200 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06006201 W (ret);
6202 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006203 }
6204 /* Return the good/bad news */
6205 return (vam->retval);
6206}
6207
6208static int
Eyal Barifead6702017-04-04 04:46:32 +03006209api_bridge_domain_set_mac_age (vat_main_t * vam)
6210{
6211 unformat_input_t *i = vam->input;
6212 vl_api_bridge_domain_set_mac_age_t *mp;
6213 u32 bd_id = ~0;
6214 u32 mac_age = 0;
6215 int ret;
6216
6217 /* Parse args required to build the message */
6218 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6219 {
6220 if (unformat (i, "bd_id %d", &bd_id));
6221 else if (unformat (i, "mac-age %d", &mac_age));
6222 else
6223 break;
6224 }
6225
6226 if (bd_id == ~0)
6227 {
6228 errmsg ("missing bridge domain");
6229 return -99;
6230 }
6231
6232 if (mac_age > 255)
6233 {
6234 errmsg ("mac age must be less than 256 ");
6235 return -99;
6236 }
6237
6238 M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
6239
6240 mp->bd_id = htonl (bd_id);
6241 mp->mac_age = (u8) mac_age;
6242
6243 S (mp);
6244 W (ret);
6245 return ret;
6246}
6247
6248static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01006249api_l2_flags (vat_main_t * vam)
6250{
6251 unformat_input_t *i = vam->input;
6252 vl_api_l2_flags_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006253 u32 sw_if_index;
6254 u32 feature_bitmap = 0;
6255 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006256 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006257
6258 /* Parse args required to build the message */
6259 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6260 {
6261 if (unformat (i, "sw_if_index %d", &sw_if_index))
6262 sw_if_index_set = 1;
6263 else if (unformat (i, "sw_if"))
6264 {
6265 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6266 {
6267 if (unformat
6268 (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6269 sw_if_index_set = 1;
6270 }
6271 else
6272 break;
6273 }
6274 else if (unformat (i, "learn"))
6275 feature_bitmap |= L2INPUT_FEAT_LEARN;
6276 else if (unformat (i, "forward"))
6277 feature_bitmap |= L2INPUT_FEAT_FWD;
6278 else if (unformat (i, "flood"))
6279 feature_bitmap |= L2INPUT_FEAT_FLOOD;
6280 else if (unformat (i, "uu-flood"))
6281 feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
6282 else
6283 break;
6284 }
6285
6286 if (sw_if_index_set == 0)
6287 {
6288 errmsg ("missing interface name or sw_if_index");
6289 return -99;
6290 }
6291
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006292 M (L2_FLAGS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006293
6294 mp->sw_if_index = ntohl (sw_if_index);
6295 mp->feature_bitmap = ntohl (feature_bitmap);
6296
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006297 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06006298 W (ret);
6299 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006300}
6301
6302static int
6303api_bridge_flags (vat_main_t * vam)
6304{
6305 unformat_input_t *i = vam->input;
6306 vl_api_bridge_flags_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006307 u32 bd_id;
6308 u8 bd_id_set = 0;
6309 u8 is_set = 1;
6310 u32 flags = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006311 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006312
6313 /* Parse args required to build the message */
6314 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6315 {
6316 if (unformat (i, "bd_id %d", &bd_id))
6317 bd_id_set = 1;
6318 else if (unformat (i, "learn"))
6319 flags |= L2_LEARN;
6320 else if (unformat (i, "forward"))
6321 flags |= L2_FWD;
6322 else if (unformat (i, "flood"))
6323 flags |= L2_FLOOD;
6324 else if (unformat (i, "uu-flood"))
6325 flags |= L2_UU_FLOOD;
6326 else if (unformat (i, "arp-term"))
6327 flags |= L2_ARP_TERM;
6328 else if (unformat (i, "off"))
6329 is_set = 0;
6330 else if (unformat (i, "disable"))
6331 is_set = 0;
6332 else
6333 break;
6334 }
6335
6336 if (bd_id_set == 0)
6337 {
6338 errmsg ("missing bridge domain");
6339 return -99;
6340 }
6341
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006342 M (BRIDGE_FLAGS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006343
6344 mp->bd_id = ntohl (bd_id);
6345 mp->feature_bitmap = ntohl (flags);
6346 mp->is_set = is_set;
6347
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006348 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06006349 W (ret);
6350 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006351}
6352
6353static int
6354api_bd_ip_mac_add_del (vat_main_t * vam)
6355{
6356 unformat_input_t *i = vam->input;
6357 vl_api_bd_ip_mac_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006358 u32 bd_id;
6359 u8 is_ipv6 = 0;
6360 u8 is_add = 1;
6361 u8 bd_id_set = 0;
6362 u8 ip_set = 0;
6363 u8 mac_set = 0;
6364 ip4_address_t v4addr;
6365 ip6_address_t v6addr;
6366 u8 macaddr[6];
Jon Loeliger56c7b012017-02-01 12:31:41 -06006367 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006368
6369
6370 /* Parse args required to build the message */
6371 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6372 {
6373 if (unformat (i, "bd_id %d", &bd_id))
6374 {
6375 bd_id_set++;
6376 }
6377 else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
6378 {
6379 ip_set++;
6380 }
6381 else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
6382 {
6383 ip_set++;
6384 is_ipv6++;
6385 }
6386 else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
6387 {
6388 mac_set++;
6389 }
6390 else if (unformat (i, "del"))
6391 is_add = 0;
6392 else
6393 break;
6394 }
6395
6396 if (bd_id_set == 0)
6397 {
6398 errmsg ("missing bridge domain");
6399 return -99;
6400 }
6401 else if (ip_set == 0)
6402 {
6403 errmsg ("missing IP address");
6404 return -99;
6405 }
6406 else if (mac_set == 0)
6407 {
6408 errmsg ("missing MAC address");
6409 return -99;
6410 }
6411
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006412 M (BD_IP_MAC_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006413
6414 mp->bd_id = ntohl (bd_id);
6415 mp->is_ipv6 = is_ipv6;
6416 mp->is_add = is_add;
6417 if (is_ipv6)
6418 clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
6419 else
6420 clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
6421 clib_memcpy (mp->mac_address, macaddr, 6);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006422 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06006423 W (ret);
6424 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006425}
6426
6427static int
6428api_tap_connect (vat_main_t * vam)
6429{
6430 unformat_input_t *i = vam->input;
6431 vl_api_tap_connect_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006432 u8 mac_address[6];
6433 u8 random_mac = 1;
6434 u8 name_set = 0;
6435 u8 *tap_name;
6436 u8 *tag = 0;
Dave Barach2feaffc2017-01-14 10:30:50 -05006437 ip4_address_t ip4_address;
6438 u32 ip4_mask_width;
6439 int ip4_address_set = 0;
6440 ip6_address_t ip6_address;
6441 u32 ip6_mask_width;
6442 int ip6_address_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006443 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006444
6445 memset (mac_address, 0, sizeof (mac_address));
6446
6447 /* Parse args required to build the message */
6448 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6449 {
6450 if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6451 {
6452 random_mac = 0;
6453 }
6454 else if (unformat (i, "random-mac"))
6455 random_mac = 1;
6456 else if (unformat (i, "tapname %s", &tap_name))
6457 name_set = 1;
6458 else if (unformat (i, "tag %s", &tag))
6459 ;
Dave Barach2feaffc2017-01-14 10:30:50 -05006460 else if (unformat (i, "address %U/%d",
6461 unformat_ip4_address, &ip4_address, &ip4_mask_width))
6462 ip4_address_set = 1;
6463 else if (unformat (i, "address %U/%d",
6464 unformat_ip6_address, &ip6_address, &ip6_mask_width))
6465 ip6_address_set = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006466 else
6467 break;
6468 }
6469
6470 if (name_set == 0)
6471 {
6472 errmsg ("missing tap name");
6473 return -99;
6474 }
6475 if (vec_len (tap_name) > 63)
6476 {
6477 errmsg ("tap name too long");
6478 return -99;
6479 }
6480 vec_add1 (tap_name, 0);
6481
6482 if (vec_len (tag) > 63)
6483 {
6484 errmsg ("tag too long");
6485 return -99;
6486 }
6487
6488 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006489 M (TAP_CONNECT, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006490
6491 mp->use_random_mac = random_mac;
6492 clib_memcpy (mp->mac_address, mac_address, 6);
6493 clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6494 if (tag)
6495 clib_memcpy (mp->tag, tag, vec_len (tag));
6496
Dave Barach2feaffc2017-01-14 10:30:50 -05006497 if (ip4_address_set)
6498 {
6499 mp->ip4_address_set = 1;
6500 clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
6501 mp->ip4_mask_width = ip4_mask_width;
6502 }
6503 if (ip6_address_set)
6504 {
6505 mp->ip6_address_set = 1;
6506 clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
6507 mp->ip6_mask_width = ip6_mask_width;
6508 }
6509
Damjan Marion7cd468a2016-12-19 23:05:39 +01006510 vec_free (tap_name);
6511 vec_free (tag);
6512
6513 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006514 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006515
6516 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06006517 W (ret);
6518 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006519}
6520
6521static int
6522api_tap_modify (vat_main_t * vam)
6523{
6524 unformat_input_t *i = vam->input;
6525 vl_api_tap_modify_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006526 u8 mac_address[6];
6527 u8 random_mac = 1;
6528 u8 name_set = 0;
6529 u8 *tap_name;
6530 u32 sw_if_index = ~0;
6531 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006532 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006533
6534 memset (mac_address, 0, sizeof (mac_address));
6535
6536 /* Parse args required to build the message */
6537 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6538 {
6539 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6540 sw_if_index_set = 1;
6541 else if (unformat (i, "sw_if_index %d", &sw_if_index))
6542 sw_if_index_set = 1;
6543 else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6544 {
6545 random_mac = 0;
6546 }
6547 else if (unformat (i, "random-mac"))
6548 random_mac = 1;
6549 else if (unformat (i, "tapname %s", &tap_name))
6550 name_set = 1;
6551 else
6552 break;
6553 }
6554
6555 if (sw_if_index_set == 0)
6556 {
6557 errmsg ("missing vpp interface name");
6558 return -99;
6559 }
6560 if (name_set == 0)
6561 {
6562 errmsg ("missing tap name");
6563 return -99;
6564 }
6565 if (vec_len (tap_name) > 63)
6566 {
6567 errmsg ("tap name too long");
6568 }
6569 vec_add1 (tap_name, 0);
6570
6571 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006572 M (TAP_MODIFY, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006573
6574 mp->use_random_mac = random_mac;
6575 mp->sw_if_index = ntohl (sw_if_index);
6576 clib_memcpy (mp->mac_address, mac_address, 6);
6577 clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6578 vec_free (tap_name);
6579
6580 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006581 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006582
6583 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06006584 W (ret);
6585 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006586}
6587
6588static int
6589api_tap_delete (vat_main_t * vam)
6590{
6591 unformat_input_t *i = vam->input;
6592 vl_api_tap_delete_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006593 u32 sw_if_index = ~0;
6594 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006595 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006596
6597 /* Parse args required to build the message */
6598 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6599 {
6600 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6601 sw_if_index_set = 1;
6602 else if (unformat (i, "sw_if_index %d", &sw_if_index))
6603 sw_if_index_set = 1;
6604 else
6605 break;
6606 }
6607
6608 if (sw_if_index_set == 0)
6609 {
6610 errmsg ("missing vpp interface name");
6611 return -99;
6612 }
6613
6614 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006615 M (TAP_DELETE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006616
6617 mp->sw_if_index = ntohl (sw_if_index);
6618
6619 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006620 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006621
6622 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06006623 W (ret);
6624 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006625}
6626
6627static int
6628api_ip_add_del_route (vat_main_t * vam)
6629{
6630 unformat_input_t *i = vam->input;
6631 vl_api_ip_add_del_route_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006632 u32 sw_if_index = ~0, vrf_id = 0;
6633 u8 is_ipv6 = 0;
6634 u8 is_local = 0, is_drop = 0;
6635 u8 is_unreach = 0, is_prohibit = 0;
6636 u8 create_vrf_if_needed = 0;
6637 u8 is_add = 1;
6638 u32 next_hop_weight = 1;
6639 u8 not_last = 0;
6640 u8 is_multipath = 0;
6641 u8 address_set = 0;
6642 u8 address_length_set = 0;
6643 u32 next_hop_table_id = 0;
6644 u32 resolve_attempts = 0;
6645 u32 dst_address_length = 0;
6646 u8 next_hop_set = 0;
6647 ip4_address_t v4_dst_address, v4_next_hop_address;
6648 ip6_address_t v6_dst_address, v6_next_hop_address;
6649 int count = 1;
6650 int j;
6651 f64 before = 0;
6652 u32 random_add_del = 0;
6653 u32 *random_vector = 0;
6654 uword *random_hash;
6655 u32 random_seed = 0xdeaddabe;
6656 u32 classify_table_index = ~0;
6657 u8 is_classify = 0;
6658 u8 resolve_host = 0, resolve_attached = 0;
6659 mpls_label_t *next_hop_out_label_stack = NULL;
6660 mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6661 mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6662
6663 /* Parse args required to build the message */
6664 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6665 {
6666 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6667 ;
6668 else if (unformat (i, "sw_if_index %d", &sw_if_index))
6669 ;
6670 else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
6671 {
6672 address_set = 1;
6673 is_ipv6 = 0;
6674 }
6675 else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
6676 {
6677 address_set = 1;
6678 is_ipv6 = 1;
6679 }
6680 else if (unformat (i, "/%d", &dst_address_length))
6681 {
6682 address_length_set = 1;
6683 }
6684
6685 else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
6686 &v4_next_hop_address))
6687 {
6688 next_hop_set = 1;
6689 }
6690 else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
6691 &v6_next_hop_address))
6692 {
6693 next_hop_set = 1;
6694 }
6695 else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6696 ;
6697 else if (unformat (i, "weight %d", &next_hop_weight))
6698 ;
6699 else if (unformat (i, "drop"))
6700 {
6701 is_drop = 1;
6702 }
6703 else if (unformat (i, "null-send-unreach"))
6704 {
6705 is_unreach = 1;
6706 }
6707 else if (unformat (i, "null-send-prohibit"))
6708 {
6709 is_prohibit = 1;
6710 }
6711 else if (unformat (i, "local"))
6712 {
6713 is_local = 1;
6714 }
6715 else if (unformat (i, "classify %d", &classify_table_index))
6716 {
6717 is_classify = 1;
6718 }
6719 else if (unformat (i, "del"))
6720 is_add = 0;
6721 else if (unformat (i, "add"))
6722 is_add = 1;
6723 else if (unformat (i, "not-last"))
6724 not_last = 1;
6725 else if (unformat (i, "resolve-via-host"))
6726 resolve_host = 1;
6727 else if (unformat (i, "resolve-via-attached"))
6728 resolve_attached = 1;
6729 else if (unformat (i, "multipath"))
6730 is_multipath = 1;
6731 else if (unformat (i, "vrf %d", &vrf_id))
6732 ;
6733 else if (unformat (i, "create-vrf"))
6734 create_vrf_if_needed = 1;
6735 else if (unformat (i, "count %d", &count))
6736 ;
6737 else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
6738 ;
6739 else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6740 ;
6741 else if (unformat (i, "out-label %d", &next_hop_out_label))
6742 vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6743 else if (unformat (i, "via-label %d", &next_hop_via_label))
6744 ;
6745 else if (unformat (i, "random"))
6746 random_add_del = 1;
6747 else if (unformat (i, "seed %d", &random_seed))
6748 ;
6749 else
6750 {
6751 clib_warning ("parse error '%U'", format_unformat_error, i);
6752 return -99;
6753 }
6754 }
6755
6756 if (!next_hop_set && !is_drop && !is_local &&
6757 !is_classify && !is_unreach && !is_prohibit &&
6758 MPLS_LABEL_INVALID == next_hop_via_label)
6759 {
6760 errmsg
6761 ("next hop / local / drop / unreach / prohibit / classify not set");
6762 return -99;
6763 }
6764
6765 if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
6766 {
6767 errmsg ("next hop and next-hop via label set");
6768 return -99;
6769 }
6770 if (address_set == 0)
6771 {
6772 errmsg ("missing addresses");
6773 return -99;
6774 }
6775
6776 if (address_length_set == 0)
6777 {
6778 errmsg ("missing address length");
6779 return -99;
6780 }
6781
6782 /* Generate a pile of unique, random routes */
6783 if (random_add_del)
6784 {
6785 u32 this_random_address;
6786 random_hash = hash_create (count, sizeof (uword));
6787
6788 hash_set (random_hash, v4_next_hop_address.as_u32, 1);
6789 for (j = 0; j <= count; j++)
6790 {
6791 do
6792 {
6793 this_random_address = random_u32 (&random_seed);
6794 this_random_address =
6795 clib_host_to_net_u32 (this_random_address);
6796 }
6797 while (hash_get (random_hash, this_random_address));
6798 vec_add1 (random_vector, this_random_address);
6799 hash_set (random_hash, this_random_address, 1);
6800 }
6801 hash_free (random_hash);
6802 v4_dst_address.as_u32 = random_vector[0];
6803 }
6804
6805 if (count > 1)
6806 {
6807 /* Turn on async mode */
6808 vam->async_mode = 1;
6809 vam->async_errors = 0;
6810 before = vat_time_now (vam);
6811 }
6812
6813 for (j = 0; j < count; j++)
6814 {
6815 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006816 M2 (IP_ADD_DEL_ROUTE, mp,
Damjan Marion7cd468a2016-12-19 23:05:39 +01006817 sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6818
6819 mp->next_hop_sw_if_index = ntohl (sw_if_index);
6820 mp->table_id = ntohl (vrf_id);
6821 mp->create_vrf_if_needed = create_vrf_if_needed;
6822
6823 mp->is_add = is_add;
6824 mp->is_drop = is_drop;
6825 mp->is_unreach = is_unreach;
6826 mp->is_prohibit = is_prohibit;
6827 mp->is_ipv6 = is_ipv6;
6828 mp->is_local = is_local;
6829 mp->is_classify = is_classify;
6830 mp->is_multipath = is_multipath;
6831 mp->is_resolve_host = resolve_host;
6832 mp->is_resolve_attached = resolve_attached;
6833 mp->not_last = not_last;
6834 mp->next_hop_weight = next_hop_weight;
6835 mp->dst_address_length = dst_address_length;
6836 mp->next_hop_table_id = ntohl (next_hop_table_id);
6837 mp->classify_table_index = ntohl (classify_table_index);
6838 mp->next_hop_via_label = ntohl (next_hop_via_label);
6839 mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6840 if (0 != mp->next_hop_n_out_labels)
6841 {
6842 memcpy (mp->next_hop_out_label_stack,
6843 next_hop_out_label_stack,
6844 vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6845 vec_free (next_hop_out_label_stack);
6846 }
6847
6848 if (is_ipv6)
6849 {
6850 clib_memcpy (mp->dst_address, &v6_dst_address,
6851 sizeof (v6_dst_address));
6852 if (next_hop_set)
6853 clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
6854 sizeof (v6_next_hop_address));
6855 increment_v6_address (&v6_dst_address);
6856 }
6857 else
6858 {
6859 clib_memcpy (mp->dst_address, &v4_dst_address,
6860 sizeof (v4_dst_address));
6861 if (next_hop_set)
6862 clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
6863 sizeof (v4_next_hop_address));
6864 if (random_add_del)
6865 v4_dst_address.as_u32 = random_vector[j + 1];
6866 else
6867 increment_v4_address (&v4_dst_address);
6868 }
6869 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006870 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006871 /* If we receive SIGTERM, stop now... */
6872 if (vam->do_exit)
6873 break;
6874 }
6875
6876 /* When testing multiple add/del ops, use a control-ping to sync */
6877 if (count > 1)
6878 {
Jon Loeliger2d23eca2017-02-01 13:09:58 -06006879 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006880 f64 after;
Jon Loeliger1f9191f2017-01-31 15:27:19 -06006881 f64 timeout;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006882
6883 /* Shut off async mode */
6884 vam->async_mode = 0;
6885
Jon Loeliger2d23eca2017-02-01 13:09:58 -06006886 M (CONTROL_PING, mp_ping);
6887 S (mp_ping);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006888
6889 timeout = vat_time_now (vam) + 1.0;
6890 while (vat_time_now (vam) < timeout)
6891 if (vam->result_ready == 1)
6892 goto out;
6893 vam->retval = -99;
6894
6895 out:
6896 if (vam->retval == -99)
6897 errmsg ("timeout");
6898
6899 if (vam->async_errors > 0)
6900 {
6901 errmsg ("%d asynchronous errors", vam->async_errors);
6902 vam->retval = -98;
6903 }
6904 vam->async_errors = 0;
6905 after = vat_time_now (vam);
6906
6907 /* slim chance, but we might have eaten SIGTERM on the first iteration */
6908 if (j > 0)
6909 count = j;
6910
6911 print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6912 count, after - before, count / (after - before));
6913 }
6914 else
6915 {
Jon Loeliger56c7b012017-02-01 12:31:41 -06006916 int ret;
6917
Damjan Marion7cd468a2016-12-19 23:05:39 +01006918 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06006919 W (ret);
6920 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006921 }
6922
6923 /* Return the good/bad news */
6924 return (vam->retval);
6925}
6926
6927static int
Neale Ranns32e1c012016-11-22 17:07:28 +00006928api_ip_mroute_add_del (vat_main_t * vam)
6929{
6930 unformat_input_t *i = vam->input;
6931 vl_api_ip_mroute_add_del_t *mp;
Neale Ranns32e1c012016-11-22 17:07:28 +00006932 u32 sw_if_index = ~0, vrf_id = 0;
6933 u8 is_ipv6 = 0;
6934 u8 is_local = 0;
6935 u8 create_vrf_if_needed = 0;
6936 u8 is_add = 1;
6937 u8 address_set = 0;
6938 u32 grp_address_length = 0;
6939 ip4_address_t v4_grp_address, v4_src_address;
6940 ip6_address_t v6_grp_address, v6_src_address;
6941 mfib_itf_flags_t iflags = 0;
6942 mfib_entry_flags_t eflags = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006943 int ret;
Neale Ranns32e1c012016-11-22 17:07:28 +00006944
6945 /* Parse args required to build the message */
6946 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6947 {
6948 if (unformat (i, "sw_if_index %d", &sw_if_index))
6949 ;
6950 else if (unformat (i, "%U %U",
6951 unformat_ip4_address, &v4_src_address,
6952 unformat_ip4_address, &v4_grp_address))
6953 {
6954 grp_address_length = 64;
6955 address_set = 1;
6956 is_ipv6 = 0;
6957 }
6958 else if (unformat (i, "%U %U",
6959 unformat_ip6_address, &v6_src_address,
6960 unformat_ip6_address, &v6_grp_address))
6961 {
6962 grp_address_length = 256;
6963 address_set = 1;
6964 is_ipv6 = 1;
6965 }
6966 else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
6967 {
6968 memset (&v4_src_address, 0, sizeof (v4_src_address));
6969 grp_address_length = 32;
6970 address_set = 1;
6971 is_ipv6 = 0;
6972 }
6973 else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
6974 {
6975 memset (&v6_src_address, 0, sizeof (v6_src_address));
6976 grp_address_length = 128;
6977 address_set = 1;
6978 is_ipv6 = 1;
6979 }
6980 else if (unformat (i, "/%d", &grp_address_length))
6981 ;
6982 else if (unformat (i, "local"))
6983 {
6984 is_local = 1;
6985 }
6986 else if (unformat (i, "del"))
6987 is_add = 0;
6988 else if (unformat (i, "add"))
6989 is_add = 1;
6990 else if (unformat (i, "vrf %d", &vrf_id))
6991 ;
6992 else if (unformat (i, "create-vrf"))
6993 create_vrf_if_needed = 1;
6994 else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
6995 ;
6996 else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
6997 ;
6998 else
6999 {
7000 clib_warning ("parse error '%U'", format_unformat_error, i);
7001 return -99;
7002 }
7003 }
7004
7005 if (address_set == 0)
7006 {
7007 errmsg ("missing addresses\n");
7008 return -99;
7009 }
7010
7011 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007012 M (IP_MROUTE_ADD_DEL, mp);
Neale Ranns32e1c012016-11-22 17:07:28 +00007013
7014 mp->next_hop_sw_if_index = ntohl (sw_if_index);
7015 mp->table_id = ntohl (vrf_id);
7016 mp->create_vrf_if_needed = create_vrf_if_needed;
7017
7018 mp->is_add = is_add;
7019 mp->is_ipv6 = is_ipv6;
7020 mp->is_local = is_local;
7021 mp->itf_flags = ntohl (iflags);
7022 mp->entry_flags = ntohl (eflags);
7023 mp->grp_address_length = grp_address_length;
7024 mp->grp_address_length = ntohs (mp->grp_address_length);
7025
7026 if (is_ipv6)
7027 {
7028 clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
7029 clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
7030 }
7031 else
7032 {
7033 clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
7034 clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
7035
7036 }
7037
7038 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007039 S (mp);
Neale Ranns32e1c012016-11-22 17:07:28 +00007040 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06007041 W (ret);
7042 return ret;
Neale Ranns32e1c012016-11-22 17:07:28 +00007043}
7044
7045static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01007046api_mpls_route_add_del (vat_main_t * vam)
7047{
7048 unformat_input_t *i = vam->input;
7049 vl_api_mpls_route_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007050 u32 sw_if_index = ~0, table_id = 0;
7051 u8 create_table_if_needed = 0;
7052 u8 is_add = 1;
7053 u32 next_hop_weight = 1;
7054 u8 is_multipath = 0;
7055 u32 next_hop_table_id = 0;
7056 u8 next_hop_set = 0;
7057 ip4_address_t v4_next_hop_address = {
7058 .as_u32 = 0,
7059 };
7060 ip6_address_t v6_next_hop_address = { {0} };
7061 int count = 1;
7062 int j;
7063 f64 before = 0;
7064 u32 classify_table_index = ~0;
7065 u8 is_classify = 0;
7066 u8 resolve_host = 0, resolve_attached = 0;
7067 mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
7068 mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
7069 mpls_label_t *next_hop_out_label_stack = NULL;
7070 mpls_label_t local_label = MPLS_LABEL_INVALID;
7071 u8 is_eos = 0;
7072 u8 next_hop_proto_is_ip4 = 1;
7073
7074 /* Parse args required to build the message */
7075 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7076 {
7077 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7078 ;
7079 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7080 ;
7081 else if (unformat (i, "%d", &local_label))
7082 ;
7083 else if (unformat (i, "eos"))
7084 is_eos = 1;
7085 else if (unformat (i, "non-eos"))
7086 is_eos = 0;
7087 else if (unformat (i, "via %U", unformat_ip4_address,
7088 &v4_next_hop_address))
7089 {
7090 next_hop_set = 1;
7091 next_hop_proto_is_ip4 = 1;
7092 }
7093 else if (unformat (i, "via %U", unformat_ip6_address,
7094 &v6_next_hop_address))
7095 {
7096 next_hop_set = 1;
7097 next_hop_proto_is_ip4 = 0;
7098 }
7099 else if (unformat (i, "weight %d", &next_hop_weight))
7100 ;
7101 else if (unformat (i, "create-table"))
7102 create_table_if_needed = 1;
7103 else if (unformat (i, "classify %d", &classify_table_index))
7104 {
7105 is_classify = 1;
7106 }
7107 else if (unformat (i, "del"))
7108 is_add = 0;
7109 else if (unformat (i, "add"))
7110 is_add = 1;
7111 else if (unformat (i, "resolve-via-host"))
7112 resolve_host = 1;
7113 else if (unformat (i, "resolve-via-attached"))
7114 resolve_attached = 1;
7115 else if (unformat (i, "multipath"))
7116 is_multipath = 1;
7117 else if (unformat (i, "count %d", &count))
7118 ;
7119 else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
7120 {
7121 next_hop_set = 1;
7122 next_hop_proto_is_ip4 = 1;
7123 }
7124 else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
7125 {
7126 next_hop_set = 1;
7127 next_hop_proto_is_ip4 = 0;
7128 }
7129 else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7130 ;
7131 else if (unformat (i, "via-label %d", &next_hop_via_label))
7132 ;
7133 else if (unformat (i, "out-label %d", &next_hop_out_label))
7134 vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
7135 else
7136 {
7137 clib_warning ("parse error '%U'", format_unformat_error, i);
7138 return -99;
7139 }
7140 }
7141
7142 if (!next_hop_set && !is_classify)
7143 {
7144 errmsg ("next hop / classify not set");
7145 return -99;
7146 }
7147
7148 if (MPLS_LABEL_INVALID == local_label)
7149 {
7150 errmsg ("missing label");
7151 return -99;
7152 }
7153
7154 if (count > 1)
7155 {
7156 /* Turn on async mode */
7157 vam->async_mode = 1;
7158 vam->async_errors = 0;
7159 before = vat_time_now (vam);
7160 }
7161
7162 for (j = 0; j < count; j++)
7163 {
7164 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007165 M2 (MPLS_ROUTE_ADD_DEL, mp,
Damjan Marion7cd468a2016-12-19 23:05:39 +01007166 sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
7167
7168 mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
7169 mp->mr_table_id = ntohl (table_id);
7170 mp->mr_create_table_if_needed = create_table_if_needed;
7171
7172 mp->mr_is_add = is_add;
7173 mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7174 mp->mr_is_classify = is_classify;
7175 mp->mr_is_multipath = is_multipath;
7176 mp->mr_is_resolve_host = resolve_host;
7177 mp->mr_is_resolve_attached = resolve_attached;
7178 mp->mr_next_hop_weight = next_hop_weight;
7179 mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
7180 mp->mr_classify_table_index = ntohl (classify_table_index);
7181 mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
7182 mp->mr_label = ntohl (local_label);
7183 mp->mr_eos = is_eos;
7184
7185 mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
7186 if (0 != mp->mr_next_hop_n_out_labels)
7187 {
7188 memcpy (mp->mr_next_hop_out_label_stack,
7189 next_hop_out_label_stack,
7190 vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
7191 vec_free (next_hop_out_label_stack);
7192 }
7193
7194 if (next_hop_set)
7195 {
7196 if (next_hop_proto_is_ip4)
7197 {
7198 clib_memcpy (mp->mr_next_hop,
7199 &v4_next_hop_address,
7200 sizeof (v4_next_hop_address));
7201 }
7202 else
7203 {
7204 clib_memcpy (mp->mr_next_hop,
7205 &v6_next_hop_address,
7206 sizeof (v6_next_hop_address));
7207 }
7208 }
7209 local_label++;
7210
7211 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007212 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007213 /* If we receive SIGTERM, stop now... */
7214 if (vam->do_exit)
7215 break;
7216 }
7217
7218 /* When testing multiple add/del ops, use a control-ping to sync */
7219 if (count > 1)
7220 {
Jon Loeliger2d23eca2017-02-01 13:09:58 -06007221 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007222 f64 after;
Jon Loeliger1f9191f2017-01-31 15:27:19 -06007223 f64 timeout;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007224
7225 /* Shut off async mode */
7226 vam->async_mode = 0;
7227
Jon Loeliger2d23eca2017-02-01 13:09:58 -06007228 M (CONTROL_PING, mp_ping);
7229 S (mp_ping);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007230
7231 timeout = vat_time_now (vam) + 1.0;
7232 while (vat_time_now (vam) < timeout)
7233 if (vam->result_ready == 1)
7234 goto out;
7235 vam->retval = -99;
7236
7237 out:
7238 if (vam->retval == -99)
7239 errmsg ("timeout");
7240
7241 if (vam->async_errors > 0)
7242 {
7243 errmsg ("%d asynchronous errors", vam->async_errors);
7244 vam->retval = -98;
7245 }
7246 vam->async_errors = 0;
7247 after = vat_time_now (vam);
7248
7249 /* slim chance, but we might have eaten SIGTERM on the first iteration */
7250 if (j > 0)
7251 count = j;
7252
7253 print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7254 count, after - before, count / (after - before));
7255 }
7256 else
7257 {
Jon Loeliger56c7b012017-02-01 12:31:41 -06007258 int ret;
7259
Damjan Marion7cd468a2016-12-19 23:05:39 +01007260 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06007261 W (ret);
7262 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007263 }
7264
7265 /* Return the good/bad news */
7266 return (vam->retval);
7267}
7268
7269static int
7270api_mpls_ip_bind_unbind (vat_main_t * vam)
7271{
7272 unformat_input_t *i = vam->input;
7273 vl_api_mpls_ip_bind_unbind_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007274 u32 ip_table_id = 0;
7275 u8 create_table_if_needed = 0;
7276 u8 is_bind = 1;
7277 u8 is_ip4 = 1;
7278 ip4_address_t v4_address;
7279 ip6_address_t v6_address;
7280 u32 address_length;
7281 u8 address_set = 0;
7282 mpls_label_t local_label = MPLS_LABEL_INVALID;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007283 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007284
7285 /* Parse args required to build the message */
7286 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7287 {
7288 if (unformat (i, "%U/%d", unformat_ip4_address,
7289 &v4_address, &address_length))
7290 {
7291 is_ip4 = 1;
7292 address_set = 1;
7293 }
7294 else if (unformat (i, "%U/%d", unformat_ip6_address,
7295 &v6_address, &address_length))
7296 {
7297 is_ip4 = 0;
7298 address_set = 1;
7299 }
7300 else if (unformat (i, "%d", &local_label))
7301 ;
7302 else if (unformat (i, "create-table"))
7303 create_table_if_needed = 1;
7304 else if (unformat (i, "table-id %d", &ip_table_id))
7305 ;
7306 else if (unformat (i, "unbind"))
7307 is_bind = 0;
7308 else if (unformat (i, "bind"))
7309 is_bind = 1;
7310 else
7311 {
7312 clib_warning ("parse error '%U'", format_unformat_error, i);
7313 return -99;
7314 }
7315 }
7316
7317 if (!address_set)
7318 {
7319 errmsg ("IP addres not set");
7320 return -99;
7321 }
7322
7323 if (MPLS_LABEL_INVALID == local_label)
7324 {
7325 errmsg ("missing label");
7326 return -99;
7327 }
7328
7329 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007330 M (MPLS_IP_BIND_UNBIND, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007331
7332 mp->mb_create_table_if_needed = create_table_if_needed;
7333 mp->mb_is_bind = is_bind;
7334 mp->mb_is_ip4 = is_ip4;
7335 mp->mb_ip_table_id = ntohl (ip_table_id);
7336 mp->mb_mpls_table_id = 0;
7337 mp->mb_label = ntohl (local_label);
7338 mp->mb_address_length = address_length;
7339
7340 if (is_ip4)
7341 clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
7342 else
7343 clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
7344
7345 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007346 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007347
7348 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06007349 W (ret);
7350 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007351}
7352
7353static int
7354api_proxy_arp_add_del (vat_main_t * vam)
7355{
7356 unformat_input_t *i = vam->input;
7357 vl_api_proxy_arp_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007358 u32 vrf_id = 0;
7359 u8 is_add = 1;
7360 ip4_address_t lo, hi;
7361 u8 range_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007362 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007363
7364 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7365 {
7366 if (unformat (i, "vrf %d", &vrf_id))
7367 ;
7368 else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
7369 unformat_ip4_address, &hi))
7370 range_set = 1;
7371 else if (unformat (i, "del"))
7372 is_add = 0;
7373 else
7374 {
7375 clib_warning ("parse error '%U'", format_unformat_error, i);
7376 return -99;
7377 }
7378 }
7379
7380 if (range_set == 0)
7381 {
7382 errmsg ("address range not set");
7383 return -99;
7384 }
7385
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007386 M (PROXY_ARP_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007387
7388 mp->vrf_id = ntohl (vrf_id);
7389 mp->is_add = is_add;
7390 clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
7391 clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
7392
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007393 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007394 W (ret);
7395 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007396}
7397
7398static int
7399api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
7400{
7401 unformat_input_t *i = vam->input;
7402 vl_api_proxy_arp_intfc_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007403 u32 sw_if_index;
7404 u8 enable = 1;
7405 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007406 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007407
7408 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7409 {
7410 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7411 sw_if_index_set = 1;
7412 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7413 sw_if_index_set = 1;
7414 else if (unformat (i, "enable"))
7415 enable = 1;
7416 else if (unformat (i, "disable"))
7417 enable = 0;
7418 else
7419 {
7420 clib_warning ("parse error '%U'", format_unformat_error, i);
7421 return -99;
7422 }
7423 }
7424
7425 if (sw_if_index_set == 0)
7426 {
7427 errmsg ("missing interface name or sw_if_index");
7428 return -99;
7429 }
7430
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007431 M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007432
7433 mp->sw_if_index = ntohl (sw_if_index);
7434 mp->enable_disable = enable;
7435
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007436 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007437 W (ret);
7438 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007439}
7440
7441static int
7442api_mpls_tunnel_add_del (vat_main_t * vam)
7443{
7444 unformat_input_t *i = vam->input;
7445 vl_api_mpls_tunnel_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007446
7447 u8 is_add = 1;
7448 u8 l2_only = 0;
7449 u32 sw_if_index = ~0;
7450 u32 next_hop_sw_if_index = ~0;
7451 u32 next_hop_proto_is_ip4 = 1;
7452
7453 u32 next_hop_table_id = 0;
7454 ip4_address_t v4_next_hop_address = {
7455 .as_u32 = 0,
7456 };
7457 ip6_address_t v6_next_hop_address = { {0} };
7458 mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007459 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007460
7461 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7462 {
7463 if (unformat (i, "add"))
7464 is_add = 1;
7465 else if (unformat (i, "del sw_if_index %d", &sw_if_index))
7466 is_add = 0;
7467 else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
7468 ;
7469 else if (unformat (i, "via %U",
7470 unformat_ip4_address, &v4_next_hop_address))
7471 {
7472 next_hop_proto_is_ip4 = 1;
7473 }
7474 else if (unformat (i, "via %U",
7475 unformat_ip6_address, &v6_next_hop_address))
7476 {
7477 next_hop_proto_is_ip4 = 0;
7478 }
7479 else if (unformat (i, "l2-only"))
7480 l2_only = 1;
7481 else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7482 ;
7483 else if (unformat (i, "out-label %d", &next_hop_out_label))
7484 vec_add1 (labels, ntohl (next_hop_out_label));
7485 else
7486 {
7487 clib_warning ("parse error '%U'", format_unformat_error, i);
7488 return -99;
7489 }
7490 }
7491
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007492 M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
Damjan Marion7cd468a2016-12-19 23:05:39 +01007493
7494 mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
7495 mp->mt_sw_if_index = ntohl (sw_if_index);
7496 mp->mt_is_add = is_add;
7497 mp->mt_l2_only = l2_only;
7498 mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
7499 mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7500
7501 mp->mt_next_hop_n_out_labels = vec_len (labels);
7502
7503 if (0 != mp->mt_next_hop_n_out_labels)
7504 {
7505 clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
7506 sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
7507 vec_free (labels);
7508 }
7509
7510 if (next_hop_proto_is_ip4)
7511 {
7512 clib_memcpy (mp->mt_next_hop,
7513 &v4_next_hop_address, sizeof (v4_next_hop_address));
7514 }
7515 else
7516 {
7517 clib_memcpy (mp->mt_next_hop,
7518 &v6_next_hop_address, sizeof (v6_next_hop_address));
7519 }
7520
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007521 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007522 W (ret);
7523 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007524}
7525
7526static int
7527api_sw_interface_set_unnumbered (vat_main_t * vam)
7528{
7529 unformat_input_t *i = vam->input;
7530 vl_api_sw_interface_set_unnumbered_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007531 u32 sw_if_index;
7532 u32 unnum_sw_index = ~0;
7533 u8 is_add = 1;
7534 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007535 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007536
7537 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7538 {
7539 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7540 sw_if_index_set = 1;
7541 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7542 sw_if_index_set = 1;
7543 else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
7544 ;
7545 else if (unformat (i, "del"))
7546 is_add = 0;
7547 else
7548 {
7549 clib_warning ("parse error '%U'", format_unformat_error, i);
7550 return -99;
7551 }
7552 }
7553
7554 if (sw_if_index_set == 0)
7555 {
7556 errmsg ("missing interface name or sw_if_index");
7557 return -99;
7558 }
7559
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007560 M (SW_INTERFACE_SET_UNNUMBERED, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007561
7562 mp->sw_if_index = ntohl (sw_if_index);
7563 mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
7564 mp->is_add = is_add;
7565
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007566 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007567 W (ret);
7568 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007569}
7570
7571static int
7572api_ip_neighbor_add_del (vat_main_t * vam)
7573{
7574 unformat_input_t *i = vam->input;
7575 vl_api_ip_neighbor_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007576 u32 sw_if_index;
7577 u8 sw_if_index_set = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007578 u8 is_add = 1;
7579 u8 is_static = 0;
Neale Rannsb3b2de72017-03-08 05:17:22 -08007580 u8 is_no_fib_entry = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007581 u8 mac_address[6];
7582 u8 mac_set = 0;
7583 u8 v4_address_set = 0;
7584 u8 v6_address_set = 0;
7585 ip4_address_t v4address;
7586 ip6_address_t v6address;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007587 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007588
7589 memset (mac_address, 0, sizeof (mac_address));
7590
7591 /* Parse args required to build the message */
7592 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7593 {
7594 if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7595 {
7596 mac_set = 1;
7597 }
7598 else if (unformat (i, "del"))
7599 is_add = 0;
7600 else
7601 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7602 sw_if_index_set = 1;
7603 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7604 sw_if_index_set = 1;
7605 else if (unformat (i, "is_static"))
7606 is_static = 1;
Neale Rannsb3b2de72017-03-08 05:17:22 -08007607 else if (unformat (i, "no-fib-entry"))
7608 is_no_fib_entry = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007609 else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
7610 v4_address_set = 1;
7611 else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
7612 v6_address_set = 1;
7613 else
7614 {
7615 clib_warning ("parse error '%U'", format_unformat_error, i);
7616 return -99;
7617 }
7618 }
7619
7620 if (sw_if_index_set == 0)
7621 {
7622 errmsg ("missing interface name or sw_if_index");
7623 return -99;
7624 }
7625 if (v4_address_set && v6_address_set)
7626 {
7627 errmsg ("both v4 and v6 addresses set");
7628 return -99;
7629 }
7630 if (!v4_address_set && !v6_address_set)
7631 {
7632 errmsg ("no address set");
7633 return -99;
7634 }
7635
7636 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007637 M (IP_NEIGHBOR_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007638
7639 mp->sw_if_index = ntohl (sw_if_index);
7640 mp->is_add = is_add;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007641 mp->is_static = is_static;
Neale Rannsb3b2de72017-03-08 05:17:22 -08007642 mp->is_no_adj_fib = is_no_fib_entry;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007643 if (mac_set)
7644 clib_memcpy (mp->mac_address, mac_address, 6);
7645 if (v6_address_set)
7646 {
7647 mp->is_ipv6 = 1;
7648 clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
7649 }
7650 else
7651 {
7652 /* mp->is_ipv6 = 0; via memset in M macro above */
7653 clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
7654 }
7655
7656 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007657 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007658
7659 /* Wait for a reply, return good/bad news */
Jon Loeliger56c7b012017-02-01 12:31:41 -06007660 W (ret);
7661 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007662}
7663
7664static int
7665api_reset_vrf (vat_main_t * vam)
7666{
7667 unformat_input_t *i = vam->input;
7668 vl_api_reset_vrf_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007669 u32 vrf_id = 0;
7670 u8 is_ipv6 = 0;
7671 u8 vrf_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, "vrf %d", &vrf_id))
7677 vrf_id_set = 1;
7678 else if (unformat (i, "ipv6"))
7679 is_ipv6 = 1;
7680 else
7681 {
7682 clib_warning ("parse error '%U'", format_unformat_error, i);
7683 return -99;
7684 }
7685 }
7686
7687 if (vrf_id_set == 0)
7688 {
7689 errmsg ("missing vrf id");
7690 return -99;
7691 }
7692
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007693 M (RESET_VRF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007694
7695 mp->vrf_id = ntohl (vrf_id);
7696 mp->is_ipv6 = is_ipv6;
7697
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007698 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007699 W (ret);
7700 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007701}
7702
7703static int
7704api_create_vlan_subif (vat_main_t * vam)
7705{
7706 unformat_input_t *i = vam->input;
7707 vl_api_create_vlan_subif_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007708 u32 sw_if_index;
7709 u8 sw_if_index_set = 0;
7710 u32 vlan_id;
7711 u8 vlan_id_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007712 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007713
7714 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7715 {
7716 if (unformat (i, "sw_if_index %d", &sw_if_index))
7717 sw_if_index_set = 1;
7718 else
7719 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7720 sw_if_index_set = 1;
7721 else if (unformat (i, "vlan %d", &vlan_id))
7722 vlan_id_set = 1;
7723 else
7724 {
7725 clib_warning ("parse error '%U'", format_unformat_error, i);
7726 return -99;
7727 }
7728 }
7729
7730 if (sw_if_index_set == 0)
7731 {
7732 errmsg ("missing interface name or sw_if_index");
7733 return -99;
7734 }
7735
7736 if (vlan_id_set == 0)
7737 {
7738 errmsg ("missing vlan_id");
7739 return -99;
7740 }
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007741 M (CREATE_VLAN_SUBIF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007742
7743 mp->sw_if_index = ntohl (sw_if_index);
7744 mp->vlan_id = ntohl (vlan_id);
7745
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007746 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007747 W (ret);
7748 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007749}
7750
7751#define foreach_create_subif_bit \
7752_(no_tags) \
7753_(one_tag) \
7754_(two_tags) \
7755_(dot1ad) \
7756_(exact_match) \
7757_(default_sub) \
7758_(outer_vlan_id_any) \
7759_(inner_vlan_id_any)
7760
7761static int
7762api_create_subif (vat_main_t * vam)
7763{
7764 unformat_input_t *i = vam->input;
7765 vl_api_create_subif_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007766 u32 sw_if_index;
7767 u8 sw_if_index_set = 0;
7768 u32 sub_id;
7769 u8 sub_id_set = 0;
7770 u32 no_tags = 0;
7771 u32 one_tag = 0;
7772 u32 two_tags = 0;
7773 u32 dot1ad = 0;
7774 u32 exact_match = 0;
7775 u32 default_sub = 0;
7776 u32 outer_vlan_id_any = 0;
7777 u32 inner_vlan_id_any = 0;
7778 u32 tmp;
7779 u16 outer_vlan_id = 0;
7780 u16 inner_vlan_id = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007781 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007782
7783 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7784 {
7785 if (unformat (i, "sw_if_index %d", &sw_if_index))
7786 sw_if_index_set = 1;
7787 else
7788 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7789 sw_if_index_set = 1;
7790 else if (unformat (i, "sub_id %d", &sub_id))
7791 sub_id_set = 1;
7792 else if (unformat (i, "outer_vlan_id %d", &tmp))
7793 outer_vlan_id = tmp;
7794 else if (unformat (i, "inner_vlan_id %d", &tmp))
7795 inner_vlan_id = tmp;
7796
7797#define _(a) else if (unformat (i, #a)) a = 1 ;
7798 foreach_create_subif_bit
7799#undef _
7800 else
7801 {
7802 clib_warning ("parse error '%U'", format_unformat_error, i);
7803 return -99;
7804 }
7805 }
7806
7807 if (sw_if_index_set == 0)
7808 {
7809 errmsg ("missing interface name or sw_if_index");
7810 return -99;
7811 }
7812
7813 if (sub_id_set == 0)
7814 {
7815 errmsg ("missing sub_id");
7816 return -99;
7817 }
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007818 M (CREATE_SUBIF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007819
7820 mp->sw_if_index = ntohl (sw_if_index);
7821 mp->sub_id = ntohl (sub_id);
7822
7823#define _(a) mp->a = a;
7824 foreach_create_subif_bit;
7825#undef _
7826
7827 mp->outer_vlan_id = ntohs (outer_vlan_id);
7828 mp->inner_vlan_id = ntohs (inner_vlan_id);
7829
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007830 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007831 W (ret);
7832 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007833}
7834
7835static int
7836api_oam_add_del (vat_main_t * vam)
7837{
7838 unformat_input_t *i = vam->input;
7839 vl_api_oam_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007840 u32 vrf_id = 0;
7841 u8 is_add = 1;
7842 ip4_address_t src, dst;
7843 u8 src_set = 0;
7844 u8 dst_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007845 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007846
7847 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7848 {
7849 if (unformat (i, "vrf %d", &vrf_id))
7850 ;
7851 else if (unformat (i, "src %U", unformat_ip4_address, &src))
7852 src_set = 1;
7853 else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
7854 dst_set = 1;
7855 else if (unformat (i, "del"))
7856 is_add = 0;
7857 else
7858 {
7859 clib_warning ("parse error '%U'", format_unformat_error, i);
7860 return -99;
7861 }
7862 }
7863
7864 if (src_set == 0)
7865 {
7866 errmsg ("missing src addr");
7867 return -99;
7868 }
7869
7870 if (dst_set == 0)
7871 {
7872 errmsg ("missing dst addr");
7873 return -99;
7874 }
7875
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007876 M (OAM_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007877
7878 mp->vrf_id = ntohl (vrf_id);
7879 mp->is_add = is_add;
7880 clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
7881 clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
7882
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007883 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007884 W (ret);
7885 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007886}
7887
7888static int
7889api_reset_fib (vat_main_t * vam)
7890{
7891 unformat_input_t *i = vam->input;
7892 vl_api_reset_fib_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007893 u32 vrf_id = 0;
7894 u8 is_ipv6 = 0;
7895 u8 vrf_id_set = 0;
7896
Jon Loeliger56c7b012017-02-01 12:31:41 -06007897 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007898 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7899 {
7900 if (unformat (i, "vrf %d", &vrf_id))
7901 vrf_id_set = 1;
7902 else if (unformat (i, "ipv6"))
7903 is_ipv6 = 1;
7904 else
7905 {
7906 clib_warning ("parse error '%U'", format_unformat_error, i);
7907 return -99;
7908 }
7909 }
7910
7911 if (vrf_id_set == 0)
7912 {
7913 errmsg ("missing vrf id");
7914 return -99;
7915 }
7916
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007917 M (RESET_FIB, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007918
7919 mp->vrf_id = ntohl (vrf_id);
7920 mp->is_ipv6 = is_ipv6;
7921
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007922 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007923 W (ret);
7924 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007925}
7926
7927static int
7928api_dhcp_proxy_config (vat_main_t * vam)
7929{
7930 unformat_input_t *i = vam->input;
7931 vl_api_dhcp_proxy_config_t *mp;
Neale Ranns20a175a2017-02-14 07:28:41 -08007932 u32 rx_vrf_id = 0;
7933 u32 server_vrf_id = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007934 u8 is_add = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007935 u8 v4_address_set = 0;
7936 u8 v6_address_set = 0;
7937 ip4_address_t v4address;
7938 ip6_address_t v6address;
7939 u8 v4_src_address_set = 0;
7940 u8 v6_src_address_set = 0;
7941 ip4_address_t v4srcaddress;
7942 ip6_address_t v6srcaddress;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007943 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007944
7945 /* Parse args required to build the message */
7946 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7947 {
7948 if (unformat (i, "del"))
7949 is_add = 0;
Neale Ranns20a175a2017-02-14 07:28:41 -08007950 else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
Damjan Marion7cd468a2016-12-19 23:05:39 +01007951 ;
Neale Ranns20a175a2017-02-14 07:28:41 -08007952 else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
Damjan Marion7cd468a2016-12-19 23:05:39 +01007953 ;
7954 else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7955 v4_address_set = 1;
7956 else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7957 v6_address_set = 1;
7958 else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7959 v4_src_address_set = 1;
7960 else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7961 v6_src_address_set = 1;
7962 else
7963 break;
7964 }
7965
7966 if (v4_address_set && v6_address_set)
7967 {
7968 errmsg ("both v4 and v6 server addresses set");
7969 return -99;
7970 }
7971 if (!v4_address_set && !v6_address_set)
7972 {
7973 errmsg ("no server addresses set");
7974 return -99;
7975 }
7976
7977 if (v4_src_address_set && v6_src_address_set)
7978 {
7979 errmsg ("both v4 and v6 src addresses set");
7980 return -99;
7981 }
7982 if (!v4_src_address_set && !v6_src_address_set)
7983 {
7984 errmsg ("no src addresses set");
7985 return -99;
7986 }
7987
7988 if (!(v4_src_address_set && v4_address_set) &&
7989 !(v6_src_address_set && v6_address_set))
7990 {
7991 errmsg ("no matching server and src addresses set");
7992 return -99;
7993 }
7994
7995 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007996 M (DHCP_PROXY_CONFIG, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007997
Damjan Marion7cd468a2016-12-19 23:05:39 +01007998 mp->is_add = is_add;
Neale Ranns20a175a2017-02-14 07:28:41 -08007999 mp->rx_vrf_id = ntohl (rx_vrf_id);
8000 mp->server_vrf_id = ntohl (server_vrf_id);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008001 if (v6_address_set)
8002 {
8003 mp->is_ipv6 = 1;
8004 clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
8005 clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
8006 }
8007 else
8008 {
8009 clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
8010 clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
8011 }
8012
8013 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008014 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008015
8016 /* Wait for a reply, return good/bad news */
Jon Loeliger56c7b012017-02-01 12:31:41 -06008017 W (ret);
8018 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008019}
8020
Neale Ranns20a175a2017-02-14 07:28:41 -08008021#define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
8022#define vl_api_dhcp_proxy_details_t_print vl_noop_handler
8023
8024static void
8025vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01008026{
Neale Ranns20a175a2017-02-14 07:28:41 -08008027 vat_main_t *vam = &vat_main;
Neale Ranns3466c302017-02-16 07:45:03 -08008028 u32 i, count = mp->count;
8029 vl_api_dhcp_server_t *s;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008030
Neale Ranns20a175a2017-02-14 07:28:41 -08008031 if (mp->is_ipv6)
8032 print (vam->ofp,
Neale Ranns3466c302017-02-16 07:45:03 -08008033 "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
Neale Ranns20a175a2017-02-14 07:28:41 -08008034 ntohl (mp->rx_vrf_id),
Neale Ranns20a175a2017-02-14 07:28:41 -08008035 format_ip6_address, mp->dhcp_src_address,
8036 ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
8037 else
8038 print (vam->ofp,
Neale Ranns3466c302017-02-16 07:45:03 -08008039 "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
Neale Ranns20a175a2017-02-14 07:28:41 -08008040 ntohl (mp->rx_vrf_id),
Neale Ranns20a175a2017-02-14 07:28:41 -08008041 format_ip4_address, mp->dhcp_src_address,
8042 ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
Neale Ranns3466c302017-02-16 07:45:03 -08008043
8044 for (i = 0; i < count; i++)
8045 {
8046 s = &mp->servers[i];
8047
8048 if (mp->is_ipv6)
8049 print (vam->ofp,
8050 " Server Table-ID %d, Server Address %U",
8051 ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
8052 else
8053 print (vam->ofp,
8054 " Server Table-ID %d, Server Address %U",
8055 ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
8056 }
Neale Ranns20a175a2017-02-14 07:28:41 -08008057}
Damjan Marion7cd468a2016-12-19 23:05:39 +01008058
Neale Ranns20a175a2017-02-14 07:28:41 -08008059static void vl_api_dhcp_proxy_details_t_handler_json
8060 (vl_api_dhcp_proxy_details_t * mp)
8061{
8062 vat_main_t *vam = &vat_main;
8063 vat_json_node_t *node = NULL;
Neale Ranns3466c302017-02-16 07:45:03 -08008064 u32 i, count = mp->count;
Neale Ranns20a175a2017-02-14 07:28:41 -08008065 struct in_addr ip4;
8066 struct in6_addr ip6;
Neale Ranns3466c302017-02-16 07:45:03 -08008067 vl_api_dhcp_server_t *s;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008068
Neale Ranns20a175a2017-02-14 07:28:41 -08008069 if (VAT_JSON_ARRAY != vam->json_tree.type)
Damjan Marion7cd468a2016-12-19 23:05:39 +01008070 {
Neale Ranns20a175a2017-02-14 07:28:41 -08008071 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
8072 vat_json_init_array (&vam->json_tree);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008073 }
Neale Ranns20a175a2017-02-14 07:28:41 -08008074 node = vat_json_array_add (&vam->json_tree);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008075
Neale Ranns20a175a2017-02-14 07:28:41 -08008076 vat_json_init_object (node);
8077 vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
Neale Ranns3466c302017-02-16 07:45:03 -08008078 vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
8079 vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
8080
Neale Ranns20a175a2017-02-14 07:28:41 -08008081 if (mp->is_ipv6)
Damjan Marion7cd468a2016-12-19 23:05:39 +01008082 {
Neale Ranns20a175a2017-02-14 07:28:41 -08008083 clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
8084 vat_json_object_add_ip6 (node, "src_address", ip6);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008085 }
8086 else
8087 {
Neale Ranns20a175a2017-02-14 07:28:41 -08008088 clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
8089 vat_json_object_add_ip4 (node, "src_address", ip4);
8090 }
Neale Ranns3466c302017-02-16 07:45:03 -08008091
8092 for (i = 0; i < count; i++)
8093 {
8094 s = &mp->servers[i];
8095
8096 vat_json_object_add_uint (node, "server-table-id",
8097 ntohl (s->server_vrf_id));
8098
8099 if (mp->is_ipv6)
8100 {
8101 clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
8102 vat_json_object_add_ip4 (node, "src_address", ip4);
8103 }
8104 else
8105 {
8106 clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
8107 vat_json_object_add_ip6 (node, "server_address", ip6);
8108 }
8109 }
Neale Ranns20a175a2017-02-14 07:28:41 -08008110}
8111
8112static int
8113api_dhcp_proxy_dump (vat_main_t * vam)
8114{
8115 unformat_input_t *i = vam->input;
8116 vl_api_control_ping_t *mp_ping;
8117 vl_api_dhcp_proxy_dump_t *mp;
8118 u8 is_ipv6 = 0;
8119 int ret;
8120
8121 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8122 {
8123 if (unformat (i, "ipv6"))
8124 is_ipv6 = 1;
8125 else
8126 {
8127 clib_warning ("parse error '%U'", format_unformat_error, i);
8128 return -99;
8129 }
Damjan Marion7cd468a2016-12-19 23:05:39 +01008130 }
8131
Neale Ranns20a175a2017-02-14 07:28:41 -08008132 M (DHCP_PROXY_DUMP, mp);
8133
8134 mp->is_ip6 = is_ipv6;
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008135 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008136
Neale Ranns20a175a2017-02-14 07:28:41 -08008137 /* Use a control ping for synchronization */
8138 M (CONTROL_PING, mp_ping);
8139 S (mp_ping);
8140
Jon Loeliger56c7b012017-02-01 12:31:41 -06008141 W (ret);
8142 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008143}
8144
8145static int
8146api_dhcp_proxy_set_vss (vat_main_t * vam)
8147{
8148 unformat_input_t *i = vam->input;
8149 vl_api_dhcp_proxy_set_vss_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008150 u8 is_ipv6 = 0;
8151 u8 is_add = 1;
8152 u32 tbl_id;
8153 u8 tbl_id_set = 0;
8154 u32 oui;
8155 u8 oui_set = 0;
8156 u32 fib_id;
8157 u8 fib_id_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008158 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008159
8160 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8161 {
8162 if (unformat (i, "tbl_id %d", &tbl_id))
8163 tbl_id_set = 1;
8164 if (unformat (i, "fib_id %d", &fib_id))
8165 fib_id_set = 1;
8166 if (unformat (i, "oui %d", &oui))
8167 oui_set = 1;
8168 else if (unformat (i, "ipv6"))
8169 is_ipv6 = 1;
8170 else if (unformat (i, "del"))
8171 is_add = 0;
8172 else
8173 {
8174 clib_warning ("parse error '%U'", format_unformat_error, i);
8175 return -99;
8176 }
8177 }
8178
8179 if (tbl_id_set == 0)
8180 {
8181 errmsg ("missing tbl id");
8182 return -99;
8183 }
8184
8185 if (fib_id_set == 0)
8186 {
8187 errmsg ("missing fib id");
8188 return -99;
8189 }
8190 if (oui_set == 0)
8191 {
8192 errmsg ("missing oui");
8193 return -99;
8194 }
8195
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008196 M (DHCP_PROXY_SET_VSS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008197 mp->tbl_id = ntohl (tbl_id);
8198 mp->fib_id = ntohl (fib_id);
8199 mp->oui = ntohl (oui);
8200 mp->is_ipv6 = is_ipv6;
8201 mp->is_add = is_add;
8202
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008203 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008204 W (ret);
8205 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008206}
8207
8208static int
8209api_dhcp_client_config (vat_main_t * vam)
8210{
8211 unformat_input_t *i = vam->input;
8212 vl_api_dhcp_client_config_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008213 u32 sw_if_index;
8214 u8 sw_if_index_set = 0;
8215 u8 is_add = 1;
8216 u8 *hostname = 0;
8217 u8 disable_event = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008218 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008219
8220 /* Parse args required to build the message */
8221 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8222 {
8223 if (unformat (i, "del"))
8224 is_add = 0;
8225 else
8226 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8227 sw_if_index_set = 1;
8228 else if (unformat (i, "sw_if_index %d", &sw_if_index))
8229 sw_if_index_set = 1;
8230 else if (unformat (i, "hostname %s", &hostname))
8231 ;
8232 else if (unformat (i, "disable_event"))
8233 disable_event = 1;
8234 else
8235 break;
8236 }
8237
8238 if (sw_if_index_set == 0)
8239 {
8240 errmsg ("missing interface name or sw_if_index");
8241 return -99;
8242 }
8243
8244 if (vec_len (hostname) > 63)
8245 {
8246 errmsg ("hostname too long");
8247 }
8248 vec_add1 (hostname, 0);
8249
8250 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008251 M (DHCP_CLIENT_CONFIG, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008252
John Lo20e1f2a2017-03-29 13:35:43 -04008253 mp->sw_if_index = htonl (sw_if_index);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008254 clib_memcpy (mp->hostname, hostname, vec_len (hostname));
8255 vec_free (hostname);
8256 mp->is_add = is_add;
8257 mp->want_dhcp_event = disable_event ? 0 : 1;
John Lo20e1f2a2017-03-29 13:35:43 -04008258 mp->pid = htonl (getpid ());
Damjan Marion7cd468a2016-12-19 23:05:39 +01008259
8260 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008261 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008262
8263 /* Wait for a reply, return good/bad news */
Jon Loeliger56c7b012017-02-01 12:31:41 -06008264 W (ret);
8265 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008266}
8267
8268static int
8269api_set_ip_flow_hash (vat_main_t * vam)
8270{
8271 unformat_input_t *i = vam->input;
8272 vl_api_set_ip_flow_hash_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008273 u32 vrf_id = 0;
8274 u8 is_ipv6 = 0;
8275 u8 vrf_id_set = 0;
8276 u8 src = 0;
8277 u8 dst = 0;
8278 u8 sport = 0;
8279 u8 dport = 0;
8280 u8 proto = 0;
8281 u8 reverse = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008282 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008283
8284 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8285 {
8286 if (unformat (i, "vrf %d", &vrf_id))
8287 vrf_id_set = 1;
8288 else if (unformat (i, "ipv6"))
8289 is_ipv6 = 1;
8290 else if (unformat (i, "src"))
8291 src = 1;
8292 else if (unformat (i, "dst"))
8293 dst = 1;
8294 else if (unformat (i, "sport"))
8295 sport = 1;
8296 else if (unformat (i, "dport"))
8297 dport = 1;
8298 else if (unformat (i, "proto"))
8299 proto = 1;
8300 else if (unformat (i, "reverse"))
8301 reverse = 1;
8302
8303 else
8304 {
8305 clib_warning ("parse error '%U'", format_unformat_error, i);
8306 return -99;
8307 }
8308 }
8309
8310 if (vrf_id_set == 0)
8311 {
8312 errmsg ("missing vrf id");
8313 return -99;
8314 }
8315
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008316 M (SET_IP_FLOW_HASH, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008317 mp->src = src;
8318 mp->dst = dst;
8319 mp->sport = sport;
8320 mp->dport = dport;
8321 mp->proto = proto;
8322 mp->reverse = reverse;
8323 mp->vrf_id = ntohl (vrf_id);
8324 mp->is_ipv6 = is_ipv6;
8325
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008326 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008327 W (ret);
8328 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008329}
8330
8331static int
8332api_sw_interface_ip6_enable_disable (vat_main_t * vam)
8333{
8334 unformat_input_t *i = vam->input;
8335 vl_api_sw_interface_ip6_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008336 u32 sw_if_index;
8337 u8 sw_if_index_set = 0;
8338 u8 enable = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008339 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008340
8341 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8342 {
8343 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8344 sw_if_index_set = 1;
8345 else if (unformat (i, "sw_if_index %d", &sw_if_index))
8346 sw_if_index_set = 1;
8347 else if (unformat (i, "enable"))
8348 enable = 1;
8349 else if (unformat (i, "disable"))
8350 enable = 0;
8351 else
8352 {
8353 clib_warning ("parse error '%U'", format_unformat_error, i);
8354 return -99;
8355 }
8356 }
8357
8358 if (sw_if_index_set == 0)
8359 {
8360 errmsg ("missing interface name or sw_if_index");
8361 return -99;
8362 }
8363
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008364 M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008365
8366 mp->sw_if_index = ntohl (sw_if_index);
8367 mp->enable = enable;
8368
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008369 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008370 W (ret);
8371 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008372}
8373
8374static int
8375api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
8376{
8377 unformat_input_t *i = vam->input;
8378 vl_api_sw_interface_ip6_set_link_local_address_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008379 u32 sw_if_index;
8380 u8 sw_if_index_set = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008381 u8 v6_address_set = 0;
8382 ip6_address_t v6address;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008383 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008384
8385 /* Parse args required to build the message */
8386 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8387 {
8388 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8389 sw_if_index_set = 1;
8390 else if (unformat (i, "sw_if_index %d", &sw_if_index))
8391 sw_if_index_set = 1;
Neale Ranns75152282017-01-09 01:00:45 -08008392 else if (unformat (i, "%U", unformat_ip6_address, &v6address))
Damjan Marion7cd468a2016-12-19 23:05:39 +01008393 v6_address_set = 1;
8394 else
8395 break;
8396 }
8397
8398 if (sw_if_index_set == 0)
8399 {
8400 errmsg ("missing interface name or sw_if_index");
8401 return -99;
8402 }
8403 if (!v6_address_set)
8404 {
8405 errmsg ("no address set");
8406 return -99;
8407 }
8408
8409 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008410 M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008411
8412 mp->sw_if_index = ntohl (sw_if_index);
8413 clib_memcpy (mp->address, &v6address, sizeof (v6address));
Damjan Marion7cd468a2016-12-19 23:05:39 +01008414
8415 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008416 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008417
8418 /* Wait for a reply, return good/bad news */
Jon Loeliger56c7b012017-02-01 12:31:41 -06008419 W (ret);
8420 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008421}
8422
Neale Ranns3f844d02017-02-18 00:03:54 -08008423static int
8424api_ip6nd_proxy_add_del (vat_main_t * vam)
8425{
8426 unformat_input_t *i = vam->input;
8427 vl_api_ip6nd_proxy_add_del_t *mp;
8428 u32 sw_if_index = ~0;
8429 u8 v6_address_set = 0;
8430 ip6_address_t v6address;
8431 u8 is_del = 0;
8432 int ret;
8433
8434 /* Parse args required to build the message */
8435 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8436 {
8437 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8438 ;
8439 else if (unformat (i, "sw_if_index %d", &sw_if_index))
8440 ;
8441 else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8442 v6_address_set = 1;
8443 if (unformat (i, "del"))
8444 is_del = 1;
8445 else
8446 {
8447 clib_warning ("parse error '%U'", format_unformat_error, i);
8448 return -99;
8449 }
8450 }
8451
8452 if (sw_if_index == ~0)
8453 {
8454 errmsg ("missing interface name or sw_if_index");
8455 return -99;
8456 }
8457 if (!v6_address_set)
8458 {
8459 errmsg ("no address set");
8460 return -99;
8461 }
8462
8463 /* Construct the API message */
8464 M (IP6ND_PROXY_ADD_DEL, mp);
8465
8466 mp->is_del = is_del;
8467 mp->sw_if_index = ntohl (sw_if_index);
8468 clib_memcpy (mp->address, &v6address, sizeof (v6address));
8469
8470 /* send it... */
8471 S (mp);
8472
8473 /* Wait for a reply, return good/bad news */
8474 W (ret);
8475 return ret;
8476}
8477
8478static int
8479api_ip6nd_proxy_dump (vat_main_t * vam)
8480{
8481 vl_api_ip6nd_proxy_dump_t *mp;
8482 vl_api_control_ping_t *mp_ping;
8483 int ret;
8484
8485 M (IP6ND_PROXY_DUMP, mp);
8486
8487 S (mp);
8488
8489 /* Use a control ping for synchronization */
8490 M (CONTROL_PING, mp_ping);
8491 S (mp_ping);
8492
8493 W (ret);
8494 return ret;
8495}
8496
8497static void vl_api_ip6nd_proxy_details_t_handler
8498 (vl_api_ip6nd_proxy_details_t * mp)
8499{
8500 vat_main_t *vam = &vat_main;
8501
8502 print (vam->ofp, "host %U sw_if_index %d",
8503 format_ip6_address, mp->address, ntohl (mp->sw_if_index));
8504}
8505
8506static void vl_api_ip6nd_proxy_details_t_handler_json
8507 (vl_api_ip6nd_proxy_details_t * mp)
8508{
8509 vat_main_t *vam = &vat_main;
8510 struct in6_addr ip6;
8511 vat_json_node_t *node = NULL;
8512
8513 if (VAT_JSON_ARRAY != vam->json_tree.type)
8514 {
8515 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
8516 vat_json_init_array (&vam->json_tree);
8517 }
8518 node = vat_json_array_add (&vam->json_tree);
8519
8520 vat_json_init_object (node);
8521 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
8522
8523 clib_memcpy (&ip6, mp->address, sizeof (ip6));
8524 vat_json_object_add_ip6 (node, "host", ip6);
8525}
Damjan Marion7cd468a2016-12-19 23:05:39 +01008526
8527static int
8528api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
8529{
8530 unformat_input_t *i = vam->input;
8531 vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008532 u32 sw_if_index;
8533 u8 sw_if_index_set = 0;
8534 u32 address_length = 0;
8535 u8 v6_address_set = 0;
8536 ip6_address_t v6address;
8537 u8 use_default = 0;
8538 u8 no_advertise = 0;
8539 u8 off_link = 0;
8540 u8 no_autoconfig = 0;
8541 u8 no_onlink = 0;
8542 u8 is_no = 0;
8543 u32 val_lifetime = 0;
8544 u32 pref_lifetime = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008545 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008546
8547 /* Parse args required to build the message */
8548 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8549 {
8550 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8551 sw_if_index_set = 1;
8552 else if (unformat (i, "sw_if_index %d", &sw_if_index))
8553 sw_if_index_set = 1;
8554 else if (unformat (i, "%U/%d",
8555 unformat_ip6_address, &v6address, &address_length))
8556 v6_address_set = 1;
8557 else if (unformat (i, "val_life %d", &val_lifetime))
8558 ;
8559 else if (unformat (i, "pref_life %d", &pref_lifetime))
8560 ;
8561 else if (unformat (i, "def"))
8562 use_default = 1;
8563 else if (unformat (i, "noadv"))
8564 no_advertise = 1;
8565 else if (unformat (i, "offl"))
8566 off_link = 1;
8567 else if (unformat (i, "noauto"))
8568 no_autoconfig = 1;
8569 else if (unformat (i, "nolink"))
8570 no_onlink = 1;
8571 else if (unformat (i, "isno"))
8572 is_no = 1;
8573 else
8574 {
8575 clib_warning ("parse error '%U'", format_unformat_error, i);
8576 return -99;
8577 }
8578 }
8579
8580 if (sw_if_index_set == 0)
8581 {
8582 errmsg ("missing interface name or sw_if_index");
8583 return -99;
8584 }
8585 if (!v6_address_set)
8586 {
8587 errmsg ("no address set");
8588 return -99;
8589 }
8590
8591 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008592 M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008593
8594 mp->sw_if_index = ntohl (sw_if_index);
8595 clib_memcpy (mp->address, &v6address, sizeof (v6address));
8596 mp->address_length = address_length;
8597 mp->use_default = use_default;
8598 mp->no_advertise = no_advertise;
8599 mp->off_link = off_link;
8600 mp->no_autoconfig = no_autoconfig;
8601 mp->no_onlink = no_onlink;
8602 mp->is_no = is_no;
8603 mp->val_lifetime = ntohl (val_lifetime);
8604 mp->pref_lifetime = ntohl (pref_lifetime);
8605
8606 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008607 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008608
8609 /* Wait for a reply, return good/bad news */
Jon Loeliger56c7b012017-02-01 12:31:41 -06008610 W (ret);
8611 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008612}
8613
8614static int
8615api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
8616{
8617 unformat_input_t *i = vam->input;
8618 vl_api_sw_interface_ip6nd_ra_config_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008619 u32 sw_if_index;
8620 u8 sw_if_index_set = 0;
8621 u8 suppress = 0;
8622 u8 managed = 0;
8623 u8 other = 0;
8624 u8 ll_option = 0;
8625 u8 send_unicast = 0;
8626 u8 cease = 0;
8627 u8 is_no = 0;
8628 u8 default_router = 0;
8629 u32 max_interval = 0;
8630 u32 min_interval = 0;
8631 u32 lifetime = 0;
8632 u32 initial_count = 0;
8633 u32 initial_interval = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008634 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008635
8636
8637 /* Parse args required to build the message */
8638 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8639 {
8640 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8641 sw_if_index_set = 1;
8642 else if (unformat (i, "sw_if_index %d", &sw_if_index))
8643 sw_if_index_set = 1;
8644 else if (unformat (i, "maxint %d", &max_interval))
8645 ;
8646 else if (unformat (i, "minint %d", &min_interval))
8647 ;
8648 else if (unformat (i, "life %d", &lifetime))
8649 ;
8650 else if (unformat (i, "count %d", &initial_count))
8651 ;
8652 else if (unformat (i, "interval %d", &initial_interval))
8653 ;
8654 else if (unformat (i, "suppress") || unformat (i, "surpress"))
8655 suppress = 1;
8656 else if (unformat (i, "managed"))
8657 managed = 1;
8658 else if (unformat (i, "other"))
8659 other = 1;
8660 else if (unformat (i, "ll"))
8661 ll_option = 1;
8662 else if (unformat (i, "send"))
8663 send_unicast = 1;
8664 else if (unformat (i, "cease"))
8665 cease = 1;
8666 else if (unformat (i, "isno"))
8667 is_no = 1;
8668 else if (unformat (i, "def"))
8669 default_router = 1;
8670 else
8671 {
8672 clib_warning ("parse error '%U'", format_unformat_error, i);
8673 return -99;
8674 }
8675 }
8676
8677 if (sw_if_index_set == 0)
8678 {
8679 errmsg ("missing interface name or sw_if_index");
8680 return -99;
8681 }
8682
8683 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008684 M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008685
8686 mp->sw_if_index = ntohl (sw_if_index);
8687 mp->max_interval = ntohl (max_interval);
8688 mp->min_interval = ntohl (min_interval);
8689 mp->lifetime = ntohl (lifetime);
8690 mp->initial_count = ntohl (initial_count);
8691 mp->initial_interval = ntohl (initial_interval);
8692 mp->suppress = suppress;
8693 mp->managed = managed;
8694 mp->other = other;
8695 mp->ll_option = ll_option;
8696 mp->send_unicast = send_unicast;
8697 mp->cease = cease;
8698 mp->is_no = is_no;
8699 mp->default_router = default_router;
8700
8701 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008702 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008703
8704 /* Wait for a reply, return good/bad news */
Jon Loeliger56c7b012017-02-01 12:31:41 -06008705 W (ret);
8706 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008707}
8708
8709static int
8710api_set_arp_neighbor_limit (vat_main_t * vam)
8711{
8712 unformat_input_t *i = vam->input;
8713 vl_api_set_arp_neighbor_limit_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008714 u32 arp_nbr_limit;
8715 u8 limit_set = 0;
8716 u8 is_ipv6 = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008717 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008718
8719 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8720 {
8721 if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
8722 limit_set = 1;
8723 else if (unformat (i, "ipv6"))
8724 is_ipv6 = 1;
8725 else
8726 {
8727 clib_warning ("parse error '%U'", format_unformat_error, i);
8728 return -99;
8729 }
8730 }
8731
8732 if (limit_set == 0)
8733 {
8734 errmsg ("missing limit value");
8735 return -99;
8736 }
8737
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008738 M (SET_ARP_NEIGHBOR_LIMIT, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008739
8740 mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
8741 mp->is_ipv6 = is_ipv6;
8742
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008743 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008744 W (ret);
8745 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008746}
8747
8748static int
8749api_l2_patch_add_del (vat_main_t * vam)
8750{
8751 unformat_input_t *i = vam->input;
8752 vl_api_l2_patch_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008753 u32 rx_sw_if_index;
8754 u8 rx_sw_if_index_set = 0;
8755 u32 tx_sw_if_index;
8756 u8 tx_sw_if_index_set = 0;
8757 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008758 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008759
8760 /* Parse args required to build the message */
8761 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8762 {
8763 if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
8764 rx_sw_if_index_set = 1;
8765 else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
8766 tx_sw_if_index_set = 1;
8767 else if (unformat (i, "rx"))
8768 {
8769 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8770 {
8771 if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8772 &rx_sw_if_index))
8773 rx_sw_if_index_set = 1;
8774 }
8775 else
8776 break;
8777 }
8778 else if (unformat (i, "tx"))
8779 {
8780 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8781 {
8782 if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8783 &tx_sw_if_index))
8784 tx_sw_if_index_set = 1;
8785 }
8786 else
8787 break;
8788 }
8789 else if (unformat (i, "del"))
8790 is_add = 0;
8791 else
8792 break;
8793 }
8794
8795 if (rx_sw_if_index_set == 0)
8796 {
8797 errmsg ("missing rx interface name or rx_sw_if_index");
8798 return -99;
8799 }
8800
8801 if (tx_sw_if_index_set == 0)
8802 {
8803 errmsg ("missing tx interface name or tx_sw_if_index");
8804 return -99;
8805 }
8806
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008807 M (L2_PATCH_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008808
8809 mp->rx_sw_if_index = ntohl (rx_sw_if_index);
8810 mp->tx_sw_if_index = ntohl (tx_sw_if_index);
8811 mp->is_add = is_add;
8812
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008813 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008814 W (ret);
8815 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008816}
8817
Pablo Camarillofb380952016-12-07 18:34:18 +01008818u8 is_del;
8819u8 localsid_addr[16];
8820u8 end_psp;
8821u8 behavior;
8822u32 sw_if_index;
8823u32 vlan_index;
8824u32 fib_table;
8825u8 nh_addr[16];
8826
8827static int
8828api_sr_localsid_add_del (vat_main_t * vam)
8829{
8830 unformat_input_t *i = vam->input;
8831 vl_api_sr_localsid_add_del_t *mp;
8832
8833 u8 is_del;
8834 ip6_address_t localsid;
8835 u8 end_psp = 0;
8836 u8 behavior = ~0;
8837 u32 sw_if_index;
8838 u32 fib_table = ~(u32) 0;
8839 ip6_address_t next_hop;
8840
8841 bool nexthop_set = 0;
8842
8843 int ret;
8844
8845 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8846 {
8847 if (unformat (i, "del"))
8848 is_del = 1;
8849 else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
8850 else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
8851 nexthop_set = 1;
8852 else if (unformat (i, "behavior %u", &behavior));
8853 else if (unformat (i, "sw_if_index %u", &sw_if_index));
8854 else if (unformat (i, "fib-table %u", &fib_table));
8855 else if (unformat (i, "end.psp %u", &behavior));
8856 else
8857 break;
8858 }
8859
8860 M (SR_LOCALSID_ADD_DEL, mp);
8861
8862 clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
8863 if (nexthop_set)
8864 clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
8865 mp->behavior = behavior;
8866 mp->sw_if_index = ntohl (sw_if_index);
8867 mp->fib_table = ntohl (fib_table);
8868 mp->end_psp = end_psp;
8869 mp->is_del = is_del;
8870
8871 S (mp);
8872 W (ret);
8873 return ret;
8874}
8875
Damjan Marion7cd468a2016-12-19 23:05:39 +01008876static int
8877api_ioam_enable (vat_main_t * vam)
8878{
8879 unformat_input_t *input = vam->input;
8880 vl_api_ioam_enable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008881 u32 id = 0;
8882 int has_trace_option = 0;
8883 int has_pot_option = 0;
8884 int has_seqno_option = 0;
8885 int has_analyse_option = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008886 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008887
8888 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8889 {
8890 if (unformat (input, "trace"))
8891 has_trace_option = 1;
8892 else if (unformat (input, "pot"))
8893 has_pot_option = 1;
8894 else if (unformat (input, "seqno"))
8895 has_seqno_option = 1;
8896 else if (unformat (input, "analyse"))
8897 has_analyse_option = 1;
8898 else
8899 break;
8900 }
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008901 M (IOAM_ENABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008902 mp->id = htons (id);
8903 mp->seqno = has_seqno_option;
8904 mp->analyse = has_analyse_option;
8905 mp->pot_enable = has_pot_option;
8906 mp->trace_enable = has_trace_option;
8907
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008908 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008909 W (ret);
8910 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008911}
8912
8913
8914static int
8915api_ioam_disable (vat_main_t * vam)
8916{
8917 vl_api_ioam_disable_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008918 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008919
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008920 M (IOAM_DISABLE, mp);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008921 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008922 W (ret);
8923 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008924}
8925
Damjan Marion7cd468a2016-12-19 23:05:39 +01008926#define foreach_tcp_proto_field \
8927_(src_port) \
8928_(dst_port)
8929
8930#define foreach_udp_proto_field \
8931_(src_port) \
8932_(dst_port)
8933
8934#define foreach_ip4_proto_field \
8935_(src_address) \
8936_(dst_address) \
8937_(tos) \
8938_(length) \
8939_(fragment_id) \
8940_(ttl) \
8941_(protocol) \
8942_(checksum)
8943
Dave Barach4a3f69c2017-02-22 12:44:56 -05008944typedef struct
8945{
8946 u16 src_port, dst_port;
8947} tcpudp_header_t;
8948
8949#if VPP_API_TEST_BUILTIN == 0
Damjan Marion7cd468a2016-12-19 23:05:39 +01008950uword
8951unformat_tcp_mask (unformat_input_t * input, va_list * args)
8952{
8953 u8 **maskp = va_arg (*args, u8 **);
8954 u8 *mask = 0;
8955 u8 found_something = 0;
8956 tcp_header_t *tcp;
8957
8958#define _(a) u8 a=0;
8959 foreach_tcp_proto_field;
8960#undef _
8961
8962 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8963 {
8964 if (0);
8965#define _(a) else if (unformat (input, #a)) a=1;
8966 foreach_tcp_proto_field
8967#undef _
8968 else
8969 break;
8970 }
8971
8972#define _(a) found_something += a;
8973 foreach_tcp_proto_field;
8974#undef _
8975
8976 if (found_something == 0)
8977 return 0;
8978
8979 vec_validate (mask, sizeof (*tcp) - 1);
8980
8981 tcp = (tcp_header_t *) mask;
8982
8983#define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8984 foreach_tcp_proto_field;
8985#undef _
8986
8987 *maskp = mask;
8988 return 1;
8989}
8990
8991uword
8992unformat_udp_mask (unformat_input_t * input, va_list * args)
8993{
8994 u8 **maskp = va_arg (*args, u8 **);
8995 u8 *mask = 0;
8996 u8 found_something = 0;
8997 udp_header_t *udp;
8998
8999#define _(a) u8 a=0;
9000 foreach_udp_proto_field;
9001#undef _
9002
9003 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9004 {
9005 if (0);
9006#define _(a) else if (unformat (input, #a)) a=1;
9007 foreach_udp_proto_field
9008#undef _
9009 else
9010 break;
9011 }
9012
9013#define _(a) found_something += a;
9014 foreach_udp_proto_field;
9015#undef _
9016
9017 if (found_something == 0)
9018 return 0;
9019
9020 vec_validate (mask, sizeof (*udp) - 1);
9021
9022 udp = (udp_header_t *) mask;
9023
9024#define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
9025 foreach_udp_proto_field;
9026#undef _
9027
9028 *maskp = mask;
9029 return 1;
9030}
9031
Damjan Marion7cd468a2016-12-19 23:05:39 +01009032uword
9033unformat_l4_mask (unformat_input_t * input, va_list * args)
9034{
9035 u8 **maskp = va_arg (*args, u8 **);
9036 u16 src_port = 0, dst_port = 0;
9037 tcpudp_header_t *tcpudp;
9038
9039 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9040 {
9041 if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
9042 return 1;
9043 else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
9044 return 1;
9045 else if (unformat (input, "src_port"))
9046 src_port = 0xFFFF;
9047 else if (unformat (input, "dst_port"))
9048 dst_port = 0xFFFF;
9049 else
9050 return 0;
9051 }
9052
9053 if (!src_port && !dst_port)
9054 return 0;
9055
9056 u8 *mask = 0;
9057 vec_validate (mask, sizeof (tcpudp_header_t) - 1);
9058
9059 tcpudp = (tcpudp_header_t *) mask;
9060 tcpudp->src_port = src_port;
9061 tcpudp->dst_port = dst_port;
9062
9063 *maskp = mask;
9064
9065 return 1;
9066}
9067
9068uword
9069unformat_ip4_mask (unformat_input_t * input, va_list * args)
9070{
9071 u8 **maskp = va_arg (*args, u8 **);
9072 u8 *mask = 0;
9073 u8 found_something = 0;
9074 ip4_header_t *ip;
9075
9076#define _(a) u8 a=0;
9077 foreach_ip4_proto_field;
9078#undef _
9079 u8 version = 0;
9080 u8 hdr_length = 0;
9081
9082
9083 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9084 {
9085 if (unformat (input, "version"))
9086 version = 1;
9087 else if (unformat (input, "hdr_length"))
9088 hdr_length = 1;
9089 else if (unformat (input, "src"))
9090 src_address = 1;
9091 else if (unformat (input, "dst"))
9092 dst_address = 1;
9093 else if (unformat (input, "proto"))
9094 protocol = 1;
9095
9096#define _(a) else if (unformat (input, #a)) a=1;
9097 foreach_ip4_proto_field
9098#undef _
9099 else
9100 break;
9101 }
9102
9103#define _(a) found_something += a;
9104 foreach_ip4_proto_field;
9105#undef _
9106
9107 if (found_something == 0)
9108 return 0;
9109
9110 vec_validate (mask, sizeof (*ip) - 1);
9111
9112 ip = (ip4_header_t *) mask;
9113
9114#define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
9115 foreach_ip4_proto_field;
9116#undef _
9117
9118 ip->ip_version_and_header_length = 0;
9119
9120 if (version)
9121 ip->ip_version_and_header_length |= 0xF0;
9122
9123 if (hdr_length)
9124 ip->ip_version_and_header_length |= 0x0F;
9125
9126 *maskp = mask;
9127 return 1;
9128}
9129
9130#define foreach_ip6_proto_field \
9131_(src_address) \
9132_(dst_address) \
9133_(payload_length) \
9134_(hop_limit) \
9135_(protocol)
9136
9137uword
9138unformat_ip6_mask (unformat_input_t * input, va_list * args)
9139{
9140 u8 **maskp = va_arg (*args, u8 **);
9141 u8 *mask = 0;
9142 u8 found_something = 0;
9143 ip6_header_t *ip;
9144 u32 ip_version_traffic_class_and_flow_label;
9145
9146#define _(a) u8 a=0;
9147 foreach_ip6_proto_field;
9148#undef _
9149 u8 version = 0;
9150 u8 traffic_class = 0;
9151 u8 flow_label = 0;
9152
9153 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9154 {
9155 if (unformat (input, "version"))
9156 version = 1;
9157 else if (unformat (input, "traffic-class"))
9158 traffic_class = 1;
9159 else if (unformat (input, "flow-label"))
9160 flow_label = 1;
9161 else if (unformat (input, "src"))
9162 src_address = 1;
9163 else if (unformat (input, "dst"))
9164 dst_address = 1;
9165 else if (unformat (input, "proto"))
9166 protocol = 1;
9167
9168#define _(a) else if (unformat (input, #a)) a=1;
9169 foreach_ip6_proto_field
9170#undef _
9171 else
9172 break;
9173 }
9174
9175#define _(a) found_something += a;
9176 foreach_ip6_proto_field;
9177#undef _
9178
9179 if (found_something == 0)
9180 return 0;
9181
9182 vec_validate (mask, sizeof (*ip) - 1);
9183
9184 ip = (ip6_header_t *) mask;
9185
9186#define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
9187 foreach_ip6_proto_field;
9188#undef _
9189
9190 ip_version_traffic_class_and_flow_label = 0;
9191
9192 if (version)
9193 ip_version_traffic_class_and_flow_label |= 0xF0000000;
9194
9195 if (traffic_class)
9196 ip_version_traffic_class_and_flow_label |= 0x0FF00000;
9197
9198 if (flow_label)
9199 ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
9200
9201 ip->ip_version_traffic_class_and_flow_label =
9202 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9203
9204 *maskp = mask;
9205 return 1;
9206}
9207
9208uword
9209unformat_l3_mask (unformat_input_t * input, va_list * args)
9210{
9211 u8 **maskp = va_arg (*args, u8 **);
9212
9213 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9214 {
9215 if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
9216 return 1;
9217 else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
9218 return 1;
9219 else
9220 break;
9221 }
9222 return 0;
9223}
9224
9225uword
9226unformat_l2_mask (unformat_input_t * input, va_list * args)
9227{
9228 u8 **maskp = va_arg (*args, u8 **);
9229 u8 *mask = 0;
9230 u8 src = 0;
9231 u8 dst = 0;
9232 u8 proto = 0;
9233 u8 tag1 = 0;
9234 u8 tag2 = 0;
9235 u8 ignore_tag1 = 0;
9236 u8 ignore_tag2 = 0;
9237 u8 cos1 = 0;
9238 u8 cos2 = 0;
9239 u8 dot1q = 0;
9240 u8 dot1ad = 0;
9241 int len = 14;
9242
9243 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9244 {
9245 if (unformat (input, "src"))
9246 src = 1;
9247 else if (unformat (input, "dst"))
9248 dst = 1;
9249 else if (unformat (input, "proto"))
9250 proto = 1;
9251 else if (unformat (input, "tag1"))
9252 tag1 = 1;
9253 else if (unformat (input, "tag2"))
9254 tag2 = 1;
9255 else if (unformat (input, "ignore-tag1"))
9256 ignore_tag1 = 1;
9257 else if (unformat (input, "ignore-tag2"))
9258 ignore_tag2 = 1;
9259 else if (unformat (input, "cos1"))
9260 cos1 = 1;
9261 else if (unformat (input, "cos2"))
9262 cos2 = 1;
9263 else if (unformat (input, "dot1q"))
9264 dot1q = 1;
9265 else if (unformat (input, "dot1ad"))
9266 dot1ad = 1;
9267 else
9268 break;
9269 }
9270 if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9271 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9272 return 0;
9273
9274 if (tag1 || ignore_tag1 || cos1 || dot1q)
9275 len = 18;
9276 if (tag2 || ignore_tag2 || cos2 || dot1ad)
9277 len = 22;
9278
9279 vec_validate (mask, len - 1);
9280
9281 if (dst)
9282 memset (mask, 0xff, 6);
9283
9284 if (src)
9285 memset (mask + 6, 0xff, 6);
9286
9287 if (tag2 || dot1ad)
9288 {
9289 /* inner vlan tag */
9290 if (tag2)
9291 {
9292 mask[19] = 0xff;
9293 mask[18] = 0x0f;
9294 }
9295 if (cos2)
9296 mask[18] |= 0xe0;
9297 if (proto)
9298 mask[21] = mask[20] = 0xff;
9299 if (tag1)
9300 {
9301 mask[15] = 0xff;
9302 mask[14] = 0x0f;
9303 }
9304 if (cos1)
9305 mask[14] |= 0xe0;
9306 *maskp = mask;
9307 return 1;
9308 }
9309 if (tag1 | dot1q)
9310 {
9311 if (tag1)
9312 {
9313 mask[15] = 0xff;
9314 mask[14] = 0x0f;
9315 }
9316 if (cos1)
9317 mask[14] |= 0xe0;
9318 if (proto)
9319 mask[16] = mask[17] = 0xff;
9320
9321 *maskp = mask;
9322 return 1;
9323 }
9324 if (cos2)
9325 mask[18] |= 0xe0;
9326 if (cos1)
9327 mask[14] |= 0xe0;
9328 if (proto)
9329 mask[12] = mask[13] = 0xff;
9330
9331 *maskp = mask;
9332 return 1;
9333}
9334
9335uword
9336unformat_classify_mask (unformat_input_t * input, va_list * args)
9337{
9338 u8 **maskp = va_arg (*args, u8 **);
9339 u32 *skipp = va_arg (*args, u32 *);
9340 u32 *matchp = va_arg (*args, u32 *);
9341 u32 match;
9342 u8 *mask = 0;
9343 u8 *l2 = 0;
9344 u8 *l3 = 0;
9345 u8 *l4 = 0;
9346 int i;
9347
9348 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9349 {
9350 if (unformat (input, "hex %U", unformat_hex_string, &mask))
9351 ;
9352 else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
9353 ;
9354 else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
9355 ;
9356 else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
9357 ;
9358 else
9359 break;
9360 }
9361
9362 if (l4 && !l3)
9363 {
9364 vec_free (mask);
9365 vec_free (l2);
9366 vec_free (l4);
9367 return 0;
9368 }
9369
9370 if (mask || l2 || l3 || l4)
9371 {
9372 if (l2 || l3 || l4)
9373 {
9374 /* "With a free Ethernet header in every package" */
9375 if (l2 == 0)
9376 vec_validate (l2, 13);
9377 mask = l2;
9378 if (vec_len (l3))
9379 {
9380 vec_append (mask, l3);
9381 vec_free (l3);
9382 }
9383 if (vec_len (l4))
9384 {
9385 vec_append (mask, l4);
9386 vec_free (l4);
9387 }
9388 }
9389
9390 /* Scan forward looking for the first significant mask octet */
9391 for (i = 0; i < vec_len (mask); i++)
9392 if (mask[i])
9393 break;
9394
9395 /* compute (skip, match) params */
9396 *skipp = i / sizeof (u32x4);
9397 vec_delete (mask, *skipp * sizeof (u32x4), 0);
9398
9399 /* Pad mask to an even multiple of the vector size */
9400 while (vec_len (mask) % sizeof (u32x4))
9401 vec_add1 (mask, 0);
9402
9403 match = vec_len (mask) / sizeof (u32x4);
9404
9405 for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9406 {
9407 u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9408 if (*tmp || *(tmp + 1))
9409 break;
9410 match--;
9411 }
9412 if (match == 0)
9413 clib_warning ("BUG: match 0");
9414
9415 _vec_len (mask) = match * sizeof (u32x4);
9416
9417 *matchp = match;
9418 *maskp = mask;
9419
9420 return 1;
9421 }
9422
9423 return 0;
9424}
Dave Barach4a3f69c2017-02-22 12:44:56 -05009425#endif /* VPP_API_TEST_BUILTIN */
Damjan Marion7cd468a2016-12-19 23:05:39 +01009426
9427#define foreach_l2_next \
9428_(drop, DROP) \
9429_(ethernet, ETHERNET_INPUT) \
9430_(ip4, IP4_INPUT) \
9431_(ip6, IP6_INPUT)
9432
9433uword
9434unformat_l2_next_index (unformat_input_t * input, va_list * args)
9435{
9436 u32 *miss_next_indexp = va_arg (*args, u32 *);
9437 u32 next_index = 0;
9438 u32 tmp;
9439
9440#define _(n,N) \
9441 if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9442 foreach_l2_next;
9443#undef _
9444
9445 if (unformat (input, "%d", &tmp))
9446 {
9447 next_index = tmp;
9448 goto out;
9449 }
9450
9451 return 0;
9452
9453out:
9454 *miss_next_indexp = next_index;
9455 return 1;
9456}
9457
9458#define foreach_ip_next \
9459_(drop, DROP) \
9460_(local, LOCAL) \
9461_(rewrite, REWRITE)
9462
9463uword
Dave Barach4a3f69c2017-02-22 12:44:56 -05009464api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
Damjan Marion7cd468a2016-12-19 23:05:39 +01009465{
9466 u32 *miss_next_indexp = va_arg (*args, u32 *);
9467 u32 next_index = 0;
9468 u32 tmp;
9469
9470#define _(n,N) \
9471 if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9472 foreach_ip_next;
9473#undef _
9474
9475 if (unformat (input, "%d", &tmp))
9476 {
9477 next_index = tmp;
9478 goto out;
9479 }
9480
9481 return 0;
9482
9483out:
9484 *miss_next_indexp = next_index;
9485 return 1;
9486}
9487
9488#define foreach_acl_next \
9489_(deny, DENY)
9490
9491uword
Dave Barach4a3f69c2017-02-22 12:44:56 -05009492api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
Damjan Marion7cd468a2016-12-19 23:05:39 +01009493{
9494 u32 *miss_next_indexp = va_arg (*args, u32 *);
9495 u32 next_index = 0;
9496 u32 tmp;
9497
9498#define _(n,N) \
9499 if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
9500 foreach_acl_next;
9501#undef _
9502
9503 if (unformat (input, "permit"))
9504 {
9505 next_index = ~0;
9506 goto out;
9507 }
9508 else if (unformat (input, "%d", &tmp))
9509 {
9510 next_index = tmp;
9511 goto out;
9512 }
9513
9514 return 0;
9515
9516out:
9517 *miss_next_indexp = next_index;
9518 return 1;
9519}
9520
9521uword
9522unformat_policer_precolor (unformat_input_t * input, va_list * args)
9523{
9524 u32 *r = va_arg (*args, u32 *);
9525
9526 if (unformat (input, "conform-color"))
9527 *r = POLICE_CONFORM;
9528 else if (unformat (input, "exceed-color"))
9529 *r = POLICE_EXCEED;
9530 else
9531 return 0;
9532
9533 return 1;
9534}
9535
9536static int
9537api_classify_add_del_table (vat_main_t * vam)
9538{
9539 unformat_input_t *i = vam->input;
9540 vl_api_classify_add_del_table_t *mp;
9541
9542 u32 nbuckets = 2;
9543 u32 skip = ~0;
9544 u32 match = ~0;
9545 int is_add = 1;
9546 int del_chain = 0;
9547 u32 table_index = ~0;
9548 u32 next_table_index = ~0;
9549 u32 miss_next_index = ~0;
9550 u32 memory_size = 32 << 20;
9551 u8 *mask = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009552 u32 current_data_flag = 0;
9553 int current_data_offset = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009554 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009555
9556 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9557 {
9558 if (unformat (i, "del"))
9559 is_add = 0;
9560 else if (unformat (i, "del-chain"))
9561 {
9562 is_add = 0;
9563 del_chain = 1;
9564 }
9565 else if (unformat (i, "buckets %d", &nbuckets))
9566 ;
9567 else if (unformat (i, "memory_size %d", &memory_size))
9568 ;
9569 else if (unformat (i, "skip %d", &skip))
9570 ;
9571 else if (unformat (i, "match %d", &match))
9572 ;
9573 else if (unformat (i, "table %d", &table_index))
9574 ;
9575 else if (unformat (i, "mask %U", unformat_classify_mask,
9576 &mask, &skip, &match))
9577 ;
9578 else if (unformat (i, "next-table %d", &next_table_index))
9579 ;
Dave Barach4a3f69c2017-02-22 12:44:56 -05009580 else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
Damjan Marion7cd468a2016-12-19 23:05:39 +01009581 &miss_next_index))
9582 ;
9583 else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
9584 &miss_next_index))
9585 ;
Dave Barach4a3f69c2017-02-22 12:44:56 -05009586 else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
Damjan Marion7cd468a2016-12-19 23:05:39 +01009587 &miss_next_index))
9588 ;
9589 else if (unformat (i, "current-data-flag %d", &current_data_flag))
9590 ;
9591 else if (unformat (i, "current-data-offset %d", &current_data_offset))
9592 ;
9593 else
9594 break;
9595 }
9596
9597 if (is_add && mask == 0)
9598 {
9599 errmsg ("Mask required");
9600 return -99;
9601 }
9602
9603 if (is_add && skip == ~0)
9604 {
9605 errmsg ("skip count required");
9606 return -99;
9607 }
9608
9609 if (is_add && match == ~0)
9610 {
9611 errmsg ("match count required");
9612 return -99;
9613 }
9614
9615 if (!is_add && table_index == ~0)
9616 {
9617 errmsg ("table index required for delete");
9618 return -99;
9619 }
9620
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009621 M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
Damjan Marion7cd468a2016-12-19 23:05:39 +01009622
9623 mp->is_add = is_add;
9624 mp->del_chain = del_chain;
9625 mp->table_index = ntohl (table_index);
9626 mp->nbuckets = ntohl (nbuckets);
9627 mp->memory_size = ntohl (memory_size);
9628 mp->skip_n_vectors = ntohl (skip);
9629 mp->match_n_vectors = ntohl (match);
9630 mp->next_table_index = ntohl (next_table_index);
9631 mp->miss_next_index = ntohl (miss_next_index);
9632 mp->current_data_flag = ntohl (current_data_flag);
9633 mp->current_data_offset = ntohl (current_data_offset);
9634 clib_memcpy (mp->mask, mask, vec_len (mask));
9635
9636 vec_free (mask);
9637
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009638 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06009639 W (ret);
9640 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009641}
9642
Dave Barach4a3f69c2017-02-22 12:44:56 -05009643#if VPP_API_TEST_BUILTIN == 0
Damjan Marion7cd468a2016-12-19 23:05:39 +01009644uword
9645unformat_l4_match (unformat_input_t * input, va_list * args)
9646{
9647 u8 **matchp = va_arg (*args, u8 **);
9648
9649 u8 *proto_header = 0;
9650 int src_port = 0;
9651 int dst_port = 0;
9652
9653 tcpudp_header_t h;
9654
9655 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9656 {
9657 if (unformat (input, "src_port %d", &src_port))
9658 ;
9659 else if (unformat (input, "dst_port %d", &dst_port))
9660 ;
9661 else
9662 return 0;
9663 }
9664
9665 h.src_port = clib_host_to_net_u16 (src_port);
9666 h.dst_port = clib_host_to_net_u16 (dst_port);
9667 vec_validate (proto_header, sizeof (h) - 1);
9668 memcpy (proto_header, &h, sizeof (h));
9669
9670 *matchp = proto_header;
9671
9672 return 1;
9673}
9674
9675uword
9676unformat_ip4_match (unformat_input_t * input, va_list * args)
9677{
9678 u8 **matchp = va_arg (*args, u8 **);
9679 u8 *match = 0;
9680 ip4_header_t *ip;
9681 int version = 0;
9682 u32 version_val;
9683 int hdr_length = 0;
9684 u32 hdr_length_val;
9685 int src = 0, dst = 0;
9686 ip4_address_t src_val, dst_val;
9687 int proto = 0;
9688 u32 proto_val;
9689 int tos = 0;
9690 u32 tos_val;
9691 int length = 0;
9692 u32 length_val;
9693 int fragment_id = 0;
9694 u32 fragment_id_val;
9695 int ttl = 0;
9696 int ttl_val;
9697 int checksum = 0;
9698 u32 checksum_val;
9699
9700 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9701 {
9702 if (unformat (input, "version %d", &version_val))
9703 version = 1;
9704 else if (unformat (input, "hdr_length %d", &hdr_length_val))
9705 hdr_length = 1;
9706 else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
9707 src = 1;
9708 else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
9709 dst = 1;
9710 else if (unformat (input, "proto %d", &proto_val))
9711 proto = 1;
9712 else if (unformat (input, "tos %d", &tos_val))
9713 tos = 1;
9714 else if (unformat (input, "length %d", &length_val))
9715 length = 1;
9716 else if (unformat (input, "fragment_id %d", &fragment_id_val))
9717 fragment_id = 1;
9718 else if (unformat (input, "ttl %d", &ttl_val))
9719 ttl = 1;
9720 else if (unformat (input, "checksum %d", &checksum_val))
9721 checksum = 1;
9722 else
9723 break;
9724 }
9725
9726 if (version + hdr_length + src + dst + proto + tos + length + fragment_id
9727 + ttl + checksum == 0)
9728 return 0;
9729
9730 /*
9731 * Aligned because we use the real comparison functions
9732 */
9733 vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9734
9735 ip = (ip4_header_t *) match;
9736
9737 /* These are realistically matched in practice */
9738 if (src)
9739 ip->src_address.as_u32 = src_val.as_u32;
9740
9741 if (dst)
9742 ip->dst_address.as_u32 = dst_val.as_u32;
9743
9744 if (proto)
9745 ip->protocol = proto_val;
9746
9747
9748 /* These are not, but they're included for completeness */
9749 if (version)
9750 ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
9751
9752 if (hdr_length)
9753 ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
9754
9755 if (tos)
9756 ip->tos = tos_val;
9757
9758 if (length)
9759 ip->length = clib_host_to_net_u16 (length_val);
9760
9761 if (ttl)
9762 ip->ttl = ttl_val;
9763
9764 if (checksum)
9765 ip->checksum = clib_host_to_net_u16 (checksum_val);
9766
9767 *matchp = match;
9768 return 1;
9769}
9770
9771uword
9772unformat_ip6_match (unformat_input_t * input, va_list * args)
9773{
9774 u8 **matchp = va_arg (*args, u8 **);
9775 u8 *match = 0;
9776 ip6_header_t *ip;
9777 int version = 0;
9778 u32 version_val;
9779 u8 traffic_class = 0;
9780 u32 traffic_class_val = 0;
9781 u8 flow_label = 0;
9782 u8 flow_label_val;
9783 int src = 0, dst = 0;
9784 ip6_address_t src_val, dst_val;
9785 int proto = 0;
9786 u32 proto_val;
9787 int payload_length = 0;
9788 u32 payload_length_val;
9789 int hop_limit = 0;
9790 int hop_limit_val;
9791 u32 ip_version_traffic_class_and_flow_label;
9792
9793 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9794 {
9795 if (unformat (input, "version %d", &version_val))
9796 version = 1;
9797 else if (unformat (input, "traffic_class %d", &traffic_class_val))
9798 traffic_class = 1;
9799 else if (unformat (input, "flow_label %d", &flow_label_val))
9800 flow_label = 1;
9801 else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
9802 src = 1;
9803 else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
9804 dst = 1;
9805 else if (unformat (input, "proto %d", &proto_val))
9806 proto = 1;
9807 else if (unformat (input, "payload_length %d", &payload_length_val))
9808 payload_length = 1;
9809 else if (unformat (input, "hop_limit %d", &hop_limit_val))
9810 hop_limit = 1;
9811 else
9812 break;
9813 }
9814
9815 if (version + traffic_class + flow_label + src + dst + proto +
9816 payload_length + hop_limit == 0)
9817 return 0;
9818
9819 /*
9820 * Aligned because we use the real comparison functions
9821 */
9822 vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9823
9824 ip = (ip6_header_t *) match;
9825
9826 if (src)
9827 clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9828
9829 if (dst)
9830 clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9831
9832 if (proto)
9833 ip->protocol = proto_val;
9834
9835 ip_version_traffic_class_and_flow_label = 0;
9836
9837 if (version)
9838 ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9839
9840 if (traffic_class)
9841 ip_version_traffic_class_and_flow_label |=
9842 (traffic_class_val & 0xFF) << 20;
9843
9844 if (flow_label)
9845 ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9846
9847 ip->ip_version_traffic_class_and_flow_label =
9848 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9849
9850 if (payload_length)
9851 ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9852
9853 if (hop_limit)
9854 ip->hop_limit = hop_limit_val;
9855
9856 *matchp = match;
9857 return 1;
9858}
9859
9860uword
9861unformat_l3_match (unformat_input_t * input, va_list * args)
9862{
9863 u8 **matchp = va_arg (*args, u8 **);
9864
9865 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9866 {
9867 if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9868 return 1;
9869 else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9870 return 1;
9871 else
9872 break;
9873 }
9874 return 0;
9875}
9876
9877uword
9878unformat_vlan_tag (unformat_input_t * input, va_list * args)
9879{
9880 u8 *tagp = va_arg (*args, u8 *);
9881 u32 tag;
9882
9883 if (unformat (input, "%d", &tag))
9884 {
9885 tagp[0] = (tag >> 8) & 0x0F;
9886 tagp[1] = tag & 0xFF;
9887 return 1;
9888 }
9889
9890 return 0;
9891}
9892
9893uword
9894unformat_l2_match (unformat_input_t * input, va_list * args)
9895{
9896 u8 **matchp = va_arg (*args, u8 **);
9897 u8 *match = 0;
9898 u8 src = 0;
9899 u8 src_val[6];
9900 u8 dst = 0;
9901 u8 dst_val[6];
9902 u8 proto = 0;
9903 u16 proto_val;
9904 u8 tag1 = 0;
9905 u8 tag1_val[2];
9906 u8 tag2 = 0;
9907 u8 tag2_val[2];
9908 int len = 14;
9909 u8 ignore_tag1 = 0;
9910 u8 ignore_tag2 = 0;
9911 u8 cos1 = 0;
9912 u8 cos2 = 0;
9913 u32 cos1_val = 0;
9914 u32 cos2_val = 0;
9915
9916 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9917 {
9918 if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9919 src = 1;
9920 else
9921 if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9922 dst = 1;
9923 else if (unformat (input, "proto %U",
9924 unformat_ethernet_type_host_byte_order, &proto_val))
9925 proto = 1;
9926 else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9927 tag1 = 1;
9928 else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9929 tag2 = 1;
9930 else if (unformat (input, "ignore-tag1"))
9931 ignore_tag1 = 1;
9932 else if (unformat (input, "ignore-tag2"))
9933 ignore_tag2 = 1;
9934 else if (unformat (input, "cos1 %d", &cos1_val))
9935 cos1 = 1;
9936 else if (unformat (input, "cos2 %d", &cos2_val))
9937 cos2 = 1;
9938 else
9939 break;
9940 }
9941 if ((src + dst + proto + tag1 + tag2 +
9942 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9943 return 0;
9944
9945 if (tag1 || ignore_tag1 || cos1)
9946 len = 18;
9947 if (tag2 || ignore_tag2 || cos2)
9948 len = 22;
9949
9950 vec_validate_aligned (match, len - 1, sizeof (u32x4));
9951
9952 if (dst)
9953 clib_memcpy (match, dst_val, 6);
9954
9955 if (src)
9956 clib_memcpy (match + 6, src_val, 6);
9957
9958 if (tag2)
9959 {
9960 /* inner vlan tag */
9961 match[19] = tag2_val[1];
9962 match[18] = tag2_val[0];
9963 if (cos2)
9964 match[18] |= (cos2_val & 0x7) << 5;
9965 if (proto)
9966 {
9967 match[21] = proto_val & 0xff;
9968 match[20] = proto_val >> 8;
9969 }
9970 if (tag1)
9971 {
9972 match[15] = tag1_val[1];
9973 match[14] = tag1_val[0];
9974 }
9975 if (cos1)
9976 match[14] |= (cos1_val & 0x7) << 5;
9977 *matchp = match;
9978 return 1;
9979 }
9980 if (tag1)
9981 {
9982 match[15] = tag1_val[1];
9983 match[14] = tag1_val[0];
9984 if (proto)
9985 {
9986 match[17] = proto_val & 0xff;
9987 match[16] = proto_val >> 8;
9988 }
9989 if (cos1)
9990 match[14] |= (cos1_val & 0x7) << 5;
9991
9992 *matchp = match;
9993 return 1;
9994 }
9995 if (cos2)
9996 match[18] |= (cos2_val & 0x7) << 5;
9997 if (cos1)
9998 match[14] |= (cos1_val & 0x7) << 5;
9999 if (proto)
10000 {
10001 match[13] = proto_val & 0xff;
10002 match[12] = proto_val >> 8;
10003 }
10004
10005 *matchp = match;
10006 return 1;
10007}
Dave Barach4a3f69c2017-02-22 12:44:56 -050010008#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +010010009
10010uword
Dave Barach4a3f69c2017-02-22 12:44:56 -050010011api_unformat_classify_match (unformat_input_t * input, va_list * args)
Damjan Marion7cd468a2016-12-19 23:05:39 +010010012{
10013 u8 **matchp = va_arg (*args, u8 **);
10014 u32 skip_n_vectors = va_arg (*args, u32);
10015 u32 match_n_vectors = va_arg (*args, u32);
10016
10017 u8 *match = 0;
10018 u8 *l2 = 0;
10019 u8 *l3 = 0;
10020 u8 *l4 = 0;
10021
10022 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10023 {
10024 if (unformat (input, "hex %U", unformat_hex_string, &match))
10025 ;
10026 else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
10027 ;
10028 else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
10029 ;
10030 else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
10031 ;
10032 else
10033 break;
10034 }
10035
10036 if (l4 && !l3)
10037 {
10038 vec_free (match);
10039 vec_free (l2);
10040 vec_free (l4);
10041 return 0;
10042 }
10043
10044 if (match || l2 || l3 || l4)
10045 {
10046 if (l2 || l3 || l4)
10047 {
10048 /* "Win a free Ethernet header in every packet" */
10049 if (l2 == 0)
10050 vec_validate_aligned (l2, 13, sizeof (u32x4));
10051 match = l2;
10052 if (vec_len (l3))
10053 {
10054 vec_append_aligned (match, l3, sizeof (u32x4));
10055 vec_free (l3);
10056 }
10057 if (vec_len (l4))
10058 {
10059 vec_append_aligned (match, l4, sizeof (u32x4));
10060 vec_free (l4);
10061 }
10062 }
10063
10064 /* Make sure the vector is big enough even if key is all 0's */
10065 vec_validate_aligned
10066 (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
10067 sizeof (u32x4));
10068
10069 /* Set size, include skipped vectors */
10070 _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
10071
10072 *matchp = match;
10073
10074 return 1;
10075 }
10076
10077 return 0;
10078}
10079
10080static int
10081api_classify_add_del_session (vat_main_t * vam)
10082{
10083 unformat_input_t *i = vam->input;
10084 vl_api_classify_add_del_session_t *mp;
10085 int is_add = 1;
10086 u32 table_index = ~0;
10087 u32 hit_next_index = ~0;
10088 u32 opaque_index = ~0;
10089 u8 *match = 0;
10090 i32 advance = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010091 u32 skip_n_vectors = 0;
10092 u32 match_n_vectors = 0;
10093 u32 action = 0;
10094 u32 metadata = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010095 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010096
10097 /*
10098 * Warning: you have to supply skip_n and match_n
10099 * because the API client cant simply look at the classify
10100 * table object.
10101 */
10102
10103 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10104 {
10105 if (unformat (i, "del"))
10106 is_add = 0;
Dave Barach4a3f69c2017-02-22 12:44:56 -050010107 else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
Damjan Marion7cd468a2016-12-19 23:05:39 +010010108 &hit_next_index))
10109 ;
10110 else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
10111 &hit_next_index))
10112 ;
Dave Barach4a3f69c2017-02-22 12:44:56 -050010113 else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
Damjan Marion7cd468a2016-12-19 23:05:39 +010010114 &hit_next_index))
10115 ;
10116 else if (unformat (i, "policer-hit-next %d", &hit_next_index))
10117 ;
10118 else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
10119 ;
10120 else if (unformat (i, "opaque-index %d", &opaque_index))
10121 ;
10122 else if (unformat (i, "skip_n %d", &skip_n_vectors))
10123 ;
10124 else if (unformat (i, "match_n %d", &match_n_vectors))
10125 ;
Dave Barach4a3f69c2017-02-22 12:44:56 -050010126 else if (unformat (i, "match %U", api_unformat_classify_match,
Damjan Marion7cd468a2016-12-19 23:05:39 +010010127 &match, skip_n_vectors, match_n_vectors))
10128 ;
10129 else if (unformat (i, "advance %d", &advance))
10130 ;
10131 else if (unformat (i, "table-index %d", &table_index))
10132 ;
10133 else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
10134 action = 1;
10135 else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
10136 action = 2;
10137 else if (unformat (i, "action %d", &action))
10138 ;
10139 else if (unformat (i, "metadata %d", &metadata))
10140 ;
10141 else
10142 break;
10143 }
10144
10145 if (table_index == ~0)
10146 {
10147 errmsg ("Table index required");
10148 return -99;
10149 }
10150
10151 if (is_add && match == 0)
10152 {
10153 errmsg ("Match value required");
10154 return -99;
10155 }
10156
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010157 M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
Damjan Marion7cd468a2016-12-19 23:05:39 +010010158
10159 mp->is_add = is_add;
10160 mp->table_index = ntohl (table_index);
10161 mp->hit_next_index = ntohl (hit_next_index);
10162 mp->opaque_index = ntohl (opaque_index);
10163 mp->advance = ntohl (advance);
10164 mp->action = action;
10165 mp->metadata = ntohl (metadata);
10166 clib_memcpy (mp->match, match, vec_len (match));
10167 vec_free (match);
10168
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010169 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010170 W (ret);
10171 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010172}
10173
10174static int
10175api_classify_set_interface_ip_table (vat_main_t * vam)
10176{
10177 unformat_input_t *i = vam->input;
10178 vl_api_classify_set_interface_ip_table_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010179 u32 sw_if_index;
10180 int sw_if_index_set;
10181 u32 table_index = ~0;
10182 u8 is_ipv6 = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010183 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010184
10185 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10186 {
10187 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10188 sw_if_index_set = 1;
10189 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10190 sw_if_index_set = 1;
10191 else if (unformat (i, "table %d", &table_index))
10192 ;
10193 else
10194 {
10195 clib_warning ("parse error '%U'", format_unformat_error, i);
10196 return -99;
10197 }
10198 }
10199
10200 if (sw_if_index_set == 0)
10201 {
10202 errmsg ("missing interface name or sw_if_index");
10203 return -99;
10204 }
10205
10206
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010207 M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010208
10209 mp->sw_if_index = ntohl (sw_if_index);
10210 mp->table_index = ntohl (table_index);
10211 mp->is_ipv6 = is_ipv6;
10212
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010213 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010214 W (ret);
10215 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010216}
10217
10218static int
10219api_classify_set_interface_l2_tables (vat_main_t * vam)
10220{
10221 unformat_input_t *i = vam->input;
10222 vl_api_classify_set_interface_l2_tables_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010223 u32 sw_if_index;
10224 int sw_if_index_set;
10225 u32 ip4_table_index = ~0;
10226 u32 ip6_table_index = ~0;
10227 u32 other_table_index = ~0;
10228 u32 is_input = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010229 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010230
10231 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10232 {
10233 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10234 sw_if_index_set = 1;
10235 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10236 sw_if_index_set = 1;
10237 else if (unformat (i, "ip4-table %d", &ip4_table_index))
10238 ;
10239 else if (unformat (i, "ip6-table %d", &ip6_table_index))
10240 ;
10241 else if (unformat (i, "other-table %d", &other_table_index))
10242 ;
10243 else if (unformat (i, "is-input %d", &is_input))
10244 ;
10245 else
10246 {
10247 clib_warning ("parse error '%U'", format_unformat_error, i);
10248 return -99;
10249 }
10250 }
10251
10252 if (sw_if_index_set == 0)
10253 {
10254 errmsg ("missing interface name or sw_if_index");
10255 return -99;
10256 }
10257
10258
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010259 M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010260
10261 mp->sw_if_index = ntohl (sw_if_index);
10262 mp->ip4_table_index = ntohl (ip4_table_index);
10263 mp->ip6_table_index = ntohl (ip6_table_index);
10264 mp->other_table_index = ntohl (other_table_index);
10265 mp->is_input = (u8) is_input;
10266
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010267 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010268 W (ret);
10269 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010270}
10271
10272static int
10273api_set_ipfix_exporter (vat_main_t * vam)
10274{
10275 unformat_input_t *i = vam->input;
10276 vl_api_set_ipfix_exporter_t *mp;
10277 ip4_address_t collector_address;
10278 u8 collector_address_set = 0;
10279 u32 collector_port = ~0;
10280 ip4_address_t src_address;
10281 u8 src_address_set = 0;
10282 u32 vrf_id = ~0;
10283 u32 path_mtu = ~0;
10284 u32 template_interval = ~0;
10285 u8 udp_checksum = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010286 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010287
10288 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10289 {
10290 if (unformat (i, "collector_address %U", unformat_ip4_address,
10291 &collector_address))
10292 collector_address_set = 1;
10293 else if (unformat (i, "collector_port %d", &collector_port))
10294 ;
10295 else if (unformat (i, "src_address %U", unformat_ip4_address,
10296 &src_address))
10297 src_address_set = 1;
10298 else if (unformat (i, "vrf_id %d", &vrf_id))
10299 ;
10300 else if (unformat (i, "path_mtu %d", &path_mtu))
10301 ;
10302 else if (unformat (i, "template_interval %d", &template_interval))
10303 ;
10304 else if (unformat (i, "udp_checksum"))
10305 udp_checksum = 1;
10306 else
10307 break;
10308 }
10309
10310 if (collector_address_set == 0)
10311 {
10312 errmsg ("collector_address required");
10313 return -99;
10314 }
10315
10316 if (src_address_set == 0)
10317 {
10318 errmsg ("src_address required");
10319 return -99;
10320 }
10321
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010322 M (SET_IPFIX_EXPORTER, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010323
10324 memcpy (mp->collector_address, collector_address.data,
10325 sizeof (collector_address.data));
10326 mp->collector_port = htons ((u16) collector_port);
10327 memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
10328 mp->vrf_id = htonl (vrf_id);
10329 mp->path_mtu = htonl (path_mtu);
10330 mp->template_interval = htonl (template_interval);
10331 mp->udp_checksum = udp_checksum;
10332
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010333 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010334 W (ret);
10335 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010336}
10337
10338static int
10339api_set_ipfix_classify_stream (vat_main_t * vam)
10340{
10341 unformat_input_t *i = vam->input;
10342 vl_api_set_ipfix_classify_stream_t *mp;
10343 u32 domain_id = 0;
10344 u32 src_port = UDP_DST_PORT_ipfix;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010345 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010346
10347 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10348 {
10349 if (unformat (i, "domain %d", &domain_id))
10350 ;
10351 else if (unformat (i, "src_port %d", &src_port))
10352 ;
10353 else
10354 {
10355 errmsg ("unknown input `%U'", format_unformat_error, i);
10356 return -99;
10357 }
10358 }
10359
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010360 M (SET_IPFIX_CLASSIFY_STREAM, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010361
10362 mp->domain_id = htonl (domain_id);
10363 mp->src_port = htons ((u16) src_port);
10364
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010365 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010366 W (ret);
10367 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010368}
10369
10370static int
10371api_ipfix_classify_table_add_del (vat_main_t * vam)
10372{
10373 unformat_input_t *i = vam->input;
10374 vl_api_ipfix_classify_table_add_del_t *mp;
10375 int is_add = -1;
10376 u32 classify_table_index = ~0;
10377 u8 ip_version = 0;
10378 u8 transport_protocol = 255;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010379 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010380
10381 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10382 {
10383 if (unformat (i, "add"))
10384 is_add = 1;
10385 else if (unformat (i, "del"))
10386 is_add = 0;
10387 else if (unformat (i, "table %d", &classify_table_index))
10388 ;
10389 else if (unformat (i, "ip4"))
10390 ip_version = 4;
10391 else if (unformat (i, "ip6"))
10392 ip_version = 6;
10393 else if (unformat (i, "tcp"))
10394 transport_protocol = 6;
10395 else if (unformat (i, "udp"))
10396 transport_protocol = 17;
10397 else
10398 {
10399 errmsg ("unknown input `%U'", format_unformat_error, i);
10400 return -99;
10401 }
10402 }
10403
10404 if (is_add == -1)
10405 {
10406 errmsg ("expecting: add|del");
10407 return -99;
10408 }
10409 if (classify_table_index == ~0)
10410 {
10411 errmsg ("classifier table not specified");
10412 return -99;
10413 }
10414 if (ip_version == 0)
10415 {
10416 errmsg ("IP version not specified");
10417 return -99;
10418 }
10419
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010420 M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010421
10422 mp->is_add = is_add;
10423 mp->table_id = htonl (classify_table_index);
10424 mp->ip_version = ip_version;
10425 mp->transport_protocol = transport_protocol;
10426
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010427 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010428 W (ret);
10429 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010430}
10431
10432static int
10433api_get_node_index (vat_main_t * vam)
10434{
10435 unformat_input_t *i = vam->input;
10436 vl_api_get_node_index_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010437 u8 *name = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010438 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010439
10440 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10441 {
10442 if (unformat (i, "node %s", &name))
10443 ;
10444 else
10445 break;
10446 }
10447 if (name == 0)
10448 {
10449 errmsg ("node name required");
10450 return -99;
10451 }
10452 if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10453 {
10454 errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10455 return -99;
10456 }
10457
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010458 M (GET_NODE_INDEX, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010459 clib_memcpy (mp->node_name, name, vec_len (name));
10460 vec_free (name);
10461
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010462 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010463 W (ret);
10464 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010465}
10466
10467static int
10468api_get_next_index (vat_main_t * vam)
10469{
10470 unformat_input_t *i = vam->input;
10471 vl_api_get_next_index_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010472 u8 *node_name = 0, *next_node_name = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010473 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010474
10475 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10476 {
10477 if (unformat (i, "node-name %s", &node_name))
10478 ;
10479 else if (unformat (i, "next-node-name %s", &next_node_name))
10480 break;
10481 }
10482
10483 if (node_name == 0)
10484 {
10485 errmsg ("node name required");
10486 return -99;
10487 }
10488 if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
10489 {
10490 errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10491 return -99;
10492 }
10493
10494 if (next_node_name == 0)
10495 {
10496 errmsg ("next node name required");
10497 return -99;
10498 }
10499 if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
10500 {
10501 errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
10502 return -99;
10503 }
10504
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010505 M (GET_NEXT_INDEX, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010506 clib_memcpy (mp->node_name, node_name, vec_len (node_name));
10507 clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
10508 vec_free (node_name);
10509 vec_free (next_node_name);
10510
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010511 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010512 W (ret);
10513 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010514}
10515
10516static int
10517api_add_node_next (vat_main_t * vam)
10518{
10519 unformat_input_t *i = vam->input;
10520 vl_api_add_node_next_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010521 u8 *name = 0;
10522 u8 *next = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010523 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010524
10525 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10526 {
10527 if (unformat (i, "node %s", &name))
10528 ;
10529 else if (unformat (i, "next %s", &next))
10530 ;
10531 else
10532 break;
10533 }
10534 if (name == 0)
10535 {
10536 errmsg ("node name required");
10537 return -99;
10538 }
10539 if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10540 {
10541 errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10542 return -99;
10543 }
10544 if (next == 0)
10545 {
10546 errmsg ("next node required");
10547 return -99;
10548 }
10549 if (vec_len (next) >= ARRAY_LEN (mp->next_name))
10550 {
10551 errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
10552 return -99;
10553 }
10554
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010555 M (ADD_NODE_NEXT, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010556 clib_memcpy (mp->node_name, name, vec_len (name));
10557 clib_memcpy (mp->next_name, next, vec_len (next));
10558 vec_free (name);
10559 vec_free (next);
10560
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010561 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010562 W (ret);
10563 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010564}
10565
10566static int
10567api_l2tpv3_create_tunnel (vat_main_t * vam)
10568{
10569 unformat_input_t *i = vam->input;
10570 ip6_address_t client_address, our_address;
10571 int client_address_set = 0;
10572 int our_address_set = 0;
10573 u32 local_session_id = 0;
10574 u32 remote_session_id = 0;
10575 u64 local_cookie = 0;
10576 u64 remote_cookie = 0;
10577 u8 l2_sublayer_present = 0;
10578 vl_api_l2tpv3_create_tunnel_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010579 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010580
10581 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10582 {
10583 if (unformat (i, "client_address %U", unformat_ip6_address,
10584 &client_address))
10585 client_address_set = 1;
10586 else if (unformat (i, "our_address %U", unformat_ip6_address,
10587 &our_address))
10588 our_address_set = 1;
10589 else if (unformat (i, "local_session_id %d", &local_session_id))
10590 ;
10591 else if (unformat (i, "remote_session_id %d", &remote_session_id))
10592 ;
10593 else if (unformat (i, "local_cookie %lld", &local_cookie))
10594 ;
10595 else if (unformat (i, "remote_cookie %lld", &remote_cookie))
10596 ;
10597 else if (unformat (i, "l2-sublayer-present"))
10598 l2_sublayer_present = 1;
10599 else
10600 break;
10601 }
10602
10603 if (client_address_set == 0)
10604 {
10605 errmsg ("client_address required");
10606 return -99;
10607 }
10608
10609 if (our_address_set == 0)
10610 {
10611 errmsg ("our_address required");
10612 return -99;
10613 }
10614
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010615 M (L2TPV3_CREATE_TUNNEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010616
10617 clib_memcpy (mp->client_address, client_address.as_u8,
10618 sizeof (mp->client_address));
10619
10620 clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
10621
10622 mp->local_session_id = ntohl (local_session_id);
10623 mp->remote_session_id = ntohl (remote_session_id);
10624 mp->local_cookie = clib_host_to_net_u64 (local_cookie);
10625 mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
10626 mp->l2_sublayer_present = l2_sublayer_present;
10627 mp->is_ipv6 = 1;
10628
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010629 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010630 W (ret);
10631 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010632}
10633
10634static int
10635api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
10636{
10637 unformat_input_t *i = vam->input;
10638 u32 sw_if_index;
10639 u8 sw_if_index_set = 0;
10640 u64 new_local_cookie = 0;
10641 u64 new_remote_cookie = 0;
10642 vl_api_l2tpv3_set_tunnel_cookies_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010643 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010644
10645 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10646 {
10647 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10648 sw_if_index_set = 1;
10649 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10650 sw_if_index_set = 1;
10651 else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
10652 ;
10653 else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
10654 ;
10655 else
10656 break;
10657 }
10658
10659 if (sw_if_index_set == 0)
10660 {
10661 errmsg ("missing interface name or sw_if_index");
10662 return -99;
10663 }
10664
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010665 M (L2TPV3_SET_TUNNEL_COOKIES, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010666
10667 mp->sw_if_index = ntohl (sw_if_index);
10668 mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
10669 mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
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_interface_enable_disable (vat_main_t * vam)
10678{
10679 unformat_input_t *i = vam->input;
10680 vl_api_l2tpv3_interface_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010681 u32 sw_if_index;
10682 u8 sw_if_index_set = 0;
10683 u8 enable_disable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010684 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010685
10686 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10687 {
10688 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10689 sw_if_index_set = 1;
10690 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10691 sw_if_index_set = 1;
10692 else if (unformat (i, "enable"))
10693 enable_disable = 1;
10694 else if (unformat (i, "disable"))
10695 enable_disable = 0;
10696 else
10697 break;
10698 }
10699
10700 if (sw_if_index_set == 0)
10701 {
10702 errmsg ("missing interface name or sw_if_index");
10703 return -99;
10704 }
10705
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010706 M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010707
10708 mp->sw_if_index = ntohl (sw_if_index);
10709 mp->enable_disable = enable_disable;
10710
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010711 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010712 W (ret);
10713 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010714}
10715
10716static int
10717api_l2tpv3_set_lookup_key (vat_main_t * vam)
10718{
10719 unformat_input_t *i = vam->input;
10720 vl_api_l2tpv3_set_lookup_key_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010721 u8 key = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010722 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010723
10724 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10725 {
10726 if (unformat (i, "lookup_v6_src"))
10727 key = L2T_LOOKUP_SRC_ADDRESS;
10728 else if (unformat (i, "lookup_v6_dst"))
10729 key = L2T_LOOKUP_DST_ADDRESS;
10730 else if (unformat (i, "lookup_session_id"))
10731 key = L2T_LOOKUP_SESSION_ID;
10732 else
10733 break;
10734 }
10735
10736 if (key == (u8) ~ 0)
10737 {
10738 errmsg ("l2tp session lookup key unset");
10739 return -99;
10740 }
10741
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010742 M (L2TPV3_SET_LOOKUP_KEY, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010743
10744 mp->key = key;
10745
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010746 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010747 W (ret);
10748 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010749}
10750
10751static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
10752 (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10753{
10754 vat_main_t *vam = &vat_main;
10755
10756 print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
10757 format_ip6_address, mp->our_address,
10758 format_ip6_address, mp->client_address,
10759 clib_net_to_host_u32 (mp->sw_if_index));
10760
10761 print (vam->ofp,
10762 " local cookies %016llx %016llx remote cookie %016llx",
10763 clib_net_to_host_u64 (mp->local_cookie[0]),
10764 clib_net_to_host_u64 (mp->local_cookie[1]),
10765 clib_net_to_host_u64 (mp->remote_cookie));
10766
10767 print (vam->ofp, " local session-id %d remote session-id %d",
10768 clib_net_to_host_u32 (mp->local_session_id),
10769 clib_net_to_host_u32 (mp->remote_session_id));
10770
10771 print (vam->ofp, " l2 specific sublayer %s\n",
10772 mp->l2_sublayer_present ? "preset" : "absent");
10773
10774}
10775
10776static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
10777 (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10778{
10779 vat_main_t *vam = &vat_main;
10780 vat_json_node_t *node = NULL;
10781 struct in6_addr addr;
10782
10783 if (VAT_JSON_ARRAY != vam->json_tree.type)
10784 {
10785 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10786 vat_json_init_array (&vam->json_tree);
10787 }
10788 node = vat_json_array_add (&vam->json_tree);
10789
10790 vat_json_init_object (node);
10791
10792 clib_memcpy (&addr, mp->our_address, sizeof (addr));
10793 vat_json_object_add_ip6 (node, "our_address", addr);
10794 clib_memcpy (&addr, mp->client_address, sizeof (addr));
10795 vat_json_object_add_ip6 (node, "client_address", addr);
10796
10797 vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
10798 vat_json_init_array (lc);
10799 vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
10800 vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
10801 vat_json_object_add_uint (node, "remote_cookie",
10802 clib_net_to_host_u64 (mp->remote_cookie));
10803
10804 printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
10805 vat_json_object_add_uint (node, "local_session_id",
10806 clib_net_to_host_u32 (mp->local_session_id));
10807 vat_json_object_add_uint (node, "remote_session_id",
10808 clib_net_to_host_u32 (mp->remote_session_id));
10809 vat_json_object_add_string_copy (node, "l2_sublayer",
10810 mp->l2_sublayer_present ? (u8 *) "present"
10811 : (u8 *) "absent");
10812}
10813
10814static int
10815api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
10816{
10817 vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010818 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010819 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010820
10821 /* Get list of l2tpv3-tunnel interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010822 M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010823 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010824
10825 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010826 M (CONTROL_PING, mp_ping);
10827 S (mp_ping);
10828
Jon Loeliger56c7b012017-02-01 12:31:41 -060010829 W (ret);
10830 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010831}
10832
10833
10834static void vl_api_sw_interface_tap_details_t_handler
10835 (vl_api_sw_interface_tap_details_t * mp)
10836{
10837 vat_main_t *vam = &vat_main;
10838
10839 print (vam->ofp, "%-16s %d",
10840 mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10841}
10842
10843static void vl_api_sw_interface_tap_details_t_handler_json
10844 (vl_api_sw_interface_tap_details_t * mp)
10845{
10846 vat_main_t *vam = &vat_main;
10847 vat_json_node_t *node = NULL;
10848
10849 if (VAT_JSON_ARRAY != vam->json_tree.type)
10850 {
10851 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10852 vat_json_init_array (&vam->json_tree);
10853 }
10854 node = vat_json_array_add (&vam->json_tree);
10855
10856 vat_json_init_object (node);
10857 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10858 vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10859}
10860
10861static int
10862api_sw_interface_tap_dump (vat_main_t * vam)
10863{
10864 vl_api_sw_interface_tap_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010865 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010866 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010867
10868 print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
10869 /* Get list of tap interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010870 M (SW_INTERFACE_TAP_DUMP, mp);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010871 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010872
10873 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010874 M (CONTROL_PING, mp_ping);
10875 S (mp_ping);
10876
Jon Loeliger56c7b012017-02-01 12:31:41 -060010877 W (ret);
10878 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010879}
10880
10881static uword unformat_vxlan_decap_next
10882 (unformat_input_t * input, va_list * args)
10883{
10884 u32 *result = va_arg (*args, u32 *);
10885 u32 tmp;
10886
10887 if (unformat (input, "l2"))
10888 *result = VXLAN_INPUT_NEXT_L2_INPUT;
10889 else if (unformat (input, "%d", &tmp))
10890 *result = tmp;
10891 else
10892 return 0;
10893 return 1;
10894}
10895
10896static int
10897api_vxlan_add_del_tunnel (vat_main_t * vam)
10898{
10899 unformat_input_t *line_input = vam->input;
10900 vl_api_vxlan_add_del_tunnel_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010901 ip46_address_t src, dst;
10902 u8 is_add = 1;
10903 u8 ipv4_set = 0, ipv6_set = 0;
10904 u8 src_set = 0;
10905 u8 dst_set = 0;
10906 u8 grp_set = 0;
10907 u32 mcast_sw_if_index = ~0;
10908 u32 encap_vrf_id = 0;
10909 u32 decap_next_index = ~0;
10910 u32 vni = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010911 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010912
10913 /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
10914 memset (&src, 0, sizeof src);
10915 memset (&dst, 0, sizeof dst);
10916
10917 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10918 {
10919 if (unformat (line_input, "del"))
10920 is_add = 0;
10921 else
10922 if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
10923 {
10924 ipv4_set = 1;
10925 src_set = 1;
10926 }
10927 else
10928 if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
10929 {
10930 ipv4_set = 1;
10931 dst_set = 1;
10932 }
10933 else
10934 if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
10935 {
10936 ipv6_set = 1;
10937 src_set = 1;
10938 }
10939 else
10940 if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
10941 {
10942 ipv6_set = 1;
10943 dst_set = 1;
10944 }
10945 else if (unformat (line_input, "group %U %U",
10946 unformat_ip4_address, &dst.ip4,
10947 api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10948 {
10949 grp_set = dst_set = 1;
10950 ipv4_set = 1;
10951 }
10952 else if (unformat (line_input, "group %U",
10953 unformat_ip4_address, &dst.ip4))
10954 {
10955 grp_set = dst_set = 1;
10956 ipv4_set = 1;
10957 }
10958 else if (unformat (line_input, "group %U %U",
10959 unformat_ip6_address, &dst.ip6,
10960 api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10961 {
10962 grp_set = dst_set = 1;
10963 ipv6_set = 1;
10964 }
10965 else if (unformat (line_input, "group %U",
10966 unformat_ip6_address, &dst.ip6))
10967 {
10968 grp_set = dst_set = 1;
10969 ipv6_set = 1;
10970 }
10971 else
10972 if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10973 ;
10974 else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10975 ;
10976 else if (unformat (line_input, "decap-next %U",
10977 unformat_vxlan_decap_next, &decap_next_index))
10978 ;
10979 else if (unformat (line_input, "vni %d", &vni))
10980 ;
10981 else
10982 {
10983 errmsg ("parse error '%U'", format_unformat_error, line_input);
10984 return -99;
10985 }
10986 }
10987
10988 if (src_set == 0)
10989 {
10990 errmsg ("tunnel src address not specified");
10991 return -99;
10992 }
10993 if (dst_set == 0)
10994 {
10995 errmsg ("tunnel dst address not specified");
10996 return -99;
10997 }
10998
10999 if (grp_set && !ip46_address_is_multicast (&dst))
11000 {
11001 errmsg ("tunnel group address not multicast");
11002 return -99;
11003 }
11004 if (grp_set && mcast_sw_if_index == ~0)
11005 {
11006 errmsg ("tunnel nonexistent multicast device");
11007 return -99;
11008 }
11009 if (grp_set == 0 && ip46_address_is_multicast (&dst))
11010 {
11011 errmsg ("tunnel dst address must be unicast");
11012 return -99;
11013 }
11014
11015
11016 if (ipv4_set && ipv6_set)
11017 {
11018 errmsg ("both IPv4 and IPv6 addresses specified");
11019 return -99;
11020 }
11021
11022 if ((vni == 0) || (vni >> 24))
11023 {
11024 errmsg ("vni not specified or out of range");
11025 return -99;
11026 }
11027
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011028 M (VXLAN_ADD_DEL_TUNNEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011029
11030 if (ipv6_set)
11031 {
11032 clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
11033 clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
11034 }
11035 else
11036 {
11037 clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
11038 clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
11039 }
11040 mp->encap_vrf_id = ntohl (encap_vrf_id);
11041 mp->decap_next_index = ntohl (decap_next_index);
11042 mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
11043 mp->vni = ntohl (vni);
11044 mp->is_add = is_add;
11045 mp->is_ipv6 = ipv6_set;
11046
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011047 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011048 W (ret);
11049 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011050}
11051
11052static void vl_api_vxlan_tunnel_details_t_handler
11053 (vl_api_vxlan_tunnel_details_t * mp)
11054{
11055 vat_main_t *vam = &vat_main;
Eyal Barie101e1f2017-03-15 08:23:42 +020011056 ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
11057 ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011058
11059 print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
11060 ntohl (mp->sw_if_index),
11061 format_ip46_address, &src, IP46_TYPE_ANY,
11062 format_ip46_address, &dst, IP46_TYPE_ANY,
11063 ntohl (mp->encap_vrf_id),
11064 ntohl (mp->decap_next_index), ntohl (mp->vni),
11065 ntohl (mp->mcast_sw_if_index));
11066}
11067
11068static void vl_api_vxlan_tunnel_details_t_handler_json
11069 (vl_api_vxlan_tunnel_details_t * mp)
11070{
11071 vat_main_t *vam = &vat_main;
11072 vat_json_node_t *node = NULL;
11073
11074 if (VAT_JSON_ARRAY != vam->json_tree.type)
11075 {
11076 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11077 vat_json_init_array (&vam->json_tree);
11078 }
11079 node = vat_json_array_add (&vam->json_tree);
11080
11081 vat_json_init_object (node);
11082 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11083 if (mp->is_ipv6)
11084 {
11085 struct in6_addr ip6;
11086
11087 clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
11088 vat_json_object_add_ip6 (node, "src_address", ip6);
11089 clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
11090 vat_json_object_add_ip6 (node, "dst_address", ip6);
11091 }
11092 else
11093 {
11094 struct in_addr ip4;
11095
11096 clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
11097 vat_json_object_add_ip4 (node, "src_address", ip4);
11098 clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
11099 vat_json_object_add_ip4 (node, "dst_address", ip4);
11100 }
11101 vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11102 vat_json_object_add_uint (node, "decap_next_index",
11103 ntohl (mp->decap_next_index));
11104 vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11105 vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11106 vat_json_object_add_uint (node, "mcast_sw_if_index",
11107 ntohl (mp->mcast_sw_if_index));
11108}
11109
11110static int
11111api_vxlan_tunnel_dump (vat_main_t * vam)
11112{
11113 unformat_input_t *i = vam->input;
11114 vl_api_vxlan_tunnel_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011115 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011116 u32 sw_if_index;
11117 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011118 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011119
11120 /* Parse args required to build the message */
11121 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11122 {
11123 if (unformat (i, "sw_if_index %d", &sw_if_index))
11124 sw_if_index_set = 1;
11125 else
11126 break;
11127 }
11128
11129 if (sw_if_index_set == 0)
11130 {
11131 sw_if_index = ~0;
11132 }
11133
11134 if (!vam->json_output)
11135 {
11136 print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
11137 "sw_if_index", "src_address", "dst_address",
11138 "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
11139 }
11140
11141 /* Get list of vxlan-tunnel interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011142 M (VXLAN_TUNNEL_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011143
11144 mp->sw_if_index = htonl (sw_if_index);
11145
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011146 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011147
11148 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011149 M (CONTROL_PING, mp_ping);
11150 S (mp_ping);
11151
Jon Loeliger56c7b012017-02-01 12:31:41 -060011152 W (ret);
11153 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011154}
11155
11156static int
11157api_gre_add_del_tunnel (vat_main_t * vam)
11158{
11159 unformat_input_t *line_input = vam->input;
11160 vl_api_gre_add_del_tunnel_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011161 ip4_address_t src4, dst4;
Ciara Loftus7eac9162016-09-30 15:47:03 +010011162 ip6_address_t src6, dst6;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011163 u8 is_add = 1;
Ciara Loftus7eac9162016-09-30 15:47:03 +010011164 u8 ipv4_set = 0;
11165 u8 ipv6_set = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011166 u8 teb = 0;
11167 u8 src_set = 0;
11168 u8 dst_set = 0;
11169 u32 outer_fib_id = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011170 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011171
Ciara Loftus7eac9162016-09-30 15:47:03 +010011172 memset (&src4, 0, sizeof src4);
11173 memset (&dst4, 0, sizeof dst4);
11174 memset (&src6, 0, sizeof src6);
11175 memset (&dst6, 0, sizeof dst6);
11176
Damjan Marion7cd468a2016-12-19 23:05:39 +010011177 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11178 {
11179 if (unformat (line_input, "del"))
11180 is_add = 0;
11181 else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
Ciara Loftus7eac9162016-09-30 15:47:03 +010011182 {
11183 src_set = 1;
11184 ipv4_set = 1;
11185 }
Damjan Marion7cd468a2016-12-19 23:05:39 +010011186 else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
Ciara Loftus7eac9162016-09-30 15:47:03 +010011187 {
11188 dst_set = 1;
11189 ipv4_set = 1;
11190 }
11191 else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
11192 {
11193 src_set = 1;
11194 ipv6_set = 1;
11195 }
11196 else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
11197 {
11198 dst_set = 1;
11199 ipv6_set = 1;
11200 }
Damjan Marion7cd468a2016-12-19 23:05:39 +010011201 else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
11202 ;
11203 else if (unformat (line_input, "teb"))
11204 teb = 1;
11205 else
11206 {
11207 errmsg ("parse error '%U'", format_unformat_error, line_input);
11208 return -99;
11209 }
11210 }
11211
11212 if (src_set == 0)
11213 {
11214 errmsg ("tunnel src address not specified");
11215 return -99;
11216 }
11217 if (dst_set == 0)
11218 {
11219 errmsg ("tunnel dst address not specified");
11220 return -99;
11221 }
Ciara Loftus7eac9162016-09-30 15:47:03 +010011222 if (ipv4_set && ipv6_set)
11223 {
11224 errmsg ("both IPv4 and IPv6 addresses specified");
11225 return -99;
11226 }
Damjan Marion7cd468a2016-12-19 23:05:39 +010011227
11228
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011229 M (GRE_ADD_DEL_TUNNEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011230
Ciara Loftus7eac9162016-09-30 15:47:03 +010011231 if (ipv4_set)
11232 {
11233 clib_memcpy (&mp->src_address, &src4, 4);
11234 clib_memcpy (&mp->dst_address, &dst4, 4);
11235 }
11236 else
11237 {
11238 clib_memcpy (&mp->src_address, &src6, 16);
11239 clib_memcpy (&mp->dst_address, &dst6, 16);
11240 }
Damjan Marion7cd468a2016-12-19 23:05:39 +010011241 mp->outer_fib_id = ntohl (outer_fib_id);
11242 mp->is_add = is_add;
11243 mp->teb = teb;
Ciara Loftus7eac9162016-09-30 15:47:03 +010011244 mp->is_ipv6 = ipv6_set;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011245
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011246 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011247 W (ret);
11248 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011249}
11250
11251static void vl_api_gre_tunnel_details_t_handler
11252 (vl_api_gre_tunnel_details_t * mp)
11253{
11254 vat_main_t *vam = &vat_main;
Ciara Loftus7eac9162016-09-30 15:47:03 +010011255 ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
11256 ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011257
Ciara Loftus7eac9162016-09-30 15:47:03 +010011258 print (vam->ofp, "%11d%24U%24U%6d%14d",
Damjan Marion7cd468a2016-12-19 23:05:39 +010011259 ntohl (mp->sw_if_index),
Ciara Loftus7eac9162016-09-30 15:47:03 +010011260 format_ip46_address, &src, IP46_TYPE_ANY,
11261 format_ip46_address, &dst, IP46_TYPE_ANY,
Damjan Marion7cd468a2016-12-19 23:05:39 +010011262 mp->teb, ntohl (mp->outer_fib_id));
11263}
11264
11265static void vl_api_gre_tunnel_details_t_handler_json
11266 (vl_api_gre_tunnel_details_t * mp)
11267{
11268 vat_main_t *vam = &vat_main;
11269 vat_json_node_t *node = NULL;
11270 struct in_addr ip4;
Ciara Loftus7eac9162016-09-30 15:47:03 +010011271 struct in6_addr ip6;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011272
11273 if (VAT_JSON_ARRAY != vam->json_tree.type)
11274 {
11275 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11276 vat_json_init_array (&vam->json_tree);
11277 }
11278 node = vat_json_array_add (&vam->json_tree);
11279
11280 vat_json_init_object (node);
11281 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
Ciara Loftus7eac9162016-09-30 15:47:03 +010011282 if (!mp->is_ipv6)
11283 {
11284 clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
11285 vat_json_object_add_ip4 (node, "src_address", ip4);
11286 clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
11287 vat_json_object_add_ip4 (node, "dst_address", ip4);
11288 }
11289 else
11290 {
11291 clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
11292 vat_json_object_add_ip6 (node, "src_address", ip6);
11293 clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
11294 vat_json_object_add_ip6 (node, "dst_address", ip6);
11295 }
Damjan Marion7cd468a2016-12-19 23:05:39 +010011296 vat_json_object_add_uint (node, "teb", mp->teb);
11297 vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
Ciara Loftus7eac9162016-09-30 15:47:03 +010011298 vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011299}
11300
11301static int
11302api_gre_tunnel_dump (vat_main_t * vam)
11303{
11304 unformat_input_t *i = vam->input;
11305 vl_api_gre_tunnel_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011306 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011307 u32 sw_if_index;
11308 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011309 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011310
11311 /* Parse args required to build the message */
11312 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11313 {
11314 if (unformat (i, "sw_if_index %d", &sw_if_index))
11315 sw_if_index_set = 1;
11316 else
11317 break;
11318 }
11319
11320 if (sw_if_index_set == 0)
11321 {
11322 sw_if_index = ~0;
11323 }
11324
11325 if (!vam->json_output)
11326 {
Ciara Loftus7eac9162016-09-30 15:47:03 +010011327 print (vam->ofp, "%11s%24s%24s%6s%14s",
Damjan Marion7cd468a2016-12-19 23:05:39 +010011328 "sw_if_index", "src_address", "dst_address", "teb",
11329 "outer_fib_id");
11330 }
11331
11332 /* Get list of gre-tunnel interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011333 M (GRE_TUNNEL_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011334
11335 mp->sw_if_index = htonl (sw_if_index);
11336
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011337 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011338
11339 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011340 M (CONTROL_PING, mp_ping);
11341 S (mp_ping);
11342
Jon Loeliger56c7b012017-02-01 12:31:41 -060011343 W (ret);
11344 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011345}
11346
11347static int
11348api_l2_fib_clear_table (vat_main_t * vam)
11349{
11350// unformat_input_t * i = vam->input;
11351 vl_api_l2_fib_clear_table_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011352 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011353
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011354 M (L2_FIB_CLEAR_TABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011355
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011356 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011357 W (ret);
11358 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011359}
11360
11361static int
11362api_l2_interface_efp_filter (vat_main_t * vam)
11363{
11364 unformat_input_t *i = vam->input;
11365 vl_api_l2_interface_efp_filter_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011366 u32 sw_if_index;
11367 u8 enable = 1;
11368 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011369 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011370
11371 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11372 {
11373 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11374 sw_if_index_set = 1;
11375 else if (unformat (i, "sw_if_index %d", &sw_if_index))
11376 sw_if_index_set = 1;
11377 else if (unformat (i, "enable"))
11378 enable = 1;
11379 else if (unformat (i, "disable"))
11380 enable = 0;
11381 else
11382 {
11383 clib_warning ("parse error '%U'", format_unformat_error, i);
11384 return -99;
11385 }
11386 }
11387
11388 if (sw_if_index_set == 0)
11389 {
11390 errmsg ("missing sw_if_index");
11391 return -99;
11392 }
11393
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011394 M (L2_INTERFACE_EFP_FILTER, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011395
11396 mp->sw_if_index = ntohl (sw_if_index);
11397 mp->enable_disable = enable;
11398
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011399 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011400 W (ret);
11401 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011402}
11403
11404#define foreach_vtr_op \
11405_("disable", L2_VTR_DISABLED) \
11406_("push-1", L2_VTR_PUSH_1) \
11407_("push-2", L2_VTR_PUSH_2) \
11408_("pop-1", L2_VTR_POP_1) \
11409_("pop-2", L2_VTR_POP_2) \
11410_("translate-1-1", L2_VTR_TRANSLATE_1_1) \
11411_("translate-1-2", L2_VTR_TRANSLATE_1_2) \
11412_("translate-2-1", L2_VTR_TRANSLATE_2_1) \
11413_("translate-2-2", L2_VTR_TRANSLATE_2_2)
11414
11415static int
11416api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
11417{
11418 unformat_input_t *i = vam->input;
11419 vl_api_l2_interface_vlan_tag_rewrite_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011420 u32 sw_if_index;
11421 u8 sw_if_index_set = 0;
11422 u8 vtr_op_set = 0;
11423 u32 vtr_op = 0;
11424 u32 push_dot1q = 1;
11425 u32 tag1 = ~0;
11426 u32 tag2 = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011427 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011428
11429 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11430 {
11431 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11432 sw_if_index_set = 1;
11433 else if (unformat (i, "sw_if_index %d", &sw_if_index))
11434 sw_if_index_set = 1;
11435 else if (unformat (i, "vtr_op %d", &vtr_op))
11436 vtr_op_set = 1;
11437#define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
11438 foreach_vtr_op
11439#undef _
11440 else if (unformat (i, "push_dot1q %d", &push_dot1q))
11441 ;
11442 else if (unformat (i, "tag1 %d", &tag1))
11443 ;
11444 else if (unformat (i, "tag2 %d", &tag2))
11445 ;
11446 else
11447 {
11448 clib_warning ("parse error '%U'", format_unformat_error, i);
11449 return -99;
11450 }
11451 }
11452
11453 if ((sw_if_index_set == 0) || (vtr_op_set == 0))
11454 {
11455 errmsg ("missing vtr operation or sw_if_index");
11456 return -99;
11457 }
11458
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011459 M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
11460 mp->sw_if_index = ntohl (sw_if_index);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011461 mp->vtr_op = ntohl (vtr_op);
11462 mp->push_dot1q = ntohl (push_dot1q);
11463 mp->tag1 = ntohl (tag1);
11464 mp->tag2 = ntohl (tag2);
11465
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011466 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011467 W (ret);
11468 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011469}
11470
11471static int
11472api_create_vhost_user_if (vat_main_t * vam)
11473{
11474 unformat_input_t *i = vam->input;
11475 vl_api_create_vhost_user_if_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011476 u8 *file_name;
11477 u8 is_server = 0;
11478 u8 file_name_set = 0;
11479 u32 custom_dev_instance = ~0;
11480 u8 hwaddr[6];
11481 u8 use_custom_mac = 0;
11482 u8 *tag = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011483 int ret;
Steven7312cc72017-03-15 21:18:55 -070011484 u8 operation_mode = VHOST_USER_POLLING_MODE;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011485
11486 /* Shut up coverity */
11487 memset (hwaddr, 0, sizeof (hwaddr));
11488
11489 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11490 {
11491 if (unformat (i, "socket %s", &file_name))
11492 {
11493 file_name_set = 1;
11494 }
11495 else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11496 ;
11497 else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
11498 use_custom_mac = 1;
11499 else if (unformat (i, "server"))
11500 is_server = 1;
11501 else if (unformat (i, "tag %s", &tag))
11502 ;
Steven7312cc72017-03-15 21:18:55 -070011503 else if (unformat (i, "mode %U",
11504 api_unformat_vhost_user_operation_mode,
11505 &operation_mode))
11506 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011507 else
11508 break;
11509 }
11510
11511 if (file_name_set == 0)
11512 {
11513 errmsg ("missing socket file name");
11514 return -99;
11515 }
11516
11517 if (vec_len (file_name) > 255)
11518 {
11519 errmsg ("socket file name too long");
11520 return -99;
11521 }
11522 vec_add1 (file_name, 0);
11523
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011524 M (CREATE_VHOST_USER_IF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011525
Steven7312cc72017-03-15 21:18:55 -070011526 mp->operation_mode = operation_mode;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011527 mp->is_server = is_server;
11528 clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11529 vec_free (file_name);
11530 if (custom_dev_instance != ~0)
11531 {
11532 mp->renumber = 1;
11533 mp->custom_dev_instance = ntohl (custom_dev_instance);
11534 }
11535 mp->use_custom_mac = use_custom_mac;
11536 clib_memcpy (mp->mac_address, hwaddr, 6);
11537 if (tag)
11538 strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
11539 vec_free (tag);
11540
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011541 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011542 W (ret);
11543 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011544}
11545
11546static int
11547api_modify_vhost_user_if (vat_main_t * vam)
11548{
11549 unformat_input_t *i = vam->input;
11550 vl_api_modify_vhost_user_if_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011551 u8 *file_name;
11552 u8 is_server = 0;
11553 u8 file_name_set = 0;
11554 u32 custom_dev_instance = ~0;
11555 u8 sw_if_index_set = 0;
11556 u32 sw_if_index = (u32) ~ 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011557 int ret;
Steven7312cc72017-03-15 21:18:55 -070011558 u8 operation_mode = VHOST_USER_POLLING_MODE;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011559
11560 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11561 {
11562 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11563 sw_if_index_set = 1;
11564 else if (unformat (i, "sw_if_index %d", &sw_if_index))
11565 sw_if_index_set = 1;
11566 else if (unformat (i, "socket %s", &file_name))
11567 {
11568 file_name_set = 1;
11569 }
11570 else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11571 ;
11572 else if (unformat (i, "server"))
11573 is_server = 1;
Steven7312cc72017-03-15 21:18:55 -070011574 else if (unformat (i, "mode %U",
11575 api_unformat_vhost_user_operation_mode,
11576 &operation_mode))
11577 ;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011578 else
11579 break;
11580 }
11581
11582 if (sw_if_index_set == 0)
11583 {
11584 errmsg ("missing sw_if_index or interface name");
11585 return -99;
11586 }
11587
11588 if (file_name_set == 0)
11589 {
11590 errmsg ("missing socket file name");
11591 return -99;
11592 }
11593
11594 if (vec_len (file_name) > 255)
11595 {
11596 errmsg ("socket file name too long");
11597 return -99;
11598 }
11599 vec_add1 (file_name, 0);
11600
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011601 M (MODIFY_VHOST_USER_IF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011602
Steven7312cc72017-03-15 21:18:55 -070011603 mp->operation_mode = operation_mode;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011604 mp->sw_if_index = ntohl (sw_if_index);
11605 mp->is_server = is_server;
11606 clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11607 vec_free (file_name);
11608 if (custom_dev_instance != ~0)
11609 {
11610 mp->renumber = 1;
11611 mp->custom_dev_instance = ntohl (custom_dev_instance);
11612 }
11613
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011614 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011615 W (ret);
11616 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011617}
11618
11619static int
11620api_delete_vhost_user_if (vat_main_t * vam)
11621{
11622 unformat_input_t *i = vam->input;
11623 vl_api_delete_vhost_user_if_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011624 u32 sw_if_index = ~0;
11625 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011626 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011627
11628 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11629 {
11630 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11631 sw_if_index_set = 1;
11632 else if (unformat (i, "sw_if_index %d", &sw_if_index))
11633 sw_if_index_set = 1;
11634 else
11635 break;
11636 }
11637
11638 if (sw_if_index_set == 0)
11639 {
11640 errmsg ("missing sw_if_index or interface name");
11641 return -99;
11642 }
11643
11644
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011645 M (DELETE_VHOST_USER_IF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011646
11647 mp->sw_if_index = ntohl (sw_if_index);
11648
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011649 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011650 W (ret);
11651 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011652}
11653
11654static void vl_api_sw_interface_vhost_user_details_t_handler
11655 (vl_api_sw_interface_vhost_user_details_t * mp)
11656{
11657 vat_main_t *vam = &vat_main;
11658
Steven7312cc72017-03-15 21:18:55 -070011659 print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %U %s",
Damjan Marion7cd468a2016-12-19 23:05:39 +010011660 (char *) mp->interface_name,
11661 ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
11662 clib_net_to_host_u64 (mp->features), mp->is_server,
Steven7312cc72017-03-15 21:18:55 -070011663 ntohl (mp->num_regions), api_format_vhost_user_operation_mode,
11664 mp->operation_mode, (char *) mp->sock_filename);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011665 print (vam->ofp, " Status: '%s'", strerror (ntohl (mp->sock_errno)));
11666}
11667
11668static void vl_api_sw_interface_vhost_user_details_t_handler_json
11669 (vl_api_sw_interface_vhost_user_details_t * mp)
11670{
11671 vat_main_t *vam = &vat_main;
11672 vat_json_node_t *node = NULL;
11673
11674 if (VAT_JSON_ARRAY != vam->json_tree.type)
11675 {
11676 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11677 vat_json_init_array (&vam->json_tree);
11678 }
11679 node = vat_json_array_add (&vam->json_tree);
11680
11681 vat_json_init_object (node);
11682 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11683 vat_json_object_add_string_copy (node, "interface_name",
11684 mp->interface_name);
11685 vat_json_object_add_uint (node, "virtio_net_hdr_sz",
11686 ntohl (mp->virtio_net_hdr_sz));
11687 vat_json_object_add_uint (node, "features",
11688 clib_net_to_host_u64 (mp->features));
11689 vat_json_object_add_uint (node, "is_server", mp->is_server);
11690 vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
11691 vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
11692 vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
Steven7312cc72017-03-15 21:18:55 -070011693 vat_json_object_add_uint (node, "mode", mp->operation_mode);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011694}
11695
11696static int
11697api_sw_interface_vhost_user_dump (vat_main_t * vam)
11698{
11699 vl_api_sw_interface_vhost_user_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011700 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011701 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011702 print (vam->ofp,
Steven7312cc72017-03-15 21:18:55 -070011703 "Interface name idx hdr_sz features server regions mode"
11704 " filename");
Damjan Marion7cd468a2016-12-19 23:05:39 +010011705
11706 /* Get list of vhost-user interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011707 M (SW_INTERFACE_VHOST_USER_DUMP, mp);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011708 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011709
11710 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011711 M (CONTROL_PING, mp_ping);
11712 S (mp_ping);
11713
Jon Loeliger56c7b012017-02-01 12:31:41 -060011714 W (ret);
11715 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011716}
11717
11718static int
11719api_show_version (vat_main_t * vam)
11720{
11721 vl_api_show_version_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011722 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011723
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011724 M (SHOW_VERSION, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011725
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011726 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011727 W (ret);
11728 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011729}
11730
11731
11732static int
11733api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
11734{
11735 unformat_input_t *line_input = vam->input;
11736 vl_api_vxlan_gpe_add_del_tunnel_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011737 ip4_address_t local4, remote4;
11738 ip6_address_t local6, remote6;
11739 u8 is_add = 1;
11740 u8 ipv4_set = 0, ipv6_set = 0;
11741 u8 local_set = 0;
11742 u8 remote_set = 0;
11743 u32 encap_vrf_id = 0;
11744 u32 decap_vrf_id = 0;
11745 u8 protocol = ~0;
11746 u32 vni;
11747 u8 vni_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011748 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011749
11750 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11751 {
11752 if (unformat (line_input, "del"))
11753 is_add = 0;
11754 else if (unformat (line_input, "local %U",
11755 unformat_ip4_address, &local4))
11756 {
11757 local_set = 1;
11758 ipv4_set = 1;
11759 }
11760 else if (unformat (line_input, "remote %U",
11761 unformat_ip4_address, &remote4))
11762 {
11763 remote_set = 1;
11764 ipv4_set = 1;
11765 }
11766 else if (unformat (line_input, "local %U",
11767 unformat_ip6_address, &local6))
11768 {
11769 local_set = 1;
11770 ipv6_set = 1;
11771 }
11772 else if (unformat (line_input, "remote %U",
11773 unformat_ip6_address, &remote6))
11774 {
11775 remote_set = 1;
11776 ipv6_set = 1;
11777 }
11778 else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11779 ;
11780 else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
11781 ;
11782 else if (unformat (line_input, "vni %d", &vni))
11783 vni_set = 1;
11784 else if (unformat (line_input, "next-ip4"))
11785 protocol = 1;
11786 else if (unformat (line_input, "next-ip6"))
11787 protocol = 2;
11788 else if (unformat (line_input, "next-ethernet"))
11789 protocol = 3;
11790 else if (unformat (line_input, "next-nsh"))
11791 protocol = 4;
11792 else
11793 {
11794 errmsg ("parse error '%U'", format_unformat_error, line_input);
11795 return -99;
11796 }
11797 }
11798
11799 if (local_set == 0)
11800 {
11801 errmsg ("tunnel local address not specified");
11802 return -99;
11803 }
11804 if (remote_set == 0)
11805 {
11806 errmsg ("tunnel remote address not specified");
11807 return -99;
11808 }
11809 if (ipv4_set && ipv6_set)
11810 {
11811 errmsg ("both IPv4 and IPv6 addresses specified");
11812 return -99;
11813 }
11814
11815 if (vni_set == 0)
11816 {
11817 errmsg ("vni not specified");
11818 return -99;
11819 }
11820
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011821 M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011822
11823
11824 if (ipv6_set)
11825 {
11826 clib_memcpy (&mp->local, &local6, sizeof (local6));
11827 clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
11828 }
11829 else
11830 {
11831 clib_memcpy (&mp->local, &local4, sizeof (local4));
11832 clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
11833 }
11834
11835 mp->encap_vrf_id = ntohl (encap_vrf_id);
11836 mp->decap_vrf_id = ntohl (decap_vrf_id);
11837 mp->protocol = protocol;
11838 mp->vni = ntohl (vni);
11839 mp->is_add = is_add;
11840 mp->is_ipv6 = ipv6_set;
11841
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011842 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011843 W (ret);
11844 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011845}
11846
11847static void vl_api_vxlan_gpe_tunnel_details_t_handler
11848 (vl_api_vxlan_gpe_tunnel_details_t * mp)
11849{
11850 vat_main_t *vam = &vat_main;
11851
11852 print (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d",
11853 ntohl (mp->sw_if_index),
11854 format_ip46_address, &(mp->local[0]),
11855 format_ip46_address, &(mp->remote[0]),
11856 ntohl (mp->vni),
11857 ntohl (mp->protocol),
11858 ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
11859}
11860
11861static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
11862 (vl_api_vxlan_gpe_tunnel_details_t * mp)
11863{
11864 vat_main_t *vam = &vat_main;
11865 vat_json_node_t *node = NULL;
11866 struct in_addr ip4;
11867 struct in6_addr ip6;
11868
11869 if (VAT_JSON_ARRAY != vam->json_tree.type)
11870 {
11871 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11872 vat_json_init_array (&vam->json_tree);
11873 }
11874 node = vat_json_array_add (&vam->json_tree);
11875
11876 vat_json_init_object (node);
11877 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11878 if (mp->is_ipv6)
11879 {
11880 clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
11881 vat_json_object_add_ip6 (node, "local", ip6);
11882 clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
11883 vat_json_object_add_ip6 (node, "remote", ip6);
11884 }
11885 else
11886 {
11887 clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
11888 vat_json_object_add_ip4 (node, "local", ip4);
11889 clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
11890 vat_json_object_add_ip4 (node, "remote", ip4);
11891 }
11892 vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11893 vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
11894 vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11895 vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
11896 vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11897}
11898
11899static int
11900api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
11901{
11902 unformat_input_t *i = vam->input;
11903 vl_api_vxlan_gpe_tunnel_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011904 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011905 u32 sw_if_index;
11906 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011907 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011908
11909 /* Parse args required to build the message */
11910 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11911 {
11912 if (unformat (i, "sw_if_index %d", &sw_if_index))
11913 sw_if_index_set = 1;
11914 else
11915 break;
11916 }
11917
11918 if (sw_if_index_set == 0)
11919 {
11920 sw_if_index = ~0;
11921 }
11922
11923 if (!vam->json_output)
11924 {
11925 print (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s",
11926 "sw_if_index", "local", "remote", "vni",
11927 "protocol", "encap_vrf_id", "decap_vrf_id");
11928 }
11929
11930 /* Get list of vxlan-tunnel interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011931 M (VXLAN_GPE_TUNNEL_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011932
11933 mp->sw_if_index = htonl (sw_if_index);
11934
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011935 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011936
11937 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011938 M (CONTROL_PING, mp_ping);
11939 S (mp_ping);
11940
Jon Loeliger56c7b012017-02-01 12:31:41 -060011941 W (ret);
11942 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011943}
11944
11945u8 *
11946format_l2_fib_mac_address (u8 * s, va_list * args)
11947{
11948 u8 *a = va_arg (*args, u8 *);
11949
11950 return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11951 a[2], a[3], a[4], a[5], a[6], a[7]);
11952}
11953
Ole Troan01384fe2017-05-12 11:55:35 +020011954static void vl_api_l2_fib_table_details_t_handler
11955 (vl_api_l2_fib_table_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010011956{
11957 vat_main_t *vam = &vat_main;
11958
11959 print (vam->ofp, "%3" PRIu32 " %U %3" PRIu32
11960 " %d %d %d",
11961 ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11962 ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11963 mp->bvi_mac);
11964}
11965
Ole Troan01384fe2017-05-12 11:55:35 +020011966static void vl_api_l2_fib_table_details_t_handler_json
11967 (vl_api_l2_fib_table_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010011968{
11969 vat_main_t *vam = &vat_main;
11970 vat_json_node_t *node = NULL;
11971
11972 if (VAT_JSON_ARRAY != vam->json_tree.type)
11973 {
11974 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11975 vat_json_init_array (&vam->json_tree);
11976 }
11977 node = vat_json_array_add (&vam->json_tree);
11978
11979 vat_json_init_object (node);
11980 vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11981 vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11982 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11983 vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11984 vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11985 vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11986}
11987
11988static int
11989api_l2_fib_table_dump (vat_main_t * vam)
11990{
11991 unformat_input_t *i = vam->input;
11992 vl_api_l2_fib_table_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011993 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011994 u32 bd_id;
11995 u8 bd_id_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011996 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011997
11998 /* Parse args required to build the message */
11999 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12000 {
12001 if (unformat (i, "bd_id %d", &bd_id))
12002 bd_id_set = 1;
12003 else
12004 break;
12005 }
12006
12007 if (bd_id_set == 0)
12008 {
12009 errmsg ("missing bridge domain");
12010 return -99;
12011 }
12012
12013 print (vam->ofp, "BD-ID Mac Address sw-ndx Static Filter BVI");
12014
12015 /* Get list of l2 fib entries */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012016 M (L2_FIB_TABLE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012017
12018 mp->bd_id = ntohl (bd_id);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012019 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012020
12021 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012022 M (CONTROL_PING, mp_ping);
12023 S (mp_ping);
12024
Jon Loeliger56c7b012017-02-01 12:31:41 -060012025 W (ret);
12026 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012027}
12028
12029
12030static int
12031api_interface_name_renumber (vat_main_t * vam)
12032{
12033 unformat_input_t *line_input = vam->input;
12034 vl_api_interface_name_renumber_t *mp;
12035 u32 sw_if_index = ~0;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012036 u32 new_show_dev_instance = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012037 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012038
12039 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12040 {
12041 if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
12042 &sw_if_index))
12043 ;
12044 else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12045 ;
12046 else if (unformat (line_input, "new_show_dev_instance %d",
12047 &new_show_dev_instance))
12048 ;
12049 else
12050 break;
12051 }
12052
12053 if (sw_if_index == ~0)
12054 {
12055 errmsg ("missing interface name or sw_if_index");
12056 return -99;
12057 }
12058
12059 if (new_show_dev_instance == ~0)
12060 {
12061 errmsg ("missing new_show_dev_instance");
12062 return -99;
12063 }
12064
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012065 M (INTERFACE_NAME_RENUMBER, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012066
12067 mp->sw_if_index = ntohl (sw_if_index);
12068 mp->new_show_dev_instance = ntohl (new_show_dev_instance);
12069
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012070 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012071 W (ret);
12072 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012073}
12074
12075static int
12076api_want_ip4_arp_events (vat_main_t * vam)
12077{
12078 unformat_input_t *line_input = vam->input;
12079 vl_api_want_ip4_arp_events_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012080 ip4_address_t address;
12081 int address_set = 0;
12082 u32 enable_disable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012083 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012084
12085 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12086 {
12087 if (unformat (line_input, "address %U", unformat_ip4_address, &address))
12088 address_set = 1;
12089 else if (unformat (line_input, "del"))
12090 enable_disable = 0;
12091 else
12092 break;
12093 }
12094
12095 if (address_set == 0)
12096 {
12097 errmsg ("missing addresses");
12098 return -99;
12099 }
12100
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012101 M (WANT_IP4_ARP_EVENTS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012102 mp->enable_disable = enable_disable;
John Lo20e1f2a2017-03-29 13:35:43 -040012103 mp->pid = htonl (getpid ());
Damjan Marion7cd468a2016-12-19 23:05:39 +010012104 mp->address = address.as_u32;
12105
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012106 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012107 W (ret);
12108 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012109}
12110
12111static int
12112api_want_ip6_nd_events (vat_main_t * vam)
12113{
12114 unformat_input_t *line_input = vam->input;
12115 vl_api_want_ip6_nd_events_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012116 ip6_address_t address;
12117 int address_set = 0;
12118 u32 enable_disable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012119 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012120
12121 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12122 {
12123 if (unformat (line_input, "address %U", unformat_ip6_address, &address))
12124 address_set = 1;
12125 else if (unformat (line_input, "del"))
12126 enable_disable = 0;
12127 else
12128 break;
12129 }
12130
12131 if (address_set == 0)
12132 {
12133 errmsg ("missing addresses");
12134 return -99;
12135 }
12136
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012137 M (WANT_IP6_ND_EVENTS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012138 mp->enable_disable = enable_disable;
John Lo20e1f2a2017-03-29 13:35:43 -040012139 mp->pid = htonl (getpid ());
Damjan Marion7cd468a2016-12-19 23:05:39 +010012140 clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
12141
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012142 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012143 W (ret);
12144 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012145}
12146
12147static int
12148api_input_acl_set_interface (vat_main_t * vam)
12149{
12150 unformat_input_t *i = vam->input;
12151 vl_api_input_acl_set_interface_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012152 u32 sw_if_index;
12153 int sw_if_index_set;
12154 u32 ip4_table_index = ~0;
12155 u32 ip6_table_index = ~0;
12156 u32 l2_table_index = ~0;
12157 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012158 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012159
12160 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12161 {
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, "sw_if_index %d", &sw_if_index))
12165 sw_if_index_set = 1;
12166 else if (unformat (i, "del"))
12167 is_add = 0;
12168 else if (unformat (i, "ip4-table %d", &ip4_table_index))
12169 ;
12170 else if (unformat (i, "ip6-table %d", &ip6_table_index))
12171 ;
12172 else if (unformat (i, "l2-table %d", &l2_table_index))
12173 ;
12174 else
12175 {
12176 clib_warning ("parse error '%U'", format_unformat_error, i);
12177 return -99;
12178 }
12179 }
12180
12181 if (sw_if_index_set == 0)
12182 {
12183 errmsg ("missing interface name or sw_if_index");
12184 return -99;
12185 }
12186
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012187 M (INPUT_ACL_SET_INTERFACE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012188
12189 mp->sw_if_index = ntohl (sw_if_index);
12190 mp->ip4_table_index = ntohl (ip4_table_index);
12191 mp->ip6_table_index = ntohl (ip6_table_index);
12192 mp->l2_table_index = ntohl (l2_table_index);
12193 mp->is_add = is_add;
12194
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012195 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012196 W (ret);
12197 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012198}
12199
12200static int
12201api_ip_address_dump (vat_main_t * vam)
12202{
12203 unformat_input_t *i = vam->input;
12204 vl_api_ip_address_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012205 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012206 u32 sw_if_index = ~0;
12207 u8 sw_if_index_set = 0;
12208 u8 ipv4_set = 0;
12209 u8 ipv6_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012210 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012211
12212 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12213 {
12214 if (unformat (i, "sw_if_index %d", &sw_if_index))
12215 sw_if_index_set = 1;
12216 else
12217 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12218 sw_if_index_set = 1;
12219 else if (unformat (i, "ipv4"))
12220 ipv4_set = 1;
12221 else if (unformat (i, "ipv6"))
12222 ipv6_set = 1;
12223 else
12224 break;
12225 }
12226
12227 if (ipv4_set && ipv6_set)
12228 {
12229 errmsg ("ipv4 and ipv6 flags cannot be both set");
12230 return -99;
12231 }
12232
12233 if ((!ipv4_set) && (!ipv6_set))
12234 {
12235 errmsg ("no ipv4 nor ipv6 flag set");
12236 return -99;
12237 }
12238
12239 if (sw_if_index_set == 0)
12240 {
12241 errmsg ("missing interface name or sw_if_index");
12242 return -99;
12243 }
12244
12245 vam->current_sw_if_index = sw_if_index;
12246 vam->is_ipv6 = ipv6_set;
12247
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012248 M (IP_ADDRESS_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012249 mp->sw_if_index = ntohl (sw_if_index);
12250 mp->is_ipv6 = ipv6_set;
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012251 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012252
12253 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012254 M (CONTROL_PING, mp_ping);
12255 S (mp_ping);
12256
Jon Loeliger56c7b012017-02-01 12:31:41 -060012257 W (ret);
12258 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012259}
12260
12261static int
12262api_ip_dump (vat_main_t * vam)
12263{
12264 vl_api_ip_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012265 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012266 unformat_input_t *in = vam->input;
12267 int ipv4_set = 0;
12268 int ipv6_set = 0;
12269 int is_ipv6;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012270 int i;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012271 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012272
12273 while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
12274 {
12275 if (unformat (in, "ipv4"))
12276 ipv4_set = 1;
12277 else if (unformat (in, "ipv6"))
12278 ipv6_set = 1;
12279 else
12280 break;
12281 }
12282
12283 if (ipv4_set && ipv6_set)
12284 {
12285 errmsg ("ipv4 and ipv6 flags cannot be both set");
12286 return -99;
12287 }
12288
12289 if ((!ipv4_set) && (!ipv6_set))
12290 {
12291 errmsg ("no ipv4 nor ipv6 flag set");
12292 return -99;
12293 }
12294
12295 is_ipv6 = ipv6_set;
12296 vam->is_ipv6 = is_ipv6;
12297
12298 /* free old data */
12299 for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
12300 {
12301 vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
12302 }
12303 vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
12304
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012305 M (IP_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012306 mp->is_ipv6 = ipv6_set;
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012307 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012308
12309 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012310 M (CONTROL_PING, mp_ping);
12311 S (mp_ping);
12312
Jon Loeliger56c7b012017-02-01 12:31:41 -060012313 W (ret);
12314 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012315}
12316
12317static int
12318api_ipsec_spd_add_del (vat_main_t * vam)
12319{
12320 unformat_input_t *i = vam->input;
12321 vl_api_ipsec_spd_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012322 u32 spd_id = ~0;
12323 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012324 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012325
12326 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12327 {
12328 if (unformat (i, "spd_id %d", &spd_id))
12329 ;
12330 else if (unformat (i, "del"))
12331 is_add = 0;
12332 else
12333 {
12334 clib_warning ("parse error '%U'", format_unformat_error, i);
12335 return -99;
12336 }
12337 }
12338 if (spd_id == ~0)
12339 {
12340 errmsg ("spd_id must be set");
12341 return -99;
12342 }
12343
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012344 M (IPSEC_SPD_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012345
12346 mp->spd_id = ntohl (spd_id);
12347 mp->is_add = is_add;
12348
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012349 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012350 W (ret);
12351 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012352}
12353
12354static int
12355api_ipsec_interface_add_del_spd (vat_main_t * vam)
12356{
12357 unformat_input_t *i = vam->input;
12358 vl_api_ipsec_interface_add_del_spd_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012359 u32 sw_if_index;
12360 u8 sw_if_index_set = 0;
12361 u32 spd_id = (u32) ~ 0;
12362 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012363 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012364
12365 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12366 {
12367 if (unformat (i, "del"))
12368 is_add = 0;
12369 else if (unformat (i, "spd_id %d", &spd_id))
12370 ;
12371 else
12372 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12373 sw_if_index_set = 1;
12374 else if (unformat (i, "sw_if_index %d", &sw_if_index))
12375 sw_if_index_set = 1;
12376 else
12377 {
12378 clib_warning ("parse error '%U'", format_unformat_error, i);
12379 return -99;
12380 }
12381
12382 }
12383
12384 if (spd_id == (u32) ~ 0)
12385 {
12386 errmsg ("spd_id must be set");
12387 return -99;
12388 }
12389
12390 if (sw_if_index_set == 0)
12391 {
12392 errmsg ("missing interface name or sw_if_index");
12393 return -99;
12394 }
12395
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012396 M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012397
12398 mp->spd_id = ntohl (spd_id);
12399 mp->sw_if_index = ntohl (sw_if_index);
12400 mp->is_add = is_add;
12401
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012402 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012403 W (ret);
12404 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012405}
12406
12407static int
12408api_ipsec_spd_add_del_entry (vat_main_t * vam)
12409{
12410 unformat_input_t *i = vam->input;
12411 vl_api_ipsec_spd_add_del_entry_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012412 u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
12413 u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
12414 i32 priority = 0;
12415 u32 rport_start = 0, rport_stop = (u32) ~ 0;
12416 u32 lport_start = 0, lport_stop = (u32) ~ 0;
12417 ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
12418 ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012419 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012420
12421 laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
12422 laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
12423 laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
12424 laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
12425 laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
12426 laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
12427
12428 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12429 {
12430 if (unformat (i, "del"))
12431 is_add = 0;
12432 if (unformat (i, "outbound"))
12433 is_outbound = 1;
12434 if (unformat (i, "inbound"))
12435 is_outbound = 0;
12436 else if (unformat (i, "spd_id %d", &spd_id))
12437 ;
12438 else if (unformat (i, "sa_id %d", &sa_id))
12439 ;
12440 else if (unformat (i, "priority %d", &priority))
12441 ;
12442 else if (unformat (i, "protocol %d", &protocol))
12443 ;
12444 else if (unformat (i, "lport_start %d", &lport_start))
12445 ;
12446 else if (unformat (i, "lport_stop %d", &lport_stop))
12447 ;
12448 else if (unformat (i, "rport_start %d", &rport_start))
12449 ;
12450 else if (unformat (i, "rport_stop %d", &rport_stop))
12451 ;
12452 else
12453 if (unformat
12454 (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
12455 {
12456 is_ipv6 = 0;
12457 is_ip_any = 0;
12458 }
12459 else
12460 if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
12461 {
12462 is_ipv6 = 0;
12463 is_ip_any = 0;
12464 }
12465 else
12466 if (unformat
12467 (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
12468 {
12469 is_ipv6 = 0;
12470 is_ip_any = 0;
12471 }
12472 else
12473 if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
12474 {
12475 is_ipv6 = 0;
12476 is_ip_any = 0;
12477 }
12478 else
12479 if (unformat
12480 (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
12481 {
12482 is_ipv6 = 1;
12483 is_ip_any = 0;
12484 }
12485 else
12486 if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
12487 {
12488 is_ipv6 = 1;
12489 is_ip_any = 0;
12490 }
12491 else
12492 if (unformat
12493 (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
12494 {
12495 is_ipv6 = 1;
12496 is_ip_any = 0;
12497 }
12498 else
12499 if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
12500 {
12501 is_ipv6 = 1;
12502 is_ip_any = 0;
12503 }
12504 else
12505 if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
12506 {
12507 if (policy == IPSEC_POLICY_ACTION_RESOLVE)
12508 {
12509 clib_warning ("unsupported action: 'resolve'");
12510 return -99;
12511 }
12512 }
12513 else
12514 {
12515 clib_warning ("parse error '%U'", format_unformat_error, i);
12516 return -99;
12517 }
12518
12519 }
12520
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012521 M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012522
12523 mp->spd_id = ntohl (spd_id);
12524 mp->priority = ntohl (priority);
12525 mp->is_outbound = is_outbound;
12526
12527 mp->is_ipv6 = is_ipv6;
12528 if (is_ipv6 || is_ip_any)
12529 {
12530 clib_memcpy (mp->remote_address_start, &raddr6_start,
12531 sizeof (ip6_address_t));
12532 clib_memcpy (mp->remote_address_stop, &raddr6_stop,
12533 sizeof (ip6_address_t));
12534 clib_memcpy (mp->local_address_start, &laddr6_start,
12535 sizeof (ip6_address_t));
12536 clib_memcpy (mp->local_address_stop, &laddr6_stop,
12537 sizeof (ip6_address_t));
12538 }
12539 else
12540 {
12541 clib_memcpy (mp->remote_address_start, &raddr4_start,
12542 sizeof (ip4_address_t));
12543 clib_memcpy (mp->remote_address_stop, &raddr4_stop,
12544 sizeof (ip4_address_t));
12545 clib_memcpy (mp->local_address_start, &laddr4_start,
12546 sizeof (ip4_address_t));
12547 clib_memcpy (mp->local_address_stop, &laddr4_stop,
12548 sizeof (ip4_address_t));
12549 }
12550 mp->protocol = (u8) protocol;
12551 mp->local_port_start = ntohs ((u16) lport_start);
12552 mp->local_port_stop = ntohs ((u16) lport_stop);
12553 mp->remote_port_start = ntohs ((u16) rport_start);
12554 mp->remote_port_stop = ntohs ((u16) rport_stop);
12555 mp->policy = (u8) policy;
12556 mp->sa_id = ntohl (sa_id);
12557 mp->is_add = is_add;
12558 mp->is_ip_any = is_ip_any;
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012559 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012560 W (ret);
12561 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012562}
12563
12564static int
12565api_ipsec_sad_add_del_entry (vat_main_t * vam)
12566{
12567 unformat_input_t *i = vam->input;
12568 vl_api_ipsec_sad_add_del_entry_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012569 u32 sad_id = 0, spi = 0;
12570 u8 *ck = 0, *ik = 0;
12571 u8 is_add = 1;
12572
12573 u8 protocol = IPSEC_PROTOCOL_AH;
12574 u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
12575 u32 crypto_alg = 0, integ_alg = 0;
12576 ip4_address_t tun_src4;
12577 ip4_address_t tun_dst4;
12578 ip6_address_t tun_src6;
12579 ip6_address_t tun_dst6;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012580 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012581
12582 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12583 {
12584 if (unformat (i, "del"))
12585 is_add = 0;
12586 else if (unformat (i, "sad_id %d", &sad_id))
12587 ;
12588 else if (unformat (i, "spi %d", &spi))
12589 ;
12590 else if (unformat (i, "esp"))
12591 protocol = IPSEC_PROTOCOL_ESP;
12592 else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
12593 {
12594 is_tunnel = 1;
12595 is_tunnel_ipv6 = 0;
12596 }
12597 else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
12598 {
12599 is_tunnel = 1;
12600 is_tunnel_ipv6 = 0;
12601 }
12602 else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
12603 {
12604 is_tunnel = 1;
12605 is_tunnel_ipv6 = 1;
12606 }
12607 else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
12608 {
12609 is_tunnel = 1;
12610 is_tunnel_ipv6 = 1;
12611 }
12612 else
12613 if (unformat
12614 (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
12615 {
12616 if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
12617 crypto_alg >= IPSEC_CRYPTO_N_ALG)
12618 {
12619 clib_warning ("unsupported crypto-alg: '%U'",
12620 format_ipsec_crypto_alg, crypto_alg);
12621 return -99;
12622 }
12623 }
12624 else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12625 ;
12626 else
12627 if (unformat
12628 (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
12629 {
Damjan Marion7cd468a2016-12-19 23:05:39 +010012630 if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
Damjan Marion7cd468a2016-12-19 23:05:39 +010012631 integ_alg >= IPSEC_INTEG_N_ALG)
12632 {
12633 clib_warning ("unsupported integ-alg: '%U'",
12634 format_ipsec_integ_alg, integ_alg);
12635 return -99;
12636 }
12637 }
12638 else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12639 ;
12640 else
12641 {
12642 clib_warning ("parse error '%U'", format_unformat_error, i);
12643 return -99;
12644 }
12645
12646 }
12647
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012648 M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012649
12650 mp->sad_id = ntohl (sad_id);
12651 mp->is_add = is_add;
12652 mp->protocol = protocol;
12653 mp->spi = ntohl (spi);
12654 mp->is_tunnel = is_tunnel;
12655 mp->is_tunnel_ipv6 = is_tunnel_ipv6;
12656 mp->crypto_algorithm = crypto_alg;
12657 mp->integrity_algorithm = integ_alg;
12658 mp->crypto_key_length = vec_len (ck);
12659 mp->integrity_key_length = vec_len (ik);
12660
12661 if (mp->crypto_key_length > sizeof (mp->crypto_key))
12662 mp->crypto_key_length = sizeof (mp->crypto_key);
12663
12664 if (mp->integrity_key_length > sizeof (mp->integrity_key))
12665 mp->integrity_key_length = sizeof (mp->integrity_key);
12666
12667 if (ck)
12668 clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12669 if (ik)
12670 clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12671
12672 if (is_tunnel)
12673 {
12674 if (is_tunnel_ipv6)
12675 {
12676 clib_memcpy (mp->tunnel_src_address, &tun_src6,
12677 sizeof (ip6_address_t));
12678 clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
12679 sizeof (ip6_address_t));
12680 }
12681 else
12682 {
12683 clib_memcpy (mp->tunnel_src_address, &tun_src4,
12684 sizeof (ip4_address_t));
12685 clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
12686 sizeof (ip4_address_t));
12687 }
12688 }
12689
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012690 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012691 W (ret);
12692 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012693}
12694
12695static int
12696api_ipsec_sa_set_key (vat_main_t * vam)
12697{
12698 unformat_input_t *i = vam->input;
12699 vl_api_ipsec_sa_set_key_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012700 u32 sa_id;
12701 u8 *ck = 0, *ik = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012702 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012703
12704 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12705 {
12706 if (unformat (i, "sa_id %d", &sa_id))
12707 ;
12708 else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12709 ;
12710 else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12711 ;
12712 else
12713 {
12714 clib_warning ("parse error '%U'", format_unformat_error, i);
12715 return -99;
12716 }
12717 }
12718
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012719 M (IPSEC_SA_SET_KEY, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012720
12721 mp->sa_id = ntohl (sa_id);
12722 mp->crypto_key_length = vec_len (ck);
12723 mp->integrity_key_length = vec_len (ik);
12724
12725 if (mp->crypto_key_length > sizeof (mp->crypto_key))
12726 mp->crypto_key_length = sizeof (mp->crypto_key);
12727
12728 if (mp->integrity_key_length > sizeof (mp->integrity_key))
12729 mp->integrity_key_length = sizeof (mp->integrity_key);
12730
12731 if (ck)
12732 clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12733 if (ik)
12734 clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12735
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012736 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012737 W (ret);
12738 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012739}
12740
12741static int
Matthew Smithb0972cb2017-05-02 16:20:41 -050012742api_ipsec_tunnel_if_add_del (vat_main_t * vam)
12743{
12744 unformat_input_t *i = vam->input;
12745 vl_api_ipsec_tunnel_if_add_del_t *mp;
12746 u32 local_spi = 0, remote_spi = 0;
12747 u32 crypto_alg = 0, integ_alg = 0;
12748 u8 *lck = NULL, *rck = NULL;
12749 u8 *lik = NULL, *rik = NULL;
12750 ip4_address_t local_ip = { {0} };
12751 ip4_address_t remote_ip = { {0} };
12752 u8 is_add = 1;
12753 u8 esn = 0;
12754 u8 anti_replay = 0;
12755 int ret;
12756
12757 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12758 {
12759 if (unformat (i, "del"))
12760 is_add = 0;
12761 else if (unformat (i, "esn"))
12762 esn = 1;
12763 else if (unformat (i, "anti_replay"))
12764 anti_replay = 1;
12765 else if (unformat (i, "local_spi %d", &local_spi))
12766 ;
12767 else if (unformat (i, "remote_spi %d", &remote_spi))
12768 ;
12769 else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
12770 ;
12771 else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
12772 ;
12773 else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
12774 ;
12775 else
12776 if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
12777 ;
12778 else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
12779 ;
12780 else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
12781 ;
12782 else
12783 if (unformat
12784 (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
12785 {
12786 if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
12787 crypto_alg >= IPSEC_CRYPTO_N_ALG)
12788 {
12789 errmsg ("unsupported crypto-alg: '%U'\n",
12790 format_ipsec_crypto_alg, crypto_alg);
12791 return -99;
12792 }
12793 }
12794 else
12795 if (unformat
12796 (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
12797 {
12798 if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
12799 integ_alg >= IPSEC_INTEG_N_ALG)
12800 {
12801 errmsg ("unsupported integ-alg: '%U'\n",
12802 format_ipsec_integ_alg, integ_alg);
12803 return -99;
12804 }
12805 }
12806 else
12807 {
12808 errmsg ("parse error '%U'\n", format_unformat_error, i);
12809 return -99;
12810 }
12811 }
12812
12813 M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
12814
12815 mp->is_add = is_add;
12816 mp->esn = esn;
12817 mp->anti_replay = anti_replay;
12818
12819 clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
12820 clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
12821
12822 mp->local_spi = htonl (local_spi);
12823 mp->remote_spi = htonl (remote_spi);
12824 mp->crypto_alg = (u8) crypto_alg;
12825
12826 mp->local_crypto_key_len = 0;
12827 if (lck)
12828 {
12829 mp->local_crypto_key_len = vec_len (lck);
12830 if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
12831 mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
12832 clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
12833 }
12834
12835 mp->remote_crypto_key_len = 0;
12836 if (rck)
12837 {
12838 mp->remote_crypto_key_len = vec_len (rck);
12839 if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
12840 mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
12841 clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
12842 }
12843
12844 mp->integ_alg = (u8) integ_alg;
12845
12846 mp->local_integ_key_len = 0;
12847 if (lik)
12848 {
12849 mp->local_integ_key_len = vec_len (lik);
12850 if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
12851 mp->local_integ_key_len = sizeof (mp->local_integ_key);
12852 clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
12853 }
12854
12855 mp->remote_integ_key_len = 0;
12856 if (rik)
12857 {
12858 mp->remote_integ_key_len = vec_len (rik);
12859 if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
12860 mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
12861 clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
12862 }
12863
12864 S (mp);
12865 W (ret);
12866 return ret;
12867}
12868
12869static int
Damjan Marion7cd468a2016-12-19 23:05:39 +010012870api_ikev2_profile_add_del (vat_main_t * vam)
12871{
12872 unformat_input_t *i = vam->input;
12873 vl_api_ikev2_profile_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012874 u8 is_add = 1;
12875 u8 *name = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012876 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012877
12878 const char *valid_chars = "a-zA-Z0-9_";
12879
12880 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12881 {
12882 if (unformat (i, "del"))
12883 is_add = 0;
12884 else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12885 vec_add1 (name, 0);
12886 else
12887 {
12888 errmsg ("parse error '%U'", format_unformat_error, i);
12889 return -99;
12890 }
12891 }
12892
12893 if (!vec_len (name))
12894 {
12895 errmsg ("profile name must be specified");
12896 return -99;
12897 }
12898
12899 if (vec_len (name) > 64)
12900 {
12901 errmsg ("profile name too long");
12902 return -99;
12903 }
12904
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012905 M (IKEV2_PROFILE_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012906
12907 clib_memcpy (mp->name, name, vec_len (name));
12908 mp->is_add = is_add;
12909 vec_free (name);
12910
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012911 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012912 W (ret);
12913 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012914}
12915
12916static int
12917api_ikev2_profile_set_auth (vat_main_t * vam)
12918{
12919 unformat_input_t *i = vam->input;
12920 vl_api_ikev2_profile_set_auth_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012921 u8 *name = 0;
12922 u8 *data = 0;
12923 u32 auth_method = 0;
12924 u8 is_hex = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012925 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012926
12927 const char *valid_chars = "a-zA-Z0-9_";
12928
12929 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12930 {
12931 if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12932 vec_add1 (name, 0);
12933 else if (unformat (i, "auth_method %U",
12934 unformat_ikev2_auth_method, &auth_method))
12935 ;
12936 else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
12937 is_hex = 1;
12938 else if (unformat (i, "auth_data %v", &data))
12939 ;
12940 else
12941 {
12942 errmsg ("parse error '%U'", format_unformat_error, i);
12943 return -99;
12944 }
12945 }
12946
12947 if (!vec_len (name))
12948 {
12949 errmsg ("profile name must be specified");
12950 return -99;
12951 }
12952
12953 if (vec_len (name) > 64)
12954 {
12955 errmsg ("profile name too long");
12956 return -99;
12957 }
12958
12959 if (!vec_len (data))
12960 {
12961 errmsg ("auth_data must be specified");
12962 return -99;
12963 }
12964
12965 if (!auth_method)
12966 {
12967 errmsg ("auth_method must be specified");
12968 return -99;
12969 }
12970
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012971 M (IKEV2_PROFILE_SET_AUTH, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012972
12973 mp->is_hex = is_hex;
12974 mp->auth_method = (u8) auth_method;
12975 mp->data_len = vec_len (data);
12976 clib_memcpy (mp->name, name, vec_len (name));
12977 clib_memcpy (mp->data, data, vec_len (data));
12978 vec_free (name);
12979 vec_free (data);
12980
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012981 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012982 W (ret);
12983 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012984}
12985
12986static int
12987api_ikev2_profile_set_id (vat_main_t * vam)
12988{
12989 unformat_input_t *i = vam->input;
12990 vl_api_ikev2_profile_set_id_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012991 u8 *name = 0;
12992 u8 *data = 0;
12993 u8 is_local = 0;
12994 u32 id_type = 0;
12995 ip4_address_t ip4;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012996 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012997
12998 const char *valid_chars = "a-zA-Z0-9_";
12999
13000 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13001 {
13002 if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13003 vec_add1 (name, 0);
13004 else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
13005 ;
13006 else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
13007 {
13008 data = vec_new (u8, 4);
13009 clib_memcpy (data, ip4.as_u8, 4);
13010 }
13011 else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
13012 ;
13013 else if (unformat (i, "id_data %v", &data))
13014 ;
13015 else if (unformat (i, "local"))
13016 is_local = 1;
13017 else if (unformat (i, "remote"))
13018 is_local = 0;
13019 else
13020 {
13021 errmsg ("parse error '%U'", format_unformat_error, i);
13022 return -99;
13023 }
13024 }
13025
13026 if (!vec_len (name))
13027 {
13028 errmsg ("profile name must be specified");
13029 return -99;
13030 }
13031
13032 if (vec_len (name) > 64)
13033 {
13034 errmsg ("profile name too long");
13035 return -99;
13036 }
13037
13038 if (!vec_len (data))
13039 {
13040 errmsg ("id_data must be specified");
13041 return -99;
13042 }
13043
13044 if (!id_type)
13045 {
13046 errmsg ("id_type must be specified");
13047 return -99;
13048 }
13049
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013050 M (IKEV2_PROFILE_SET_ID, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013051
13052 mp->is_local = is_local;
13053 mp->id_type = (u8) id_type;
13054 mp->data_len = vec_len (data);
13055 clib_memcpy (mp->name, name, vec_len (name));
13056 clib_memcpy (mp->data, data, vec_len (data));
13057 vec_free (name);
13058 vec_free (data);
13059
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013060 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013061 W (ret);
13062 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013063}
13064
13065static int
13066api_ikev2_profile_set_ts (vat_main_t * vam)
13067{
13068 unformat_input_t *i = vam->input;
13069 vl_api_ikev2_profile_set_ts_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013070 u8 *name = 0;
13071 u8 is_local = 0;
13072 u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
13073 ip4_address_t start_addr, end_addr;
13074
13075 const char *valid_chars = "a-zA-Z0-9_";
Jon Loeliger56c7b012017-02-01 12:31:41 -060013076 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013077
13078 start_addr.as_u32 = 0;
13079 end_addr.as_u32 = (u32) ~ 0;
13080
13081 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13082 {
13083 if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13084 vec_add1 (name, 0);
13085 else if (unformat (i, "protocol %d", &proto))
13086 ;
13087 else if (unformat (i, "start_port %d", &start_port))
13088 ;
13089 else if (unformat (i, "end_port %d", &end_port))
13090 ;
13091 else
13092 if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
13093 ;
13094 else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
13095 ;
13096 else if (unformat (i, "local"))
13097 is_local = 1;
13098 else if (unformat (i, "remote"))
13099 is_local = 0;
13100 else
13101 {
13102 errmsg ("parse error '%U'", format_unformat_error, i);
13103 return -99;
13104 }
13105 }
13106
13107 if (!vec_len (name))
13108 {
13109 errmsg ("profile name must be specified");
13110 return -99;
13111 }
13112
13113 if (vec_len (name) > 64)
13114 {
13115 errmsg ("profile name too long");
13116 return -99;
13117 }
13118
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013119 M (IKEV2_PROFILE_SET_TS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013120
13121 mp->is_local = is_local;
13122 mp->proto = (u8) proto;
13123 mp->start_port = (u16) start_port;
13124 mp->end_port = (u16) end_port;
13125 mp->start_addr = start_addr.as_u32;
13126 mp->end_addr = end_addr.as_u32;
13127 clib_memcpy (mp->name, name, vec_len (name));
13128 vec_free (name);
13129
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013130 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013131 W (ret);
13132 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013133}
13134
13135static int
13136api_ikev2_set_local_key (vat_main_t * vam)
13137{
13138 unformat_input_t *i = vam->input;
13139 vl_api_ikev2_set_local_key_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013140 u8 *file = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013141 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013142
13143 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13144 {
13145 if (unformat (i, "file %v", &file))
13146 vec_add1 (file, 0);
13147 else
13148 {
13149 errmsg ("parse error '%U'", format_unformat_error, i);
13150 return -99;
13151 }
13152 }
13153
13154 if (!vec_len (file))
13155 {
13156 errmsg ("RSA key file must be specified");
13157 return -99;
13158 }
13159
13160 if (vec_len (file) > 256)
13161 {
13162 errmsg ("file name too long");
13163 return -99;
13164 }
13165
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013166 M (IKEV2_SET_LOCAL_KEY, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013167
13168 clib_memcpy (mp->key_file, file, vec_len (file));
13169 vec_free (file);
13170
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013171 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013172 W (ret);
13173 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013174}
13175
Radu Nicolaucb33dc22017-02-16 16:49:46 +000013176static int
13177api_ikev2_set_responder (vat_main_t * vam)
13178{
13179 unformat_input_t *i = vam->input;
13180 vl_api_ikev2_set_responder_t *mp;
13181 int ret;
13182 u8 *name = 0;
13183 u32 sw_if_index = ~0;
13184 ip4_address_t address;
13185
13186 const char *valid_chars = "a-zA-Z0-9_";
13187
13188 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13189 {
13190 if (unformat
13191 (i, "%U interface %d address %U", unformat_token, valid_chars,
13192 &name, &sw_if_index, unformat_ip4_address, &address))
13193 vec_add1 (name, 0);
13194 else
13195 {
13196 errmsg ("parse error '%U'", format_unformat_error, i);
13197 return -99;
13198 }
13199 }
13200
13201 if (!vec_len (name))
13202 {
13203 errmsg ("profile name must be specified");
13204 return -99;
13205 }
13206
13207 if (vec_len (name) > 64)
13208 {
13209 errmsg ("profile name too long");
13210 return -99;
13211 }
13212
13213 M (IKEV2_SET_RESPONDER, mp);
13214
13215 clib_memcpy (mp->name, name, vec_len (name));
13216 vec_free (name);
13217
13218 mp->sw_if_index = sw_if_index;
13219 clib_memcpy (mp->address, &address, sizeof (address));
13220
13221 S (mp);
13222 W (ret);
13223 return ret;
13224}
13225
13226static int
13227api_ikev2_set_ike_transforms (vat_main_t * vam)
13228{
13229 unformat_input_t *i = vam->input;
13230 vl_api_ikev2_set_ike_transforms_t *mp;
13231 int ret;
13232 u8 *name = 0;
13233 u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
13234
13235 const char *valid_chars = "a-zA-Z0-9_";
13236
13237 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13238 {
13239 if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
13240 &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
13241 vec_add1 (name, 0);
13242 else
13243 {
13244 errmsg ("parse error '%U'", format_unformat_error, i);
13245 return -99;
13246 }
13247 }
13248
13249 if (!vec_len (name))
13250 {
13251 errmsg ("profile name must be specified");
13252 return -99;
13253 }
13254
13255 if (vec_len (name) > 64)
13256 {
13257 errmsg ("profile name too long");
13258 return -99;
13259 }
13260
13261 M (IKEV2_SET_IKE_TRANSFORMS, mp);
13262
13263 clib_memcpy (mp->name, name, vec_len (name));
13264 vec_free (name);
13265 mp->crypto_alg = crypto_alg;
13266 mp->crypto_key_size = crypto_key_size;
13267 mp->integ_alg = integ_alg;
13268 mp->dh_group = dh_group;
13269
13270 S (mp);
13271 W (ret);
13272 return ret;
13273}
13274
13275
13276static int
13277api_ikev2_set_esp_transforms (vat_main_t * vam)
13278{
13279 unformat_input_t *i = vam->input;
13280 vl_api_ikev2_set_esp_transforms_t *mp;
13281 int ret;
13282 u8 *name = 0;
13283 u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
13284
13285 const char *valid_chars = "a-zA-Z0-9_";
13286
13287 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13288 {
13289 if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
13290 &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
13291 vec_add1 (name, 0);
13292 else
13293 {
13294 errmsg ("parse error '%U'", format_unformat_error, i);
13295 return -99;
13296 }
13297 }
13298
13299 if (!vec_len (name))
13300 {
13301 errmsg ("profile name must be specified");
13302 return -99;
13303 }
13304
13305 if (vec_len (name) > 64)
13306 {
13307 errmsg ("profile name too long");
13308 return -99;
13309 }
13310
13311 M (IKEV2_SET_ESP_TRANSFORMS, mp);
13312
13313 clib_memcpy (mp->name, name, vec_len (name));
13314 vec_free (name);
13315 mp->crypto_alg = crypto_alg;
13316 mp->crypto_key_size = crypto_key_size;
13317 mp->integ_alg = integ_alg;
13318 mp->dh_group = dh_group;
13319
13320 S (mp);
13321 W (ret);
13322 return ret;
13323}
13324
13325static int
13326api_ikev2_set_sa_lifetime (vat_main_t * vam)
13327{
13328 unformat_input_t *i = vam->input;
13329 vl_api_ikev2_set_sa_lifetime_t *mp;
13330 int ret;
13331 u8 *name = 0;
13332 u64 lifetime, lifetime_maxdata;
13333 u32 lifetime_jitter, handover;
13334
13335 const char *valid_chars = "a-zA-Z0-9_";
13336
13337 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13338 {
13339 if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
13340 &lifetime, &lifetime_jitter, &handover,
13341 &lifetime_maxdata))
13342 vec_add1 (name, 0);
13343 else
13344 {
13345 errmsg ("parse error '%U'", format_unformat_error, i);
13346 return -99;
13347 }
13348 }
13349
13350 if (!vec_len (name))
13351 {
13352 errmsg ("profile name must be specified");
13353 return -99;
13354 }
13355
13356 if (vec_len (name) > 64)
13357 {
13358 errmsg ("profile name too long");
13359 return -99;
13360 }
13361
13362 M (IKEV2_SET_SA_LIFETIME, mp);
13363
13364 clib_memcpy (mp->name, name, vec_len (name));
13365 vec_free (name);
13366 mp->lifetime = lifetime;
13367 mp->lifetime_jitter = lifetime_jitter;
13368 mp->handover = handover;
13369 mp->lifetime_maxdata = lifetime_maxdata;
13370
13371 S (mp);
13372 W (ret);
13373 return ret;
13374}
13375
13376static int
13377api_ikev2_initiate_sa_init (vat_main_t * vam)
13378{
13379 unformat_input_t *i = vam->input;
13380 vl_api_ikev2_initiate_sa_init_t *mp;
13381 int ret;
13382 u8 *name = 0;
13383
13384 const char *valid_chars = "a-zA-Z0-9_";
13385
13386 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13387 {
13388 if (unformat (i, "%U", unformat_token, valid_chars, &name))
13389 vec_add1 (name, 0);
13390 else
13391 {
13392 errmsg ("parse error '%U'", format_unformat_error, i);
13393 return -99;
13394 }
13395 }
13396
13397 if (!vec_len (name))
13398 {
13399 errmsg ("profile name must be specified");
13400 return -99;
13401 }
13402
13403 if (vec_len (name) > 64)
13404 {
13405 errmsg ("profile name too long");
13406 return -99;
13407 }
13408
13409 M (IKEV2_INITIATE_SA_INIT, mp);
13410
13411 clib_memcpy (mp->name, name, vec_len (name));
13412 vec_free (name);
13413
13414 S (mp);
13415 W (ret);
13416 return ret;
13417}
13418
13419static int
13420api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
13421{
13422 unformat_input_t *i = vam->input;
13423 vl_api_ikev2_initiate_del_ike_sa_t *mp;
13424 int ret;
13425 u64 ispi;
13426
13427
13428 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13429 {
13430 if (unformat (i, "%lx", &ispi))
13431 ;
13432 else
13433 {
13434 errmsg ("parse error '%U'", format_unformat_error, i);
13435 return -99;
13436 }
13437 }
13438
13439 M (IKEV2_INITIATE_DEL_IKE_SA, mp);
13440
13441 mp->ispi = ispi;
13442
13443 S (mp);
13444 W (ret);
13445 return ret;
13446}
13447
13448static int
13449api_ikev2_initiate_del_child_sa (vat_main_t * vam)
13450{
13451 unformat_input_t *i = vam->input;
13452 vl_api_ikev2_initiate_del_child_sa_t *mp;
13453 int ret;
13454 u32 ispi;
13455
13456
13457 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13458 {
13459 if (unformat (i, "%x", &ispi))
13460 ;
13461 else
13462 {
13463 errmsg ("parse error '%U'", format_unformat_error, i);
13464 return -99;
13465 }
13466 }
13467
13468 M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
13469
13470 mp->ispi = ispi;
13471
13472 S (mp);
13473 W (ret);
13474 return ret;
13475}
13476
13477static int
13478api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
13479{
13480 unformat_input_t *i = vam->input;
13481 vl_api_ikev2_initiate_rekey_child_sa_t *mp;
13482 int ret;
13483 u32 ispi;
13484
13485
13486 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13487 {
13488 if (unformat (i, "%x", &ispi))
13489 ;
13490 else
13491 {
13492 errmsg ("parse error '%U'", format_unformat_error, i);
13493 return -99;
13494 }
13495 }
13496
13497 M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
13498
13499 mp->ispi = ispi;
13500
13501 S (mp);
13502 W (ret);
13503 return ret;
13504}
13505
Damjan Marion7cd468a2016-12-19 23:05:39 +010013506/*
13507 * MAP
13508 */
13509static int
13510api_map_add_domain (vat_main_t * vam)
13511{
13512 unformat_input_t *i = vam->input;
13513 vl_api_map_add_domain_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013514
13515 ip4_address_t ip4_prefix;
13516 ip6_address_t ip6_prefix;
13517 ip6_address_t ip6_src;
13518 u32 num_m_args = 0;
13519 u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
13520 0, psid_length = 0;
13521 u8 is_translation = 0;
13522 u32 mtu = 0;
13523 u32 ip6_src_len = 128;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013524 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013525
13526 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13527 {
13528 if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
13529 &ip4_prefix, &ip4_prefix_len))
13530 num_m_args++;
13531 else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
13532 &ip6_prefix, &ip6_prefix_len))
13533 num_m_args++;
13534 else
13535 if (unformat
13536 (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
13537 &ip6_src_len))
13538 num_m_args++;
13539 else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
13540 num_m_args++;
13541 else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
13542 num_m_args++;
13543 else if (unformat (i, "psid-offset %d", &psid_offset))
13544 num_m_args++;
13545 else if (unformat (i, "psid-len %d", &psid_length))
13546 num_m_args++;
13547 else if (unformat (i, "mtu %d", &mtu))
13548 num_m_args++;
13549 else if (unformat (i, "map-t"))
13550 is_translation = 1;
13551 else
13552 {
13553 clib_warning ("parse error '%U'", format_unformat_error, i);
13554 return -99;
13555 }
13556 }
13557
13558 if (num_m_args < 3)
13559 {
13560 errmsg ("mandatory argument(s) missing");
13561 return -99;
13562 }
13563
13564 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013565 M (MAP_ADD_DOMAIN, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013566
13567 clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
13568 mp->ip4_prefix_len = ip4_prefix_len;
13569
13570 clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
13571 mp->ip6_prefix_len = ip6_prefix_len;
13572
13573 clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
13574 mp->ip6_src_prefix_len = ip6_src_len;
13575
13576 mp->ea_bits_len = ea_bits_len;
13577 mp->psid_offset = psid_offset;
13578 mp->psid_length = psid_length;
13579 mp->is_translation = is_translation;
13580 mp->mtu = htons (mtu);
13581
13582 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013583 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013584
13585 /* Wait for a reply, return good/bad news */
Jon Loeliger56c7b012017-02-01 12:31:41 -060013586 W (ret);
13587 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013588}
13589
13590static int
13591api_map_del_domain (vat_main_t * vam)
13592{
13593 unformat_input_t *i = vam->input;
13594 vl_api_map_del_domain_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013595
13596 u32 num_m_args = 0;
13597 u32 index;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013598 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013599
13600 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13601 {
13602 if (unformat (i, "index %d", &index))
13603 num_m_args++;
13604 else
13605 {
13606 clib_warning ("parse error '%U'", format_unformat_error, i);
13607 return -99;
13608 }
13609 }
13610
13611 if (num_m_args != 1)
13612 {
13613 errmsg ("mandatory argument(s) missing");
13614 return -99;
13615 }
13616
13617 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013618 M (MAP_DEL_DOMAIN, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013619
13620 mp->index = ntohl (index);
13621
13622 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013623 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013624
13625 /* Wait for a reply, return good/bad news */
Jon Loeliger56c7b012017-02-01 12:31:41 -060013626 W (ret);
13627 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013628}
13629
13630static int
13631api_map_add_del_rule (vat_main_t * vam)
13632{
13633 unformat_input_t *i = vam->input;
13634 vl_api_map_add_del_rule_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013635 u8 is_add = 1;
13636 ip6_address_t ip6_dst;
13637 u32 num_m_args = 0, index, psid = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013638 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013639
13640 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13641 {
13642 if (unformat (i, "index %d", &index))
13643 num_m_args++;
13644 else if (unformat (i, "psid %d", &psid))
13645 num_m_args++;
13646 else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
13647 num_m_args++;
13648 else if (unformat (i, "del"))
13649 {
13650 is_add = 0;
13651 }
13652 else
13653 {
13654 clib_warning ("parse error '%U'", format_unformat_error, i);
13655 return -99;
13656 }
13657 }
13658
13659 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013660 M (MAP_ADD_DEL_RULE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013661
13662 mp->index = ntohl (index);
13663 mp->is_add = is_add;
13664 clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
13665 mp->psid = ntohs (psid);
13666
13667 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013668 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013669
13670 /* Wait for a reply, return good/bad news */
Jon Loeliger56c7b012017-02-01 12:31:41 -060013671 W (ret);
13672 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013673}
13674
13675static int
13676api_map_domain_dump (vat_main_t * vam)
13677{
13678 vl_api_map_domain_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060013679 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013680 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013681
13682 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013683 M (MAP_DOMAIN_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013684
13685 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013686 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013687
13688 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060013689 M (CONTROL_PING, mp_ping);
13690 S (mp_ping);
13691
Jon Loeliger56c7b012017-02-01 12:31:41 -060013692 W (ret);
13693 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013694}
13695
13696static int
13697api_map_rule_dump (vat_main_t * vam)
13698{
13699 unformat_input_t *i = vam->input;
13700 vl_api_map_rule_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060013701 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013702 u32 domain_index = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013703 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013704
13705 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13706 {
13707 if (unformat (i, "index %u", &domain_index))
13708 ;
13709 else
13710 break;
13711 }
13712
13713 if (domain_index == ~0)
13714 {
13715 clib_warning ("parse error: domain index expected");
13716 return -99;
13717 }
13718
13719 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013720 M (MAP_RULE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013721
13722 mp->domain_index = htonl (domain_index);
13723
13724 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013725 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013726
13727 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060013728 M (CONTROL_PING, mp_ping);
13729 S (mp_ping);
13730
Jon Loeliger56c7b012017-02-01 12:31:41 -060013731 W (ret);
13732 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013733}
13734
13735static void vl_api_map_add_domain_reply_t_handler
13736 (vl_api_map_add_domain_reply_t * mp)
13737{
13738 vat_main_t *vam = &vat_main;
13739 i32 retval = ntohl (mp->retval);
13740
13741 if (vam->async_mode)
13742 {
13743 vam->async_errors += (retval < 0);
13744 }
13745 else
13746 {
13747 vam->retval = retval;
13748 vam->result_ready = 1;
13749 }
13750}
13751
13752static void vl_api_map_add_domain_reply_t_handler_json
13753 (vl_api_map_add_domain_reply_t * mp)
13754{
13755 vat_main_t *vam = &vat_main;
13756 vat_json_node_t node;
13757
13758 vat_json_init_object (&node);
13759 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
13760 vat_json_object_add_uint (&node, "index", ntohl (mp->index));
13761
13762 vat_json_print (vam->ofp, &node);
13763 vat_json_free (&node);
13764
13765 vam->retval = ntohl (mp->retval);
13766 vam->result_ready = 1;
13767}
13768
13769static int
13770api_get_first_msg_id (vat_main_t * vam)
13771{
13772 vl_api_get_first_msg_id_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013773 unformat_input_t *i = vam->input;
13774 u8 *name;
13775 u8 name_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013776 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013777
13778 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13779 {
13780 if (unformat (i, "client %s", &name))
13781 name_set = 1;
13782 else
13783 break;
13784 }
13785
13786 if (name_set == 0)
13787 {
13788 errmsg ("missing client name");
13789 return -99;
13790 }
13791 vec_add1 (name, 0);
13792
13793 if (vec_len (name) > 63)
13794 {
13795 errmsg ("client name too long");
13796 return -99;
13797 }
13798
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013799 M (GET_FIRST_MSG_ID, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013800 clib_memcpy (mp->name, name, vec_len (name));
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013801 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013802 W (ret);
13803 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013804}
13805
13806static int
13807api_cop_interface_enable_disable (vat_main_t * vam)
13808{
13809 unformat_input_t *line_input = vam->input;
13810 vl_api_cop_interface_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013811 u32 sw_if_index = ~0;
13812 u8 enable_disable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013813 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013814
13815 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13816 {
13817 if (unformat (line_input, "disable"))
13818 enable_disable = 0;
13819 if (unformat (line_input, "enable"))
13820 enable_disable = 1;
13821 else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13822 vam, &sw_if_index))
13823 ;
13824 else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13825 ;
13826 else
13827 break;
13828 }
13829
13830 if (sw_if_index == ~0)
13831 {
13832 errmsg ("missing interface name or sw_if_index");
13833 return -99;
13834 }
13835
13836 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013837 M (COP_INTERFACE_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013838 mp->sw_if_index = ntohl (sw_if_index);
13839 mp->enable_disable = enable_disable;
13840
13841 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013842 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013843 /* Wait for the reply */
Jon Loeliger56c7b012017-02-01 12:31:41 -060013844 W (ret);
13845 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013846}
13847
13848static int
13849api_cop_whitelist_enable_disable (vat_main_t * vam)
13850{
13851 unformat_input_t *line_input = vam->input;
13852 vl_api_cop_whitelist_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013853 u32 sw_if_index = ~0;
13854 u8 ip4 = 0, ip6 = 0, default_cop = 0;
13855 u32 fib_id = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013856 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013857
13858 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13859 {
13860 if (unformat (line_input, "ip4"))
13861 ip4 = 1;
13862 else if (unformat (line_input, "ip6"))
13863 ip6 = 1;
13864 else if (unformat (line_input, "default"))
13865 default_cop = 1;
13866 else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13867 vam, &sw_if_index))
13868 ;
13869 else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13870 ;
13871 else if (unformat (line_input, "fib-id %d", &fib_id))
13872 ;
13873 else
13874 break;
13875 }
13876
13877 if (sw_if_index == ~0)
13878 {
13879 errmsg ("missing interface name or sw_if_index");
13880 return -99;
13881 }
13882
13883 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013884 M (COP_WHITELIST_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013885 mp->sw_if_index = ntohl (sw_if_index);
13886 mp->fib_id = ntohl (fib_id);
13887 mp->ip4 = ip4;
13888 mp->ip6 = ip6;
13889 mp->default_cop = default_cop;
13890
13891 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013892 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013893 /* Wait for the reply */
Jon Loeliger56c7b012017-02-01 12:31:41 -060013894 W (ret);
13895 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013896}
13897
13898static int
13899api_get_node_graph (vat_main_t * vam)
13900{
13901 vl_api_get_node_graph_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013902 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013903
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013904 M (GET_NODE_GRAPH, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013905
13906 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013907 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013908 /* Wait for the reply */
Jon Loeliger56c7b012017-02-01 12:31:41 -060013909 W (ret);
13910 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013911}
13912
13913/* *INDENT-OFF* */
13914/** Used for parsing LISP eids */
13915typedef CLIB_PACKED(struct{
13916 u8 addr[16]; /**< eid address */
13917 u32 len; /**< prefix length if IP */
13918 u8 type; /**< type of eid */
13919}) lisp_eid_vat_t;
13920/* *INDENT-ON* */
13921
13922static uword
13923unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
13924{
13925 lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
13926
13927 memset (a, 0, sizeof (a[0]));
13928
13929 if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
13930 {
13931 a->type = 0; /* ipv4 type */
13932 }
13933 else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
13934 {
13935 a->type = 1; /* ipv6 type */
13936 }
13937 else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
13938 {
13939 a->type = 2; /* mac type */
13940 }
13941 else
13942 {
13943 return 0;
13944 }
13945
13946 if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
13947 {
13948 return 0;
13949 }
13950
13951 return 1;
13952}
13953
13954static int
13955lisp_eid_size_vat (u8 type)
13956{
13957 switch (type)
13958 {
13959 case 0:
13960 return 4;
13961 case 1:
13962 return 16;
13963 case 2:
13964 return 6;
13965 }
13966 return 0;
13967}
13968
13969static void
13970lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
13971{
13972 clib_memcpy (dst, eid, lisp_eid_size_vat (type));
13973}
13974
Damjan Marion7cd468a2016-12-19 23:05:39 +010013975static int
Filip Tehlar694396d2017-02-17 14:29:11 +010013976api_one_add_del_locator_set (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010013977{
13978 unformat_input_t *input = vam->input;
Filip Tehlar694396d2017-02-17 14:29:11 +010013979 vl_api_one_add_del_locator_set_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013980 u8 is_add = 1;
13981 u8 *locator_set_name = NULL;
13982 u8 locator_set_name_set = 0;
Filip Tehlar05a057b2017-02-01 08:50:31 +010013983 vl_api_local_locator_t locator, *locators = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013984 u32 sw_if_index, priority, weight;
13985 u32 data_len = 0;
13986
Jon Loeliger56c7b012017-02-01 12:31:41 -060013987 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013988 /* Parse args required to build the message */
13989 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13990 {
13991 if (unformat (input, "del"))
13992 {
13993 is_add = 0;
13994 }
13995 else if (unformat (input, "locator-set %s", &locator_set_name))
13996 {
13997 locator_set_name_set = 1;
13998 }
13999 else if (unformat (input, "sw_if_index %u p %u w %u",
14000 &sw_if_index, &priority, &weight))
14001 {
14002 locator.sw_if_index = htonl (sw_if_index);
14003 locator.priority = priority;
14004 locator.weight = weight;
14005 vec_add1 (locators, locator);
14006 }
14007 else
14008 if (unformat
14009 (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
14010 &sw_if_index, &priority, &weight))
14011 {
14012 locator.sw_if_index = htonl (sw_if_index);
14013 locator.priority = priority;
14014 locator.weight = weight;
14015 vec_add1 (locators, locator);
14016 }
14017 else
14018 break;
14019 }
14020
14021 if (locator_set_name_set == 0)
14022 {
14023 errmsg ("missing locator-set name");
14024 vec_free (locators);
14025 return -99;
14026 }
14027
14028 if (vec_len (locator_set_name) > 64)
14029 {
14030 errmsg ("locator-set name too long");
14031 vec_free (locator_set_name);
14032 vec_free (locators);
14033 return -99;
14034 }
14035 vec_add1 (locator_set_name, 0);
14036
Filip Tehlar05a057b2017-02-01 08:50:31 +010014037 data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014038
14039 /* Construct the API message */
Filip Tehlar694396d2017-02-17 14:29:11 +010014040 M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014041
14042 mp->is_add = is_add;
14043 clib_memcpy (mp->locator_set_name, locator_set_name,
14044 vec_len (locator_set_name));
14045 vec_free (locator_set_name);
14046
14047 mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
14048 if (locators)
14049 clib_memcpy (mp->locators, locators, data_len);
14050 vec_free (locators);
14051
14052 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014053 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014054
14055 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014056 W (ret);
14057 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014058}
14059
Filip Tehlar694396d2017-02-17 14:29:11 +010014060#define api_lisp_add_del_locator_set api_one_add_del_locator_set
14061
Damjan Marion7cd468a2016-12-19 23:05:39 +010014062static int
Filip Tehlar694396d2017-02-17 14:29:11 +010014063api_one_add_del_locator (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010014064{
14065 unformat_input_t *input = vam->input;
Filip Tehlar694396d2017-02-17 14:29:11 +010014066 vl_api_one_add_del_locator_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014067 u32 tmp_if_index = ~0;
14068 u32 sw_if_index = ~0;
14069 u8 sw_if_index_set = 0;
14070 u8 sw_if_index_if_name_set = 0;
14071 u32 priority = ~0;
14072 u8 priority_set = 0;
14073 u32 weight = ~0;
14074 u8 weight_set = 0;
14075 u8 is_add = 1;
14076 u8 *locator_set_name = NULL;
14077 u8 locator_set_name_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014078 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014079
14080 /* Parse args required to build the message */
14081 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14082 {
14083 if (unformat (input, "del"))
14084 {
14085 is_add = 0;
14086 }
14087 else if (unformat (input, "locator-set %s", &locator_set_name))
14088 {
14089 locator_set_name_set = 1;
14090 }
14091 else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
14092 &tmp_if_index))
14093 {
14094 sw_if_index_if_name_set = 1;
14095 sw_if_index = tmp_if_index;
14096 }
14097 else if (unformat (input, "sw_if_index %d", &tmp_if_index))
14098 {
14099 sw_if_index_set = 1;
14100 sw_if_index = tmp_if_index;
14101 }
14102 else if (unformat (input, "p %d", &priority))
14103 {
14104 priority_set = 1;
14105 }
14106 else if (unformat (input, "w %d", &weight))
14107 {
14108 weight_set = 1;
14109 }
14110 else
14111 break;
14112 }
14113
14114 if (locator_set_name_set == 0)
14115 {
14116 errmsg ("missing locator-set name");
14117 return -99;
14118 }
14119
14120 if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
14121 {
14122 errmsg ("missing sw_if_index");
14123 vec_free (locator_set_name);
14124 return -99;
14125 }
14126
14127 if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
14128 {
14129 errmsg ("cannot use both params interface name and sw_if_index");
14130 vec_free (locator_set_name);
14131 return -99;
14132 }
14133
14134 if (priority_set == 0)
14135 {
14136 errmsg ("missing locator-set priority");
14137 vec_free (locator_set_name);
14138 return -99;
14139 }
14140
14141 if (weight_set == 0)
14142 {
14143 errmsg ("missing locator-set weight");
14144 vec_free (locator_set_name);
14145 return -99;
14146 }
14147
14148 if (vec_len (locator_set_name) > 64)
14149 {
14150 errmsg ("locator-set name too long");
14151 vec_free (locator_set_name);
14152 return -99;
14153 }
14154 vec_add1 (locator_set_name, 0);
14155
14156 /* Construct the API message */
Filip Tehlar694396d2017-02-17 14:29:11 +010014157 M (ONE_ADD_DEL_LOCATOR, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014158
14159 mp->is_add = is_add;
14160 mp->sw_if_index = ntohl (sw_if_index);
14161 mp->priority = priority;
14162 mp->weight = weight;
14163 clib_memcpy (mp->locator_set_name, locator_set_name,
14164 vec_len (locator_set_name));
14165 vec_free (locator_set_name);
14166
14167 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014168 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014169
14170 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014171 W (ret);
14172 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014173}
14174
Filip Tehlar694396d2017-02-17 14:29:11 +010014175#define api_lisp_add_del_locator api_one_add_del_locator
14176
Damjan Marion7cd468a2016-12-19 23:05:39 +010014177uword
14178unformat_hmac_key_id (unformat_input_t * input, va_list * args)
14179{
14180 u32 *key_id = va_arg (*args, u32 *);
14181 u8 *s = 0;
14182
14183 if (unformat (input, "%s", &s))
14184 {
14185 if (!strcmp ((char *) s, "sha1"))
14186 key_id[0] = HMAC_SHA_1_96;
14187 else if (!strcmp ((char *) s, "sha256"))
14188 key_id[0] = HMAC_SHA_256_128;
14189 else
14190 {
14191 clib_warning ("invalid key_id: '%s'", s);
14192 key_id[0] = HMAC_NO_KEY;
14193 }
14194 }
14195 else
14196 return 0;
14197
14198 vec_free (s);
14199 return 1;
14200}
14201
14202static int
Filip Tehlar694396d2017-02-17 14:29:11 +010014203api_one_add_del_local_eid (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010014204{
14205 unformat_input_t *input = vam->input;
Filip Tehlar694396d2017-02-17 14:29:11 +010014206 vl_api_one_add_del_local_eid_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014207 u8 is_add = 1;
14208 u8 eid_set = 0;
14209 lisp_eid_vat_t _eid, *eid = &_eid;
14210 u8 *locator_set_name = 0;
14211 u8 locator_set_name_set = 0;
14212 u32 vni = 0;
14213 u16 key_id = 0;
14214 u8 *key = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014215 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014216
14217 /* Parse args required to build the message */
14218 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14219 {
14220 if (unformat (input, "del"))
14221 {
14222 is_add = 0;
14223 }
14224 else if (unformat (input, "vni %d", &vni))
14225 {
14226 ;
14227 }
14228 else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14229 {
14230 eid_set = 1;
14231 }
14232 else if (unformat (input, "locator-set %s", &locator_set_name))
14233 {
14234 locator_set_name_set = 1;
14235 }
14236 else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
14237 ;
14238 else if (unformat (input, "secret-key %_%v%_", &key))
14239 ;
14240 else
14241 break;
14242 }
14243
14244 if (locator_set_name_set == 0)
14245 {
14246 errmsg ("missing locator-set name");
14247 return -99;
14248 }
14249
14250 if (0 == eid_set)
14251 {
14252 errmsg ("EID address not set!");
14253 vec_free (locator_set_name);
14254 return -99;
14255 }
14256
14257 if (key && (0 == key_id))
14258 {
14259 errmsg ("invalid key_id!");
14260 return -99;
14261 }
14262
14263 if (vec_len (key) > 64)
14264 {
14265 errmsg ("key too long");
14266 vec_free (key);
14267 return -99;
14268 }
14269
14270 if (vec_len (locator_set_name) > 64)
14271 {
14272 errmsg ("locator-set name too long");
14273 vec_free (locator_set_name);
14274 return -99;
14275 }
14276 vec_add1 (locator_set_name, 0);
14277
14278 /* Construct the API message */
Filip Tehlar694396d2017-02-17 14:29:11 +010014279 M (ONE_ADD_DEL_LOCAL_EID, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014280
14281 mp->is_add = is_add;
14282 lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14283 mp->eid_type = eid->type;
14284 mp->prefix_len = eid->len;
14285 mp->vni = clib_host_to_net_u32 (vni);
14286 mp->key_id = clib_host_to_net_u16 (key_id);
14287 clib_memcpy (mp->locator_set_name, locator_set_name,
14288 vec_len (locator_set_name));
14289 clib_memcpy (mp->key, key, vec_len (key));
14290
14291 vec_free (locator_set_name);
14292 vec_free (key);
14293
14294 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014295 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014296
14297 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014298 W (ret);
14299 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014300}
14301
Filip Tehlar694396d2017-02-17 14:29:11 +010014302#define api_lisp_add_del_local_eid api_one_add_del_local_eid
Damjan Marion7cd468a2016-12-19 23:05:39 +010014303
14304static int
14305api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
14306{
Filip Tehlarc3af7bf2017-01-13 14:13:09 +010014307 u32 dp_table = 0, vni = 0;;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014308 unformat_input_t *input = vam->input;
Filip Tehlar82786c42017-02-20 15:20:37 +010014309 vl_api_gpe_add_del_fwd_entry_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014310 u8 is_add = 1;
14311 lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
14312 lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
14313 u8 rmt_eid_set = 0, lcl_eid_set = 0;
Filip Tehlarc3af7bf2017-01-13 14:13:09 +010014314 u32 action = ~0, w;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014315 ip4_address_t rmt_rloc4, lcl_rloc4;
14316 ip6_address_t rmt_rloc6, lcl_rloc6;
Filip Tehlar82786c42017-02-20 15:20:37 +010014317 vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014318 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014319
14320 memset (&rloc, 0, sizeof (rloc));
14321
14322 /* Parse args required to build the message */
14323 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14324 {
14325 if (unformat (input, "del"))
Filip Tehlarc3af7bf2017-01-13 14:13:09 +010014326 is_add = 0;
14327 else if (unformat (input, "add"))
14328 is_add = 1;
14329 else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
Damjan Marion7cd468a2016-12-19 23:05:39 +010014330 {
14331 rmt_eid_set = 1;
14332 }
Filip Tehlarc3af7bf2017-01-13 14:13:09 +010014333 else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
Damjan Marion7cd468a2016-12-19 23:05:39 +010014334 {
14335 lcl_eid_set = 1;
14336 }
Filip Tehlarc3af7bf2017-01-13 14:13:09 +010014337 else if (unformat (input, "vrf %d", &dp_table))
14338 ;
14339 else if (unformat (input, "bd %d", &dp_table))
14340 ;
14341 else if (unformat (input, "vni %d", &vni))
14342 ;
14343 else if (unformat (input, "w %d", &w))
Damjan Marion7cd468a2016-12-19 23:05:39 +010014344 {
14345 if (!curr_rloc)
14346 {
14347 errmsg ("No RLOC configured for setting priority/weight!");
14348 return -99;
14349 }
Damjan Marion7cd468a2016-12-19 23:05:39 +010014350 curr_rloc->weight = w;
14351 }
14352 else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
14353 &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
14354 {
14355 rloc.is_ip4 = 1;
14356
14357 clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
Filip Tehlarc3af7bf2017-01-13 14:13:09 +010014358 rloc.weight = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014359 vec_add1 (lcl_locs, rloc);
14360
14361 clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
14362 vec_add1 (rmt_locs, rloc);
Filip Tehlarc3af7bf2017-01-13 14:13:09 +010014363 /* weight saved in rmt loc */
Damjan Marion7cd468a2016-12-19 23:05:39 +010014364 curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14365 }
14366 else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
14367 &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
14368 {
14369 rloc.is_ip4 = 0;
14370 clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
Filip Tehlarc3af7bf2017-01-13 14:13:09 +010014371 rloc.weight = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014372 vec_add1 (lcl_locs, rloc);
14373
14374 clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
14375 vec_add1 (rmt_locs, rloc);
Filip Tehlarc3af7bf2017-01-13 14:13:09 +010014376 /* weight saved in rmt loc */
Damjan Marion7cd468a2016-12-19 23:05:39 +010014377 curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14378 }
14379 else if (unformat (input, "action %d", &action))
14380 {
14381 ;
14382 }
14383 else
14384 {
14385 clib_warning ("parse error '%U'", format_unformat_error, input);
14386 return -99;
14387 }
14388 }
14389
14390 if (!rmt_eid_set)
14391 {
14392 errmsg ("remote eid addresses not set");
14393 return -99;
14394 }
14395
14396 if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
14397 {
14398 errmsg ("eid types don't match");
14399 return -99;
14400 }
14401
14402 if (0 == rmt_locs && (u32) ~ 0 == action)
14403 {
14404 errmsg ("action not set for negative mapping");
14405 return -99;
14406 }
14407
14408 /* Construct the API message */
Filip Tehlar82786c42017-02-20 15:20:37 +010014409 M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
14410 sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014411
14412 mp->is_add = is_add;
14413 lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
14414 lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
14415 mp->eid_type = rmt_eid->type;
Filip Tehlarc3af7bf2017-01-13 14:13:09 +010014416 mp->dp_table = clib_host_to_net_u32 (dp_table);
14417 mp->vni = clib_host_to_net_u32 (vni);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014418 mp->rmt_len = rmt_eid->len;
14419 mp->lcl_len = lcl_eid->len;
14420 mp->action = action;
14421
14422 if (0 != rmt_locs && 0 != lcl_locs)
14423 {
Filip Tehlarc3af7bf2017-01-13 14:13:09 +010014424 mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
14425 clib_memcpy (mp->locs, lcl_locs,
Filip Tehlar82786c42017-02-20 15:20:37 +010014426 (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
Filip Tehlarc3af7bf2017-01-13 14:13:09 +010014427
Filip Tehlar82786c42017-02-20 15:20:37 +010014428 u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
Filip Tehlarc3af7bf2017-01-13 14:13:09 +010014429 clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
Filip Tehlar82786c42017-02-20 15:20:37 +010014430 (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
Damjan Marion7cd468a2016-12-19 23:05:39 +010014431 }
14432 vec_free (lcl_locs);
14433 vec_free (rmt_locs);
14434
14435 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014436 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014437
14438 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014439 W (ret);
14440 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014441}
14442
14443static int
Filip Tehlar694396d2017-02-17 14:29:11 +010014444api_one_add_del_map_server (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010014445{
14446 unformat_input_t *input = vam->input;
Filip Tehlar694396d2017-02-17 14:29:11 +010014447 vl_api_one_add_del_map_server_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014448 u8 is_add = 1;
14449 u8 ipv4_set = 0;
14450 u8 ipv6_set = 0;
14451 ip4_address_t ipv4;
14452 ip6_address_t ipv6;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014453 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014454
14455 /* Parse args required to build the message */
14456 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14457 {
14458 if (unformat (input, "del"))
14459 {
14460 is_add = 0;
14461 }
14462 else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14463 {
14464 ipv4_set = 1;
14465 }
14466 else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14467 {
14468 ipv6_set = 1;
14469 }
14470 else
14471 break;
14472 }
14473
14474 if (ipv4_set && ipv6_set)
14475 {
14476 errmsg ("both eid v4 and v6 addresses set");
14477 return -99;
14478 }
14479
14480 if (!ipv4_set && !ipv6_set)
14481 {
14482 errmsg ("eid addresses not set");
14483 return -99;
14484 }
14485
14486 /* Construct the API message */
Filip Tehlar694396d2017-02-17 14:29:11 +010014487 M (ONE_ADD_DEL_MAP_SERVER, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014488
14489 mp->is_add = is_add;
14490 if (ipv6_set)
14491 {
14492 mp->is_ipv6 = 1;
14493 clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14494 }
14495 else
14496 {
14497 mp->is_ipv6 = 0;
14498 clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14499 }
14500
14501 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014502 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014503
14504 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014505 W (ret);
14506 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014507}
14508
Filip Tehlar694396d2017-02-17 14:29:11 +010014509#define api_lisp_add_del_map_server api_one_add_del_map_server
14510
Damjan Marion7cd468a2016-12-19 23:05:39 +010014511static int
Filip Tehlar694396d2017-02-17 14:29:11 +010014512api_one_add_del_map_resolver (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010014513{
14514 unformat_input_t *input = vam->input;
Filip Tehlar694396d2017-02-17 14:29:11 +010014515 vl_api_one_add_del_map_resolver_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014516 u8 is_add = 1;
14517 u8 ipv4_set = 0;
14518 u8 ipv6_set = 0;
14519 ip4_address_t ipv4;
14520 ip6_address_t ipv6;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014521 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014522
14523 /* Parse args required to build the message */
14524 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14525 {
14526 if (unformat (input, "del"))
14527 {
14528 is_add = 0;
14529 }
14530 else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14531 {
14532 ipv4_set = 1;
14533 }
14534 else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14535 {
14536 ipv6_set = 1;
14537 }
14538 else
14539 break;
14540 }
14541
14542 if (ipv4_set && ipv6_set)
14543 {
14544 errmsg ("both eid v4 and v6 addresses set");
14545 return -99;
14546 }
14547
14548 if (!ipv4_set && !ipv6_set)
14549 {
14550 errmsg ("eid addresses not set");
14551 return -99;
14552 }
14553
14554 /* Construct the API message */
Filip Tehlar694396d2017-02-17 14:29:11 +010014555 M (ONE_ADD_DEL_MAP_RESOLVER, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014556
14557 mp->is_add = is_add;
14558 if (ipv6_set)
14559 {
14560 mp->is_ipv6 = 1;
14561 clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14562 }
14563 else
14564 {
14565 mp->is_ipv6 = 0;
14566 clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14567 }
14568
14569 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014570 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014571
14572 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014573 W (ret);
14574 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014575}
14576
Filip Tehlar694396d2017-02-17 14:29:11 +010014577#define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
14578
Damjan Marion7cd468a2016-12-19 23:05:39 +010014579static int
14580api_lisp_gpe_enable_disable (vat_main_t * vam)
14581{
14582 unformat_input_t *input = vam->input;
Filip Tehlar82786c42017-02-20 15:20:37 +010014583 vl_api_gpe_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014584 u8 is_set = 0;
14585 u8 is_en = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014586 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014587
14588 /* Parse args required to build the message */
14589 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14590 {
14591 if (unformat (input, "enable"))
14592 {
14593 is_set = 1;
14594 is_en = 1;
14595 }
14596 else if (unformat (input, "disable"))
14597 {
14598 is_set = 1;
14599 is_en = 0;
14600 }
14601 else
14602 break;
14603 }
14604
14605 if (is_set == 0)
14606 {
14607 errmsg ("Value not set");
14608 return -99;
14609 }
14610
14611 /* Construct the API message */
Filip Tehlar82786c42017-02-20 15:20:37 +010014612 M (GPE_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014613
14614 mp->is_en = is_en;
14615
14616 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014617 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014618
14619 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014620 W (ret);
14621 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014622}
14623
14624static int
Filip Tehlar694396d2017-02-17 14:29:11 +010014625api_one_rloc_probe_enable_disable (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010014626{
14627 unformat_input_t *input = vam->input;
Filip Tehlar694396d2017-02-17 14:29:11 +010014628 vl_api_one_rloc_probe_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014629 u8 is_set = 0;
14630 u8 is_en = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014631 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014632
14633 /* Parse args required to build the message */
14634 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14635 {
14636 if (unformat (input, "enable"))
14637 {
14638 is_set = 1;
14639 is_en = 1;
14640 }
14641 else if (unformat (input, "disable"))
14642 is_set = 1;
14643 else
14644 break;
14645 }
14646
14647 if (!is_set)
14648 {
14649 errmsg ("Value not set");
14650 return -99;
14651 }
14652
14653 /* Construct the API message */
Filip Tehlar694396d2017-02-17 14:29:11 +010014654 M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014655
14656 mp->is_enabled = is_en;
14657
14658 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014659 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014660
14661 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014662 W (ret);
14663 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014664}
14665
Filip Tehlar694396d2017-02-17 14:29:11 +010014666#define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
14667
Damjan Marion7cd468a2016-12-19 23:05:39 +010014668static int
Filip Tehlar694396d2017-02-17 14:29:11 +010014669api_one_map_register_enable_disable (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010014670{
14671 unformat_input_t *input = vam->input;
Filip Tehlar694396d2017-02-17 14:29:11 +010014672 vl_api_one_map_register_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014673 u8 is_set = 0;
14674 u8 is_en = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014675 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014676
14677 /* Parse args required to build the message */
14678 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14679 {
14680 if (unformat (input, "enable"))
14681 {
14682 is_set = 1;
14683 is_en = 1;
14684 }
14685 else if (unformat (input, "disable"))
14686 is_set = 1;
14687 else
14688 break;
14689 }
14690
14691 if (!is_set)
14692 {
14693 errmsg ("Value not set");
14694 return -99;
14695 }
14696
14697 /* Construct the API message */
Filip Tehlar694396d2017-02-17 14:29:11 +010014698 M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014699
14700 mp->is_enabled = is_en;
14701
14702 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014703 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014704
14705 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014706 W (ret);
14707 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014708}
14709
Filip Tehlar694396d2017-02-17 14:29:11 +010014710#define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
14711
Damjan Marion7cd468a2016-12-19 23:05:39 +010014712static int
Filip Tehlar694396d2017-02-17 14:29:11 +010014713api_one_enable_disable (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010014714{
14715 unformat_input_t *input = vam->input;
Filip Tehlar694396d2017-02-17 14:29:11 +010014716 vl_api_one_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014717 u8 is_set = 0;
14718 u8 is_en = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014719 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014720
14721 /* Parse args required to build the message */
14722 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14723 {
14724 if (unformat (input, "enable"))
14725 {
14726 is_set = 1;
14727 is_en = 1;
14728 }
14729 else if (unformat (input, "disable"))
14730 {
14731 is_set = 1;
14732 }
14733 else
14734 break;
14735 }
14736
14737 if (!is_set)
14738 {
14739 errmsg ("Value not set");
14740 return -99;
14741 }
14742
14743 /* Construct the API message */
Filip Tehlar694396d2017-02-17 14:29:11 +010014744 M (ONE_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014745
14746 mp->is_en = is_en;
14747
14748 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014749 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014750
14751 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014752 W (ret);
14753 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014754}
14755
Filip Tehlar694396d2017-02-17 14:29:11 +010014756#define api_lisp_enable_disable api_one_enable_disable
14757
Damjan Marion7cd468a2016-12-19 23:05:39 +010014758static int
Filip Tehlar694396d2017-02-17 14:29:11 +010014759api_show_one_map_register_state (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010014760{
Filip Tehlar694396d2017-02-17 14:29:11 +010014761 vl_api_show_one_map_register_state_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014762 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014763
Filip Tehlar694396d2017-02-17 14:29:11 +010014764 M (SHOW_ONE_MAP_REGISTER_STATE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014765
14766 /* send */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014767 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014768
14769 /* wait for reply */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014770 W (ret);
14771 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014772}
14773
Filip Tehlar694396d2017-02-17 14:29:11 +010014774#define api_show_lisp_map_register_state api_show_one_map_register_state
14775
Damjan Marion7cd468a2016-12-19 23:05:39 +010014776static int
Filip Tehlar694396d2017-02-17 14:29:11 +010014777api_show_one_rloc_probe_state (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010014778{
Filip Tehlar694396d2017-02-17 14:29:11 +010014779 vl_api_show_one_rloc_probe_state_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014780 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014781
Filip Tehlar694396d2017-02-17 14:29:11 +010014782 M (SHOW_ONE_RLOC_PROBE_STATE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014783
14784 /* send */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014785 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014786
14787 /* wait for reply */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014788 W (ret);
14789 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014790}
14791
Filip Tehlar694396d2017-02-17 14:29:11 +010014792#define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
14793
Damjan Marion7cd468a2016-12-19 23:05:39 +010014794static int
Filip Tehlar4868ff62017-03-09 16:48:39 +010014795api_one_stats_enable_disable (vat_main_t * vam)
14796{
14797 vl_api_one_stats_enable_disable_t *mp;
14798 unformat_input_t *input = vam->input;
14799 u8 is_set = 0;
14800 u8 is_en = 0;
14801 int ret;
14802
14803 /* Parse args required to build the message */
14804 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14805 {
14806 if (unformat (input, "enable"))
14807 {
14808 is_set = 1;
14809 is_en = 1;
14810 }
14811 else if (unformat (input, "disable"))
14812 {
14813 is_set = 1;
14814 }
14815 else
14816 break;
14817 }
14818
14819 if (!is_set)
14820 {
14821 errmsg ("Value not set");
14822 return -99;
14823 }
14824
14825 M (ONE_STATS_ENABLE_DISABLE, mp);
14826 mp->is_en = is_en;
14827
14828 /* send */
14829 S (mp);
14830
14831 /* wait for reply */
14832 W (ret);
14833 return ret;
14834}
14835
14836static int
14837api_show_one_stats_enable_disable (vat_main_t * vam)
14838{
14839 vl_api_show_one_stats_enable_disable_t *mp;
14840 int ret;
14841
14842 M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
14843
14844 /* send */
14845 S (mp);
14846
14847 /* wait for reply */
14848 W (ret);
14849 return ret;
14850}
14851
14852static int
Filip Tehlar694396d2017-02-17 14:29:11 +010014853api_show_one_map_request_mode (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010014854{
Filip Tehlar694396d2017-02-17 14:29:11 +010014855 vl_api_show_one_map_request_mode_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014856 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014857
Filip Tehlar694396d2017-02-17 14:29:11 +010014858 M (SHOW_ONE_MAP_REQUEST_MODE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014859
14860 /* send */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014861 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014862
14863 /* wait for reply */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014864 W (ret);
14865 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014866}
14867
Filip Tehlar694396d2017-02-17 14:29:11 +010014868#define api_show_lisp_map_request_mode api_show_one_map_request_mode
14869
Damjan Marion7cd468a2016-12-19 23:05:39 +010014870static int
Filip Tehlar694396d2017-02-17 14:29:11 +010014871api_one_map_request_mode (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010014872{
Damjan Marion7cd468a2016-12-19 23:05:39 +010014873 unformat_input_t *input = vam->input;
Filip Tehlar694396d2017-02-17 14:29:11 +010014874 vl_api_one_map_request_mode_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014875 u8 mode = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014876 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014877
14878 /* Parse args required to build the message */
14879 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14880 {
14881 if (unformat (input, "dst-only"))
14882 mode = 0;
14883 else if (unformat (input, "src-dst"))
14884 mode = 1;
14885 else
14886 {
14887 errmsg ("parse error '%U'", format_unformat_error, input);
14888 return -99;
14889 }
14890 }
14891
Filip Tehlar694396d2017-02-17 14:29:11 +010014892 M (ONE_MAP_REQUEST_MODE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014893
14894 mp->mode = mode;
14895
14896 /* send */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014897 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014898
14899 /* wait for reply */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014900 W (ret);
14901 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014902}
14903
Filip Tehlar694396d2017-02-17 14:29:11 +010014904#define api_lisp_map_request_mode api_one_map_request_mode
14905
Damjan Marion7cd468a2016-12-19 23:05:39 +010014906/**
Filip Tehlar694396d2017-02-17 14:29:11 +010014907 * Enable/disable ONE proxy ITR.
Damjan Marion7cd468a2016-12-19 23:05:39 +010014908 *
14909 * @param vam vpp API test context
14910 * @return return code
14911 */
14912static int
Filip Tehlar694396d2017-02-17 14:29:11 +010014913api_one_pitr_set_locator_set (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010014914{
Damjan Marion7cd468a2016-12-19 23:05:39 +010014915 u8 ls_name_set = 0;
14916 unformat_input_t *input = vam->input;
Filip Tehlar694396d2017-02-17 14:29:11 +010014917 vl_api_one_pitr_set_locator_set_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014918 u8 is_add = 1;
14919 u8 *ls_name = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014920 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014921
14922 /* Parse args required to build the message */
14923 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14924 {
14925 if (unformat (input, "del"))
14926 is_add = 0;
14927 else if (unformat (input, "locator-set %s", &ls_name))
14928 ls_name_set = 1;
14929 else
14930 {
14931 errmsg ("parse error '%U'", format_unformat_error, input);
14932 return -99;
14933 }
14934 }
14935
14936 if (!ls_name_set)
14937 {
14938 errmsg ("locator-set name not set!");
14939 return -99;
14940 }
14941
Filip Tehlar694396d2017-02-17 14:29:11 +010014942 M (ONE_PITR_SET_LOCATOR_SET, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014943
14944 mp->is_add = is_add;
14945 clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
14946 vec_free (ls_name);
14947
14948 /* send */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014949 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014950
14951 /* wait for reply */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014952 W (ret);
14953 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014954}
14955
Filip Tehlar694396d2017-02-17 14:29:11 +010014956#define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
14957
Damjan Marion7cd468a2016-12-19 23:05:39 +010014958static int
Filip Tehlar694396d2017-02-17 14:29:11 +010014959api_show_one_pitr (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010014960{
Filip Tehlar694396d2017-02-17 14:29:11 +010014961 vl_api_show_one_pitr_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014962 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014963
14964 if (!vam->json_output)
14965 {
14966 print (vam->ofp, "%=20s", "lisp status:");
14967 }
14968
Filip Tehlar694396d2017-02-17 14:29:11 +010014969 M (SHOW_ONE_PITR, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014970 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014971 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014972
14973 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014974 W (ret);
14975 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014976}
14977
Filip Tehlar694396d2017-02-17 14:29:11 +010014978#define api_show_lisp_pitr api_show_one_pitr
14979
Filip Tehlar67a99f82017-03-10 13:18:02 +010014980static int
14981api_one_use_petr (vat_main_t * vam)
14982{
14983 unformat_input_t *input = vam->input;
14984 vl_api_one_use_petr_t *mp;
14985 u8 is_add = 0;
14986 ip_address_t ip;
14987 int ret;
14988
14989 memset (&ip, 0, sizeof (ip));
14990
14991 /* Parse args required to build the message */
14992 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14993 {
14994 if (unformat (input, "disable"))
14995 is_add = 0;
14996 else
14997 if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
14998 {
14999 is_add = 1;
15000 ip_addr_version (&ip) = IP4;
15001 }
15002 else
15003 if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
15004 {
15005 is_add = 1;
15006 ip_addr_version (&ip) = IP6;
15007 }
15008 else
15009 {
15010 errmsg ("parse error '%U'", format_unformat_error, input);
15011 return -99;
15012 }
15013 }
15014
15015 M (ONE_USE_PETR, mp);
15016
15017 mp->is_add = is_add;
15018 if (is_add)
15019 {
15020 mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
15021 if (mp->is_ip4)
15022 clib_memcpy (mp->address, &ip, 4);
15023 else
15024 clib_memcpy (mp->address, &ip, 16);
15025 }
15026
15027 /* send */
15028 S (mp);
15029
15030 /* wait for reply */
15031 W (ret);
15032 return ret;
15033}
15034
15035#define api_lisp_use_petr api_one_use_petr
15036
15037static int
15038api_show_one_use_petr (vat_main_t * vam)
15039{
15040 vl_api_show_one_use_petr_t *mp;
15041 int ret;
15042
15043 if (!vam->json_output)
15044 {
15045 print (vam->ofp, "%=20s", "Proxy-ETR status:");
15046 }
15047
15048 M (SHOW_ONE_USE_PETR, mp);
15049 /* send it... */
15050 S (mp);
15051
15052 /* Wait for a reply... */
15053 W (ret);
15054 return ret;
15055}
15056
15057#define api_show_lisp_use_petr api_show_one_use_petr
15058
Damjan Marion7cd468a2016-12-19 23:05:39 +010015059/**
15060 * Add/delete mapping between vni and vrf
15061 */
15062static int
Filip Tehlar694396d2017-02-17 14:29:11 +010015063api_one_eid_table_add_del_map (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010015064{
Damjan Marion7cd468a2016-12-19 23:05:39 +010015065 unformat_input_t *input = vam->input;
Filip Tehlar694396d2017-02-17 14:29:11 +010015066 vl_api_one_eid_table_add_del_map_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015067 u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
15068 u32 vni, vrf, bd_index;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015069 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015070
15071 /* Parse args required to build the message */
15072 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15073 {
15074 if (unformat (input, "del"))
15075 is_add = 0;
15076 else if (unformat (input, "vrf %d", &vrf))
15077 vrf_set = 1;
15078 else if (unformat (input, "bd_index %d", &bd_index))
15079 bd_index_set = 1;
15080 else if (unformat (input, "vni %d", &vni))
15081 vni_set = 1;
15082 else
15083 break;
15084 }
15085
15086 if (!vni_set || (!vrf_set && !bd_index_set))
15087 {
15088 errmsg ("missing arguments!");
15089 return -99;
15090 }
15091
15092 if (vrf_set && bd_index_set)
15093 {
15094 errmsg ("error: both vrf and bd entered!");
15095 return -99;
15096 }
15097
Filip Tehlar694396d2017-02-17 14:29:11 +010015098 M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015099
15100 mp->is_add = is_add;
15101 mp->vni = htonl (vni);
15102 mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
15103 mp->is_l2 = bd_index_set;
15104
15105 /* send */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015106 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015107
15108 /* wait for reply */
Jon Loeliger56c7b012017-02-01 12:31:41 -060015109 W (ret);
15110 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015111}
15112
Filip Tehlar694396d2017-02-17 14:29:11 +010015113#define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
15114
Damjan Marion7cd468a2016-12-19 23:05:39 +010015115uword
15116unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
15117{
15118 u32 *action = va_arg (*args, u32 *);
15119 u8 *s = 0;
15120
15121 if (unformat (input, "%s", &s))
15122 {
15123 if (!strcmp ((char *) s, "no-action"))
15124 action[0] = 0;
15125 else if (!strcmp ((char *) s, "natively-forward"))
15126 action[0] = 1;
15127 else if (!strcmp ((char *) s, "send-map-request"))
15128 action[0] = 2;
15129 else if (!strcmp ((char *) s, "drop"))
15130 action[0] = 3;
15131 else
15132 {
15133 clib_warning ("invalid action: '%s'", s);
15134 action[0] = 3;
15135 }
15136 }
15137 else
15138 return 0;
15139
15140 vec_free (s);
15141 return 1;
15142}
15143
15144/**
Filip Tehlar694396d2017-02-17 14:29:11 +010015145 * Add/del remote mapping to/from ONE control plane
Damjan Marion7cd468a2016-12-19 23:05:39 +010015146 *
15147 * @param vam vpp API test context
15148 * @return return code
15149 */
15150static int
Filip Tehlar694396d2017-02-17 14:29:11 +010015151api_one_add_del_remote_mapping (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010015152{
15153 unformat_input_t *input = vam->input;
Filip Tehlar694396d2017-02-17 14:29:11 +010015154 vl_api_one_add_del_remote_mapping_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015155 u32 vni = 0;
15156 lisp_eid_vat_t _eid, *eid = &_eid;
15157 lisp_eid_vat_t _seid, *seid = &_seid;
15158 u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
15159 u32 action = ~0, p, w, data_len;
15160 ip4_address_t rloc4;
15161 ip6_address_t rloc6;
Filip Tehlar05a057b2017-02-01 08:50:31 +010015162 vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015163 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015164
15165 memset (&rloc, 0, sizeof (rloc));
15166
15167 /* Parse args required to build the message */
15168 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15169 {
15170 if (unformat (input, "del-all"))
15171 {
15172 del_all = 1;
15173 }
15174 else if (unformat (input, "del"))
15175 {
15176 is_add = 0;
15177 }
15178 else if (unformat (input, "add"))
15179 {
15180 is_add = 1;
15181 }
15182 else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15183 {
15184 eid_set = 1;
15185 }
15186 else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
15187 {
15188 seid_set = 1;
15189 }
15190 else if (unformat (input, "vni %d", &vni))
15191 {
15192 ;
15193 }
15194 else if (unformat (input, "p %d w %d", &p, &w))
15195 {
15196 if (!curr_rloc)
15197 {
15198 errmsg ("No RLOC configured for setting priority/weight!");
15199 return -99;
15200 }
15201 curr_rloc->priority = p;
15202 curr_rloc->weight = w;
15203 }
15204 else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
15205 {
15206 rloc.is_ip4 = 1;
15207 clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
15208 vec_add1 (rlocs, rloc);
15209 curr_rloc = &rlocs[vec_len (rlocs) - 1];
15210 }
15211 else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
15212 {
15213 rloc.is_ip4 = 0;
15214 clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
15215 vec_add1 (rlocs, rloc);
15216 curr_rloc = &rlocs[vec_len (rlocs) - 1];
15217 }
15218 else if (unformat (input, "action %U",
15219 unformat_negative_mapping_action, &action))
15220 {
15221 ;
15222 }
15223 else
15224 {
15225 clib_warning ("parse error '%U'", format_unformat_error, input);
15226 return -99;
15227 }
15228 }
15229
15230 if (0 == eid_set)
15231 {
15232 errmsg ("missing params!");
15233 return -99;
15234 }
15235
15236 if (is_add && (~0 == action) && 0 == vec_len (rlocs))
15237 {
15238 errmsg ("no action set for negative map-reply!");
15239 return -99;
15240 }
15241
Filip Tehlar05a057b2017-02-01 08:50:31 +010015242 data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015243
Filip Tehlar694396d2017-02-17 14:29:11 +010015244 M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015245 mp->is_add = is_add;
15246 mp->vni = htonl (vni);
15247 mp->action = (u8) action;
15248 mp->is_src_dst = seid_set;
15249 mp->eid_len = eid->len;
15250 mp->seid_len = seid->len;
15251 mp->del_all = del_all;
15252 mp->eid_type = eid->type;
15253 lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15254 lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
15255
15256 mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
15257 clib_memcpy (mp->rlocs, rlocs, data_len);
15258 vec_free (rlocs);
15259
15260 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015261 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015262
15263 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060015264 W (ret);
15265 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015266}
15267
Filip Tehlar694396d2017-02-17 14:29:11 +010015268#define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
15269
Damjan Marion7cd468a2016-12-19 23:05:39 +010015270/**
Filip Tehlar694396d2017-02-17 14:29:11 +010015271 * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
Damjan Marion7cd468a2016-12-19 23:05:39 +010015272 * forwarding entries in data-plane accordingly.
15273 *
15274 * @param vam vpp API test context
15275 * @return return code
15276 */
15277static int
Filip Tehlar694396d2017-02-17 14:29:11 +010015278api_one_add_del_adjacency (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010015279{
15280 unformat_input_t *input = vam->input;
Filip Tehlar694396d2017-02-17 14:29:11 +010015281 vl_api_one_add_del_adjacency_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015282 u32 vni = 0;
15283 ip4_address_t leid4, reid4;
15284 ip6_address_t leid6, reid6;
15285 u8 reid_mac[6] = { 0 };
15286 u8 leid_mac[6] = { 0 };
15287 u8 reid_type, leid_type;
15288 u32 leid_len = 0, reid_len = 0, len;
15289 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015290 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015291
15292 leid_type = reid_type = (u8) ~ 0;
15293
15294 /* Parse args required to build the message */
15295 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15296 {
15297 if (unformat (input, "del"))
15298 {
15299 is_add = 0;
15300 }
15301 else if (unformat (input, "add"))
15302 {
15303 is_add = 1;
15304 }
15305 else if (unformat (input, "reid %U/%d", unformat_ip4_address,
15306 &reid4, &len))
15307 {
15308 reid_type = 0; /* ipv4 */
15309 reid_len = len;
15310 }
15311 else if (unformat (input, "reid %U/%d", unformat_ip6_address,
15312 &reid6, &len))
15313 {
15314 reid_type = 1; /* ipv6 */
15315 reid_len = len;
15316 }
15317 else if (unformat (input, "reid %U", unformat_ethernet_address,
15318 reid_mac))
15319 {
15320 reid_type = 2; /* mac */
15321 }
15322 else if (unformat (input, "leid %U/%d", unformat_ip4_address,
15323 &leid4, &len))
15324 {
15325 leid_type = 0; /* ipv4 */
15326 leid_len = len;
15327 }
15328 else if (unformat (input, "leid %U/%d", unformat_ip6_address,
15329 &leid6, &len))
15330 {
15331 leid_type = 1; /* ipv6 */
15332 leid_len = len;
15333 }
15334 else if (unformat (input, "leid %U", unformat_ethernet_address,
15335 leid_mac))
15336 {
15337 leid_type = 2; /* mac */
15338 }
15339 else if (unformat (input, "vni %d", &vni))
15340 {
15341 ;
15342 }
15343 else
15344 {
15345 errmsg ("parse error '%U'", format_unformat_error, input);
15346 return -99;
15347 }
15348 }
15349
15350 if ((u8) ~ 0 == reid_type)
15351 {
15352 errmsg ("missing params!");
15353 return -99;
15354 }
15355
15356 if (leid_type != reid_type)
15357 {
15358 errmsg ("remote and local EIDs are of different types!");
15359 return -99;
15360 }
15361
Filip Tehlar694396d2017-02-17 14:29:11 +010015362 M (ONE_ADD_DEL_ADJACENCY, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015363 mp->is_add = is_add;
15364 mp->vni = htonl (vni);
15365 mp->leid_len = leid_len;
15366 mp->reid_len = reid_len;
15367 mp->eid_type = reid_type;
15368
15369 switch (mp->eid_type)
15370 {
15371 case 0:
15372 clib_memcpy (mp->leid, &leid4, sizeof (leid4));
15373 clib_memcpy (mp->reid, &reid4, sizeof (reid4));
15374 break;
15375 case 1:
15376 clib_memcpy (mp->leid, &leid6, sizeof (leid6));
15377 clib_memcpy (mp->reid, &reid6, sizeof (reid6));
15378 break;
15379 case 2:
15380 clib_memcpy (mp->leid, leid_mac, 6);
15381 clib_memcpy (mp->reid, reid_mac, 6);
15382 break;
15383 default:
15384 errmsg ("unknown EID type %d!", mp->eid_type);
15385 return 0;
15386 }
15387
15388 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015389 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015390
15391 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060015392 W (ret);
15393 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015394}
15395
Filip Tehlar694396d2017-02-17 14:29:11 +010015396#define api_lisp_add_del_adjacency api_one_add_del_adjacency
15397
Filip Tehlar3e7b56932017-02-21 18:28:34 +010015398uword
15399unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
15400{
15401 u32 *mode = va_arg (*args, u32 *);
15402
15403 if (unformat (input, "lisp"))
15404 *mode = 0;
15405 else if (unformat (input, "vxlan"))
15406 *mode = 1;
15407 else
15408 return 0;
15409
15410 return 1;
15411}
15412
15413static int
15414api_gpe_get_encap_mode (vat_main_t * vam)
15415{
15416 vl_api_gpe_get_encap_mode_t *mp;
15417 int ret;
15418
15419 /* Construct the API message */
15420 M (GPE_GET_ENCAP_MODE, mp);
15421
15422 /* send it... */
15423 S (mp);
15424
15425 /* Wait for a reply... */
15426 W (ret);
15427 return ret;
15428}
15429
15430static int
15431api_gpe_set_encap_mode (vat_main_t * vam)
15432{
15433 unformat_input_t *input = vam->input;
15434 vl_api_gpe_set_encap_mode_t *mp;
15435 int ret;
15436 u32 mode = 0;
15437
15438 /* Parse args required to build the message */
15439 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15440 {
15441 if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
15442 ;
15443 else
15444 break;
15445 }
15446
15447 /* Construct the API message */
15448 M (GPE_SET_ENCAP_MODE, mp);
15449
15450 mp->mode = mode;
15451
15452 /* send it... */
15453 S (mp);
15454
15455 /* Wait for a reply... */
15456 W (ret);
15457 return ret;
15458}
15459
Damjan Marion7cd468a2016-12-19 23:05:39 +010015460static int
15461api_lisp_gpe_add_del_iface (vat_main_t * vam)
15462{
15463 unformat_input_t *input = vam->input;
Filip Tehlar82786c42017-02-20 15:20:37 +010015464 vl_api_gpe_add_del_iface_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015465 u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
15466 u32 dp_table = 0, vni = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015467 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015468
15469 /* Parse args required to build the message */
15470 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15471 {
15472 if (unformat (input, "up"))
15473 {
15474 action_set = 1;
15475 is_add = 1;
15476 }
15477 else if (unformat (input, "down"))
15478 {
15479 action_set = 1;
15480 is_add = 0;
15481 }
15482 else if (unformat (input, "table_id %d", &dp_table))
15483 {
15484 dp_table_set = 1;
15485 }
15486 else if (unformat (input, "bd_id %d", &dp_table))
15487 {
15488 dp_table_set = 1;
15489 is_l2 = 1;
15490 }
15491 else if (unformat (input, "vni %d", &vni))
15492 {
15493 vni_set = 1;
15494 }
15495 else
15496 break;
15497 }
15498
15499 if (action_set == 0)
15500 {
15501 errmsg ("Action not set");
15502 return -99;
15503 }
15504 if (dp_table_set == 0 || vni_set == 0)
15505 {
15506 errmsg ("vni and dp_table must be set");
15507 return -99;
15508 }
15509
15510 /* Construct the API message */
Filip Tehlar82786c42017-02-20 15:20:37 +010015511 M (GPE_ADD_DEL_IFACE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015512
15513 mp->is_add = is_add;
15514 mp->dp_table = dp_table;
15515 mp->is_l2 = is_l2;
15516 mp->vni = vni;
15517
15518 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015519 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015520
15521 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060015522 W (ret);
15523 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015524}
15525
15526/**
Filip Tehlar694396d2017-02-17 14:29:11 +010015527 * Add/del map request itr rlocs from ONE control plane and updates
Damjan Marion7cd468a2016-12-19 23:05:39 +010015528 *
15529 * @param vam vpp API test context
15530 * @return return code
15531 */
15532static int
Filip Tehlar694396d2017-02-17 14:29:11 +010015533api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010015534{
15535 unformat_input_t *input = vam->input;
Filip Tehlar694396d2017-02-17 14:29:11 +010015536 vl_api_one_add_del_map_request_itr_rlocs_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015537 u8 *locator_set_name = 0;
15538 u8 locator_set_name_set = 0;
15539 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015540 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015541
15542 /* Parse args required to build the message */
15543 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15544 {
15545 if (unformat (input, "del"))
15546 {
15547 is_add = 0;
15548 }
15549 else if (unformat (input, "%_%v%_", &locator_set_name))
15550 {
15551 locator_set_name_set = 1;
15552 }
15553 else
15554 {
15555 clib_warning ("parse error '%U'", format_unformat_error, input);
15556 return -99;
15557 }
15558 }
15559
15560 if (is_add && !locator_set_name_set)
15561 {
15562 errmsg ("itr-rloc is not set!");
15563 return -99;
15564 }
15565
15566 if (is_add && vec_len (locator_set_name) > 64)
15567 {
15568 errmsg ("itr-rloc locator-set name too long");
15569 vec_free (locator_set_name);
15570 return -99;
15571 }
15572
Filip Tehlar694396d2017-02-17 14:29:11 +010015573 M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015574 mp->is_add = is_add;
15575 if (is_add)
15576 {
15577 clib_memcpy (mp->locator_set_name, locator_set_name,
15578 vec_len (locator_set_name));
15579 }
15580 else
15581 {
15582 memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
15583 }
15584 vec_free (locator_set_name);
15585
15586 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015587 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015588
15589 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060015590 W (ret);
15591 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015592}
15593
Filip Tehlar694396d2017-02-17 14:29:11 +010015594#define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
15595
Damjan Marion7cd468a2016-12-19 23:05:39 +010015596static int
Filip Tehlar694396d2017-02-17 14:29:11 +010015597api_one_locator_dump (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010015598{
15599 unformat_input_t *input = vam->input;
Filip Tehlar694396d2017-02-17 14:29:11 +010015600 vl_api_one_locator_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060015601 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015602 u8 is_index_set = 0, is_name_set = 0;
15603 u8 *ls_name = 0;
15604 u32 ls_index = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015605 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015606
15607 /* Parse args required to build the message */
15608 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15609 {
15610 if (unformat (input, "ls_name %_%v%_", &ls_name))
15611 {
15612 is_name_set = 1;
15613 }
15614 else if (unformat (input, "ls_index %d", &ls_index))
15615 {
15616 is_index_set = 1;
15617 }
15618 else
15619 {
15620 errmsg ("parse error '%U'", format_unformat_error, input);
15621 return -99;
15622 }
15623 }
15624
15625 if (!is_index_set && !is_name_set)
15626 {
15627 errmsg ("error: expected one of index or name!");
15628 return -99;
15629 }
15630
15631 if (is_index_set && is_name_set)
15632 {
15633 errmsg ("error: only one param expected!");
15634 return -99;
15635 }
15636
15637 if (vec_len (ls_name) > 62)
15638 {
15639 errmsg ("error: locator set name too long!");
15640 return -99;
15641 }
15642
15643 if (!vam->json_output)
15644 {
15645 print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
15646 }
15647
Filip Tehlar694396d2017-02-17 14:29:11 +010015648 M (ONE_LOCATOR_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015649 mp->is_index_set = is_index_set;
15650
15651 if (is_index_set)
15652 mp->ls_index = clib_host_to_net_u32 (ls_index);
15653 else
15654 {
15655 vec_add1 (ls_name, 0);
15656 strncpy ((char *) mp->ls_name, (char *) ls_name,
15657 sizeof (mp->ls_name) - 1);
15658 }
15659
15660 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015661 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015662
15663 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060015664 M (CONTROL_PING, mp_ping);
15665 S (mp_ping);
15666
Damjan Marion7cd468a2016-12-19 23:05:39 +010015667 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060015668 W (ret);
15669 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015670}
15671
Filip Tehlar694396d2017-02-17 14:29:11 +010015672#define api_lisp_locator_dump api_one_locator_dump
15673
Damjan Marion7cd468a2016-12-19 23:05:39 +010015674static int
Filip Tehlar694396d2017-02-17 14:29:11 +010015675api_one_locator_set_dump (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010015676{
Filip Tehlar694396d2017-02-17 14:29:11 +010015677 vl_api_one_locator_set_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060015678 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015679 unformat_input_t *input = vam->input;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015680 u8 filter = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015681 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015682
15683 /* Parse args required to build the message */
15684 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15685 {
15686 if (unformat (input, "local"))
15687 {
15688 filter = 1;
15689 }
15690 else if (unformat (input, "remote"))
15691 {
15692 filter = 2;
15693 }
15694 else
15695 {
15696 errmsg ("parse error '%U'", format_unformat_error, input);
15697 return -99;
15698 }
15699 }
15700
15701 if (!vam->json_output)
15702 {
15703 print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
15704 }
15705
Filip Tehlar694396d2017-02-17 14:29:11 +010015706 M (ONE_LOCATOR_SET_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015707
15708 mp->filter = filter;
15709
15710 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015711 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015712
15713 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060015714 M (CONTROL_PING, mp_ping);
15715 S (mp_ping);
15716
Damjan Marion7cd468a2016-12-19 23:05:39 +010015717 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060015718 W (ret);
15719 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015720}
15721
Filip Tehlar694396d2017-02-17 14:29:11 +010015722#define api_lisp_locator_set_dump api_one_locator_set_dump
15723
Damjan Marion7cd468a2016-12-19 23:05:39 +010015724static int
Filip Tehlar694396d2017-02-17 14:29:11 +010015725api_one_eid_table_map_dump (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010015726{
15727 u8 is_l2 = 0;
15728 u8 mode_set = 0;
15729 unformat_input_t *input = vam->input;
Filip Tehlar694396d2017-02-17 14:29:11 +010015730 vl_api_one_eid_table_map_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 /* Parse args required to build the message */
15735 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15736 {
15737 if (unformat (input, "l2"))
15738 {
15739 is_l2 = 1;
15740 mode_set = 1;
15741 }
15742 else if (unformat (input, "l3"))
15743 {
15744 is_l2 = 0;
15745 mode_set = 1;
15746 }
15747 else
15748 {
15749 errmsg ("parse error '%U'", format_unformat_error, input);
15750 return -99;
15751 }
15752 }
15753
15754 if (!mode_set)
15755 {
15756 errmsg ("expected one of 'l2' or 'l3' parameter!");
15757 return -99;
15758 }
15759
15760 if (!vam->json_output)
15761 {
15762 print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
15763 }
15764
Filip Tehlar694396d2017-02-17 14:29:11 +010015765 M (ONE_EID_TABLE_MAP_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015766 mp->is_l2 = is_l2;
15767
15768 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015769 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015770
15771 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060015772 M (CONTROL_PING, mp_ping);
15773 S (mp_ping);
15774
Damjan Marion7cd468a2016-12-19 23:05:39 +010015775 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060015776 W (ret);
15777 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015778}
15779
Filip Tehlar694396d2017-02-17 14:29:11 +010015780#define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
15781
Damjan Marion7cd468a2016-12-19 23:05:39 +010015782static int
Filip Tehlar694396d2017-02-17 14:29:11 +010015783api_one_eid_table_vni_dump (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010015784{
Filip Tehlar694396d2017-02-17 14:29:11 +010015785 vl_api_one_eid_table_vni_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060015786 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015787 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015788
15789 if (!vam->json_output)
15790 {
15791 print (vam->ofp, "VNI");
15792 }
15793
Filip Tehlar694396d2017-02-17 14:29:11 +010015794 M (ONE_EID_TABLE_VNI_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015795
15796 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015797 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015798
15799 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060015800 M (CONTROL_PING, mp_ping);
15801 S (mp_ping);
15802
Damjan Marion7cd468a2016-12-19 23:05:39 +010015803 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060015804 W (ret);
15805 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015806}
15807
Filip Tehlar694396d2017-02-17 14:29:11 +010015808#define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
15809
Damjan Marion7cd468a2016-12-19 23:05:39 +010015810static int
Filip Tehlar694396d2017-02-17 14:29:11 +010015811api_one_eid_table_dump (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010015812{
15813 unformat_input_t *i = vam->input;
Filip Tehlar694396d2017-02-17 14:29:11 +010015814 vl_api_one_eid_table_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060015815 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015816 struct in_addr ip4;
15817 struct in6_addr ip6;
15818 u8 mac[6];
15819 u8 eid_type = ~0, eid_set = 0;
15820 u32 prefix_length = ~0, t, vni = 0;
15821 u8 filter = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015822 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015823
15824 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15825 {
15826 if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
15827 {
15828 eid_set = 1;
15829 eid_type = 0;
15830 prefix_length = t;
15831 }
15832 else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
15833 {
15834 eid_set = 1;
15835 eid_type = 1;
15836 prefix_length = t;
15837 }
15838 else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
15839 {
15840 eid_set = 1;
15841 eid_type = 2;
15842 }
15843 else if (unformat (i, "vni %d", &t))
15844 {
15845 vni = t;
15846 }
15847 else if (unformat (i, "local"))
15848 {
15849 filter = 1;
15850 }
15851 else if (unformat (i, "remote"))
15852 {
15853 filter = 2;
15854 }
15855 else
15856 {
15857 errmsg ("parse error '%U'", format_unformat_error, i);
15858 return -99;
15859 }
15860 }
15861
15862 if (!vam->json_output)
15863 {
15864 print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
15865 "type", "ls_index", "ttl", "authoritative", "key_id", "key");
15866 }
15867
Filip Tehlar694396d2017-02-17 14:29:11 +010015868 M (ONE_EID_TABLE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015869
15870 mp->filter = filter;
15871 if (eid_set)
15872 {
15873 mp->eid_set = 1;
15874 mp->vni = htonl (vni);
15875 mp->eid_type = eid_type;
15876 switch (eid_type)
15877 {
15878 case 0:
15879 mp->prefix_length = prefix_length;
15880 clib_memcpy (mp->eid, &ip4, sizeof (ip4));
15881 break;
15882 case 1:
15883 mp->prefix_length = prefix_length;
15884 clib_memcpy (mp->eid, &ip6, sizeof (ip6));
15885 break;
15886 case 2:
15887 clib_memcpy (mp->eid, mac, sizeof (mac));
15888 break;
15889 default:
15890 errmsg ("unknown EID type %d!", eid_type);
15891 return -99;
15892 }
15893 }
15894
15895 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015896 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015897
15898 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060015899 M (CONTROL_PING, mp_ping);
15900 S (mp_ping);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015901
15902 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060015903 W (ret);
15904 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015905}
15906
Filip Tehlar694396d2017-02-17 14:29:11 +010015907#define api_lisp_eid_table_dump api_one_eid_table_dump
15908
Damjan Marion7cd468a2016-12-19 23:05:39 +010015909static int
Filip Tehlar5fae99c2017-01-18 12:57:37 +010015910api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
15911{
15912 unformat_input_t *i = vam->input;
Filip Tehlar82786c42017-02-20 15:20:37 +010015913 vl_api_gpe_fwd_entries_get_t *mp;
Filip Tehlar5fae99c2017-01-18 12:57:37 +010015914 u8 vni_set = 0;
15915 u32 vni = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015916 int ret;
Filip Tehlar5fae99c2017-01-18 12:57:37 +010015917
15918 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15919 {
15920 if (unformat (i, "vni %d", &vni))
15921 {
15922 vni_set = 1;
15923 }
15924 else
15925 {
15926 errmsg ("parse error '%U'", format_unformat_error, i);
15927 return -99;
15928 }
15929 }
15930
15931 if (!vni_set)
15932 {
15933 errmsg ("vni not set!");
15934 return -99;
15935 }
15936
15937 if (!vam->json_output)
15938 {
15939 print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
15940 "leid", "reid");
15941 }
15942
Filip Tehlar82786c42017-02-20 15:20:37 +010015943 M (GPE_FWD_ENTRIES_GET, mp);
Filip Tehlar5fae99c2017-01-18 12:57:37 +010015944 mp->vni = clib_host_to_net_u32 (vni);
15945
15946 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015947 S (mp);
Filip Tehlar5fae99c2017-01-18 12:57:37 +010015948
15949 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060015950 W (ret);
15951 return ret;
Filip Tehlar5fae99c2017-01-18 12:57:37 +010015952}
15953
Filip Tehlar0eb874e2017-05-18 14:23:32 +020015954#define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
15955#define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
Filip Tehlar82786c42017-02-20 15:20:37 +010015956#define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
15957#define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
15958#define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
15959#define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
Filip Tehlar5fae99c2017-01-18 12:57:37 +010015960
15961static int
Filip Tehlar694396d2017-02-17 14:29:11 +010015962api_one_adjacencies_get (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010015963{
15964 unformat_input_t *i = vam->input;
Filip Tehlar694396d2017-02-17 14:29:11 +010015965 vl_api_one_adjacencies_get_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015966 u8 vni_set = 0;
15967 u32 vni = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015968 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015969
15970 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15971 {
15972 if (unformat (i, "vni %d", &vni))
15973 {
15974 vni_set = 1;
15975 }
15976 else
15977 {
15978 errmsg ("parse error '%U'", format_unformat_error, i);
15979 return -99;
15980 }
15981 }
15982
15983 if (!vni_set)
15984 {
15985 errmsg ("vni not set!");
15986 return -99;
15987 }
15988
15989 if (!vam->json_output)
15990 {
15991 print (vam->ofp, "%s %40s", "leid", "reid");
15992 }
15993
Filip Tehlar694396d2017-02-17 14:29:11 +010015994 M (ONE_ADJACENCIES_GET, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015995 mp->vni = clib_host_to_net_u32 (vni);
15996
15997 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015998 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015999
16000 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060016001 W (ret);
16002 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016003}
16004
Filip Tehlar694396d2017-02-17 14:29:11 +010016005#define api_lisp_adjacencies_get api_one_adjacencies_get
16006
Damjan Marion7cd468a2016-12-19 23:05:39 +010016007static int
Filip Tehlar0eb874e2017-05-18 14:23:32 +020016008api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
16009{
16010 vl_api_gpe_fwd_entry_vnis_get_t *mp;
16011 int ret;
16012
16013 if (!vam->json_output)
16014 {
16015 print (vam->ofp, "VNIs");
16016 }
16017
16018 M (GPE_FWD_ENTRY_VNIS_GET, mp);
16019
16020 /* send it... */
16021 S (mp);
16022
16023 /* Wait for a reply... */
16024 W (ret);
16025 return ret;
16026}
16027
16028static int
Filip Tehlar694396d2017-02-17 14:29:11 +010016029api_one_map_server_dump (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010016030{
Filip Tehlar694396d2017-02-17 14:29:11 +010016031 vl_api_one_map_server_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016032 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016033 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016034
16035 if (!vam->json_output)
16036 {
16037 print (vam->ofp, "%=20s", "Map server");
16038 }
16039
Filip Tehlar694396d2017-02-17 14:29:11 +010016040 M (ONE_MAP_SERVER_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016041 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016042 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016043
16044 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016045 M (CONTROL_PING, mp_ping);
16046 S (mp_ping);
16047
Damjan Marion7cd468a2016-12-19 23:05:39 +010016048 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060016049 W (ret);
16050 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016051}
16052
Filip Tehlar694396d2017-02-17 14:29:11 +010016053#define api_lisp_map_server_dump api_one_map_server_dump
16054
Damjan Marion7cd468a2016-12-19 23:05:39 +010016055static int
Filip Tehlar694396d2017-02-17 14:29:11 +010016056api_one_map_resolver_dump (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010016057{
Filip Tehlar694396d2017-02-17 14:29:11 +010016058 vl_api_one_map_resolver_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016059 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016060 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016061
16062 if (!vam->json_output)
16063 {
16064 print (vam->ofp, "%=20s", "Map resolver");
16065 }
16066
Filip Tehlar694396d2017-02-17 14:29:11 +010016067 M (ONE_MAP_RESOLVER_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016068 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016069 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016070
16071 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016072 M (CONTROL_PING, mp_ping);
16073 S (mp_ping);
16074
Damjan Marion7cd468a2016-12-19 23:05:39 +010016075 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060016076 W (ret);
16077 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016078}
16079
Filip Tehlar694396d2017-02-17 14:29:11 +010016080#define api_lisp_map_resolver_dump api_one_map_resolver_dump
16081
Damjan Marion7cd468a2016-12-19 23:05:39 +010016082static int
Filip Tehlar21511912017-04-07 10:41:42 +020016083api_one_stats_flush (vat_main_t * vam)
16084{
16085 vl_api_one_stats_flush_t *mp;
16086 int ret = 0;
16087
16088 M (ONE_STATS_FLUSH, mp);
16089 S (mp);
16090 W (ret);
16091 return ret;
16092}
16093
16094static int
Filip Tehlar4868ff62017-03-09 16:48:39 +010016095api_one_stats_dump (vat_main_t * vam)
16096{
16097 vl_api_one_stats_dump_t *mp;
16098 vl_api_control_ping_t *mp_ping;
16099 int ret;
16100
16101 M (ONE_STATS_DUMP, mp);
16102 /* send it... */
16103 S (mp);
16104
16105 /* Use a control ping for synchronization */
16106 M (CONTROL_PING, mp_ping);
16107 S (mp_ping);
16108
16109 /* Wait for a reply... */
16110 W (ret);
16111 return ret;
16112}
16113
16114static int
Filip Tehlar694396d2017-02-17 14:29:11 +010016115api_show_one_status (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010016116{
Filip Tehlar694396d2017-02-17 14:29:11 +010016117 vl_api_show_one_status_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016118 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016119
16120 if (!vam->json_output)
16121 {
Filip Tehlar694396d2017-02-17 14:29:11 +010016122 print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
Damjan Marion7cd468a2016-12-19 23:05:39 +010016123 }
16124
Filip Tehlar694396d2017-02-17 14:29:11 +010016125 M (SHOW_ONE_STATUS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016126 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016127 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016128 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060016129 W (ret);
16130 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016131}
16132
Filip Tehlar694396d2017-02-17 14:29:11 +010016133#define api_show_lisp_status api_show_one_status
16134
Damjan Marion7cd468a2016-12-19 23:05:39 +010016135static int
Filip Tehlar5fae99c2017-01-18 12:57:37 +010016136api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
16137{
Filip Tehlar82786c42017-02-20 15:20:37 +010016138 vl_api_gpe_fwd_entry_path_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016139 vl_api_control_ping_t *mp_ping;
Filip Tehlar5fae99c2017-01-18 12:57:37 +010016140 unformat_input_t *i = vam->input;
16141 u32 fwd_entry_index = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016142 int ret;
Filip Tehlar5fae99c2017-01-18 12:57:37 +010016143
16144 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16145 {
16146 if (unformat (i, "index %d", &fwd_entry_index))
16147 ;
16148 else
16149 break;
16150 }
16151
16152 if (~0 == fwd_entry_index)
16153 {
16154 errmsg ("no index specified!");
16155 return -99;
16156 }
16157
16158 if (!vam->json_output)
16159 {
16160 print (vam->ofp, "first line");
16161 }
16162
Filip Tehlar82786c42017-02-20 15:20:37 +010016163 M (GPE_FWD_ENTRY_PATH_DUMP, mp);
Filip Tehlar5fae99c2017-01-18 12:57:37 +010016164
16165 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016166 S (mp);
Filip Tehlar5fae99c2017-01-18 12:57:37 +010016167 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016168 M (CONTROL_PING, mp_ping);
16169 S (mp_ping);
16170
Filip Tehlar5fae99c2017-01-18 12:57:37 +010016171 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060016172 W (ret);
16173 return ret;
Filip Tehlar5fae99c2017-01-18 12:57:37 +010016174}
16175
16176static int
Filip Tehlar694396d2017-02-17 14:29:11 +010016177api_one_get_map_request_itr_rlocs (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010016178{
Filip Tehlar694396d2017-02-17 14:29:11 +010016179 vl_api_one_get_map_request_itr_rlocs_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016180 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016181
16182 if (!vam->json_output)
16183 {
16184 print (vam->ofp, "%=20s", "itr-rlocs:");
16185 }
16186
Filip Tehlar694396d2017-02-17 14:29:11 +010016187 M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016188 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016189 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016190 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060016191 W (ret);
16192 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016193}
16194
Filip Tehlar694396d2017-02-17 14:29:11 +010016195#define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
16196
Damjan Marion7cd468a2016-12-19 23:05:39 +010016197static int
16198api_af_packet_create (vat_main_t * vam)
16199{
16200 unformat_input_t *i = vam->input;
16201 vl_api_af_packet_create_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016202 u8 *host_if_name = 0;
16203 u8 hw_addr[6];
16204 u8 random_hw_addr = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016205 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016206
16207 memset (hw_addr, 0, sizeof (hw_addr));
16208
16209 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16210 {
16211 if (unformat (i, "name %s", &host_if_name))
16212 vec_add1 (host_if_name, 0);
16213 else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
16214 random_hw_addr = 0;
16215 else
16216 break;
16217 }
16218
16219 if (!vec_len (host_if_name))
16220 {
16221 errmsg ("host-interface name must be specified");
16222 return -99;
16223 }
16224
16225 if (vec_len (host_if_name) > 64)
16226 {
16227 errmsg ("host-interface name too long");
16228 return -99;
16229 }
16230
Jon Loeliger8a2aea32017-01-31 13:19:40 -060016231 M (AF_PACKET_CREATE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016232
16233 clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
16234 clib_memcpy (mp->hw_addr, hw_addr, 6);
16235 mp->use_random_hw_addr = random_hw_addr;
16236 vec_free (host_if_name);
16237
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016238 S (mp);
Dave Baracha1a093d2017-03-02 13:13:23 -050016239
16240 /* *INDENT-OFF* */
16241 W2 (ret,
16242 ({
16243 if (ret == 0)
16244 fprintf (vam->ofp ? vam->ofp : stderr,
16245 " new sw_if_index = %d\n", vam->sw_if_index);
16246 }));
16247 /* *INDENT-ON* */
Jon Loeliger56c7b012017-02-01 12:31:41 -060016248 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016249}
16250
16251static int
16252api_af_packet_delete (vat_main_t * vam)
16253{
16254 unformat_input_t *i = vam->input;
16255 vl_api_af_packet_delete_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016256 u8 *host_if_name = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016257 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016258
16259 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16260 {
16261 if (unformat (i, "name %s", &host_if_name))
16262 vec_add1 (host_if_name, 0);
16263 else
16264 break;
16265 }
16266
16267 if (!vec_len (host_if_name))
16268 {
16269 errmsg ("host-interface name must be specified");
16270 return -99;
16271 }
16272
16273 if (vec_len (host_if_name) > 64)
16274 {
16275 errmsg ("host-interface name too long");
16276 return -99;
16277 }
16278
Jon Loeliger8a2aea32017-01-31 13:19:40 -060016279 M (AF_PACKET_DELETE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016280
16281 clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
16282 vec_free (host_if_name);
16283
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016284 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060016285 W (ret);
16286 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016287}
16288
16289static int
16290api_policer_add_del (vat_main_t * vam)
16291{
16292 unformat_input_t *i = vam->input;
16293 vl_api_policer_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016294 u8 is_add = 1;
16295 u8 *name = 0;
16296 u32 cir = 0;
16297 u32 eir = 0;
16298 u64 cb = 0;
16299 u64 eb = 0;
16300 u8 rate_type = 0;
16301 u8 round_type = 0;
16302 u8 type = 0;
16303 u8 color_aware = 0;
16304 sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016305 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016306
16307 conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
16308 conform_action.dscp = 0;
16309 exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
16310 exceed_action.dscp = 0;
16311 violate_action.action_type = SSE2_QOS_ACTION_DROP;
16312 violate_action.dscp = 0;
16313
16314 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16315 {
16316 if (unformat (i, "del"))
16317 is_add = 0;
16318 else if (unformat (i, "name %s", &name))
16319 vec_add1 (name, 0);
16320 else if (unformat (i, "cir %u", &cir))
16321 ;
16322 else if (unformat (i, "eir %u", &eir))
16323 ;
16324 else if (unformat (i, "cb %u", &cb))
16325 ;
16326 else if (unformat (i, "eb %u", &eb))
16327 ;
16328 else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
16329 &rate_type))
16330 ;
16331 else if (unformat (i, "round_type %U", unformat_policer_round_type,
16332 &round_type))
16333 ;
16334 else if (unformat (i, "type %U", unformat_policer_type, &type))
16335 ;
16336 else if (unformat (i, "conform_action %U", unformat_policer_action_type,
16337 &conform_action))
16338 ;
16339 else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
16340 &exceed_action))
16341 ;
16342 else if (unformat (i, "violate_action %U", unformat_policer_action_type,
16343 &violate_action))
16344 ;
16345 else if (unformat (i, "color-aware"))
16346 color_aware = 1;
16347 else
16348 break;
16349 }
16350
16351 if (!vec_len (name))
16352 {
16353 errmsg ("policer name must be specified");
16354 return -99;
16355 }
16356
16357 if (vec_len (name) > 64)
16358 {
16359 errmsg ("policer name too long");
16360 return -99;
16361 }
16362
Jon Loeliger8a2aea32017-01-31 13:19:40 -060016363 M (POLICER_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016364
16365 clib_memcpy (mp->name, name, vec_len (name));
16366 vec_free (name);
16367 mp->is_add = is_add;
16368 mp->cir = cir;
16369 mp->eir = eir;
16370 mp->cb = cb;
16371 mp->eb = eb;
16372 mp->rate_type = rate_type;
16373 mp->round_type = round_type;
16374 mp->type = type;
16375 mp->conform_action_type = conform_action.action_type;
16376 mp->conform_dscp = conform_action.dscp;
16377 mp->exceed_action_type = exceed_action.action_type;
16378 mp->exceed_dscp = exceed_action.dscp;
16379 mp->violate_action_type = violate_action.action_type;
16380 mp->violate_dscp = violate_action.dscp;
16381 mp->color_aware = color_aware;
16382
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016383 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060016384 W (ret);
16385 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016386}
16387
16388static int
16389api_policer_dump (vat_main_t * vam)
16390{
16391 unformat_input_t *i = vam->input;
16392 vl_api_policer_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016393 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016394 u8 *match_name = 0;
16395 u8 match_name_valid = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016396 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016397
16398 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16399 {
16400 if (unformat (i, "name %s", &match_name))
16401 {
16402 vec_add1 (match_name, 0);
16403 match_name_valid = 1;
16404 }
16405 else
16406 break;
16407 }
16408
Jon Loeliger8a2aea32017-01-31 13:19:40 -060016409 M (POLICER_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016410 mp->match_name_valid = match_name_valid;
16411 clib_memcpy (mp->match_name, match_name, vec_len (match_name));
16412 vec_free (match_name);
16413 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016414 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016415
16416 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016417 M (CONTROL_PING, mp_ping);
16418 S (mp_ping);
16419
Damjan Marion7cd468a2016-12-19 23:05:39 +010016420 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060016421 W (ret);
16422 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016423}
16424
16425static int
16426api_policer_classify_set_interface (vat_main_t * vam)
16427{
16428 unformat_input_t *i = vam->input;
16429 vl_api_policer_classify_set_interface_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016430 u32 sw_if_index;
16431 int sw_if_index_set;
16432 u32 ip4_table_index = ~0;
16433 u32 ip6_table_index = ~0;
16434 u32 l2_table_index = ~0;
16435 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016436 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016437
16438 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16439 {
16440 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16441 sw_if_index_set = 1;
16442 else if (unformat (i, "sw_if_index %d", &sw_if_index))
16443 sw_if_index_set = 1;
16444 else if (unformat (i, "del"))
16445 is_add = 0;
16446 else if (unformat (i, "ip4-table %d", &ip4_table_index))
16447 ;
16448 else if (unformat (i, "ip6-table %d", &ip6_table_index))
16449 ;
16450 else if (unformat (i, "l2-table %d", &l2_table_index))
16451 ;
16452 else
16453 {
16454 clib_warning ("parse error '%U'", format_unformat_error, i);
16455 return -99;
16456 }
16457 }
16458
16459 if (sw_if_index_set == 0)
16460 {
16461 errmsg ("missing interface name or sw_if_index");
16462 return -99;
16463 }
16464
Jon Loeliger8a2aea32017-01-31 13:19:40 -060016465 M (POLICER_CLASSIFY_SET_INTERFACE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016466
16467 mp->sw_if_index = ntohl (sw_if_index);
16468 mp->ip4_table_index = ntohl (ip4_table_index);
16469 mp->ip6_table_index = ntohl (ip6_table_index);
16470 mp->l2_table_index = ntohl (l2_table_index);
16471 mp->is_add = is_add;
16472
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016473 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060016474 W (ret);
16475 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016476}
16477
16478static int
16479api_policer_classify_dump (vat_main_t * vam)
16480{
16481 unformat_input_t *i = vam->input;
16482 vl_api_policer_classify_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016483 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016484 u8 type = POLICER_CLASSIFY_N_TABLES;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016485 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016486
16487 if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
16488 ;
16489 else
16490 {
16491 errmsg ("classify table type must be specified");
16492 return -99;
16493 }
16494
16495 if (!vam->json_output)
16496 {
16497 print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
16498 }
16499
Jon Loeliger8a2aea32017-01-31 13:19:40 -060016500 M (POLICER_CLASSIFY_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016501 mp->type = type;
16502 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016503 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016504
16505 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016506 M (CONTROL_PING, mp_ping);
16507 S (mp_ping);
16508
Damjan Marion7cd468a2016-12-19 23:05:39 +010016509 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060016510 W (ret);
16511 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016512}
16513
16514static int
16515api_netmap_create (vat_main_t * vam)
16516{
16517 unformat_input_t *i = vam->input;
16518 vl_api_netmap_create_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016519 u8 *if_name = 0;
16520 u8 hw_addr[6];
16521 u8 random_hw_addr = 1;
16522 u8 is_pipe = 0;
16523 u8 is_master = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016524 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016525
16526 memset (hw_addr, 0, sizeof (hw_addr));
16527
16528 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16529 {
16530 if (unformat (i, "name %s", &if_name))
16531 vec_add1 (if_name, 0);
16532 else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
16533 random_hw_addr = 0;
16534 else if (unformat (i, "pipe"))
16535 is_pipe = 1;
16536 else if (unformat (i, "master"))
16537 is_master = 1;
16538 else if (unformat (i, "slave"))
16539 is_master = 0;
16540 else
16541 break;
16542 }
16543
16544 if (!vec_len (if_name))
16545 {
16546 errmsg ("interface name must be specified");
16547 return -99;
16548 }
16549
16550 if (vec_len (if_name) > 64)
16551 {
16552 errmsg ("interface name too long");
16553 return -99;
16554 }
16555
Jon Loeliger8a2aea32017-01-31 13:19:40 -060016556 M (NETMAP_CREATE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016557
16558 clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
16559 clib_memcpy (mp->hw_addr, hw_addr, 6);
16560 mp->use_random_hw_addr = random_hw_addr;
16561 mp->is_pipe = is_pipe;
16562 mp->is_master = is_master;
16563 vec_free (if_name);
16564
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016565 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060016566 W (ret);
16567 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016568}
16569
16570static int
16571api_netmap_delete (vat_main_t * vam)
16572{
16573 unformat_input_t *i = vam->input;
16574 vl_api_netmap_delete_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016575 u8 *if_name = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016576 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016577
16578 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16579 {
16580 if (unformat (i, "name %s", &if_name))
16581 vec_add1 (if_name, 0);
16582 else
16583 break;
16584 }
16585
16586 if (!vec_len (if_name))
16587 {
16588 errmsg ("interface name must be specified");
16589 return -99;
16590 }
16591
16592 if (vec_len (if_name) > 64)
16593 {
16594 errmsg ("interface name too long");
16595 return -99;
16596 }
16597
Jon Loeliger8a2aea32017-01-31 13:19:40 -060016598 M (NETMAP_DELETE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016599
16600 clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
16601 vec_free (if_name);
16602
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016603 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060016604 W (ret);
16605 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016606}
16607
Neale Ranns0f26c5a2017-03-01 15:12:11 -080016608static void
16609vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path2_t * fp)
16610{
16611 if (fp->afi == IP46_TYPE_IP6)
16612 print (vam->ofp,
16613 " weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16614 "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16615 ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16616 fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16617 format_ip6_address, fp->next_hop);
16618 else if (fp->afi == IP46_TYPE_IP4)
16619 print (vam->ofp,
16620 " weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16621 "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16622 ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16623 fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16624 format_ip4_address, fp->next_hop);
16625}
16626
16627static void
16628vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
16629 vl_api_fib_path2_t * fp)
16630{
16631 struct in_addr ip4;
16632 struct in6_addr ip6;
16633
16634 vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16635 vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16636 vat_json_object_add_uint (node, "is_local", fp->is_local);
16637 vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16638 vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16639 vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16640 vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16641 if (fp->afi == IP46_TYPE_IP4)
16642 {
16643 clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16644 vat_json_object_add_ip4 (node, "next_hop", ip4);
16645 }
16646 else if (fp->afi == IP46_TYPE_IP6)
16647 {
16648 clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16649 vat_json_object_add_ip6 (node, "next_hop", ip6);
16650 }
16651}
16652
16653static void
16654vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010016655{
16656 vat_main_t *vam = &vat_main;
Neale Ranns0f26c5a2017-03-01 15:12:11 -080016657 int count = ntohl (mp->mt_count);
16658 vl_api_fib_path2_t *fp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016659 i32 i;
16660
Neale Ranns0f26c5a2017-03-01 15:12:11 -080016661 print (vam->ofp, "[%d]: sw_if_index %d via:",
16662 ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
16663 fp = mp->mt_paths;
16664 for (i = 0; i < count; i++)
Damjan Marion7cd468a2016-12-19 23:05:39 +010016665 {
Neale Ranns0f26c5a2017-03-01 15:12:11 -080016666 vl_api_mpls_fib_path_print (vam, fp);
16667 fp++;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016668 }
Neale Ranns0f26c5a2017-03-01 15:12:11 -080016669
Damjan Marion7cd468a2016-12-19 23:05:39 +010016670 print (vam->ofp, "");
16671}
16672
Neale Ranns0f26c5a2017-03-01 15:12:11 -080016673#define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
16674#define vl_api_mpls_tunnel_details_t_print vl_noop_handler
16675
16676static void
16677vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +010016678{
16679 vat_main_t *vam = &vat_main;
16680 vat_json_node_t *node = NULL;
Neale Ranns0f26c5a2017-03-01 15:12:11 -080016681 int count = ntohl (mp->mt_count);
16682 vl_api_fib_path2_t *fp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016683 i32 i;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016684
16685 if (VAT_JSON_ARRAY != vam->json_tree.type)
16686 {
16687 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16688 vat_json_init_array (&vam->json_tree);
16689 }
16690 node = vat_json_array_add (&vam->json_tree);
16691
16692 vat_json_init_object (node);
Neale Ranns0f26c5a2017-03-01 15:12:11 -080016693 vat_json_object_add_uint (node, "tunnel_index",
16694 ntohl (mp->mt_tunnel_index));
16695 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
16696
16697 vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
16698
16699 fp = mp->mt_paths;
16700 for (i = 0; i < count; i++)
Damjan Marion7cd468a2016-12-19 23:05:39 +010016701 {
Neale Ranns0f26c5a2017-03-01 15:12:11 -080016702 vl_api_mpls_fib_path_json_print (node, fp);
16703 fp++;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016704 }
16705}
16706
16707static int
16708api_mpls_tunnel_dump (vat_main_t * vam)
16709{
16710 vl_api_mpls_tunnel_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016711 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016712 i32 index = -1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016713 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016714
16715 /* Parse args required to build the message */
16716 while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
16717 {
16718 if (!unformat (vam->input, "tunnel_index %d", &index))
16719 {
16720 index = -1;
16721 break;
16722 }
16723 }
16724
16725 print (vam->ofp, " tunnel_index %d", index);
16726
Jon Loeliger8a2aea32017-01-31 13:19:40 -060016727 M (MPLS_TUNNEL_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016728 mp->tunnel_index = htonl (index);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016729 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016730
16731 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016732 M (CONTROL_PING, mp_ping);
16733 S (mp_ping);
16734
Jon Loeliger56c7b012017-02-01 12:31:41 -060016735 W (ret);
16736 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016737}
16738
16739#define vl_api_mpls_fib_details_t_endian vl_noop_handler
16740#define vl_api_mpls_fib_details_t_print vl_noop_handler
16741
Neale Ranns0f26c5a2017-03-01 15:12:11 -080016742
Damjan Marion7cd468a2016-12-19 23:05:39 +010016743static void
16744vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
16745{
16746 vat_main_t *vam = &vat_main;
16747 int count = ntohl (mp->count);
16748 vl_api_fib_path2_t *fp;
16749 int i;
16750
16751 print (vam->ofp,
16752 "table-id %d, label %u, ess_bit %u",
16753 ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
16754 fp = mp->path;
16755 for (i = 0; i < count; i++)
16756 {
Neale Ranns0f26c5a2017-03-01 15:12:11 -080016757 vl_api_mpls_fib_path_print (vam, fp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016758 fp++;
16759 }
16760}
16761
16762static void vl_api_mpls_fib_details_t_handler_json
16763 (vl_api_mpls_fib_details_t * mp)
16764{
16765 vat_main_t *vam = &vat_main;
16766 int count = ntohl (mp->count);
16767 vat_json_node_t *node = NULL;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016768 vl_api_fib_path2_t *fp;
16769 int i;
16770
16771 if (VAT_JSON_ARRAY != vam->json_tree.type)
16772 {
16773 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16774 vat_json_init_array (&vam->json_tree);
16775 }
16776 node = vat_json_array_add (&vam->json_tree);
16777
16778 vat_json_init_object (node);
16779 vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16780 vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
16781 vat_json_object_add_uint (node, "label", ntohl (mp->label));
16782 vat_json_object_add_uint (node, "path_count", count);
16783 fp = mp->path;
16784 for (i = 0; i < count; i++)
16785 {
Neale Ranns0f26c5a2017-03-01 15:12:11 -080016786 vl_api_mpls_fib_path_json_print (node, fp);
16787 fp++;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016788 }
16789}
16790
16791static int
16792api_mpls_fib_dump (vat_main_t * vam)
16793{
16794 vl_api_mpls_fib_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016795 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016796 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016797
Jon Loeliger8a2aea32017-01-31 13:19:40 -060016798 M (MPLS_FIB_DUMP, mp);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016799 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016800
16801 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016802 M (CONTROL_PING, mp_ping);
16803 S (mp_ping);
16804
Jon Loeliger56c7b012017-02-01 12:31:41 -060016805 W (ret);
16806 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016807}
16808
16809#define vl_api_ip_fib_details_t_endian vl_noop_handler
16810#define vl_api_ip_fib_details_t_print vl_noop_handler
16811
16812static void
16813vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
16814{
16815 vat_main_t *vam = &vat_main;
16816 int count = ntohl (mp->count);
16817 vl_api_fib_path_t *fp;
16818 int i;
16819
16820 print (vam->ofp,
16821 "table-id %d, prefix %U/%d",
16822 ntohl (mp->table_id), format_ip4_address, mp->address,
16823 mp->address_length);
16824 fp = mp->path;
16825 for (i = 0; i < count; i++)
16826 {
16827 if (fp->afi == IP46_TYPE_IP6)
16828 print (vam->ofp,
16829 " weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16830 "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16831 ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16832 fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16833 format_ip6_address, fp->next_hop);
16834 else if (fp->afi == IP46_TYPE_IP4)
16835 print (vam->ofp,
16836 " weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16837 "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16838 ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16839 fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16840 format_ip4_address, fp->next_hop);
16841 fp++;
16842 }
16843}
16844
16845static void vl_api_ip_fib_details_t_handler_json
16846 (vl_api_ip_fib_details_t * mp)
16847{
16848 vat_main_t *vam = &vat_main;
16849 int count = ntohl (mp->count);
16850 vat_json_node_t *node = NULL;
16851 struct in_addr ip4;
16852 struct in6_addr ip6;
16853 vl_api_fib_path_t *fp;
16854 int i;
16855
16856 if (VAT_JSON_ARRAY != vam->json_tree.type)
16857 {
16858 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16859 vat_json_init_array (&vam->json_tree);
16860 }
16861 node = vat_json_array_add (&vam->json_tree);
16862
16863 vat_json_init_object (node);
16864 vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16865 clib_memcpy (&ip4, &mp->address, sizeof (ip4));
16866 vat_json_object_add_ip4 (node, "prefix", ip4);
16867 vat_json_object_add_uint (node, "mask_length", mp->address_length);
16868 vat_json_object_add_uint (node, "path_count", count);
16869 fp = mp->path;
16870 for (i = 0; i < count; i++)
16871 {
16872 vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16873 vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16874 vat_json_object_add_uint (node, "is_local", fp->is_local);
16875 vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16876 vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16877 vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16878 vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16879 if (fp->afi == IP46_TYPE_IP4)
16880 {
16881 clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16882 vat_json_object_add_ip4 (node, "next_hop", ip4);
16883 }
16884 else if (fp->afi == IP46_TYPE_IP6)
16885 {
16886 clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16887 vat_json_object_add_ip6 (node, "next_hop", ip6);
16888 }
16889 }
16890}
16891
16892static int
16893api_ip_fib_dump (vat_main_t * vam)
16894{
16895 vl_api_ip_fib_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016896 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016897 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016898
Jon Loeliger8a2aea32017-01-31 13:19:40 -060016899 M (IP_FIB_DUMP, mp);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016900 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016901
16902 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016903 M (CONTROL_PING, mp_ping);
16904 S (mp_ping);
16905
Jon Loeliger56c7b012017-02-01 12:31:41 -060016906 W (ret);
16907 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016908}
16909
Neale Ranns5a8123b2017-01-26 01:18:23 -080016910static int
16911api_ip_mfib_dump (vat_main_t * vam)
16912{
16913 vl_api_ip_mfib_dump_t *mp;
16914 vl_api_control_ping_t *mp_ping;
16915 int ret;
16916
16917 M (IP_MFIB_DUMP, mp);
16918 S (mp);
16919
16920 /* Use a control ping for synchronization */
16921 M (CONTROL_PING, mp_ping);
16922 S (mp_ping);
16923
16924 W (ret);
16925 return ret;
16926}
16927
Damjan Marion7cd468a2016-12-19 23:05:39 +010016928static void vl_api_ip_neighbor_details_t_handler
16929 (vl_api_ip_neighbor_details_t * mp)
16930{
16931 vat_main_t *vam = &vat_main;
16932
16933 print (vam->ofp, "%c %U %U",
16934 (mp->is_static) ? 'S' : 'D',
16935 format_ethernet_address, &mp->mac_address,
16936 (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
16937 &mp->ip_address);
16938}
16939
16940static void vl_api_ip_neighbor_details_t_handler_json
16941 (vl_api_ip_neighbor_details_t * mp)
16942{
16943
16944 vat_main_t *vam = &vat_main;
16945 vat_json_node_t *node;
16946 struct in_addr ip4;
16947 struct in6_addr ip6;
16948
16949 if (VAT_JSON_ARRAY != vam->json_tree.type)
16950 {
16951 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16952 vat_json_init_array (&vam->json_tree);
16953 }
16954 node = vat_json_array_add (&vam->json_tree);
16955
16956 vat_json_init_object (node);
16957 vat_json_object_add_string_copy (node, "flag",
16958 (mp->is_static) ? (u8 *) "static" : (u8 *)
16959 "dynamic");
16960
16961 vat_json_object_add_string_copy (node, "link_layer",
16962 format (0, "%U", format_ethernet_address,
16963 &mp->mac_address));
16964
16965 if (mp->is_ipv6)
16966 {
16967 clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
16968 vat_json_object_add_ip6 (node, "ip_address", ip6);
16969 }
16970 else
16971 {
16972 clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
16973 vat_json_object_add_ip4 (node, "ip_address", ip4);
16974 }
16975}
16976
16977static int
16978api_ip_neighbor_dump (vat_main_t * vam)
16979{
16980 unformat_input_t *i = vam->input;
16981 vl_api_ip_neighbor_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016982 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016983 u8 is_ipv6 = 0;
16984 u32 sw_if_index = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016985 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016986
16987 /* Parse args required to build the message */
16988 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16989 {
16990 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16991 ;
16992 else if (unformat (i, "sw_if_index %d", &sw_if_index))
16993 ;
16994 else if (unformat (i, "ip6"))
16995 is_ipv6 = 1;
16996 else
16997 break;
16998 }
16999
17000 if (sw_if_index == ~0)
17001 {
17002 errmsg ("missing interface name or sw_if_index");
17003 return -99;
17004 }
17005
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017006 M (IP_NEIGHBOR_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017007 mp->is_ipv6 = (u8) is_ipv6;
17008 mp->sw_if_index = ntohl (sw_if_index);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017009 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017010
17011 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060017012 M (CONTROL_PING, mp_ping);
17013 S (mp_ping);
17014
Jon Loeliger56c7b012017-02-01 12:31:41 -060017015 W (ret);
17016 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017017}
17018
17019#define vl_api_ip6_fib_details_t_endian vl_noop_handler
17020#define vl_api_ip6_fib_details_t_print vl_noop_handler
17021
17022static void
17023vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
17024{
17025 vat_main_t *vam = &vat_main;
17026 int count = ntohl (mp->count);
17027 vl_api_fib_path_t *fp;
17028 int i;
17029
17030 print (vam->ofp,
17031 "table-id %d, prefix %U/%d",
17032 ntohl (mp->table_id), format_ip6_address, mp->address,
17033 mp->address_length);
17034 fp = mp->path;
17035 for (i = 0; i < count; i++)
17036 {
17037 if (fp->afi == IP46_TYPE_IP6)
17038 print (vam->ofp,
17039 " weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17040 "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17041 ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17042 fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17043 format_ip6_address, fp->next_hop);
17044 else if (fp->afi == IP46_TYPE_IP4)
17045 print (vam->ofp,
17046 " weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17047 "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17048 ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17049 fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17050 format_ip4_address, fp->next_hop);
17051 fp++;
17052 }
17053}
17054
17055static void vl_api_ip6_fib_details_t_handler_json
17056 (vl_api_ip6_fib_details_t * mp)
17057{
17058 vat_main_t *vam = &vat_main;
17059 int count = ntohl (mp->count);
17060 vat_json_node_t *node = NULL;
17061 struct in_addr ip4;
17062 struct in6_addr ip6;
17063 vl_api_fib_path_t *fp;
17064 int i;
17065
17066 if (VAT_JSON_ARRAY != vam->json_tree.type)
17067 {
17068 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17069 vat_json_init_array (&vam->json_tree);
17070 }
17071 node = vat_json_array_add (&vam->json_tree);
17072
17073 vat_json_init_object (node);
17074 vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
17075 clib_memcpy (&ip6, &mp->address, sizeof (ip6));
17076 vat_json_object_add_ip6 (node, "prefix", ip6);
17077 vat_json_object_add_uint (node, "mask_length", mp->address_length);
17078 vat_json_object_add_uint (node, "path_count", count);
17079 fp = mp->path;
17080 for (i = 0; i < count; i++)
17081 {
17082 vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17083 vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17084 vat_json_object_add_uint (node, "is_local", fp->is_local);
17085 vat_json_object_add_uint (node, "is_drop", fp->is_drop);
17086 vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
17087 vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
17088 vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
17089 if (fp->afi == IP46_TYPE_IP4)
17090 {
17091 clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
17092 vat_json_object_add_ip4 (node, "next_hop", ip4);
17093 }
17094 else if (fp->afi == IP46_TYPE_IP6)
17095 {
17096 clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
17097 vat_json_object_add_ip6 (node, "next_hop", ip6);
17098 }
17099 }
17100}
17101
17102static int
17103api_ip6_fib_dump (vat_main_t * vam)
17104{
17105 vl_api_ip6_fib_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060017106 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017107 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017108
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017109 M (IP6_FIB_DUMP, mp);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017110 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017111
17112 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060017113 M (CONTROL_PING, mp_ping);
17114 S (mp_ping);
17115
Jon Loeliger56c7b012017-02-01 12:31:41 -060017116 W (ret);
17117 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017118}
17119
Neale Ranns5a8123b2017-01-26 01:18:23 -080017120static int
17121api_ip6_mfib_dump (vat_main_t * vam)
17122{
17123 vl_api_ip6_mfib_dump_t *mp;
17124 vl_api_control_ping_t *mp_ping;
17125 int ret;
17126
17127 M (IP6_MFIB_DUMP, mp);
17128 S (mp);
17129
17130 /* Use a control ping for synchronization */
17131 M (CONTROL_PING, mp_ping);
17132 S (mp_ping);
17133
17134 W (ret);
17135 return ret;
17136}
17137
Damjan Marion7cd468a2016-12-19 23:05:39 +010017138int
17139api_classify_table_ids (vat_main_t * vam)
17140{
17141 vl_api_classify_table_ids_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017142 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017143
17144 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017145 M (CLASSIFY_TABLE_IDS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017146 mp->context = 0;
17147
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017148 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060017149 W (ret);
17150 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017151}
17152
17153int
17154api_classify_table_by_interface (vat_main_t * vam)
17155{
17156 unformat_input_t *input = vam->input;
17157 vl_api_classify_table_by_interface_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017158
17159 u32 sw_if_index = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017160 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017161 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17162 {
17163 if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17164 ;
17165 else if (unformat (input, "sw_if_index %d", &sw_if_index))
17166 ;
17167 else
17168 break;
17169 }
17170 if (sw_if_index == ~0)
17171 {
17172 errmsg ("missing interface name or sw_if_index");
17173 return -99;
17174 }
17175
17176 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017177 M (CLASSIFY_TABLE_BY_INTERFACE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017178 mp->context = 0;
17179 mp->sw_if_index = ntohl (sw_if_index);
17180
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017181 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060017182 W (ret);
17183 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017184}
17185
17186int
17187api_classify_table_info (vat_main_t * vam)
17188{
17189 unformat_input_t *input = vam->input;
17190 vl_api_classify_table_info_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017191
17192 u32 table_id = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017193 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017194 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17195 {
17196 if (unformat (input, "table_id %d", &table_id))
17197 ;
17198 else
17199 break;
17200 }
17201 if (table_id == ~0)
17202 {
17203 errmsg ("missing table id");
17204 return -99;
17205 }
17206
17207 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017208 M (CLASSIFY_TABLE_INFO, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017209 mp->context = 0;
17210 mp->table_id = ntohl (table_id);
17211
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017212 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060017213 W (ret);
17214 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017215}
17216
17217int
17218api_classify_session_dump (vat_main_t * vam)
17219{
17220 unformat_input_t *input = vam->input;
17221 vl_api_classify_session_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060017222 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017223
17224 u32 table_id = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017225 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017226 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17227 {
17228 if (unformat (input, "table_id %d", &table_id))
17229 ;
17230 else
17231 break;
17232 }
17233 if (table_id == ~0)
17234 {
17235 errmsg ("missing table id");
17236 return -99;
17237 }
17238
17239 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017240 M (CLASSIFY_SESSION_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017241 mp->context = 0;
17242 mp->table_id = ntohl (table_id);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017243 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017244
17245 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060017246 M (CONTROL_PING, mp_ping);
17247 S (mp_ping);
17248
Jon Loeliger56c7b012017-02-01 12:31:41 -060017249 W (ret);
17250 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017251}
17252
17253static void
17254vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
17255{
17256 vat_main_t *vam = &vat_main;
17257
17258 print (vam->ofp, "collector_address %U, collector_port %d, "
17259 "src_address %U, vrf_id %d, path_mtu %u, "
17260 "template_interval %u, udp_checksum %d",
17261 format_ip4_address, mp->collector_address,
17262 ntohs (mp->collector_port),
17263 format_ip4_address, mp->src_address,
17264 ntohl (mp->vrf_id), ntohl (mp->path_mtu),
17265 ntohl (mp->template_interval), mp->udp_checksum);
17266
17267 vam->retval = 0;
17268 vam->result_ready = 1;
17269}
17270
17271static void
17272 vl_api_ipfix_exporter_details_t_handler_json
17273 (vl_api_ipfix_exporter_details_t * mp)
17274{
17275 vat_main_t *vam = &vat_main;
17276 vat_json_node_t node;
17277 struct in_addr collector_address;
17278 struct in_addr src_address;
17279
17280 vat_json_init_object (&node);
17281 clib_memcpy (&collector_address, &mp->collector_address,
17282 sizeof (collector_address));
17283 vat_json_object_add_ip4 (&node, "collector_address", collector_address);
17284 vat_json_object_add_uint (&node, "collector_port",
17285 ntohs (mp->collector_port));
17286 clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
17287 vat_json_object_add_ip4 (&node, "src_address", src_address);
17288 vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
17289 vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
17290 vat_json_object_add_uint (&node, "template_interval",
17291 ntohl (mp->template_interval));
17292 vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
17293
17294 vat_json_print (vam->ofp, &node);
17295 vat_json_free (&node);
17296 vam->retval = 0;
17297 vam->result_ready = 1;
17298}
17299
17300int
17301api_ipfix_exporter_dump (vat_main_t * vam)
17302{
17303 vl_api_ipfix_exporter_dump_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017304 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017305
17306 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017307 M (IPFIX_EXPORTER_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017308 mp->context = 0;
17309
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017310 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060017311 W (ret);
17312 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017313}
17314
17315static int
17316api_ipfix_classify_stream_dump (vat_main_t * vam)
17317{
17318 vl_api_ipfix_classify_stream_dump_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017319 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017320
17321 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017322 M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017323 mp->context = 0;
17324
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017325 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060017326 W (ret);
17327 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017328 /* NOTREACHED */
17329 return 0;
17330}
17331
17332static void
17333 vl_api_ipfix_classify_stream_details_t_handler
17334 (vl_api_ipfix_classify_stream_details_t * mp)
17335{
17336 vat_main_t *vam = &vat_main;
17337 print (vam->ofp, "domain_id %d, src_port %d",
17338 ntohl (mp->domain_id), ntohs (mp->src_port));
17339 vam->retval = 0;
17340 vam->result_ready = 1;
17341}
17342
17343static void
17344 vl_api_ipfix_classify_stream_details_t_handler_json
17345 (vl_api_ipfix_classify_stream_details_t * mp)
17346{
17347 vat_main_t *vam = &vat_main;
17348 vat_json_node_t node;
17349
17350 vat_json_init_object (&node);
17351 vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
17352 vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
17353
17354 vat_json_print (vam->ofp, &node);
17355 vat_json_free (&node);
17356 vam->retval = 0;
17357 vam->result_ready = 1;
17358}
17359
17360static int
17361api_ipfix_classify_table_dump (vat_main_t * vam)
17362{
17363 vl_api_ipfix_classify_table_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060017364 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017365 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017366
17367 if (!vam->json_output)
17368 {
17369 print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
17370 "transport_protocol");
17371 }
17372
17373 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017374 M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017375
17376 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017377 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017378
17379 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060017380 M (CONTROL_PING, mp_ping);
17381 S (mp_ping);
17382
Jon Loeliger56c7b012017-02-01 12:31:41 -060017383 W (ret);
17384 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017385}
17386
17387static void
17388 vl_api_ipfix_classify_table_details_t_handler
17389 (vl_api_ipfix_classify_table_details_t * mp)
17390{
17391 vat_main_t *vam = &vat_main;
17392 print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
17393 mp->transport_protocol);
17394}
17395
17396static void
17397 vl_api_ipfix_classify_table_details_t_handler_json
17398 (vl_api_ipfix_classify_table_details_t * mp)
17399{
17400 vat_json_node_t *node = NULL;
17401 vat_main_t *vam = &vat_main;
17402
17403 if (VAT_JSON_ARRAY != vam->json_tree.type)
17404 {
17405 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17406 vat_json_init_array (&vam->json_tree);
17407 }
17408
17409 node = vat_json_array_add (&vam->json_tree);
17410 vat_json_init_object (node);
17411
17412 vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
17413 vat_json_object_add_uint (node, "ip_version", mp->ip_version);
17414 vat_json_object_add_uint (node, "transport_protocol",
17415 mp->transport_protocol);
17416}
17417
17418static int
17419api_sw_interface_span_enable_disable (vat_main_t * vam)
17420{
17421 unformat_input_t *i = vam->input;
17422 vl_api_sw_interface_span_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017423 u32 src_sw_if_index = ~0;
17424 u32 dst_sw_if_index = ~0;
17425 u8 state = 3;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017426 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017427
17428 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17429 {
17430 if (unformat
17431 (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
17432 ;
17433 else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
17434 ;
17435 else
17436 if (unformat
17437 (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
17438 ;
17439 else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
17440 ;
17441 else if (unformat (i, "disable"))
17442 state = 0;
17443 else if (unformat (i, "rx"))
17444 state = 1;
17445 else if (unformat (i, "tx"))
17446 state = 2;
17447 else if (unformat (i, "both"))
17448 state = 3;
17449 else
17450 break;
17451 }
17452
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017453 M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017454
17455 mp->sw_if_index_from = htonl (src_sw_if_index);
17456 mp->sw_if_index_to = htonl (dst_sw_if_index);
17457 mp->state = state;
17458
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017459 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060017460 W (ret);
17461 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017462}
17463
17464static void
17465vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
17466 * mp)
17467{
17468 vat_main_t *vam = &vat_main;
17469 u8 *sw_if_from_name = 0;
17470 u8 *sw_if_to_name = 0;
17471 u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
17472 u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
17473 char *states[] = { "none", "rx", "tx", "both" };
17474 hash_pair_t *p;
17475
17476 /* *INDENT-OFF* */
17477 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
17478 ({
17479 if ((u32) p->value[0] == sw_if_index_from)
17480 {
17481 sw_if_from_name = (u8 *)(p->key);
17482 if (sw_if_to_name)
17483 break;
17484 }
17485 if ((u32) p->value[0] == sw_if_index_to)
17486 {
17487 sw_if_to_name = (u8 *)(p->key);
17488 if (sw_if_from_name)
17489 break;
17490 }
17491 }));
17492 /* *INDENT-ON* */
17493 print (vam->ofp, "%20s => %20s (%s)",
17494 sw_if_from_name, sw_if_to_name, states[mp->state]);
17495}
17496
17497static void
17498 vl_api_sw_interface_span_details_t_handler_json
17499 (vl_api_sw_interface_span_details_t * mp)
17500{
17501 vat_main_t *vam = &vat_main;
17502 vat_json_node_t *node = NULL;
17503 u8 *sw_if_from_name = 0;
17504 u8 *sw_if_to_name = 0;
17505 u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
17506 u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
17507 hash_pair_t *p;
17508
17509 /* *INDENT-OFF* */
17510 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
17511 ({
17512 if ((u32) p->value[0] == sw_if_index_from)
17513 {
17514 sw_if_from_name = (u8 *)(p->key);
17515 if (sw_if_to_name)
17516 break;
17517 }
17518 if ((u32) p->value[0] == sw_if_index_to)
17519 {
17520 sw_if_to_name = (u8 *)(p->key);
17521 if (sw_if_from_name)
17522 break;
17523 }
17524 }));
17525 /* *INDENT-ON* */
17526
17527 if (VAT_JSON_ARRAY != vam->json_tree.type)
17528 {
17529 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17530 vat_json_init_array (&vam->json_tree);
17531 }
17532 node = vat_json_array_add (&vam->json_tree);
17533
17534 vat_json_init_object (node);
17535 vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
17536 vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
17537 vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
Neale Ranns05b2bf22017-01-30 06:44:58 -080017538 if (0 != sw_if_to_name)
17539 {
17540 vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
17541 }
Damjan Marion7cd468a2016-12-19 23:05:39 +010017542 vat_json_object_add_uint (node, "state", mp->state);
17543}
17544
17545static int
17546api_sw_interface_span_dump (vat_main_t * vam)
17547{
17548 vl_api_sw_interface_span_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060017549 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017550 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017551
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017552 M (SW_INTERFACE_SPAN_DUMP, mp);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017553 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017554
17555 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060017556 M (CONTROL_PING, mp_ping);
17557 S (mp_ping);
17558
Jon Loeliger56c7b012017-02-01 12:31:41 -060017559 W (ret);
17560 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017561}
17562
17563int
17564api_pg_create_interface (vat_main_t * vam)
17565{
17566 unformat_input_t *input = vam->input;
17567 vl_api_pg_create_interface_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017568
17569 u32 if_id = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017570 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017571 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17572 {
17573 if (unformat (input, "if_id %d", &if_id))
17574 ;
17575 else
17576 break;
17577 }
17578 if (if_id == ~0)
17579 {
17580 errmsg ("missing pg interface index");
17581 return -99;
17582 }
17583
17584 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017585 M (PG_CREATE_INTERFACE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017586 mp->context = 0;
17587 mp->interface_id = ntohl (if_id);
17588
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017589 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060017590 W (ret);
17591 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017592}
17593
17594int
17595api_pg_capture (vat_main_t * vam)
17596{
17597 unformat_input_t *input = vam->input;
17598 vl_api_pg_capture_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017599
17600 u32 if_id = ~0;
17601 u8 enable = 1;
17602 u32 count = 1;
17603 u8 pcap_file_set = 0;
17604 u8 *pcap_file = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017605 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017606 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17607 {
17608 if (unformat (input, "if_id %d", &if_id))
17609 ;
17610 else if (unformat (input, "pcap %s", &pcap_file))
17611 pcap_file_set = 1;
17612 else if (unformat (input, "count %d", &count))
17613 ;
17614 else if (unformat (input, "disable"))
17615 enable = 0;
17616 else
17617 break;
17618 }
17619 if (if_id == ~0)
17620 {
17621 errmsg ("missing pg interface index");
17622 return -99;
17623 }
17624 if (pcap_file_set > 0)
17625 {
17626 if (vec_len (pcap_file) > 255)
17627 {
17628 errmsg ("pcap file name is too long");
17629 return -99;
17630 }
17631 }
17632
17633 u32 name_len = vec_len (pcap_file);
17634 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017635 M (PG_CAPTURE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017636 mp->context = 0;
17637 mp->interface_id = ntohl (if_id);
17638 mp->is_enabled = enable;
17639 mp->count = ntohl (count);
17640 mp->pcap_name_length = ntohl (name_len);
17641 if (pcap_file_set != 0)
17642 {
17643 clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
17644 }
17645 vec_free (pcap_file);
17646
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017647 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060017648 W (ret);
17649 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017650}
17651
17652int
17653api_pg_enable_disable (vat_main_t * vam)
17654{
17655 unformat_input_t *input = vam->input;
17656 vl_api_pg_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017657
17658 u8 enable = 1;
17659 u8 stream_name_set = 0;
17660 u8 *stream_name = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017661 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017662 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17663 {
17664 if (unformat (input, "stream %s", &stream_name))
17665 stream_name_set = 1;
17666 else if (unformat (input, "disable"))
17667 enable = 0;
17668 else
17669 break;
17670 }
17671
17672 if (stream_name_set > 0)
17673 {
17674 if (vec_len (stream_name) > 255)
17675 {
17676 errmsg ("stream name too long");
17677 return -99;
17678 }
17679 }
17680
17681 u32 name_len = vec_len (stream_name);
17682 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017683 M (PG_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017684 mp->context = 0;
17685 mp->is_enabled = enable;
17686 if (stream_name_set != 0)
17687 {
17688 mp->stream_name_length = ntohl (name_len);
17689 clib_memcpy (mp->stream_name, stream_name, name_len);
17690 }
17691 vec_free (stream_name);
17692
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017693 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060017694 W (ret);
17695 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017696}
17697
17698int
17699api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
17700{
17701 unformat_input_t *input = vam->input;
17702 vl_api_ip_source_and_port_range_check_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017703
17704 u16 *low_ports = 0;
17705 u16 *high_ports = 0;
17706 u16 this_low;
17707 u16 this_hi;
17708 ip4_address_t ip4_addr;
17709 ip6_address_t ip6_addr;
17710 u32 length;
17711 u32 tmp, tmp2;
17712 u8 prefix_set = 0;
17713 u32 vrf_id = ~0;
17714 u8 is_add = 1;
17715 u8 is_ipv6 = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017716 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017717
17718 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17719 {
17720 if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
17721 {
17722 prefix_set = 1;
17723 }
17724 else
17725 if (unformat
17726 (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
17727 {
17728 prefix_set = 1;
17729 is_ipv6 = 1;
17730 }
17731 else if (unformat (input, "vrf %d", &vrf_id))
17732 ;
17733 else if (unformat (input, "del"))
17734 is_add = 0;
17735 else if (unformat (input, "port %d", &tmp))
17736 {
17737 if (tmp == 0 || tmp > 65535)
17738 {
17739 errmsg ("port %d out of range", tmp);
17740 return -99;
17741 }
17742 this_low = tmp;
17743 this_hi = this_low + 1;
17744 vec_add1 (low_ports, this_low);
17745 vec_add1 (high_ports, this_hi);
17746 }
17747 else if (unformat (input, "range %d - %d", &tmp, &tmp2))
17748 {
17749 if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
17750 {
17751 errmsg ("incorrect range parameters");
17752 return -99;
17753 }
17754 this_low = tmp;
17755 /* Note: in debug CLI +1 is added to high before
17756 passing to real fn that does "the work"
17757 (ip_source_and_port_range_check_add_del).
17758 This fn is a wrapper around the binary API fn a
17759 control plane will call, which expects this increment
17760 to have occurred. Hence letting the binary API control
17761 plane fn do the increment for consistency between VAT
17762 and other control planes.
17763 */
17764 this_hi = tmp2;
17765 vec_add1 (low_ports, this_low);
17766 vec_add1 (high_ports, this_hi);
17767 }
17768 else
17769 break;
17770 }
17771
17772 if (prefix_set == 0)
17773 {
17774 errmsg ("<address>/<mask> not specified");
17775 return -99;
17776 }
17777
17778 if (vrf_id == ~0)
17779 {
17780 errmsg ("VRF ID required, not specified");
17781 return -99;
17782 }
17783
17784 if (vrf_id == 0)
17785 {
17786 errmsg
17787 ("VRF ID should not be default. Should be distinct VRF for this purpose.");
17788 return -99;
17789 }
17790
17791 if (vec_len (low_ports) == 0)
17792 {
17793 errmsg ("At least one port or port range required");
17794 return -99;
17795 }
17796
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017797 M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017798
17799 mp->is_add = is_add;
17800
17801 if (is_ipv6)
17802 {
17803 mp->is_ipv6 = 1;
17804 clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
17805 }
17806 else
17807 {
17808 mp->is_ipv6 = 0;
17809 clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
17810 }
17811
17812 mp->mask_length = length;
17813 mp->number_of_ranges = vec_len (low_ports);
17814
17815 clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
17816 vec_free (low_ports);
17817
17818 clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
17819 vec_free (high_ports);
17820
17821 mp->vrf_id = ntohl (vrf_id);
17822
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017823 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060017824 W (ret);
17825 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017826}
17827
17828int
17829api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
17830{
17831 unformat_input_t *input = vam->input;
17832 vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017833 u32 sw_if_index = ~0;
17834 int vrf_set = 0;
17835 u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
17836 u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
17837 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017838 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017839
17840 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17841 {
17842 if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17843 ;
17844 else if (unformat (input, "sw_if_index %d", &sw_if_index))
17845 ;
17846 else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
17847 vrf_set = 1;
17848 else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
17849 vrf_set = 1;
17850 else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
17851 vrf_set = 1;
17852 else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
17853 vrf_set = 1;
17854 else if (unformat (input, "del"))
17855 is_add = 0;
17856 else
17857 break;
17858 }
17859
17860 if (sw_if_index == ~0)
17861 {
17862 errmsg ("Interface required but not specified");
17863 return -99;
17864 }
17865
17866 if (vrf_set == 0)
17867 {
17868 errmsg ("VRF ID required but not specified");
17869 return -99;
17870 }
17871
17872 if (tcp_out_vrf_id == 0
17873 || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
17874 {
17875 errmsg
17876 ("VRF ID should not be default. Should be distinct VRF for this purpose.");
17877 return -99;
17878 }
17879
17880 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017881 M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017882
17883 mp->sw_if_index = ntohl (sw_if_index);
17884 mp->is_add = is_add;
17885 mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
17886 mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
17887 mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
17888 mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
17889
17890 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017891 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017892
17893 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060017894 W (ret);
17895 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017896}
17897
17898static int
17899api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
17900{
17901 unformat_input_t *i = vam->input;
17902 vl_api_ipsec_gre_add_del_tunnel_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017903 u32 local_sa_id = 0;
17904 u32 remote_sa_id = 0;
17905 ip4_address_t src_address;
17906 ip4_address_t dst_address;
17907 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017908 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017909
17910 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17911 {
17912 if (unformat (i, "local_sa %d", &local_sa_id))
17913 ;
17914 else if (unformat (i, "remote_sa %d", &remote_sa_id))
17915 ;
17916 else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
17917 ;
17918 else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
17919 ;
17920 else if (unformat (i, "del"))
17921 is_add = 0;
17922 else
17923 {
17924 clib_warning ("parse error '%U'", format_unformat_error, i);
17925 return -99;
17926 }
17927 }
17928
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017929 M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017930
17931 mp->local_sa_id = ntohl (local_sa_id);
17932 mp->remote_sa_id = ntohl (remote_sa_id);
17933 clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
17934 clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
17935 mp->is_add = is_add;
17936
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017937 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060017938 W (ret);
17939 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017940}
17941
17942static int
17943api_punt (vat_main_t * vam)
17944{
17945 unformat_input_t *i = vam->input;
17946 vl_api_punt_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017947 u32 ipv = ~0;
17948 u32 protocol = ~0;
17949 u32 port = ~0;
17950 int is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017951 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017952
17953 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17954 {
17955 if (unformat (i, "ip %d", &ipv))
17956 ;
17957 else if (unformat (i, "protocol %d", &protocol))
17958 ;
17959 else if (unformat (i, "port %d", &port))
17960 ;
17961 else if (unformat (i, "del"))
17962 is_add = 0;
17963 else
17964 {
17965 clib_warning ("parse error '%U'", format_unformat_error, i);
17966 return -99;
17967 }
17968 }
17969
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017970 M (PUNT, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017971
17972 mp->is_add = (u8) is_add;
17973 mp->ipv = (u8) ipv;
17974 mp->l4_protocol = (u8) protocol;
17975 mp->l4_port = htons ((u16) port);
17976
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017977 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060017978 W (ret);
17979 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017980}
17981
17982static void vl_api_ipsec_gre_tunnel_details_t_handler
17983 (vl_api_ipsec_gre_tunnel_details_t * mp)
17984{
17985 vat_main_t *vam = &vat_main;
17986
17987 print (vam->ofp, "%11d%15U%15U%14d%14d",
17988 ntohl (mp->sw_if_index),
17989 format_ip4_address, &mp->src_address,
17990 format_ip4_address, &mp->dst_address,
17991 ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
17992}
17993
17994static void vl_api_ipsec_gre_tunnel_details_t_handler_json
17995 (vl_api_ipsec_gre_tunnel_details_t * mp)
17996{
17997 vat_main_t *vam = &vat_main;
17998 vat_json_node_t *node = NULL;
17999 struct in_addr ip4;
18000
18001 if (VAT_JSON_ARRAY != vam->json_tree.type)
18002 {
18003 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18004 vat_json_init_array (&vam->json_tree);
18005 }
18006 node = vat_json_array_add (&vam->json_tree);
18007
18008 vat_json_init_object (node);
18009 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
18010 clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
18011 vat_json_object_add_ip4 (node, "src_address", ip4);
18012 clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
18013 vat_json_object_add_ip4 (node, "dst_address", ip4);
18014 vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
18015 vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
18016}
18017
18018static int
18019api_ipsec_gre_tunnel_dump (vat_main_t * vam)
18020{
18021 unformat_input_t *i = vam->input;
18022 vl_api_ipsec_gre_tunnel_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060018023 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010018024 u32 sw_if_index;
18025 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060018026 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010018027
18028 /* Parse args required to build the message */
18029 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18030 {
18031 if (unformat (i, "sw_if_index %d", &sw_if_index))
18032 sw_if_index_set = 1;
18033 else
18034 break;
18035 }
18036
18037 if (sw_if_index_set == 0)
18038 {
18039 sw_if_index = ~0;
18040 }
18041
18042 if (!vam->json_output)
18043 {
18044 print (vam->ofp, "%11s%15s%15s%14s%14s",
18045 "sw_if_index", "src_address", "dst_address",
18046 "local_sa_id", "remote_sa_id");
18047 }
18048
18049 /* Get list of gre-tunnel interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060018050 M (IPSEC_GRE_TUNNEL_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010018051
18052 mp->sw_if_index = htonl (sw_if_index);
18053
Jon Loeliger7bc770c2017-01-31 14:03:33 -060018054 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010018055
18056 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060018057 M (CONTROL_PING, mp_ping);
18058 S (mp_ping);
18059
Jon Loeliger56c7b012017-02-01 12:31:41 -060018060 W (ret);
18061 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010018062}
18063
18064static int
18065api_delete_subif (vat_main_t * vam)
18066{
18067 unformat_input_t *i = vam->input;
18068 vl_api_delete_subif_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010018069 u32 sw_if_index = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060018070 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010018071
18072 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18073 {
18074 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18075 ;
18076 if (unformat (i, "sw_if_index %d", &sw_if_index))
18077 ;
18078 else
18079 break;
18080 }
18081
18082 if (sw_if_index == ~0)
18083 {
18084 errmsg ("missing sw_if_index");
18085 return -99;
18086 }
18087
18088 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060018089 M (DELETE_SUBIF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010018090 mp->sw_if_index = ntohl (sw_if_index);
18091
Jon Loeliger7bc770c2017-01-31 14:03:33 -060018092 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060018093 W (ret);
18094 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010018095}
18096
18097#define foreach_pbb_vtr_op \
18098_("disable", L2_VTR_DISABLED) \
18099_("pop", L2_VTR_POP_2) \
18100_("push", L2_VTR_PUSH_2)
18101
18102static int
18103api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
18104{
18105 unformat_input_t *i = vam->input;
18106 vl_api_l2_interface_pbb_tag_rewrite_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010018107 u32 sw_if_index = ~0, vtr_op = ~0;
18108 u16 outer_tag = ~0;
18109 u8 dmac[6], smac[6];
18110 u8 dmac_set = 0, smac_set = 0;
18111 u16 vlanid = 0;
18112 u32 sid = ~0;
18113 u32 tmp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060018114 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010018115
18116 /* Shut up coverity */
18117 memset (dmac, 0, sizeof (dmac));
18118 memset (smac, 0, sizeof (smac));
18119
18120 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18121 {
18122 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18123 ;
18124 else if (unformat (i, "sw_if_index %d", &sw_if_index))
18125 ;
18126 else if (unformat (i, "vtr_op %d", &vtr_op))
18127 ;
18128#define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
18129 foreach_pbb_vtr_op
18130#undef _
18131 else if (unformat (i, "translate_pbb_stag"))
18132 {
18133 if (unformat (i, "%d", &tmp))
18134 {
18135 vtr_op = L2_VTR_TRANSLATE_2_1;
18136 outer_tag = tmp;
18137 }
18138 else
18139 {
18140 errmsg
18141 ("translate_pbb_stag operation requires outer tag definition");
18142 return -99;
18143 }
18144 }
18145 else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
18146 dmac_set++;
18147 else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
18148 smac_set++;
18149 else if (unformat (i, "sid %d", &sid))
18150 ;
18151 else if (unformat (i, "vlanid %d", &tmp))
18152 vlanid = tmp;
18153 else
18154 {
18155 clib_warning ("parse error '%U'", format_unformat_error, i);
18156 return -99;
18157 }
18158 }
18159
18160 if ((sw_if_index == ~0) || (vtr_op == ~0))
18161 {
18162 errmsg ("missing sw_if_index or vtr operation");
18163 return -99;
18164 }
18165 if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
18166 && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
18167 {
18168 errmsg
18169 ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
18170 return -99;
18171 }
18172
Jon Loeliger8a2aea32017-01-31 13:19:40 -060018173 M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010018174 mp->sw_if_index = ntohl (sw_if_index);
18175 mp->vtr_op = ntohl (vtr_op);
18176 mp->outer_tag = ntohs (outer_tag);
18177 clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
18178 clib_memcpy (mp->b_smac, smac, sizeof (smac));
18179 mp->b_vlanid = ntohs (vlanid);
18180 mp->i_sid = ntohl (sid);
18181
Jon Loeliger7bc770c2017-01-31 14:03:33 -060018182 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060018183 W (ret);
18184 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010018185}
18186
18187static int
18188api_flow_classify_set_interface (vat_main_t * vam)
18189{
18190 unformat_input_t *i = vam->input;
18191 vl_api_flow_classify_set_interface_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010018192 u32 sw_if_index;
18193 int sw_if_index_set;
18194 u32 ip4_table_index = ~0;
18195 u32 ip6_table_index = ~0;
18196 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060018197 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010018198
18199 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18200 {
18201 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18202 sw_if_index_set = 1;
18203 else if (unformat (i, "sw_if_index %d", &sw_if_index))
18204 sw_if_index_set = 1;
18205 else if (unformat (i, "del"))
18206 is_add = 0;
18207 else if (unformat (i, "ip4-table %d", &ip4_table_index))
18208 ;
18209 else if (unformat (i, "ip6-table %d", &ip6_table_index))
18210 ;
18211 else
18212 {
18213 clib_warning ("parse error '%U'", format_unformat_error, i);
18214 return -99;
18215 }
18216 }
18217
18218 if (sw_if_index_set == 0)
18219 {
18220 errmsg ("missing interface name or sw_if_index");
18221 return -99;
18222 }
18223
Jon Loeliger8a2aea32017-01-31 13:19:40 -060018224 M (FLOW_CLASSIFY_SET_INTERFACE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010018225
18226 mp->sw_if_index = ntohl (sw_if_index);
18227 mp->ip4_table_index = ntohl (ip4_table_index);
18228 mp->ip6_table_index = ntohl (ip6_table_index);
18229 mp->is_add = is_add;
18230
Jon Loeliger7bc770c2017-01-31 14:03:33 -060018231 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060018232 W (ret);
18233 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010018234}
18235
18236static int
18237api_flow_classify_dump (vat_main_t * vam)
18238{
18239 unformat_input_t *i = vam->input;
18240 vl_api_flow_classify_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060018241 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010018242 u8 type = FLOW_CLASSIFY_N_TABLES;
Jon Loeliger56c7b012017-02-01 12:31:41 -060018243 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010018244
18245 if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
18246 ;
18247 else
18248 {
18249 errmsg ("classify table type must be specified");
18250 return -99;
18251 }
18252
18253 if (!vam->json_output)
18254 {
18255 print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18256 }
18257
Jon Loeliger8a2aea32017-01-31 13:19:40 -060018258 M (FLOW_CLASSIFY_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010018259 mp->type = type;
18260 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060018261 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010018262
18263 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060018264 M (CONTROL_PING, mp_ping);
18265 S (mp_ping);
18266
Damjan Marion7cd468a2016-12-19 23:05:39 +010018267 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060018268 W (ret);
18269 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010018270}
18271
18272static int
18273api_feature_enable_disable (vat_main_t * vam)
18274{
18275 unformat_input_t *i = vam->input;
18276 vl_api_feature_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010018277 u8 *arc_name = 0;
18278 u8 *feature_name = 0;
18279 u32 sw_if_index = ~0;
18280 u8 enable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060018281 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010018282
18283 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18284 {
18285 if (unformat (i, "arc_name %s", &arc_name))
18286 ;
18287 else if (unformat (i, "feature_name %s", &feature_name))
18288 ;
18289 else
18290 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18291 ;
18292 else if (unformat (i, "sw_if_index %d", &sw_if_index))
18293 ;
18294 else if (unformat (i, "disable"))
18295 enable = 0;
18296 else
18297 break;
18298 }
18299
18300 if (arc_name == 0)
18301 {
18302 errmsg ("missing arc name");
18303 return -99;
18304 }
18305 if (vec_len (arc_name) > 63)
18306 {
18307 errmsg ("arc name too long");
18308 }
18309
18310 if (feature_name == 0)
18311 {
18312 errmsg ("missing feature name");
18313 return -99;
18314 }
18315 if (vec_len (feature_name) > 63)
18316 {
18317 errmsg ("feature name too long");
18318 }
18319
18320 if (sw_if_index == ~0)
18321 {
18322 errmsg ("missing interface name or sw_if_index");
18323 return -99;
18324 }
18325
18326 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060018327 M (FEATURE_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010018328 mp->sw_if_index = ntohl (sw_if_index);
18329 mp->enable = enable;
18330 clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
18331 clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
18332 vec_free (arc_name);
18333 vec_free (feature_name);
18334
Jon Loeliger7bc770c2017-01-31 14:03:33 -060018335 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060018336 W (ret);
18337 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010018338}
18339
18340static int
18341api_sw_interface_tag_add_del (vat_main_t * vam)
18342{
18343 unformat_input_t *i = vam->input;
18344 vl_api_sw_interface_tag_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010018345 u32 sw_if_index = ~0;
18346 u8 *tag = 0;
18347 u8 enable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060018348 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010018349
18350 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18351 {
18352 if (unformat (i, "tag %s", &tag))
18353 ;
18354 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18355 ;
18356 else if (unformat (i, "sw_if_index %d", &sw_if_index))
18357 ;
18358 else if (unformat (i, "del"))
18359 enable = 0;
18360 else
18361 break;
18362 }
18363
18364 if (sw_if_index == ~0)
18365 {
18366 errmsg ("missing interface name or sw_if_index");
18367 return -99;
18368 }
18369
18370 if (enable && (tag == 0))
18371 {
18372 errmsg ("no tag specified");
18373 return -99;
18374 }
18375
18376 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060018377 M (SW_INTERFACE_TAG_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010018378 mp->sw_if_index = ntohl (sw_if_index);
18379 mp->is_add = enable;
18380 if (enable)
18381 strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
18382 vec_free (tag);
18383
Jon Loeliger7bc770c2017-01-31 14:03:33 -060018384 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060018385 W (ret);
18386 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010018387}
18388
18389static void vl_api_l2_xconnect_details_t_handler
18390 (vl_api_l2_xconnect_details_t * mp)
18391{
18392 vat_main_t *vam = &vat_main;
18393
18394 print (vam->ofp, "%15d%15d",
18395 ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
18396}
18397
18398static void vl_api_l2_xconnect_details_t_handler_json
18399 (vl_api_l2_xconnect_details_t * mp)
18400{
18401 vat_main_t *vam = &vat_main;
18402 vat_json_node_t *node = NULL;
18403
18404 if (VAT_JSON_ARRAY != vam->json_tree.type)
18405 {
18406 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18407 vat_json_init_array (&vam->json_tree);
18408 }
18409 node = vat_json_array_add (&vam->json_tree);
18410
18411 vat_json_init_object (node);
18412 vat_json_object_add_uint (node, "rx_sw_if_index",
18413 ntohl (mp->rx_sw_if_index));
18414 vat_json_object_add_uint (node, "tx_sw_if_index",
18415 ntohl (mp->tx_sw_if_index));
18416}
18417
18418static int
18419api_l2_xconnect_dump (vat_main_t * vam)
18420{
18421 vl_api_l2_xconnect_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060018422 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060018423 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010018424
18425 if (!vam->json_output)
18426 {
18427 print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
18428 }
18429
Jon Loeliger8a2aea32017-01-31 13:19:40 -060018430 M (L2_XCONNECT_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010018431
Jon Loeliger7bc770c2017-01-31 14:03:33 -060018432 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010018433
18434 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060018435 M (CONTROL_PING, mp_ping);
18436 S (mp_ping);
18437
Jon Loeliger56c7b012017-02-01 12:31:41 -060018438 W (ret);
18439 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010018440}
18441
18442static int
18443api_sw_interface_set_mtu (vat_main_t * vam)
18444{
18445 unformat_input_t *i = vam->input;
18446 vl_api_sw_interface_set_mtu_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010018447 u32 sw_if_index = ~0;
18448 u32 mtu = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060018449 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010018450
18451 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18452 {
18453 if (unformat (i, "mtu %d", &mtu))
18454 ;
18455 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18456 ;
18457 else if (unformat (i, "sw_if_index %d", &sw_if_index))
18458 ;
18459 else
18460 break;
18461 }
18462
18463 if (sw_if_index == ~0)
18464 {
18465 errmsg ("missing interface name or sw_if_index");
18466 return -99;
18467 }
18468
18469 if (mtu == 0)
18470 {
18471 errmsg ("no mtu specified");
18472 return -99;
18473 }
18474
18475 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060018476 M (SW_INTERFACE_SET_MTU, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010018477 mp->sw_if_index = ntohl (sw_if_index);
18478 mp->mtu = ntohs ((u16) mtu);
18479
Jon Loeliger7bc770c2017-01-31 14:03:33 -060018480 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060018481 W (ret);
18482 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010018483}
18484
18485
18486static int
18487q_or_quit (vat_main_t * vam)
18488{
Dave Barachdef19da2017-02-22 17:29:20 -050018489#if VPP_API_TEST_BUILTIN == 0
Damjan Marion7cd468a2016-12-19 23:05:39 +010018490 longjmp (vam->jump_buf, 1);
Dave Barachdef19da2017-02-22 17:29:20 -050018491#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +010018492 return 0; /* not so much */
18493}
18494
18495static int
18496q (vat_main_t * vam)
18497{
18498 return q_or_quit (vam);
18499}
18500
18501static int
18502quit (vat_main_t * vam)
18503{
18504 return q_or_quit (vam);
18505}
18506
18507static int
18508comment (vat_main_t * vam)
18509{
18510 return 0;
18511}
18512
18513static int
18514cmd_cmp (void *a1, void *a2)
18515{
18516 u8 **c1 = a1;
18517 u8 **c2 = a2;
18518
18519 return strcmp ((char *) (c1[0]), (char *) (c2[0]));
18520}
18521
18522static int
18523help (vat_main_t * vam)
18524{
18525 u8 **cmds = 0;
18526 u8 *name = 0;
18527 hash_pair_t *p;
18528 unformat_input_t *i = vam->input;
18529 int j;
18530
18531 if (unformat (i, "%s", &name))
18532 {
18533 uword *hs;
18534
18535 vec_add1 (name, 0);
18536
18537 hs = hash_get_mem (vam->help_by_name, name);
18538 if (hs)
18539 print (vam->ofp, "usage: %s %s", name, hs[0]);
18540 else
18541 print (vam->ofp, "No such msg / command '%s'", name);
18542 vec_free (name);
18543 return 0;
18544 }
18545
18546 print (vam->ofp, "Help is available for the following:");
18547
18548 /* *INDENT-OFF* */
18549 hash_foreach_pair (p, vam->function_by_name,
18550 ({
18551 vec_add1 (cmds, (u8 *)(p->key));
18552 }));
18553 /* *INDENT-ON* */
18554
18555 vec_sort_with_function (cmds, cmd_cmp);
18556
18557 for (j = 0; j < vec_len (cmds); j++)
18558 print (vam->ofp, "%s", cmds[j]);
18559
18560 vec_free (cmds);
18561 return 0;
18562}
18563
18564static int
18565set (vat_main_t * vam)
18566{
18567 u8 *name = 0, *value = 0;
18568 unformat_input_t *i = vam->input;
18569
18570 if (unformat (i, "%s", &name))
18571 {
18572 /* The input buffer is a vector, not a string. */
18573 value = vec_dup (i->buffer);
18574 vec_delete (value, i->index, 0);
18575 /* Almost certainly has a trailing newline */
18576 if (value[vec_len (value) - 1] == '\n')
18577 value[vec_len (value) - 1] = 0;
18578 /* Make sure it's a proper string, one way or the other */
18579 vec_add1 (value, 0);
18580 (void) clib_macro_set_value (&vam->macro_main,
18581 (char *) name, (char *) value);
18582 }
18583 else
18584 errmsg ("usage: set <name> <value>");
18585
18586 vec_free (name);
18587 vec_free (value);
18588 return 0;
18589}
18590
18591static int
18592unset (vat_main_t * vam)
18593{
18594 u8 *name = 0;
18595
18596 if (unformat (vam->input, "%s", &name))
18597 if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
18598 errmsg ("unset: %s wasn't set", name);
18599 vec_free (name);
18600 return 0;
18601}
18602
18603typedef struct
18604{
18605 u8 *name;
18606 u8 *value;
18607} macro_sort_t;
18608
18609
18610static int
18611macro_sort_cmp (void *a1, void *a2)
18612{
18613 macro_sort_t *s1 = a1;
18614 macro_sort_t *s2 = a2;
18615
18616 return strcmp ((char *) (s1->name), (char *) (s2->name));
18617}
18618
18619static int
18620dump_macro_table (vat_main_t * vam)
18621{
18622 macro_sort_t *sort_me = 0, *sm;
18623 int i;
18624 hash_pair_t *p;
18625
18626 /* *INDENT-OFF* */
18627 hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
18628 ({
18629 vec_add2 (sort_me, sm, 1);
18630 sm->name = (u8 *)(p->key);
18631 sm->value = (u8 *) (p->value[0]);
18632 }));
18633 /* *INDENT-ON* */
18634
18635 vec_sort_with_function (sort_me, macro_sort_cmp);
18636
18637 if (vec_len (sort_me))
18638 print (vam->ofp, "%-15s%s", "Name", "Value");
18639 else
18640 print (vam->ofp, "The macro table is empty...");
18641
18642 for (i = 0; i < vec_len (sort_me); i++)
18643 print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
18644 return 0;
18645}
18646
18647static int
18648dump_node_table (vat_main_t * vam)
18649{
18650 int i, j;
18651 vlib_node_t *node, *next_node;
18652
18653 if (vec_len (vam->graph_nodes) == 0)
18654 {
18655 print (vam->ofp, "Node table empty, issue get_node_graph...");
18656 return 0;
18657 }
18658
18659 for (i = 0; i < vec_len (vam->graph_nodes); i++)
18660 {
18661 node = vam->graph_nodes[i];
18662 print (vam->ofp, "[%d] %s", i, node->name);
18663 for (j = 0; j < vec_len (node->next_nodes); j++)
18664 {
18665 if (node->next_nodes[j] != ~0)
18666 {
18667 next_node = vam->graph_nodes[node->next_nodes[j]];
18668 print (vam->ofp, " [%d] %s", j, next_node->name);
18669 }
18670 }
18671 }
18672 return 0;
18673}
18674
18675static int
18676value_sort_cmp (void *a1, void *a2)
18677{
18678 name_sort_t *n1 = a1;
18679 name_sort_t *n2 = a2;
18680
18681 if (n1->value < n2->value)
18682 return -1;
18683 if (n1->value > n2->value)
18684 return 1;
18685 return 0;
18686}
18687
18688
18689static int
18690dump_msg_api_table (vat_main_t * vam)
18691{
18692 api_main_t *am = &api_main;
18693 name_sort_t *nses = 0, *ns;
18694 hash_pair_t *hp;
18695 int i;
18696
18697 /* *INDENT-OFF* */
18698 hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
18699 ({
18700 vec_add2 (nses, ns, 1);
18701 ns->name = (u8 *)(hp->key);
18702 ns->value = (u32) hp->value[0];
18703 }));
18704 /* *INDENT-ON* */
18705
18706 vec_sort_with_function (nses, value_sort_cmp);
18707
18708 for (i = 0; i < vec_len (nses); i++)
18709 print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
18710 vec_free (nses);
18711 return 0;
18712}
18713
18714static int
18715get_msg_id (vat_main_t * vam)
18716{
18717 u8 *name_and_crc;
18718 u32 message_index;
18719
18720 if (unformat (vam->input, "%s", &name_and_crc))
18721 {
18722 message_index = vl_api_get_msg_index (name_and_crc);
18723 if (message_index == ~0)
18724 {
18725 print (vam->ofp, " '%s' not found", name_and_crc);
18726 return 0;
18727 }
18728 print (vam->ofp, " '%s' has message index %d",
18729 name_and_crc, message_index);
18730 return 0;
18731 }
18732 errmsg ("name_and_crc required...");
18733 return 0;
18734}
18735
18736static int
18737search_node_table (vat_main_t * vam)
18738{
18739 unformat_input_t *line_input = vam->input;
18740 u8 *node_to_find;
18741 int j;
18742 vlib_node_t *node, *next_node;
18743 uword *p;
18744
18745 if (vam->graph_node_index_by_name == 0)
18746 {
18747 print (vam->ofp, "Node table empty, issue get_node_graph...");
18748 return 0;
18749 }
18750
18751 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
18752 {
18753 if (unformat (line_input, "%s", &node_to_find))
18754 {
18755 vec_add1 (node_to_find, 0);
18756 p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
18757 if (p == 0)
18758 {
18759 print (vam->ofp, "%s not found...", node_to_find);
18760 goto out;
18761 }
18762 node = vam->graph_nodes[p[0]];
18763 print (vam->ofp, "[%d] %s", p[0], node->name);
18764 for (j = 0; j < vec_len (node->next_nodes); j++)
18765 {
18766 if (node->next_nodes[j] != ~0)
18767 {
18768 next_node = vam->graph_nodes[node->next_nodes[j]];
18769 print (vam->ofp, " [%d] %s", j, next_node->name);
18770 }
18771 }
18772 }
18773
18774 else
18775 {
18776 clib_warning ("parse error '%U'", format_unformat_error,
18777 line_input);
18778 return -99;
18779 }
18780
18781 out:
18782 vec_free (node_to_find);
18783
18784 }
18785
18786 return 0;
18787}
18788
18789
18790static int
18791script (vat_main_t * vam)
18792{
18793#if (VPP_API_TEST_BUILTIN==0)
18794 u8 *s = 0;
18795 char *save_current_file;
18796 unformat_input_t save_input;
18797 jmp_buf save_jump_buf;
18798 u32 save_line_number;
18799
18800 FILE *new_fp, *save_ifp;
18801
18802 if (unformat (vam->input, "%s", &s))
18803 {
18804 new_fp = fopen ((char *) s, "r");
18805 if (new_fp == 0)
18806 {
18807 errmsg ("Couldn't open script file %s", s);
18808 vec_free (s);
18809 return -99;
18810 }
18811 }
18812 else
18813 {
18814 errmsg ("Missing script name");
18815 return -99;
18816 }
18817
18818 clib_memcpy (&save_input, &vam->input, sizeof (save_input));
18819 clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
18820 save_ifp = vam->ifp;
18821 save_line_number = vam->input_line_number;
18822 save_current_file = (char *) vam->current_file;
18823
18824 vam->input_line_number = 0;
18825 vam->ifp = new_fp;
18826 vam->current_file = s;
18827 do_one_file (vam);
18828
18829 clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
18830 clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
18831 vam->ifp = save_ifp;
18832 vam->input_line_number = save_line_number;
18833 vam->current_file = (u8 *) save_current_file;
18834 vec_free (s);
18835
18836 return 0;
18837#else
18838 clib_warning ("use the exec command...");
18839 return -99;
18840#endif
18841}
18842
18843static int
18844echo (vat_main_t * vam)
18845{
18846 print (vam->ofp, "%v", vam->input->buffer);
18847 return 0;
18848}
18849
18850/* List of API message constructors, CLI names map to api_xxx */
18851#define foreach_vpe_api_msg \
Jon Loeligerc83c3b72017-02-23 13:57:35 -060018852_(create_loopback,"[mac <mac-addr>] [instance <instance>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010018853_(sw_interface_dump,"") \
18854_(sw_interface_set_flags, \
18855 "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
18856_(sw_interface_add_del_address, \
18857 "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
18858_(sw_interface_set_table, \
18859 "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]") \
18860_(sw_interface_set_mpls_enable, \
18861 "<intfc> | sw_if_index [disable | dis]") \
18862_(sw_interface_set_vpath, \
18863 "<intfc> | sw_if_index <id> enable | disable") \
18864_(sw_interface_set_vxlan_bypass, \
John Lo2b81eb82017-01-30 13:12:10 -050018865 "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010018866_(sw_interface_set_l2_xconnect, \
18867 "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
18868 "enable | disable") \
18869_(sw_interface_set_l2_bridge, \
Eyal Barif24991c2017-04-05 05:33:21 +030018870 "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n" \
Damjan Marion7cd468a2016-12-19 23:05:39 +010018871 "[shg <split-horizon-group>] [bvi]\n" \
18872 "enable | disable") \
Eyal Barif24991c2017-04-05 05:33:21 +030018873_(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010018874_(bridge_domain_add_del, \
Eyal Barifead6702017-04-04 04:46:32 +030018875 "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 +010018876_(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n") \
18877_(l2fib_add_del, \
18878 "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 +030018879_(l2fib_flush_bd, "bd_id <bridge-domain-id>") \
18880_(l2fib_flush_int, "<intfc> | sw_if_index <id>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010018881_(l2_flags, \
18882 "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n") \
18883_(bridge_flags, \
18884 "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
18885_(tap_connect, \
18886 "tapname <name> mac <mac-addr> | random-mac [tag <string>]") \
18887_(tap_modify, \
18888 "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
18889_(tap_delete, \
18890 "<vpp-if-name> | sw_if_index <id>") \
18891_(sw_interface_tap_dump, "") \
18892_(ip_add_del_route, \
18893 "<addr>/<mask> via <addr> [table-id <n>]\n" \
18894 "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n" \
18895 "[weight <n>] [drop] [local] [classify <n>] [del]\n" \
18896 "[multipath] [count <n>]") \
Neale Ranns32e1c012016-11-22 17:07:28 +000018897_(ip_mroute_add_del, \
18898 "<src> <grp>/<mask> [table-id <n>]\n" \
18899 "[<intfc> | sw_if_index <id>] [local] [del]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010018900_(mpls_route_add_del, \
18901 "<label> <eos> via <addr> [table-id <n>]\n" \
18902 "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n" \
18903 "[weight <n>] [drop] [local] [classify <n>] [del]\n" \
18904 "[multipath] [count <n>]") \
18905_(mpls_ip_bind_unbind, \
18906 "<label> <addr/len>") \
18907_(mpls_tunnel_add_del, \
18908 " via <addr> [table-id <n>]\n" \
18909 "sw_if_index <id>] [l2] [del]") \
18910_(proxy_arp_add_del, \
18911 "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]") \
18912_(proxy_arp_intfc_enable_disable, \
18913 "<intfc> | sw_if_index <id> enable | disable") \
18914_(sw_interface_set_unnumbered, \
18915 "<intfc> | sw_if_index <id> unnum_if_index <id> [del]") \
18916_(ip_neighbor_add_del, \
18917 "(<intfc> | sw_if_index <id>) dst <ip46-address> " \
18918 "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]") \
18919_(reset_vrf, "vrf <id> [ipv6]") \
18920_(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>") \
18921_(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n" \
18922 "[outer_vlan_id <n>][inner_vlan_id <n>]\n" \
18923 "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n" \
18924 "[outer_vlan_id_any][inner_vlan_id_any]") \
18925_(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]") \
18926_(reset_fib, "vrf <n> [ipv6]") \
18927_(dhcp_proxy_config, \
18928 "svr <v46-address> src <v46-address>\n" \
Neale Ranns20a175a2017-02-14 07:28:41 -080018929 "rx_vrf_id <nn> server_vrf_id <nn> [del]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010018930_(dhcp_proxy_set_vss, \
18931 "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]") \
Neale Ranns20a175a2017-02-14 07:28:41 -080018932_(dhcp_proxy_dump, "ip6") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010018933_(dhcp_client_config, \
18934 "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
18935_(set_ip_flow_hash, \
18936 "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]") \
18937_(sw_interface_ip6_enable_disable, \
18938 "<intfc> | sw_if_index <id> enable | disable") \
18939_(sw_interface_ip6_set_link_local_address, \
18940 "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>") \
Neale Ranns3f844d02017-02-18 00:03:54 -080018941_(ip6nd_proxy_add_del, \
18942 "<intfc> | sw_if_index <id> <ip6-address>") \
18943_(ip6nd_proxy_dump, "") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010018944_(sw_interface_ip6nd_ra_prefix, \
18945 "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n" \
18946 "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n" \
18947 "[nolink] [isno]") \
18948_(sw_interface_ip6nd_ra_config, \
18949 "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n" \
18950 "[life <n>] [count <n>] [interval <n>] [suppress]\n" \
18951 "[managed] [other] [ll] [send] [cease] [isno] [def]") \
18952_(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]") \
18953_(l2_patch_add_del, \
18954 "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
18955 "enable | disable") \
Pablo Camarillofb380952016-12-07 18:34:18 +010018956_(sr_localsid_add_del, \
18957 "(del) address <addr> next_hop <addr> behavior <beh>\n" \
18958 "fib-table <num> (end.psp) sw_if_index <num>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010018959_(classify_add_del_table, \
18960 "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n" \
18961 " [del] [del-chain] mask <mask-value>\n" \
18962 " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n" \
18963 " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]") \
18964_(classify_add_del_session, \
18965 "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n" \
18966 " table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n" \
18967 " [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n" \
18968 " [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]") \
18969_(classify_set_interface_ip_table, \
18970 "<intfc> | sw_if_index <nn> table <nn>") \
18971_(classify_set_interface_l2_tables, \
18972 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
18973 " [other-table <nn>]") \
18974_(get_node_index, "node <node-name") \
18975_(add_node_next, "node <node-name> next <next-node-name>") \
18976_(l2tpv3_create_tunnel, \
18977 "client_address <ip6-addr> our_address <ip6-addr>\n" \
18978 "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
18979 "[remote_cookie <nn>]\n[l2-sublayer-preset]\n") \
18980_(l2tpv3_set_tunnel_cookies, \
18981 "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n" \
18982 "[new_remote_cookie <nn>]\n") \
18983_(l2tpv3_interface_enable_disable, \
18984 "<intfc> | sw_if_index <nn> enable | disable") \
18985_(l2tpv3_set_lookup_key, \
18986 "lookup_v6_src | lookup_v6_dst | lookup_session_id") \
18987_(sw_if_l2tpv3_tunnel_dump, "") \
18988_(vxlan_add_del_tunnel, \
18989 "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n" \
18990 "{ <intfc> | mcast_sw_if_index <nn> } }\n" \
18991 "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]") \
18992_(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]") \
18993_(gre_add_del_tunnel, \
Ciara Loftus7eac9162016-09-30 15:47:03 +010018994 "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [teb] [del]\n") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010018995_(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]") \
18996_(l2_fib_clear_table, "") \
18997_(l2_interface_efp_filter, "sw_if_index <nn> enable | disable") \
18998_(l2_interface_vlan_tag_rewrite, \
18999 "<intfc> | sw_if_index <nn> \n" \
19000 "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n" \
19001 "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>") \
19002_(create_vhost_user_if, \
19003 "socket <filename> [server] [renumber <dev_instance>] " \
Steven7312cc72017-03-15 21:18:55 -070019004 "[mac <mac_address>] " \
19005 "[mode <interrupt | polling>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010019006_(modify_vhost_user_if, \
19007 "<intfc> | sw_if_index <nn> socket <filename>\n" \
Steven7312cc72017-03-15 21:18:55 -070019008 "[server] [renumber <dev_instance>] " \
19009 "[mode <interrupt | polling>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010019010_(delete_vhost_user_if, "<intfc> | sw_if_index <nn>") \
19011_(sw_interface_vhost_user_dump, "") \
19012_(show_version, "") \
19013_(vxlan_gpe_add_del_tunnel, \
19014 "local <addr> remote <addr> vni <nn>\n" \
19015 "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]" \
19016 "[next-ethernet] [next-nsh]\n") \
19017_(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]") \
19018_(l2_fib_table_dump, "bd_id <bridge-domain-id>") \
19019_(interface_name_renumber, \
19020 "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>") \
19021_(input_acl_set_interface, \
19022 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
19023 " [l2-table <nn>] [del]") \
19024_(want_ip4_arp_events, "address <ip4-address> [del]") \
19025_(want_ip6_nd_events, "address <ip6-address> [del]") \
19026_(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)") \
19027_(ip_dump, "ipv4 | ipv6") \
19028_(ipsec_spd_add_del, "spd_id <n> [del]") \
19029_(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n" \
19030 " spid_id <n> ") \
19031_(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n" \
19032 " crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n" \
19033 " integ_alg <alg> integ_key <hex>") \
19034_(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n" \
19035 " (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n" \
19036 " laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
19037 " [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
19038_(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>") \
Matthew Smithb0972cb2017-05-02 16:20:41 -050019039_(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n" \
19040 " crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
19041 " integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n" \
19042 " local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010019043_(ikev2_profile_add_del, "name <profile_name> [del]") \
19044_(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n" \
19045 "(auth_data 0x<data> | auth_data <data>)") \
19046_(ikev2_profile_set_id, "name <profile_name> id_type <type>\n" \
19047 "(id_data 0x<data> | id_data <data>) (local|remote)") \
19048_(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n" \
19049 "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
19050 "(local|remote)") \
19051_(ikev2_set_local_key, "file <absolute_file_path>") \
Radu Nicolaucb33dc22017-02-16 16:49:46 +000019052_(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
19053_(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
19054_(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
19055_(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
19056_(ikev2_initiate_sa_init, "<profile_name>") \
19057_(ikev2_initiate_del_ike_sa, "<ispi>") \
19058_(ikev2_initiate_del_child_sa, "<ispi>") \
19059_(ikev2_initiate_rekey_child_sa, "<ispi>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010019060_(delete_loopback,"sw_if_index <nn>") \
19061_(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
19062_(map_add_domain, \
19063 "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> " \
19064 "ip6-src <ip6addr> " \
19065 "ea-bits-len <n> psid-offset <n> psid-len <n>") \
19066_(map_del_domain, "index <n>") \
19067_(map_add_del_rule, \
19068 "index <n> psid <n> dst <ip6addr> [del]") \
19069_(map_domain_dump, "") \
19070_(map_rule_dump, "index <map-domain>") \
19071_(want_interface_events, "enable|disable") \
19072_(want_stats,"enable|disable") \
19073_(get_first_msg_id, "client <name>") \
19074_(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
19075_(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n" \
19076 "fib-id <nn> [ip4][ip6][default]") \
19077_(get_node_graph, " ") \
19078_(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>") \
19079_(ioam_enable, "[trace] [pow] [ppc <encap|decap>]") \
19080_(ioam_disable, "") \
Filip Tehlar694396d2017-02-17 14:29:11 +010019081_(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
19082 " sw_if_index <sw_if_index> p <priority> " \
19083 "w <weight>] [del]") \
19084_(one_add_del_locator, "locator-set <locator_name> " \
19085 "iface <intf> | sw_if_index <sw_if_index> " \
19086 "p <priority> w <weight> [del]") \
19087_(one_add_del_local_eid,"vni <vni> eid " \
19088 "<ipv4|ipv6>/<prefix> | <L2 address> " \
19089 "locator-set <locator_name> [del]" \
19090 "[key-id sha1|sha256 secret-key <secret-key>]")\
19091_(one_add_del_map_resolver, "<ip4|6-addr> [del]") \
19092_(one_add_del_map_server, "<ip4|6-addr> [del]") \
19093_(one_enable_disable, "enable|disable") \
19094_(one_map_register_enable_disable, "enable|disable") \
19095_(one_rloc_probe_enable_disable, "enable|disable") \
19096_(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> " \
19097 "[seid <seid>] " \
19098 "rloc <locator> p <prio> " \
19099 "w <weight> [rloc <loc> ... ] " \
19100 "action <action> [del-all]") \
19101_(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid " \
19102 "<local-eid>") \
19103_(one_pitr_set_locator_set, "locator-set <loc-set-name> | del") \
Filip Tehlar67a99f82017-03-10 13:18:02 +010019104_(one_use_petr, "ip-address> | disable") \
Filip Tehlar694396d2017-02-17 14:29:11 +010019105_(one_map_request_mode, "src-dst|dst-only") \
19106_(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]") \
19107_(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>") \
19108_(one_locator_set_dump, "[local | remote]") \
19109_(one_locator_dump, "ls_index <index> | ls_name <name>") \
19110_(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] " \
19111 "[local] | [remote]") \
Filip Tehlar4868ff62017-03-09 16:48:39 +010019112_(one_stats_enable_disable, "enable|disalbe") \
19113_(show_one_stats_enable_disable, "") \
Filip Tehlar694396d2017-02-17 14:29:11 +010019114_(one_eid_table_vni_dump, "") \
19115_(one_eid_table_map_dump, "l2|l3") \
19116_(one_map_resolver_dump, "") \
19117_(one_map_server_dump, "") \
19118_(one_adjacencies_get, "vni <vni>") \
19119_(show_one_rloc_probe_state, "") \
19120_(show_one_map_register_state, "") \
19121_(show_one_status, "") \
Filip Tehlar4868ff62017-03-09 16:48:39 +010019122_(one_stats_dump, "") \
Filip Tehlar21511912017-04-07 10:41:42 +020019123_(one_stats_flush, "") \
Filip Tehlar694396d2017-02-17 14:29:11 +010019124_(one_get_map_request_itr_rlocs, "") \
19125_(show_one_pitr, "") \
Filip Tehlar67a99f82017-03-10 13:18:02 +010019126_(show_one_use_petr, "") \
Filip Tehlar694396d2017-02-17 14:29:11 +010019127_(show_one_map_request_mode, "") \
19128_(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
Damjan Marion7cd468a2016-12-19 23:05:39 +010019129 " sw_if_index <sw_if_index> p <priority> " \
19130 "w <weight>] [del]") \
19131_(lisp_add_del_locator, "locator-set <locator_name> " \
19132 "iface <intf> | sw_if_index <sw_if_index> " \
19133 "p <priority> w <weight> [del]") \
19134_(lisp_add_del_local_eid,"vni <vni> eid " \
19135 "<ipv4|ipv6>/<prefix> | <L2 address> " \
19136 "locator-set <locator_name> [del]" \
19137 "[key-id sha1|sha256 secret-key <secret-key>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010019138_(lisp_add_del_map_resolver, "<ip4|6-addr> [del]") \
19139_(lisp_add_del_map_server, "<ip4|6-addr> [del]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010019140_(lisp_enable_disable, "enable|disable") \
19141_(lisp_map_register_enable_disable, "enable|disable") \
19142_(lisp_rloc_probe_enable_disable, "enable|disable") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010019143_(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> " \
19144 "[seid <seid>] " \
19145 "rloc <locator> p <prio> " \
19146 "w <weight> [rloc <loc> ... ] " \
19147 "action <action> [del-all]") \
19148_(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid " \
19149 "<local-eid>") \
19150_(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del") \
Filip Tehlar67a99f82017-03-10 13:18:02 +010019151_(lisp_use_petr, "<ip-address> | disable") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010019152_(lisp_map_request_mode, "src-dst|dst-only") \
19153_(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]") \
19154_(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>") \
19155_(lisp_locator_set_dump, "[local | remote]") \
19156_(lisp_locator_dump, "ls_index <index> | ls_name <name>") \
19157_(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] " \
19158 "[local] | [remote]") \
19159_(lisp_eid_table_vni_dump, "") \
19160_(lisp_eid_table_map_dump, "l2|l3") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010019161_(lisp_map_resolver_dump, "") \
19162_(lisp_map_server_dump, "") \
19163_(lisp_adjacencies_get, "vni <vni>") \
Filip Tehlar0eb874e2017-05-18 14:23:32 +020019164_(gpe_fwd_entry_vnis_get, "") \
Filip Tehlar5fae99c2017-01-18 12:57:37 +010019165_(lisp_gpe_fwd_entries_get, "vni <vni>") \
19166_(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>") \
Filip Tehlar3e7b56932017-02-21 18:28:34 +010019167_(gpe_set_encap_mode, "lisp|vxlan") \
19168_(gpe_get_encap_mode, "") \
Filip Tehlar82786c42017-02-20 15:20:37 +010019169_(lisp_gpe_add_del_iface, "up|down") \
19170_(lisp_gpe_enable_disable, "enable|disable") \
19171_(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>" \
19172 "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010019173_(show_lisp_rloc_probe_state, "") \
19174_(show_lisp_map_register_state, "") \
19175_(show_lisp_status, "") \
19176_(lisp_get_map_request_itr_rlocs, "") \
19177_(show_lisp_pitr, "") \
Filip Tehlar67a99f82017-03-10 13:18:02 +010019178_(show_lisp_use_petr, "") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010019179_(show_lisp_map_request_mode, "") \
19180_(af_packet_create, "name <host interface name> [hw_addr <mac>]") \
19181_(af_packet_delete, "name <host interface name>") \
19182_(policer_add_del, "name <policer name> <params> [del]") \
19183_(policer_dump, "[name <policer name>]") \
19184_(policer_classify_set_interface, \
19185 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
19186 " [l2-table <nn>] [del]") \
19187_(policer_classify_dump, "type [ip4|ip6|l2]") \
19188_(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] " \
19189 "[master|slave]") \
19190_(netmap_delete, "name <interface name>") \
19191_(mpls_tunnel_dump, "tunnel_index <tunnel-id>") \
19192_(mpls_fib_dump, "") \
19193_(classify_table_ids, "") \
19194_(classify_table_by_interface, "sw_if_index <sw_if_index>") \
19195_(classify_table_info, "table_id <nn>") \
19196_(classify_session_dump, "table_id <nn>") \
19197_(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] " \
19198 "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] " \
19199 "[template_interval <nn>] [udp_checksum]") \
19200_(ipfix_exporter_dump, "") \
19201_(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
19202_(ipfix_classify_stream_dump, "") \
19203_(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
19204_(ipfix_classify_table_dump, "") \
19205_(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
19206_(sw_interface_span_dump, "") \
19207_(get_next_index, "node-name <node-name> next-node-name <node-name>") \
19208_(pg_create_interface, "if_id <nn>") \
19209_(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]") \
19210_(pg_enable_disable, "[stream <id>] disable") \
19211_(ip_source_and_port_range_check_add_del, \
19212 "<ip-addr>/<mask> range <nn>-<nn> vrf <id>") \
19213_(ip_source_and_port_range_check_interface_add_del, \
19214 "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]" \
19215 "[udp-in-vrf <id>] [udp-out-vrf <id>]") \
19216_(ipsec_gre_add_del_tunnel, \
19217 "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]") \
19218_(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]") \
19219_(delete_subif,"<intfc> | sw_if_index <nn>") \
19220_(l2_interface_pbb_tag_rewrite, \
19221 "<intfc> | sw_if_index <nn> \n" \
19222 "[disable | push | pop | translate_pbb_stag <outer_tag>] \n" \
19223 "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]") \
19224_(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]") \
19225_(flow_classify_set_interface, \
19226 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
19227_(flow_classify_dump, "type [ip4|ip6]") \
19228_(ip_fib_dump, "") \
Neale Ranns5a8123b2017-01-26 01:18:23 -080019229_(ip_mfib_dump, "") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010019230_(ip6_fib_dump, "") \
Neale Ranns5a8123b2017-01-26 01:18:23 -080019231_(ip6_mfib_dump, "") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010019232_(feature_enable_disable, "arc_name <arc_name> " \
19233 "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]") \
19234_(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>" \
19235"[disable]") \
19236_(l2_xconnect_dump, "") \
19237_(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>") \
19238_(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>") \
19239_(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")
19240
19241/* List of command functions, CLI names map directly to functions */
19242#define foreach_cli_function \
19243_(comment, "usage: comment <ignore-rest-of-line>") \
19244_(dump_interface_table, "usage: dump_interface_table") \
19245_(dump_sub_interface_table, "usage: dump_sub_interface_table") \
19246_(dump_ipv4_table, "usage: dump_ipv4_table") \
19247_(dump_ipv6_table, "usage: dump_ipv6_table") \
19248_(dump_stats_table, "usage: dump_stats_table") \
19249_(dump_macro_table, "usage: dump_macro_table ") \
19250_(dump_node_table, "usage: dump_node_table") \
19251_(dump_msg_api_table, "usage: dump_msg_api_table") \
19252_(get_msg_id, "usage: get_msg_id name_and_crc") \
19253_(echo, "usage: echo <message>") \
19254_(exec, "usage: exec <vpe-debug-CLI-command>") \
19255_(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>") \
19256_(help, "usage: help") \
19257_(q, "usage: quit") \
19258_(quit, "usage: quit") \
19259_(search_node_table, "usage: search_node_table <name>...") \
19260_(set, "usage: set <variable-name> <value>") \
19261_(script, "usage: script <file-name>") \
19262_(unset, "usage: unset <variable-name>")
19263
19264#define _(N,n) \
19265 static void vl_api_##n##_t_handler_uni \
19266 (vl_api_##n##_t * mp) \
19267 { \
19268 vat_main_t * vam = &vat_main; \
19269 if (vam->json_output) { \
19270 vl_api_##n##_t_handler_json(mp); \
19271 } else { \
19272 vl_api_##n##_t_handler(mp); \
19273 } \
19274 }
19275foreach_vpe_api_reply_msg;
Dave Baracha1a093d2017-03-02 13:13:23 -050019276#if VPP_API_TEST_BUILTIN == 0
19277foreach_standalone_reply_msg;
19278#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +010019279#undef _
19280
19281void
19282vat_api_hookup (vat_main_t * vam)
19283{
19284#define _(N,n) \
19285 vl_msg_api_set_handlers(VL_API_##N, #n, \
19286 vl_api_##n##_t_handler_uni, \
19287 vl_noop_handler, \
19288 vl_api_##n##_t_endian, \
19289 vl_api_##n##_t_print, \
19290 sizeof(vl_api_##n##_t), 1);
19291 foreach_vpe_api_reply_msg;
Dave Baracha1a093d2017-03-02 13:13:23 -050019292#if VPP_API_TEST_BUILTIN == 0
19293 foreach_standalone_reply_msg;
19294#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +010019295#undef _
19296
19297#if (VPP_API_TEST_BUILTIN==0)
19298 vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
Damjan Marion7cd468a2016-12-19 23:05:39 +010019299
19300 vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
19301
19302 vam->function_by_name = hash_create_string (0, sizeof (uword));
19303
19304 vam->help_by_name = hash_create_string (0, sizeof (uword));
Dave Barach45e4f362017-03-07 12:52:31 -050019305#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +010019306
19307 /* API messages we can send */
19308#define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
19309 foreach_vpe_api_msg;
19310#undef _
19311
19312 /* Help strings */
19313#define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
19314 foreach_vpe_api_msg;
19315#undef _
Damjan Marion7cd468a2016-12-19 23:05:39 +010019316
19317 /* CLI functions */
19318#define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
19319 foreach_cli_function;
19320#undef _
19321
19322 /* Help strings */
19323#define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
19324 foreach_cli_function;
19325#undef _
19326}
19327
Dave Baracha1a093d2017-03-02 13:13:23 -050019328#if VPP_API_TEST_BUILTIN
19329static clib_error_t *
19330vat_api_hookup_shim (vlib_main_t * vm)
19331{
19332 vat_api_hookup (&vat_main);
19333 return 0;
19334}
19335
19336VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
19337#endif
19338
Damjan Marion7cd468a2016-12-19 23:05:39 +010019339/*
19340 * fd.io coding-style-patch-verification: ON
19341 *
19342 * Local Variables:
19343 * eval: (c-set-style "gnu")
19344 * End:
19345 */