blob: 999f986922c596a5ffa980806cb4e207c68e33f8 [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>
25#include <vnet/sr/sr_packet.h>
26#include <vnet/l2/l2_input.h>
27#include <vnet/l2tp/l2tp.h>
28#include <vnet/vxlan/vxlan.h>
29#include <vnet/gre/gre.h>
30#include <vnet/vxlan-gpe/vxlan_gpe.h>
31#include <vnet/lisp-gpe/lisp_gpe.h>
32
33#include <vpp/api/vpe_msg_enum.h>
34#include <vnet/l2/l2_classify.h>
35#include <vnet/l2/l2_vtr.h>
36#include <vnet/classify/input_acl.h>
37#include <vnet/classify/policer_classify.h>
38#include <vnet/classify/flow_classify.h>
39#include <vnet/mpls/mpls.h>
40#include <vnet/ipsec/ipsec.h>
41#include <vnet/ipsec/ikev2.h>
42#include <inttypes.h>
43#include <vnet/map/map.h>
44#include <vnet/cop/cop.h>
45#include <vnet/ip/ip6_hop_by_hop.h>
46#include <vnet/ip/ip_source_and_port_range_check.h>
47#include <vnet/policer/xlate.h>
48#include <vnet/span/span.h>
49#include <vnet/policer/policer.h>
50#include <vnet/policer/police.h>
Neale Ranns32e1c012016-11-22 17:07:28 +000051#include <vnet/mfib/mfib_types.h>
Damjan Marion7cd468a2016-12-19 23:05:39 +010052
53#include "vat/json_format.h"
54
55#include <inttypes.h>
56#include <sys/stat.h>
57
58#define vl_typedefs /* define message structures */
59#include <vpp/api/vpe_all_api_h.h>
60#undef vl_typedefs
61
62/* declare message handlers for each api */
63
64#define vl_endianfun /* define message structures */
65#include <vpp/api/vpe_all_api_h.h>
66#undef vl_endianfun
67
68/* instantiate all the print functions we know about */
69#define vl_print(handle, ...)
70#define vl_printfun
71#include <vpp/api/vpe_all_api_h.h>
72#undef vl_printfun
73
Dave Barach2d6b2d62017-01-25 16:32:08 -050074#define __plugin_msg_base 0
Dave Barachfe6bdfd2017-01-20 19:50:09 -050075#include <vlibapi/vat_helper_macros.h>
76
77f64
78vat_time_now (vat_main_t * vam)
79{
80#if VPP_API_TEST_BUILTIN
81 return vlib_time_now (vam->vlib_main);
82#else
83 return clib_time_now (&vam->clib_time);
84#endif
85}
86
87void
88errmsg (char *fmt, ...)
89{
90 vat_main_t *vam = &vat_main;
91 va_list va;
92 u8 *s;
93
94 va_start (va, fmt);
95 s = va_format (0, fmt, &va);
96 va_end (va);
97
98 vec_add1 (s, 0);
99
100#if VPP_API_TEST_BUILTIN
101 vlib_cli_output (vam->vlib_main, (char *) s);
102#else
103 {
104 if (vam->ifp != stdin)
105 fformat (vam->ofp, "%s(%d): \n", vam->current_file,
106 vam->input_line_number);
107 fformat (vam->ofp, (char *) s);
108 fflush (vam->ofp);
109 }
110#endif
111
112 vec_free (s);
113}
114
Dave Barach4a3f69c2017-02-22 12:44:56 -0500115#if VPP_API_TEST_BUILTIN == 0
Damjan Marion7cd468a2016-12-19 23:05:39 +0100116static uword
117api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
118{
119 vat_main_t *vam = va_arg (*args, vat_main_t *);
120 u32 *result = va_arg (*args, u32 *);
121 u8 *if_name;
122 uword *p;
123
124 if (!unformat (input, "%s", &if_name))
125 return 0;
126
127 p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
128 if (p == 0)
129 return 0;
130 *result = p[0];
131 return 1;
132}
133
Damjan Marion7cd468a2016-12-19 23:05:39 +0100134/* Parse an IP4 address %d.%d.%d.%d. */
135uword
136unformat_ip4_address (unformat_input_t * input, va_list * args)
137{
138 u8 *result = va_arg (*args, u8 *);
139 unsigned a[4];
140
141 if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
142 return 0;
143
144 if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
145 return 0;
146
147 result[0] = a[0];
148 result[1] = a[1];
149 result[2] = a[2];
150 result[3] = a[3];
151
152 return 1;
153}
154
155uword
156unformat_ethernet_address (unformat_input_t * input, va_list * args)
157{
158 u8 *result = va_arg (*args, u8 *);
159 u32 i, a[6];
160
161 if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
162 &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
163 return 0;
164
165 /* Check range. */
166 for (i = 0; i < 6; i++)
167 if (a[i] >= (1 << 8))
168 return 0;
169
170 for (i = 0; i < 6; i++)
171 result[i] = a[i];
172
173 return 1;
174}
175
176/* Returns ethernet type as an int in host byte order. */
177uword
178unformat_ethernet_type_host_byte_order (unformat_input_t * input,
179 va_list * args)
180{
181 u16 *result = va_arg (*args, u16 *);
182 int type;
183
184 /* Numeric type. */
185 if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
186 {
187 if (type >= (1 << 16))
188 return 0;
189 *result = type;
190 return 1;
191 }
192 return 0;
193}
194
195/* Parse an IP6 address. */
196uword
197unformat_ip6_address (unformat_input_t * input, va_list * args)
198{
199 ip6_address_t *result = va_arg (*args, ip6_address_t *);
200 u16 hex_quads[8];
201 uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
202 uword c, n_colon, double_colon_index;
203
204 n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
205 double_colon_index = ARRAY_LEN (hex_quads);
206 while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
207 {
208 hex_digit = 16;
209 if (c >= '0' && c <= '9')
210 hex_digit = c - '0';
211 else if (c >= 'a' && c <= 'f')
212 hex_digit = c + 10 - 'a';
213 else if (c >= 'A' && c <= 'F')
214 hex_digit = c + 10 - 'A';
215 else if (c == ':' && n_colon < 2)
216 n_colon++;
217 else
218 {
219 unformat_put_input (input);
220 break;
221 }
222
223 /* Too many hex quads. */
224 if (n_hex_quads >= ARRAY_LEN (hex_quads))
225 return 0;
226
227 if (hex_digit < 16)
228 {
229 hex_quad = (hex_quad << 4) | hex_digit;
230
231 /* Hex quad must fit in 16 bits. */
232 if (n_hex_digits >= 4)
233 return 0;
234
235 n_colon = 0;
236 n_hex_digits++;
237 }
238
239 /* Save position of :: */
240 if (n_colon == 2)
241 {
242 /* More than one :: ? */
243 if (double_colon_index < ARRAY_LEN (hex_quads))
244 return 0;
245 double_colon_index = n_hex_quads;
246 }
247
248 if (n_colon > 0 && n_hex_digits > 0)
249 {
250 hex_quads[n_hex_quads++] = hex_quad;
251 hex_quad = 0;
252 n_hex_digits = 0;
253 }
254 }
255
256 if (n_hex_digits > 0)
257 hex_quads[n_hex_quads++] = hex_quad;
258
259 {
260 word i;
261
262 /* Expand :: to appropriate number of zero hex quads. */
263 if (double_colon_index < ARRAY_LEN (hex_quads))
264 {
265 word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
266
267 for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
268 hex_quads[n_zero + i] = hex_quads[i];
269
270 for (i = 0; i < n_zero; i++)
271 hex_quads[double_colon_index + i] = 0;
272
273 n_hex_quads = ARRAY_LEN (hex_quads);
274 }
275
276 /* Too few hex quads given. */
277 if (n_hex_quads < ARRAY_LEN (hex_quads))
278 return 0;
279
280 for (i = 0; i < ARRAY_LEN (hex_quads); i++)
281 result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
282
283 return 1;
284 }
285}
286
287uword
288unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
289{
290 u32 *r = va_arg (*args, u32 *);
291
292 if (0);
293#define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
294 foreach_ipsec_policy_action
295#undef _
296 else
297 return 0;
298 return 1;
299}
300
301uword
302unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
303{
304 u32 *r = va_arg (*args, u32 *);
305
306 if (0);
307#define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
308 foreach_ipsec_crypto_alg
309#undef _
310 else
311 return 0;
312 return 1;
313}
314
315u8 *
316format_ipsec_crypto_alg (u8 * s, va_list * args)
317{
318 u32 i = va_arg (*args, u32);
319 u8 *t = 0;
320
321 switch (i)
322 {
323#define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
324 foreach_ipsec_crypto_alg
325#undef _
326 default:
327 return format (s, "unknown");
328 }
329 return format (s, "%s", t);
330}
331
332uword
333unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
334{
335 u32 *r = va_arg (*args, u32 *);
336
337 if (0);
338#define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
339 foreach_ipsec_integ_alg
340#undef _
341 else
342 return 0;
343 return 1;
344}
345
346u8 *
347format_ipsec_integ_alg (u8 * s, va_list * args)
348{
349 u32 i = va_arg (*args, u32);
350 u8 *t = 0;
351
352 switch (i)
353 {
354#define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
355 foreach_ipsec_integ_alg
356#undef _
357 default:
358 return format (s, "unknown");
359 }
360 return format (s, "%s", t);
361}
362
363uword
364unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
365{
366 u32 *r = va_arg (*args, u32 *);
367
368 if (0);
369#define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
370 foreach_ikev2_auth_method
371#undef _
372 else
373 return 0;
374 return 1;
375}
376
377uword
378unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
379{
380 u32 *r = va_arg (*args, u32 *);
381
382 if (0);
383#define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
384 foreach_ikev2_id_type
385#undef _
386 else
387 return 0;
388 return 1;
389}
Dave Barach4a3f69c2017-02-22 12:44:56 -0500390#else /* VPP_API_TEST_BUILTIN == 1 */
391static uword
392api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
393{
394 vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
395 vnet_main_t *vnm = vnet_get_main ();
396 u32 *result = va_arg (*args, u32 *);
397 u32 sw_if_index;
398
399 if (!unformat (input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
400 return 0;
401
402 *result = sw_if_index;
403 return 1;
404}
Damjan Marion7cd468a2016-12-19 23:05:39 +0100405#endif /* VPP_API_TEST_BUILTIN */
406
407static uword
408unformat_policer_rate_type (unformat_input_t * input, va_list * args)
409{
410 u8 *r = va_arg (*args, u8 *);
411
412 if (unformat (input, "kbps"))
413 *r = SSE2_QOS_RATE_KBPS;
414 else if (unformat (input, "pps"))
415 *r = SSE2_QOS_RATE_PPS;
416 else
417 return 0;
418 return 1;
419}
420
421static uword
422unformat_policer_round_type (unformat_input_t * input, va_list * args)
423{
424 u8 *r = va_arg (*args, u8 *);
425
426 if (unformat (input, "closest"))
427 *r = SSE2_QOS_ROUND_TO_CLOSEST;
428 else if (unformat (input, "up"))
429 *r = SSE2_QOS_ROUND_TO_UP;
430 else if (unformat (input, "down"))
431 *r = SSE2_QOS_ROUND_TO_DOWN;
432 else
433 return 0;
434 return 1;
435}
436
437static uword
438unformat_policer_type (unformat_input_t * input, va_list * args)
439{
440 u8 *r = va_arg (*args, u8 *);
441
442 if (unformat (input, "1r2c"))
443 *r = SSE2_QOS_POLICER_TYPE_1R2C;
444 else if (unformat (input, "1r3c"))
445 *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
446 else if (unformat (input, "2r3c-2698"))
447 *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
448 else if (unformat (input, "2r3c-4115"))
449 *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
450 else if (unformat (input, "2r3c-mef5cf1"))
451 *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
452 else
453 return 0;
454 return 1;
455}
456
457static uword
458unformat_dscp (unformat_input_t * input, va_list * va)
459{
460 u8 *r = va_arg (*va, u8 *);
461
462 if (0);
463#define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
464 foreach_vnet_dscp
465#undef _
466 else
467 return 0;
468 return 1;
469}
470
471static uword
472unformat_policer_action_type (unformat_input_t * input, va_list * va)
473{
474 sse2_qos_pol_action_params_st *a
475 = va_arg (*va, sse2_qos_pol_action_params_st *);
476
477 if (unformat (input, "drop"))
478 a->action_type = SSE2_QOS_ACTION_DROP;
479 else if (unformat (input, "transmit"))
480 a->action_type = SSE2_QOS_ACTION_TRANSMIT;
481 else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
482 a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
483 else
484 return 0;
485 return 1;
486}
487
488static uword
489unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
490{
491 u32 *r = va_arg (*va, u32 *);
492 u32 tid;
493
494 if (unformat (input, "ip4"))
495 tid = POLICER_CLASSIFY_TABLE_IP4;
496 else if (unformat (input, "ip6"))
497 tid = POLICER_CLASSIFY_TABLE_IP6;
498 else if (unformat (input, "l2"))
499 tid = POLICER_CLASSIFY_TABLE_L2;
500 else
501 return 0;
502
503 *r = tid;
504 return 1;
505}
506
507static uword
508unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
509{
510 u32 *r = va_arg (*va, u32 *);
511 u32 tid;
512
513 if (unformat (input, "ip4"))
514 tid = FLOW_CLASSIFY_TABLE_IP4;
515 else if (unformat (input, "ip6"))
516 tid = FLOW_CLASSIFY_TABLE_IP6;
517 else
518 return 0;
519
520 *r = tid;
521 return 1;
522}
523
Neale Ranns32e1c012016-11-22 17:07:28 +0000524static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
525static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
526static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
527static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
528
Dave Barach4a3f69c2017-02-22 12:44:56 -0500529#if (VPP_API_TEST_BUILTIN==0)
Neale Ranns32e1c012016-11-22 17:07:28 +0000530uword
531unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
532{
533 mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
534 mfib_itf_attribute_t attr;
535
536 old = *iflags;
537 FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
538 {
539 if (unformat (input, mfib_itf_flag_long_names[attr]))
540 *iflags |= (1 << attr);
541 }
542 FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
543 {
544 if (unformat (input, mfib_itf_flag_names[attr]))
545 *iflags |= (1 << attr);
546 }
547
548 return (old == *iflags ? 0 : 1);
549}
550
551uword
552unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
553{
554 mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
555 mfib_entry_attribute_t attr;
556
557 old = *eflags;
558 FOR_EACH_MFIB_ATTRIBUTE (attr)
559 {
560 if (unformat (input, mfib_flag_long_names[attr]))
561 *eflags |= (1 << attr);
562 }
563 FOR_EACH_MFIB_ATTRIBUTE (attr)
564 {
565 if (unformat (input, mfib_flag_names[attr]))
566 *eflags |= (1 << attr);
567 }
568
569 return (old == *eflags ? 0 : 1);
570}
571
Damjan Marion7cd468a2016-12-19 23:05:39 +0100572u8 *
573format_ip4_address (u8 * s, va_list * args)
574{
575 u8 *a = va_arg (*args, u8 *);
576 return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
577}
578
579u8 *
580format_ip6_address (u8 * s, va_list * args)
581{
582 ip6_address_t *a = va_arg (*args, ip6_address_t *);
583 u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
584
585 i_max_n_zero = ARRAY_LEN (a->as_u16);
586 max_n_zeros = 0;
587 i_first_zero = i_max_n_zero;
588 n_zeros = 0;
589 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
590 {
591 u32 is_zero = a->as_u16[i] == 0;
592 if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
593 {
594 i_first_zero = i;
595 n_zeros = 0;
596 }
597 n_zeros += is_zero;
598 if ((!is_zero && n_zeros > max_n_zeros)
599 || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
600 {
601 i_max_n_zero = i_first_zero;
602 max_n_zeros = n_zeros;
603 i_first_zero = ARRAY_LEN (a->as_u16);
604 n_zeros = 0;
605 }
606 }
607
608 last_double_colon = 0;
609 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
610 {
611 if (i == i_max_n_zero && max_n_zeros > 1)
612 {
613 s = format (s, "::");
614 i += max_n_zeros - 1;
615 last_double_colon = 1;
616 }
617 else
618 {
619 s = format (s, "%s%x",
620 (last_double_colon || i == 0) ? "" : ":",
621 clib_net_to_host_u16 (a->as_u16[i]));
622 last_double_colon = 0;
623 }
624 }
625
626 return s;
627}
628
629/* Format an IP46 address. */
630u8 *
631format_ip46_address (u8 * s, va_list * args)
632{
633 ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
634 ip46_type_t type = va_arg (*args, ip46_type_t);
635 int is_ip4 = 1;
636
637 switch (type)
638 {
639 case IP46_TYPE_ANY:
640 is_ip4 = ip46_address_is_ip4 (ip46);
641 break;
642 case IP46_TYPE_IP4:
643 is_ip4 = 1;
644 break;
645 case IP46_TYPE_IP6:
646 is_ip4 = 0;
647 break;
648 }
649
650 return is_ip4 ?
651 format (s, "%U", format_ip4_address, &ip46->ip4) :
652 format (s, "%U", format_ip6_address, &ip46->ip6);
653}
654
655u8 *
656format_ethernet_address (u8 * s, va_list * args)
657{
658 u8 *a = va_arg (*args, u8 *);
659
660 return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
661 a[0], a[1], a[2], a[3], a[4], a[5]);
662}
663#endif
664
665static void
666increment_v4_address (ip4_address_t * a)
667{
668 u32 v;
669
670 v = ntohl (a->as_u32) + 1;
671 a->as_u32 = ntohl (v);
672}
673
674static void
675increment_v6_address (ip6_address_t * a)
676{
677 u64 v0, v1;
678
679 v0 = clib_net_to_host_u64 (a->as_u64[0]);
680 v1 = clib_net_to_host_u64 (a->as_u64[1]);
681
682 v1 += 1;
683 if (v1 == 0)
684 v0 += 1;
685 a->as_u64[0] = clib_net_to_host_u64 (v0);
686 a->as_u64[1] = clib_net_to_host_u64 (v1);
687}
688
689static void
690increment_mac_address (u64 * mac)
691{
692 u64 tmp = *mac;
693
694 tmp = clib_net_to_host_u64 (tmp);
695 tmp += 1 << 16; /* skip unused (least significant) octets */
696 tmp = clib_host_to_net_u64 (tmp);
697 *mac = tmp;
698}
699
700static void vl_api_create_loopback_reply_t_handler
701 (vl_api_create_loopback_reply_t * mp)
702{
703 vat_main_t *vam = &vat_main;
704 i32 retval = ntohl (mp->retval);
705
706 vam->retval = retval;
707 vam->regenerate_interface_table = 1;
708 vam->sw_if_index = ntohl (mp->sw_if_index);
709 vam->result_ready = 1;
710}
711
712static void vl_api_create_loopback_reply_t_handler_json
713 (vl_api_create_loopback_reply_t * mp)
714{
715 vat_main_t *vam = &vat_main;
716 vat_json_node_t node;
717
718 vat_json_init_object (&node);
719 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
720 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
721
722 vat_json_print (vam->ofp, &node);
723 vat_json_free (&node);
724 vam->retval = ntohl (mp->retval);
725 vam->result_ready = 1;
726}
727
728static void vl_api_af_packet_create_reply_t_handler
729 (vl_api_af_packet_create_reply_t * mp)
730{
731 vat_main_t *vam = &vat_main;
732 i32 retval = ntohl (mp->retval);
733
734 vam->retval = retval;
735 vam->regenerate_interface_table = 1;
736 vam->sw_if_index = ntohl (mp->sw_if_index);
737 vam->result_ready = 1;
738}
739
740static void vl_api_af_packet_create_reply_t_handler_json
741 (vl_api_af_packet_create_reply_t * mp)
742{
743 vat_main_t *vam = &vat_main;
744 vat_json_node_t node;
745
746 vat_json_init_object (&node);
747 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
748 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
749
750 vat_json_print (vam->ofp, &node);
751 vat_json_free (&node);
752
753 vam->retval = ntohl (mp->retval);
754 vam->result_ready = 1;
755}
756
757static void vl_api_create_vlan_subif_reply_t_handler
758 (vl_api_create_vlan_subif_reply_t * mp)
759{
760 vat_main_t *vam = &vat_main;
761 i32 retval = ntohl (mp->retval);
762
763 vam->retval = retval;
764 vam->regenerate_interface_table = 1;
765 vam->sw_if_index = ntohl (mp->sw_if_index);
766 vam->result_ready = 1;
767}
768
769static void vl_api_create_vlan_subif_reply_t_handler_json
770 (vl_api_create_vlan_subif_reply_t * mp)
771{
772 vat_main_t *vam = &vat_main;
773 vat_json_node_t node;
774
775 vat_json_init_object (&node);
776 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
777 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
778
779 vat_json_print (vam->ofp, &node);
780 vat_json_free (&node);
781
782 vam->retval = ntohl (mp->retval);
783 vam->result_ready = 1;
784}
785
786static void vl_api_create_subif_reply_t_handler
787 (vl_api_create_subif_reply_t * mp)
788{
789 vat_main_t *vam = &vat_main;
790 i32 retval = ntohl (mp->retval);
791
792 vam->retval = retval;
793 vam->regenerate_interface_table = 1;
794 vam->sw_if_index = ntohl (mp->sw_if_index);
795 vam->result_ready = 1;
796}
797
798static void vl_api_create_subif_reply_t_handler_json
799 (vl_api_create_subif_reply_t * mp)
800{
801 vat_main_t *vam = &vat_main;
802 vat_json_node_t node;
803
804 vat_json_init_object (&node);
805 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
806 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
807
808 vat_json_print (vam->ofp, &node);
809 vat_json_free (&node);
810
811 vam->retval = ntohl (mp->retval);
812 vam->result_ready = 1;
813}
814
815static void vl_api_interface_name_renumber_reply_t_handler
816 (vl_api_interface_name_renumber_reply_t * mp)
817{
818 vat_main_t *vam = &vat_main;
819 i32 retval = ntohl (mp->retval);
820
821 vam->retval = retval;
822 vam->regenerate_interface_table = 1;
823 vam->result_ready = 1;
824}
825
826static void vl_api_interface_name_renumber_reply_t_handler_json
827 (vl_api_interface_name_renumber_reply_t * mp)
828{
829 vat_main_t *vam = &vat_main;
830 vat_json_node_t node;
831
832 vat_json_init_object (&node);
833 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
834
835 vat_json_print (vam->ofp, &node);
836 vat_json_free (&node);
837
838 vam->retval = ntohl (mp->retval);
839 vam->result_ready = 1;
840}
841
842/*
843 * Special-case: build the interface table, maintain
844 * the next loopback sw_if_index vbl.
845 */
846static void vl_api_sw_interface_details_t_handler
847 (vl_api_sw_interface_details_t * mp)
848{
849 vat_main_t *vam = &vat_main;
850 u8 *s = format (0, "%s%c", mp->interface_name, 0);
851
852 hash_set_mem (vam->sw_if_index_by_interface_name, s,
853 ntohl (mp->sw_if_index));
854
855 /* In sub interface case, fill the sub interface table entry */
856 if (mp->sw_if_index != mp->sup_sw_if_index)
857 {
858 sw_interface_subif_t *sub = NULL;
859
860 vec_add2 (vam->sw_if_subif_table, sub, 1);
861
862 vec_validate (sub->interface_name, strlen ((char *) s) + 1);
863 strncpy ((char *) sub->interface_name, (char *) s,
864 vec_len (sub->interface_name));
865 sub->sw_if_index = ntohl (mp->sw_if_index);
866 sub->sub_id = ntohl (mp->sub_id);
867
868 sub->sub_dot1ad = mp->sub_dot1ad;
869 sub->sub_number_of_tags = mp->sub_number_of_tags;
870 sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
871 sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
872 sub->sub_exact_match = mp->sub_exact_match;
873 sub->sub_default = mp->sub_default;
874 sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
875 sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
876
877 /* vlan tag rewrite */
878 sub->vtr_op = ntohl (mp->vtr_op);
879 sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
880 sub->vtr_tag1 = ntohl (mp->vtr_tag1);
881 sub->vtr_tag2 = ntohl (mp->vtr_tag2);
882 }
883}
884
885static void vl_api_sw_interface_details_t_handler_json
886 (vl_api_sw_interface_details_t * mp)
887{
888 vat_main_t *vam = &vat_main;
889 vat_json_node_t *node = NULL;
890
891 if (VAT_JSON_ARRAY != vam->json_tree.type)
892 {
893 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
894 vat_json_init_array (&vam->json_tree);
895 }
896 node = vat_json_array_add (&vam->json_tree);
897
898 vat_json_init_object (node);
899 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
900 vat_json_object_add_uint (node, "sup_sw_if_index",
901 ntohl (mp->sup_sw_if_index));
902 vat_json_object_add_uint (node, "l2_address_length",
903 ntohl (mp->l2_address_length));
904 vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
905 sizeof (mp->l2_address));
906 vat_json_object_add_string_copy (node, "interface_name",
907 mp->interface_name);
908 vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
909 vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
910 vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
911 vat_json_object_add_uint (node, "link_speed", mp->link_speed);
912 vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
913 vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
914 vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
915 vat_json_object_add_uint (node, "sub_number_of_tags",
916 mp->sub_number_of_tags);
917 vat_json_object_add_uint (node, "sub_outer_vlan_id",
918 ntohs (mp->sub_outer_vlan_id));
919 vat_json_object_add_uint (node, "sub_inner_vlan_id",
920 ntohs (mp->sub_inner_vlan_id));
921 vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
922 vat_json_object_add_uint (node, "sub_default", mp->sub_default);
923 vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
924 mp->sub_outer_vlan_id_any);
925 vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
926 mp->sub_inner_vlan_id_any);
927 vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
928 vat_json_object_add_uint (node, "vtr_push_dot1q",
929 ntohl (mp->vtr_push_dot1q));
930 vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
931 vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
Pavel Kotucek65e84572017-01-16 17:01:56 +0100932 if (mp->sub_dot1ah)
933 {
934 vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
935 format (0, "%U",
936 format_ethernet_address,
937 &mp->b_dmac));
938 vat_json_object_add_string_copy (node, "pbb_vtr_smac",
939 format (0, "%U",
940 format_ethernet_address,
941 &mp->b_smac));
942 vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
943 vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
944 }
Damjan Marion7cd468a2016-12-19 23:05:39 +0100945}
946
947static void vl_api_sw_interface_set_flags_t_handler
948 (vl_api_sw_interface_set_flags_t * mp)
949{
950 vat_main_t *vam = &vat_main;
951 if (vam->interface_event_display)
952 errmsg ("interface flags: sw_if_index %d %s %s",
953 ntohl (mp->sw_if_index),
954 mp->admin_up_down ? "admin-up" : "admin-down",
955 mp->link_up_down ? "link-up" : "link-down");
956}
957
958static void vl_api_sw_interface_set_flags_t_handler_json
959 (vl_api_sw_interface_set_flags_t * mp)
960{
961 /* JSON output not supported */
962}
963
964static void
965vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
966{
967 vat_main_t *vam = &vat_main;
968 i32 retval = ntohl (mp->retval);
969
970 vam->retval = retval;
971 vam->shmem_result = (u8 *) mp->reply_in_shmem;
972 vam->result_ready = 1;
973}
974
975static void
976vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
977{
978 vat_main_t *vam = &vat_main;
979 vat_json_node_t node;
980 api_main_t *am = &api_main;
981 void *oldheap;
982 u8 *reply;
983
984 vat_json_init_object (&node);
985 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
986 vat_json_object_add_uint (&node, "reply_in_shmem",
987 ntohl (mp->reply_in_shmem));
988 /* Toss the shared-memory original... */
989 pthread_mutex_lock (&am->vlib_rp->mutex);
990 oldheap = svm_push_data_heap (am->vlib_rp);
991
992 reply = (u8 *) (mp->reply_in_shmem);
993 vec_free (reply);
994
995 svm_pop_heap (oldheap);
996 pthread_mutex_unlock (&am->vlib_rp->mutex);
997
998 vat_json_print (vam->ofp, &node);
999 vat_json_free (&node);
1000
1001 vam->retval = ntohl (mp->retval);
1002 vam->result_ready = 1;
1003}
1004
1005static void
1006vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1007{
1008 vat_main_t *vam = &vat_main;
1009 i32 retval = ntohl (mp->retval);
1010
1011 vam->retval = retval;
1012 vam->cmd_reply = mp->reply;
1013 vam->result_ready = 1;
1014}
1015
1016static void
1017vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1018{
1019 vat_main_t *vam = &vat_main;
1020 vat_json_node_t node;
1021
1022 vat_json_init_object (&node);
1023 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1024 vat_json_object_add_string_copy (&node, "reply", mp->reply);
1025
1026 vat_json_print (vam->ofp, &node);
1027 vat_json_free (&node);
1028
1029 vam->retval = ntohl (mp->retval);
1030 vam->result_ready = 1;
1031}
1032
1033static void vl_api_classify_add_del_table_reply_t_handler
1034 (vl_api_classify_add_del_table_reply_t * mp)
1035{
1036 vat_main_t *vam = &vat_main;
1037 i32 retval = ntohl (mp->retval);
1038 if (vam->async_mode)
1039 {
1040 vam->async_errors += (retval < 0);
1041 }
1042 else
1043 {
1044 vam->retval = retval;
1045 if (retval == 0 &&
1046 ((mp->new_table_index != 0xFFFFFFFF) ||
1047 (mp->skip_n_vectors != 0xFFFFFFFF) ||
1048 (mp->match_n_vectors != 0xFFFFFFFF)))
1049 /*
1050 * Note: this is just barely thread-safe, depends on
1051 * the main thread spinning waiting for an answer...
1052 */
1053 errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1054 ntohl (mp->new_table_index),
1055 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1056 vam->result_ready = 1;
1057 }
1058}
1059
1060static void vl_api_classify_add_del_table_reply_t_handler_json
1061 (vl_api_classify_add_del_table_reply_t * mp)
1062{
1063 vat_main_t *vam = &vat_main;
1064 vat_json_node_t node;
1065
1066 vat_json_init_object (&node);
1067 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1068 vat_json_object_add_uint (&node, "new_table_index",
1069 ntohl (mp->new_table_index));
1070 vat_json_object_add_uint (&node, "skip_n_vectors",
1071 ntohl (mp->skip_n_vectors));
1072 vat_json_object_add_uint (&node, "match_n_vectors",
1073 ntohl (mp->match_n_vectors));
1074
1075 vat_json_print (vam->ofp, &node);
1076 vat_json_free (&node);
1077
1078 vam->retval = ntohl (mp->retval);
1079 vam->result_ready = 1;
1080}
1081
1082static void vl_api_get_node_index_reply_t_handler
1083 (vl_api_get_node_index_reply_t * mp)
1084{
1085 vat_main_t *vam = &vat_main;
1086 i32 retval = ntohl (mp->retval);
1087 if (vam->async_mode)
1088 {
1089 vam->async_errors += (retval < 0);
1090 }
1091 else
1092 {
1093 vam->retval = retval;
1094 if (retval == 0)
1095 errmsg ("node index %d", ntohl (mp->node_index));
1096 vam->result_ready = 1;
1097 }
1098}
1099
1100static void vl_api_get_node_index_reply_t_handler_json
1101 (vl_api_get_node_index_reply_t * mp)
1102{
1103 vat_main_t *vam = &vat_main;
1104 vat_json_node_t node;
1105
1106 vat_json_init_object (&node);
1107 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1108 vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1109
1110 vat_json_print (vam->ofp, &node);
1111 vat_json_free (&node);
1112
1113 vam->retval = ntohl (mp->retval);
1114 vam->result_ready = 1;
1115}
1116
1117static void vl_api_get_next_index_reply_t_handler
1118 (vl_api_get_next_index_reply_t * mp)
1119{
1120 vat_main_t *vam = &vat_main;
1121 i32 retval = ntohl (mp->retval);
1122 if (vam->async_mode)
1123 {
1124 vam->async_errors += (retval < 0);
1125 }
1126 else
1127 {
1128 vam->retval = retval;
1129 if (retval == 0)
1130 errmsg ("next node index %d", ntohl (mp->next_index));
1131 vam->result_ready = 1;
1132 }
1133}
1134
1135static void vl_api_get_next_index_reply_t_handler_json
1136 (vl_api_get_next_index_reply_t * mp)
1137{
1138 vat_main_t *vam = &vat_main;
1139 vat_json_node_t node;
1140
1141 vat_json_init_object (&node);
1142 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1143 vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1144
1145 vat_json_print (vam->ofp, &node);
1146 vat_json_free (&node);
1147
1148 vam->retval = ntohl (mp->retval);
1149 vam->result_ready = 1;
1150}
1151
1152static void vl_api_add_node_next_reply_t_handler
1153 (vl_api_add_node_next_reply_t * mp)
1154{
1155 vat_main_t *vam = &vat_main;
1156 i32 retval = ntohl (mp->retval);
1157 if (vam->async_mode)
1158 {
1159 vam->async_errors += (retval < 0);
1160 }
1161 else
1162 {
1163 vam->retval = retval;
1164 if (retval == 0)
1165 errmsg ("next index %d", ntohl (mp->next_index));
1166 vam->result_ready = 1;
1167 }
1168}
1169
1170static void vl_api_add_node_next_reply_t_handler_json
1171 (vl_api_add_node_next_reply_t * mp)
1172{
1173 vat_main_t *vam = &vat_main;
1174 vat_json_node_t node;
1175
1176 vat_json_init_object (&node);
1177 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1178 vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1179
1180 vat_json_print (vam->ofp, &node);
1181 vat_json_free (&node);
1182
1183 vam->retval = ntohl (mp->retval);
1184 vam->result_ready = 1;
1185}
1186
1187static void vl_api_show_version_reply_t_handler
1188 (vl_api_show_version_reply_t * mp)
1189{
1190 vat_main_t *vam = &vat_main;
1191 i32 retval = ntohl (mp->retval);
1192
1193 if (retval >= 0)
1194 {
1195 errmsg (" program: %s", mp->program);
1196 errmsg (" version: %s", mp->version);
1197 errmsg (" build date: %s", mp->build_date);
1198 errmsg ("build directory: %s", mp->build_directory);
1199 }
1200 vam->retval = retval;
1201 vam->result_ready = 1;
1202}
1203
1204static void vl_api_show_version_reply_t_handler_json
1205 (vl_api_show_version_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_string_copy (&node, "program", mp->program);
1213 vat_json_object_add_string_copy (&node, "version", mp->version);
1214 vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1215 vat_json_object_add_string_copy (&node, "build_directory",
1216 mp->build_directory);
1217
1218 vat_json_print (vam->ofp, &node);
1219 vat_json_free (&node);
1220
1221 vam->retval = ntohl (mp->retval);
1222 vam->result_ready = 1;
1223}
1224
1225static void
1226vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1227{
1228 errmsg ("arp %s event: address %U new mac %U sw_if_index %d",
1229 mp->mac_ip ? "mac/ip binding" : "address resolution",
1230 format_ip4_address, &mp->address,
1231 format_ethernet_address, mp->new_mac, mp->sw_if_index);
1232}
1233
1234static void
1235vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1236{
1237 /* JSON output not supported */
1238}
1239
1240static void
1241vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1242{
1243 errmsg ("ip6 nd %s event: address %U new mac %U sw_if_index %d",
1244 mp->mac_ip ? "mac/ip binding" : "address resolution",
1245 format_ip6_address, mp->address,
1246 format_ethernet_address, mp->new_mac, mp->sw_if_index);
1247}
1248
1249static void
1250vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1251{
1252 /* JSON output not supported */
1253}
1254
1255/*
1256 * Special-case: build the bridge domain table, maintain
1257 * the next bd id vbl.
1258 */
1259static void vl_api_bridge_domain_details_t_handler
1260 (vl_api_bridge_domain_details_t * mp)
1261{
1262 vat_main_t *vam = &vat_main;
1263 u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1264
1265 print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1266 " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1267
1268 print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1269 ntohl (mp->bd_id), mp->learn, mp->forward,
1270 mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1271
1272 if (n_sw_ifs)
1273 print (vam->ofp, "\n\n%s %s %s", "sw_if_index", "SHG", "Interface Name");
1274}
1275
1276static void vl_api_bridge_domain_details_t_handler_json
1277 (vl_api_bridge_domain_details_t * mp)
1278{
1279 vat_main_t *vam = &vat_main;
1280 vat_json_node_t *node, *array = NULL;
1281
1282 if (VAT_JSON_ARRAY != vam->json_tree.type)
1283 {
1284 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1285 vat_json_init_array (&vam->json_tree);
1286 }
1287 node = vat_json_array_add (&vam->json_tree);
1288
1289 vat_json_init_object (node);
1290 vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1291 vat_json_object_add_uint (node, "flood", mp->flood);
1292 vat_json_object_add_uint (node, "forward", mp->forward);
1293 vat_json_object_add_uint (node, "learn", mp->learn);
1294 vat_json_object_add_uint (node, "bvi_sw_if_index",
1295 ntohl (mp->bvi_sw_if_index));
1296 vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1297 array = vat_json_object_add (node, "sw_if");
1298 vat_json_init_array (array);
1299}
1300
1301/*
1302 * Special-case: build the bridge domain sw if table.
1303 */
1304static void vl_api_bridge_domain_sw_if_details_t_handler
1305 (vl_api_bridge_domain_sw_if_details_t * mp)
1306{
1307 vat_main_t *vam = &vat_main;
1308 hash_pair_t *p;
1309 u8 *sw_if_name = 0;
1310 u32 sw_if_index;
1311
1312 sw_if_index = ntohl (mp->sw_if_index);
1313 /* *INDENT-OFF* */
1314 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1315 ({
1316 if ((u32) p->value[0] == sw_if_index)
1317 {
1318 sw_if_name = (u8 *)(p->key);
1319 break;
1320 }
1321 }));
1322 /* *INDENT-ON* */
1323
1324 print (vam->ofp, "%7d %3d %s", sw_if_index,
1325 mp->shg, sw_if_name ? (char *) sw_if_name :
1326 "sw_if_index not found!");
1327}
1328
1329static void vl_api_bridge_domain_sw_if_details_t_handler_json
1330 (vl_api_bridge_domain_sw_if_details_t * mp)
1331{
1332 vat_main_t *vam = &vat_main;
1333 vat_json_node_t *node = NULL;
1334 uword last_index = 0;
1335
1336 ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1337 ASSERT (vec_len (vam->json_tree.array) >= 1);
1338 last_index = vec_len (vam->json_tree.array) - 1;
1339 node = &vam->json_tree.array[last_index];
1340 node = vat_json_object_get_element (node, "sw_if");
1341 ASSERT (NULL != node);
1342 node = vat_json_array_add (node);
1343
1344 vat_json_init_object (node);
1345 vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1346 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1347 vat_json_object_add_uint (node, "shg", mp->shg);
1348}
1349
1350static void vl_api_control_ping_reply_t_handler
1351 (vl_api_control_ping_reply_t * mp)
1352{
1353 vat_main_t *vam = &vat_main;
1354 i32 retval = ntohl (mp->retval);
1355 if (vam->async_mode)
1356 {
1357 vam->async_errors += (retval < 0);
1358 }
1359 else
1360 {
1361 vam->retval = retval;
1362 vam->result_ready = 1;
1363 }
1364}
1365
1366static void vl_api_control_ping_reply_t_handler_json
1367 (vl_api_control_ping_reply_t * mp)
1368{
1369 vat_main_t *vam = &vat_main;
1370 i32 retval = ntohl (mp->retval);
1371
1372 if (VAT_JSON_NONE != vam->json_tree.type)
1373 {
1374 vat_json_print (vam->ofp, &vam->json_tree);
1375 vat_json_free (&vam->json_tree);
1376 vam->json_tree.type = VAT_JSON_NONE;
1377 }
1378 else
1379 {
1380 /* just print [] */
1381 vat_json_init_array (&vam->json_tree);
1382 vat_json_print (vam->ofp, &vam->json_tree);
1383 vam->json_tree.type = VAT_JSON_NONE;
1384 }
1385
1386 vam->retval = retval;
1387 vam->result_ready = 1;
1388}
1389
1390static void
1391vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1392{
1393 vat_main_t *vam = &vat_main;
1394 i32 retval = ntohl (mp->retval);
1395 if (vam->async_mode)
1396 {
1397 vam->async_errors += (retval < 0);
1398 }
1399 else
1400 {
1401 vam->retval = retval;
1402 vam->result_ready = 1;
1403 }
1404}
1405
1406static void vl_api_l2_flags_reply_t_handler_json
1407 (vl_api_l2_flags_reply_t * mp)
1408{
1409 vat_main_t *vam = &vat_main;
1410 vat_json_node_t node;
1411
1412 vat_json_init_object (&node);
1413 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1414 vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1415 ntohl (mp->resulting_feature_bitmap));
1416
1417 vat_json_print (vam->ofp, &node);
1418 vat_json_free (&node);
1419
1420 vam->retval = ntohl (mp->retval);
1421 vam->result_ready = 1;
1422}
1423
1424static void vl_api_bridge_flags_reply_t_handler
1425 (vl_api_bridge_flags_reply_t * mp)
1426{
1427 vat_main_t *vam = &vat_main;
1428 i32 retval = ntohl (mp->retval);
1429 if (vam->async_mode)
1430 {
1431 vam->async_errors += (retval < 0);
1432 }
1433 else
1434 {
1435 vam->retval = retval;
1436 vam->result_ready = 1;
1437 }
1438}
1439
1440static void vl_api_bridge_flags_reply_t_handler_json
1441 (vl_api_bridge_flags_reply_t * mp)
1442{
1443 vat_main_t *vam = &vat_main;
1444 vat_json_node_t node;
1445
1446 vat_json_init_object (&node);
1447 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1448 vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1449 ntohl (mp->resulting_feature_bitmap));
1450
1451 vat_json_print (vam->ofp, &node);
1452 vat_json_free (&node);
1453
1454 vam->retval = ntohl (mp->retval);
1455 vam->result_ready = 1;
1456}
1457
1458static void vl_api_tap_connect_reply_t_handler
1459 (vl_api_tap_connect_reply_t * mp)
1460{
1461 vat_main_t *vam = &vat_main;
1462 i32 retval = ntohl (mp->retval);
1463 if (vam->async_mode)
1464 {
1465 vam->async_errors += (retval < 0);
1466 }
1467 else
1468 {
1469 vam->retval = retval;
1470 vam->sw_if_index = ntohl (mp->sw_if_index);
1471 vam->result_ready = 1;
1472 }
1473
1474}
1475
1476static void vl_api_tap_connect_reply_t_handler_json
1477 (vl_api_tap_connect_reply_t * mp)
1478{
1479 vat_main_t *vam = &vat_main;
1480 vat_json_node_t node;
1481
1482 vat_json_init_object (&node);
1483 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1484 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1485
1486 vat_json_print (vam->ofp, &node);
1487 vat_json_free (&node);
1488
1489 vam->retval = ntohl (mp->retval);
1490 vam->result_ready = 1;
1491
1492}
1493
1494static void
1495vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1496{
1497 vat_main_t *vam = &vat_main;
1498 i32 retval = ntohl (mp->retval);
1499 if (vam->async_mode)
1500 {
1501 vam->async_errors += (retval < 0);
1502 }
1503 else
1504 {
1505 vam->retval = retval;
1506 vam->sw_if_index = ntohl (mp->sw_if_index);
1507 vam->result_ready = 1;
1508 }
1509}
1510
1511static void vl_api_tap_modify_reply_t_handler_json
1512 (vl_api_tap_modify_reply_t * mp)
1513{
1514 vat_main_t *vam = &vat_main;
1515 vat_json_node_t node;
1516
1517 vat_json_init_object (&node);
1518 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1519 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1520
1521 vat_json_print (vam->ofp, &node);
1522 vat_json_free (&node);
1523
1524 vam->retval = ntohl (mp->retval);
1525 vam->result_ready = 1;
1526}
1527
1528static void
1529vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1530{
1531 vat_main_t *vam = &vat_main;
1532 i32 retval = ntohl (mp->retval);
1533 if (vam->async_mode)
1534 {
1535 vam->async_errors += (retval < 0);
1536 }
1537 else
1538 {
1539 vam->retval = retval;
1540 vam->result_ready = 1;
1541 }
1542}
1543
1544static void vl_api_tap_delete_reply_t_handler_json
1545 (vl_api_tap_delete_reply_t * mp)
1546{
1547 vat_main_t *vam = &vat_main;
1548 vat_json_node_t node;
1549
1550 vat_json_init_object (&node);
1551 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1552
1553 vat_json_print (vam->ofp, &node);
1554 vat_json_free (&node);
1555
1556 vam->retval = ntohl (mp->retval);
1557 vam->result_ready = 1;
1558}
1559
1560static void vl_api_mpls_tunnel_add_del_reply_t_handler
1561 (vl_api_mpls_tunnel_add_del_reply_t * mp)
1562{
1563 vat_main_t *vam = &vat_main;
1564 i32 retval = ntohl (mp->retval);
1565 if (vam->async_mode)
1566 {
1567 vam->async_errors += (retval < 0);
1568 }
1569 else
1570 {
1571 vam->retval = retval;
1572 vam->result_ready = 1;
1573 }
1574}
1575
1576static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1577 (vl_api_mpls_tunnel_add_del_reply_t * mp)
1578{
1579 vat_main_t *vam = &vat_main;
1580 vat_json_node_t node;
1581
1582 vat_json_init_object (&node);
1583 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1584 vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1585 ntohl (mp->sw_if_index));
1586
1587 vat_json_print (vam->ofp, &node);
1588 vat_json_free (&node);
1589
1590 vam->retval = ntohl (mp->retval);
1591 vam->result_ready = 1;
1592}
1593
1594static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1595 (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1596{
1597 vat_main_t *vam = &vat_main;
1598 i32 retval = ntohl (mp->retval);
1599 if (vam->async_mode)
1600 {
1601 vam->async_errors += (retval < 0);
1602 }
1603 else
1604 {
1605 vam->retval = retval;
1606 vam->sw_if_index = ntohl (mp->sw_if_index);
1607 vam->result_ready = 1;
1608 }
1609}
1610
1611static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1612 (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1613{
1614 vat_main_t *vam = &vat_main;
1615 vat_json_node_t node;
1616
1617 vat_json_init_object (&node);
1618 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1619 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1620
1621 vat_json_print (vam->ofp, &node);
1622 vat_json_free (&node);
1623
1624 vam->retval = ntohl (mp->retval);
1625 vam->result_ready = 1;
1626}
1627
1628
Filip Tehlar694396d2017-02-17 14:29:11 +01001629static void vl_api_one_add_del_locator_set_reply_t_handler
1630 (vl_api_one_add_del_locator_set_reply_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01001631{
1632 vat_main_t *vam = &vat_main;
1633 i32 retval = ntohl (mp->retval);
1634 if (vam->async_mode)
1635 {
1636 vam->async_errors += (retval < 0);
1637 }
1638 else
1639 {
1640 vam->retval = retval;
1641 vam->result_ready = 1;
1642 }
1643}
1644
Filip Tehlar694396d2017-02-17 14:29:11 +01001645static void vl_api_one_add_del_locator_set_reply_t_handler_json
1646 (vl_api_one_add_del_locator_set_reply_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01001647{
1648 vat_main_t *vam = &vat_main;
1649 vat_json_node_t node;
1650
1651 vat_json_init_object (&node);
1652 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1653 vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1654
1655 vat_json_print (vam->ofp, &node);
1656 vat_json_free (&node);
1657
1658 vam->retval = ntohl (mp->retval);
1659 vam->result_ready = 1;
1660}
1661
1662static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1663 (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1664{
1665 vat_main_t *vam = &vat_main;
1666 i32 retval = ntohl (mp->retval);
1667 if (vam->async_mode)
1668 {
1669 vam->async_errors += (retval < 0);
1670 }
1671 else
1672 {
1673 vam->retval = retval;
1674 vam->sw_if_index = ntohl (mp->sw_if_index);
1675 vam->result_ready = 1;
1676 }
1677}
1678
1679static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1680 (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1681{
1682 vat_main_t *vam = &vat_main;
1683 vat_json_node_t node;
1684
1685 vat_json_init_object (&node);
1686 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1687 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1688
1689 vat_json_print (vam->ofp, &node);
1690 vat_json_free (&node);
1691
1692 vam->retval = ntohl (mp->retval);
1693 vam->result_ready = 1;
1694}
1695
1696static void vl_api_gre_add_del_tunnel_reply_t_handler
1697 (vl_api_gre_add_del_tunnel_reply_t * mp)
1698{
1699 vat_main_t *vam = &vat_main;
1700 i32 retval = ntohl (mp->retval);
1701 if (vam->async_mode)
1702 {
1703 vam->async_errors += (retval < 0);
1704 }
1705 else
1706 {
1707 vam->retval = retval;
1708 vam->sw_if_index = ntohl (mp->sw_if_index);
1709 vam->result_ready = 1;
1710 }
1711}
1712
1713static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1714 (vl_api_gre_add_del_tunnel_reply_t * mp)
1715{
1716 vat_main_t *vam = &vat_main;
1717 vat_json_node_t node;
1718
1719 vat_json_init_object (&node);
1720 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1721 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1722
1723 vat_json_print (vam->ofp, &node);
1724 vat_json_free (&node);
1725
1726 vam->retval = ntohl (mp->retval);
1727 vam->result_ready = 1;
1728}
1729
1730static void vl_api_create_vhost_user_if_reply_t_handler
1731 (vl_api_create_vhost_user_if_reply_t * mp)
1732{
1733 vat_main_t *vam = &vat_main;
1734 i32 retval = ntohl (mp->retval);
1735 if (vam->async_mode)
1736 {
1737 vam->async_errors += (retval < 0);
1738 }
1739 else
1740 {
1741 vam->retval = retval;
1742 vam->sw_if_index = ntohl (mp->sw_if_index);
1743 vam->result_ready = 1;
1744 }
1745}
1746
1747static void vl_api_create_vhost_user_if_reply_t_handler_json
1748 (vl_api_create_vhost_user_if_reply_t * mp)
1749{
1750 vat_main_t *vam = &vat_main;
1751 vat_json_node_t node;
1752
1753 vat_json_init_object (&node);
1754 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1755 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1756
1757 vat_json_print (vam->ofp, &node);
1758 vat_json_free (&node);
1759
1760 vam->retval = ntohl (mp->retval);
1761 vam->result_ready = 1;
1762}
1763
1764static void vl_api_ip_address_details_t_handler
1765 (vl_api_ip_address_details_t * mp)
1766{
1767 vat_main_t *vam = &vat_main;
1768 static ip_address_details_t empty_ip_address_details = { {0} };
1769 ip_address_details_t *address = NULL;
1770 ip_details_t *current_ip_details = NULL;
1771 ip_details_t *details = NULL;
1772
1773 details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1774
1775 if (!details || vam->current_sw_if_index >= vec_len (details)
1776 || !details[vam->current_sw_if_index].present)
1777 {
1778 errmsg ("ip address details arrived but not stored");
1779 errmsg ("ip_dump should be called first");
1780 return;
1781 }
1782
1783 current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1784
1785#define addresses (current_ip_details->addr)
1786
1787 vec_validate_init_empty (addresses, vec_len (addresses),
1788 empty_ip_address_details);
1789
1790 address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1791
1792 clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1793 address->prefix_length = mp->prefix_length;
1794#undef addresses
1795}
1796
1797static void vl_api_ip_address_details_t_handler_json
1798 (vl_api_ip_address_details_t * mp)
1799{
1800 vat_main_t *vam = &vat_main;
1801 vat_json_node_t *node = NULL;
1802 struct in6_addr ip6;
1803 struct in_addr ip4;
1804
1805 if (VAT_JSON_ARRAY != vam->json_tree.type)
1806 {
1807 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1808 vat_json_init_array (&vam->json_tree);
1809 }
1810 node = vat_json_array_add (&vam->json_tree);
1811
1812 vat_json_init_object (node);
1813 if (vam->is_ipv6)
1814 {
1815 clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1816 vat_json_object_add_ip6 (node, "ip", ip6);
1817 }
1818 else
1819 {
1820 clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1821 vat_json_object_add_ip4 (node, "ip", ip4);
1822 }
1823 vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1824}
1825
1826static void
1827vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1828{
1829 vat_main_t *vam = &vat_main;
1830 static ip_details_t empty_ip_details = { 0 };
1831 ip_details_t *ip = NULL;
1832 u32 sw_if_index = ~0;
1833
1834 sw_if_index = ntohl (mp->sw_if_index);
1835
1836 vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1837 sw_if_index, empty_ip_details);
1838
1839 ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1840 sw_if_index);
1841
1842 ip->present = 1;
1843}
1844
1845static void
1846vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1847{
1848 vat_main_t *vam = &vat_main;
1849
1850 if (VAT_JSON_ARRAY != vam->json_tree.type)
1851 {
1852 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1853 vat_json_init_array (&vam->json_tree);
1854 }
1855 vat_json_array_add_uint (&vam->json_tree,
1856 clib_net_to_host_u32 (mp->sw_if_index));
1857}
1858
1859static void vl_api_map_domain_details_t_handler_json
1860 (vl_api_map_domain_details_t * mp)
1861{
1862 vat_json_node_t *node = NULL;
1863 vat_main_t *vam = &vat_main;
1864 struct in6_addr ip6;
1865 struct in_addr ip4;
1866
1867 if (VAT_JSON_ARRAY != vam->json_tree.type)
1868 {
1869 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1870 vat_json_init_array (&vam->json_tree);
1871 }
1872
1873 node = vat_json_array_add (&vam->json_tree);
1874 vat_json_init_object (node);
1875
1876 vat_json_object_add_uint (node, "domain_index",
1877 clib_net_to_host_u32 (mp->domain_index));
1878 clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1879 vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1880 clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1881 vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1882 clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1883 vat_json_object_add_ip6 (node, "ip6_src", ip6);
1884 vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1885 vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1886 vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1887 vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1888 vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1889 vat_json_object_add_int (node, "psid_length", mp->psid_length);
1890 vat_json_object_add_uint (node, "flags", mp->flags);
1891 vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1892 vat_json_object_add_int (node, "is_translation", mp->is_translation);
1893}
1894
1895static void vl_api_map_domain_details_t_handler
1896 (vl_api_map_domain_details_t * mp)
1897{
1898 vat_main_t *vam = &vat_main;
1899
1900 if (mp->is_translation)
1901 {
1902 print (vam->ofp,
1903 "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
1904 format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1905 format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1906 format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1907 clib_net_to_host_u32 (mp->domain_index));
1908 }
1909 else
1910 {
1911 print (vam->ofp,
1912 "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
1913 format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1914 format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1915 format_ip6_address, mp->ip6_src,
1916 clib_net_to_host_u32 (mp->domain_index));
1917 }
1918 print (vam->ofp, " ea-len %d psid-offset %d psid-len %d mtu %d %s",
1919 mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1920 mp->is_translation ? "map-t" : "");
1921}
1922
1923static void vl_api_map_rule_details_t_handler_json
1924 (vl_api_map_rule_details_t * mp)
1925{
1926 struct in6_addr ip6;
1927 vat_json_node_t *node = NULL;
1928 vat_main_t *vam = &vat_main;
1929
1930 if (VAT_JSON_ARRAY != vam->json_tree.type)
1931 {
1932 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1933 vat_json_init_array (&vam->json_tree);
1934 }
1935
1936 node = vat_json_array_add (&vam->json_tree);
1937 vat_json_init_object (node);
1938
1939 vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1940 clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1941 vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1942}
1943
1944static void
1945vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1946{
1947 vat_main_t *vam = &vat_main;
1948 print (vam->ofp, " %d (psid) %U (ip6-dst)",
1949 clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1950}
1951
1952static void
1953vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1954{
1955 errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1956 "router_addr %U host_mac %U",
1957 mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1958 format_ip4_address, &mp->host_address,
1959 format_ip4_address, &mp->router_address,
1960 format_ethernet_address, mp->host_mac);
1961}
1962
1963static void vl_api_dhcp_compl_event_t_handler_json
1964 (vl_api_dhcp_compl_event_t * mp)
1965{
1966 /* JSON output not supported */
1967}
1968
1969static void
1970set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1971 u32 counter)
1972{
1973 vat_main_t *vam = &vat_main;
1974 static u64 default_counter = 0;
1975
1976 vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
1977 NULL);
1978 vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
1979 sw_if_index, default_counter);
1980 vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1981}
1982
1983static void
1984set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1985 interface_counter_t counter)
1986{
1987 vat_main_t *vam = &vat_main;
1988 static interface_counter_t default_counter = { 0, };
1989
1990 vec_validate_init_empty (vam->combined_interface_counters,
1991 vnet_counter_type, NULL);
1992 vec_validate_init_empty (vam->combined_interface_counters
1993 [vnet_counter_type], sw_if_index, default_counter);
1994 vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1995}
1996
1997static void vl_api_vnet_interface_counters_t_handler
1998 (vl_api_vnet_interface_counters_t * mp)
1999{
2000 /* not supported */
2001}
2002
2003static void vl_api_vnet_interface_counters_t_handler_json
2004 (vl_api_vnet_interface_counters_t * mp)
2005{
2006 interface_counter_t counter;
2007 vlib_counter_t *v;
2008 u64 *v_packets;
2009 u64 packets;
2010 u32 count;
2011 u32 first_sw_if_index;
2012 int i;
2013
2014 count = ntohl (mp->count);
2015 first_sw_if_index = ntohl (mp->first_sw_if_index);
2016
2017 if (!mp->is_combined)
2018 {
2019 v_packets = (u64 *) & mp->data;
2020 for (i = 0; i < count; i++)
2021 {
2022 packets =
2023 clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2024 set_simple_interface_counter (mp->vnet_counter_type,
2025 first_sw_if_index + i, packets);
2026 v_packets++;
2027 }
2028 }
2029 else
2030 {
2031 v = (vlib_counter_t *) & mp->data;
2032 for (i = 0; i < count; i++)
2033 {
2034 counter.packets =
2035 clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2036 counter.bytes =
2037 clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2038 set_combined_interface_counter (mp->vnet_counter_type,
2039 first_sw_if_index + i, counter);
2040 v++;
2041 }
2042 }
2043}
2044
2045static u32
2046ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2047{
2048 vat_main_t *vam = &vat_main;
2049 u32 i;
2050
2051 for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2052 {
2053 if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2054 {
2055 return i;
2056 }
2057 }
2058 return ~0;
2059}
2060
2061static u32
2062ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2063{
2064 vat_main_t *vam = &vat_main;
2065 u32 i;
2066
2067 for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2068 {
2069 if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2070 {
2071 return i;
2072 }
2073 }
2074 return ~0;
2075}
2076
2077static void vl_api_vnet_ip4_fib_counters_t_handler
2078 (vl_api_vnet_ip4_fib_counters_t * mp)
2079{
2080 /* not supported */
2081}
2082
2083static void vl_api_vnet_ip4_fib_counters_t_handler_json
2084 (vl_api_vnet_ip4_fib_counters_t * mp)
2085{
2086 vat_main_t *vam = &vat_main;
2087 vl_api_ip4_fib_counter_t *v;
2088 ip4_fib_counter_t *counter;
2089 struct in_addr ip4;
2090 u32 vrf_id;
2091 u32 vrf_index;
2092 u32 count;
2093 int i;
2094
2095 vrf_id = ntohl (mp->vrf_id);
2096 vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2097 if (~0 == vrf_index)
2098 {
2099 vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2100 vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2101 vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2102 vec_validate (vam->ip4_fib_counters, vrf_index);
2103 vam->ip4_fib_counters[vrf_index] = NULL;
2104 }
2105
2106 vec_free (vam->ip4_fib_counters[vrf_index]);
2107 v = (vl_api_ip4_fib_counter_t *) & mp->c;
2108 count = ntohl (mp->count);
2109 for (i = 0; i < count; i++)
2110 {
2111 vec_validate (vam->ip4_fib_counters[vrf_index], i);
2112 counter = &vam->ip4_fib_counters[vrf_index][i];
2113 clib_memcpy (&ip4, &v->address, sizeof (ip4));
2114 counter->address = ip4;
2115 counter->address_length = v->address_length;
2116 counter->packets = clib_net_to_host_u64 (v->packets);
2117 counter->bytes = clib_net_to_host_u64 (v->bytes);
2118 v++;
2119 }
2120}
2121
Neale Ranns044183f2017-01-24 01:34:25 -08002122static void vl_api_vnet_ip4_nbr_counters_t_handler
2123 (vl_api_vnet_ip4_nbr_counters_t * mp)
2124{
2125 /* not supported */
2126}
2127
2128static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2129 (vl_api_vnet_ip4_nbr_counters_t * mp)
2130{
2131 vat_main_t *vam = &vat_main;
2132 vl_api_ip4_nbr_counter_t *v;
2133 ip4_nbr_counter_t *counter;
2134 u32 sw_if_index;
2135 u32 count;
2136 int i;
2137
2138 sw_if_index = ntohl (mp->sw_if_index);
2139 count = ntohl (mp->count);
2140 vec_validate (vam->ip4_nbr_counters, sw_if_index);
2141
2142 if (mp->begin)
2143 vec_free (vam->ip4_nbr_counters[sw_if_index]);
2144
2145 v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2146 for (i = 0; i < count; i++)
2147 {
2148 vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2149 counter = &vam->ip4_nbr_counters[sw_if_index][i];
2150 counter->address.s_addr = v->address;
2151 counter->packets = clib_net_to_host_u64 (v->packets);
2152 counter->bytes = clib_net_to_host_u64 (v->bytes);
2153 counter->linkt = v->link_type;
2154 v++;
2155 }
2156}
2157
Damjan Marion7cd468a2016-12-19 23:05:39 +01002158static void vl_api_vnet_ip6_fib_counters_t_handler
2159 (vl_api_vnet_ip6_fib_counters_t * mp)
2160{
2161 /* not supported */
2162}
2163
2164static void vl_api_vnet_ip6_fib_counters_t_handler_json
2165 (vl_api_vnet_ip6_fib_counters_t * mp)
2166{
2167 vat_main_t *vam = &vat_main;
2168 vl_api_ip6_fib_counter_t *v;
2169 ip6_fib_counter_t *counter;
2170 struct in6_addr ip6;
2171 u32 vrf_id;
2172 u32 vrf_index;
2173 u32 count;
2174 int i;
2175
2176 vrf_id = ntohl (mp->vrf_id);
2177 vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2178 if (~0 == vrf_index)
2179 {
2180 vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2181 vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2182 vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2183 vec_validate (vam->ip6_fib_counters, vrf_index);
2184 vam->ip6_fib_counters[vrf_index] = NULL;
2185 }
2186
2187 vec_free (vam->ip6_fib_counters[vrf_index]);
2188 v = (vl_api_ip6_fib_counter_t *) & mp->c;
2189 count = ntohl (mp->count);
2190 for (i = 0; i < count; i++)
2191 {
2192 vec_validate (vam->ip6_fib_counters[vrf_index], i);
2193 counter = &vam->ip6_fib_counters[vrf_index][i];
2194 clib_memcpy (&ip6, &v->address, sizeof (ip6));
2195 counter->address = ip6;
2196 counter->address_length = v->address_length;
2197 counter->packets = clib_net_to_host_u64 (v->packets);
2198 counter->bytes = clib_net_to_host_u64 (v->bytes);
2199 v++;
2200 }
2201}
2202
Neale Ranns044183f2017-01-24 01:34:25 -08002203static void vl_api_vnet_ip6_nbr_counters_t_handler
2204 (vl_api_vnet_ip6_nbr_counters_t * mp)
2205{
2206 /* not supported */
2207}
2208
2209static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2210 (vl_api_vnet_ip6_nbr_counters_t * mp)
2211{
2212 vat_main_t *vam = &vat_main;
2213 vl_api_ip6_nbr_counter_t *v;
2214 ip6_nbr_counter_t *counter;
2215 struct in6_addr ip6;
2216 u32 sw_if_index;
2217 u32 count;
2218 int i;
2219
2220 sw_if_index = ntohl (mp->sw_if_index);
2221 count = ntohl (mp->count);
2222 vec_validate (vam->ip6_nbr_counters, sw_if_index);
2223
2224 if (mp->begin)
2225 vec_free (vam->ip6_nbr_counters[sw_if_index]);
2226
2227 v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2228 for (i = 0; i < count; i++)
2229 {
2230 vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2231 counter = &vam->ip6_nbr_counters[sw_if_index][i];
2232 clib_memcpy (&ip6, &v->address, sizeof (ip6));
2233 counter->address = ip6;
2234 counter->packets = clib_net_to_host_u64 (v->packets);
2235 counter->bytes = clib_net_to_host_u64 (v->bytes);
2236 v++;
2237 }
2238}
2239
Damjan Marion7cd468a2016-12-19 23:05:39 +01002240static void vl_api_get_first_msg_id_reply_t_handler
2241 (vl_api_get_first_msg_id_reply_t * mp)
2242{
2243 vat_main_t *vam = &vat_main;
2244 i32 retval = ntohl (mp->retval);
2245
2246 if (vam->async_mode)
2247 {
2248 vam->async_errors += (retval < 0);
2249 }
2250 else
2251 {
2252 vam->retval = retval;
2253 vam->result_ready = 1;
2254 }
2255 if (retval >= 0)
2256 {
2257 errmsg ("first message id %d", ntohs (mp->first_msg_id));
2258 }
2259}
2260
2261static void vl_api_get_first_msg_id_reply_t_handler_json
2262 (vl_api_get_first_msg_id_reply_t * mp)
2263{
2264 vat_main_t *vam = &vat_main;
2265 vat_json_node_t node;
2266
2267 vat_json_init_object (&node);
2268 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2269 vat_json_object_add_uint (&node, "first_msg_id",
2270 (uint) ntohs (mp->first_msg_id));
2271
2272 vat_json_print (vam->ofp, &node);
2273 vat_json_free (&node);
2274
2275 vam->retval = ntohl (mp->retval);
2276 vam->result_ready = 1;
2277}
2278
2279static void vl_api_get_node_graph_reply_t_handler
2280 (vl_api_get_node_graph_reply_t * mp)
2281{
2282 vat_main_t *vam = &vat_main;
2283 api_main_t *am = &api_main;
2284 i32 retval = ntohl (mp->retval);
2285 u8 *pvt_copy, *reply;
2286 void *oldheap;
2287 vlib_node_t *node;
2288 int i;
2289
2290 if (vam->async_mode)
2291 {
2292 vam->async_errors += (retval < 0);
2293 }
2294 else
2295 {
2296 vam->retval = retval;
2297 vam->result_ready = 1;
2298 }
2299
2300 /* "Should never happen..." */
2301 if (retval != 0)
2302 return;
2303
2304 reply = (u8 *) (mp->reply_in_shmem);
2305 pvt_copy = vec_dup (reply);
2306
2307 /* Toss the shared-memory original... */
2308 pthread_mutex_lock (&am->vlib_rp->mutex);
2309 oldheap = svm_push_data_heap (am->vlib_rp);
2310
2311 vec_free (reply);
2312
2313 svm_pop_heap (oldheap);
2314 pthread_mutex_unlock (&am->vlib_rp->mutex);
2315
2316 if (vam->graph_nodes)
2317 {
2318 hash_free (vam->graph_node_index_by_name);
2319
2320 for (i = 0; i < vec_len (vam->graph_nodes); i++)
2321 {
2322 node = vam->graph_nodes[i];
2323 vec_free (node->name);
2324 vec_free (node->next_nodes);
2325 vec_free (node);
2326 }
2327 vec_free (vam->graph_nodes);
2328 }
2329
2330 vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2331 vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2332 vec_free (pvt_copy);
2333
2334 for (i = 0; i < vec_len (vam->graph_nodes); i++)
2335 {
2336 node = vam->graph_nodes[i];
2337 hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2338 }
2339}
2340
2341static void vl_api_get_node_graph_reply_t_handler_json
2342 (vl_api_get_node_graph_reply_t * mp)
2343{
2344 vat_main_t *vam = &vat_main;
2345 api_main_t *am = &api_main;
2346 void *oldheap;
2347 vat_json_node_t node;
2348 u8 *reply;
2349
2350 /* $$$$ make this real? */
2351 vat_json_init_object (&node);
2352 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2353 vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2354
2355 reply = (u8 *) (mp->reply_in_shmem);
2356
2357 /* Toss the shared-memory original... */
2358 pthread_mutex_lock (&am->vlib_rp->mutex);
2359 oldheap = svm_push_data_heap (am->vlib_rp);
2360
2361 vec_free (reply);
2362
2363 svm_pop_heap (oldheap);
2364 pthread_mutex_unlock (&am->vlib_rp->mutex);
2365
2366 vat_json_print (vam->ofp, &node);
2367 vat_json_free (&node);
2368
2369 vam->retval = ntohl (mp->retval);
2370 vam->result_ready = 1;
2371}
2372
2373static void
Filip Tehlar694396d2017-02-17 14:29:11 +01002374vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002375{
2376 vat_main_t *vam = &vat_main;
2377 u8 *s = 0;
2378
2379 if (mp->local)
2380 {
2381 s = format (s, "%=16d%=16d%=16d",
2382 ntohl (mp->sw_if_index), mp->priority, mp->weight);
2383 }
2384 else
2385 {
2386 s = format (s, "%=16U%=16d%=16d",
2387 mp->is_ipv6 ? format_ip6_address :
2388 format_ip4_address,
2389 mp->ip_address, mp->priority, mp->weight);
2390 }
2391
2392 print (vam->ofp, "%v", s);
2393 vec_free (s);
2394}
2395
2396static void
Filip Tehlar694396d2017-02-17 14:29:11 +01002397vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002398{
2399 vat_main_t *vam = &vat_main;
2400 vat_json_node_t *node = NULL;
2401 struct in6_addr ip6;
2402 struct in_addr ip4;
2403
2404 if (VAT_JSON_ARRAY != vam->json_tree.type)
2405 {
2406 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2407 vat_json_init_array (&vam->json_tree);
2408 }
2409 node = vat_json_array_add (&vam->json_tree);
2410 vat_json_init_object (node);
2411
2412 vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2413 vat_json_object_add_uint (node, "priority", mp->priority);
2414 vat_json_object_add_uint (node, "weight", mp->weight);
2415
2416 if (mp->local)
2417 vat_json_object_add_uint (node, "sw_if_index",
2418 clib_net_to_host_u32 (mp->sw_if_index));
2419 else
2420 {
2421 if (mp->is_ipv6)
2422 {
2423 clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2424 vat_json_object_add_ip6 (node, "address", ip6);
2425 }
2426 else
2427 {
2428 clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2429 vat_json_object_add_ip4 (node, "address", ip4);
2430 }
2431 }
2432}
2433
2434static void
Filip Tehlar694396d2017-02-17 14:29:11 +01002435vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2436 mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002437{
2438 vat_main_t *vam = &vat_main;
2439 u8 *ls_name = 0;
2440
2441 ls_name = format (0, "%s", mp->ls_name);
2442
2443 print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2444 ls_name);
2445 vec_free (ls_name);
2446}
2447
2448static void
Filip Tehlar694396d2017-02-17 14:29:11 +01002449 vl_api_one_locator_set_details_t_handler_json
2450 (vl_api_one_locator_set_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002451{
2452 vat_main_t *vam = &vat_main;
2453 vat_json_node_t *node = 0;
2454 u8 *ls_name = 0;
2455
2456 ls_name = format (0, "%s", mp->ls_name);
2457 vec_add1 (ls_name, 0);
2458
2459 if (VAT_JSON_ARRAY != vam->json_tree.type)
2460 {
2461 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2462 vat_json_init_array (&vam->json_tree);
2463 }
2464 node = vat_json_array_add (&vam->json_tree);
2465
2466 vat_json_init_object (node);
2467 vat_json_object_add_string_copy (node, "ls_name", ls_name);
2468 vat_json_object_add_uint (node, "ls_index",
2469 clib_net_to_host_u32 (mp->ls_index));
2470 vec_free (ls_name);
2471}
2472
2473static u8 *
2474format_lisp_flat_eid (u8 * s, va_list * args)
2475{
2476 u32 type = va_arg (*args, u32);
2477 u8 *eid = va_arg (*args, u8 *);
2478 u32 eid_len = va_arg (*args, u32);
2479
2480 switch (type)
2481 {
2482 case 0:
2483 return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2484 case 1:
2485 return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2486 case 2:
2487 return format (s, "%U", format_ethernet_address, eid);
2488 }
2489 return 0;
2490}
2491
2492static u8 *
2493format_lisp_eid_vat (u8 * s, va_list * args)
2494{
2495 u32 type = va_arg (*args, u32);
2496 u8 *eid = va_arg (*args, u8 *);
2497 u32 eid_len = va_arg (*args, u32);
2498 u8 *seid = va_arg (*args, u8 *);
2499 u32 seid_len = va_arg (*args, u32);
2500 u32 is_src_dst = va_arg (*args, u32);
2501
2502 if (is_src_dst)
2503 s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2504
2505 s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2506
2507 return s;
2508}
2509
2510static void
Filip Tehlar694396d2017-02-17 14:29:11 +01002511vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002512{
2513 vat_main_t *vam = &vat_main;
2514 u8 *s = 0, *eid = 0;
2515
2516 if (~0 == mp->locator_set_index)
2517 s = format (0, "action: %d", mp->action);
2518 else
2519 s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2520
2521 eid = format (0, "%U", format_lisp_eid_vat,
2522 mp->eid_type,
2523 mp->eid,
2524 mp->eid_prefix_len,
2525 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2526 vec_add1 (eid, 0);
2527
2528 print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2529 clib_net_to_host_u32 (mp->vni),
2530 eid,
2531 mp->is_local ? "local" : "remote",
2532 s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2533 clib_net_to_host_u16 (mp->key_id), mp->key);
2534
2535 vec_free (s);
2536 vec_free (eid);
2537}
2538
2539static void
Filip Tehlar694396d2017-02-17 14:29:11 +01002540vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
2541 * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002542{
2543 vat_main_t *vam = &vat_main;
2544 vat_json_node_t *node = 0;
2545 u8 *eid = 0;
2546
2547 if (VAT_JSON_ARRAY != vam->json_tree.type)
2548 {
2549 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2550 vat_json_init_array (&vam->json_tree);
2551 }
2552 node = vat_json_array_add (&vam->json_tree);
2553
2554 vat_json_init_object (node);
2555 if (~0 == mp->locator_set_index)
2556 vat_json_object_add_uint (node, "action", mp->action);
2557 else
2558 vat_json_object_add_uint (node, "locator_set_index",
2559 clib_net_to_host_u32 (mp->locator_set_index));
2560
2561 vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2562 eid = format (0, "%U", format_lisp_eid_vat,
2563 mp->eid_type,
2564 mp->eid,
2565 mp->eid_prefix_len,
2566 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2567 vec_add1 (eid, 0);
2568 vat_json_object_add_string_copy (node, "eid", eid);
2569 vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2570 vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2571 vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2572
2573 if (mp->key_id)
2574 {
2575 vat_json_object_add_uint (node, "key_id",
2576 clib_net_to_host_u16 (mp->key_id));
2577 vat_json_object_add_string_copy (node, "key", mp->key);
2578 }
2579 vec_free (eid);
2580}
2581
2582static void
Filip Tehlar694396d2017-02-17 14:29:11 +01002583 vl_api_one_eid_table_map_details_t_handler
2584 (vl_api_one_eid_table_map_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002585{
2586 vat_main_t *vam = &vat_main;
2587
2588 u8 *line = format (0, "%=10d%=10d",
2589 clib_net_to_host_u32 (mp->vni),
2590 clib_net_to_host_u32 (mp->dp_table));
2591 print (vam->ofp, "%v", line);
2592 vec_free (line);
2593}
2594
2595static void
Filip Tehlar694396d2017-02-17 14:29:11 +01002596 vl_api_one_eid_table_map_details_t_handler_json
2597 (vl_api_one_eid_table_map_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002598{
2599 vat_main_t *vam = &vat_main;
2600 vat_json_node_t *node = NULL;
2601
2602 if (VAT_JSON_ARRAY != vam->json_tree.type)
2603 {
2604 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2605 vat_json_init_array (&vam->json_tree);
2606 }
2607 node = vat_json_array_add (&vam->json_tree);
2608 vat_json_init_object (node);
2609 vat_json_object_add_uint (node, "dp_table",
2610 clib_net_to_host_u32 (mp->dp_table));
2611 vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2612}
2613
2614static void
Filip Tehlar694396d2017-02-17 14:29:11 +01002615 vl_api_one_eid_table_vni_details_t_handler
2616 (vl_api_one_eid_table_vni_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002617{
2618 vat_main_t *vam = &vat_main;
2619
2620 u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2621 print (vam->ofp, "%v", line);
2622 vec_free (line);
2623}
2624
2625static void
Filip Tehlar694396d2017-02-17 14:29:11 +01002626 vl_api_one_eid_table_vni_details_t_handler_json
2627 (vl_api_one_eid_table_vni_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002628{
2629 vat_main_t *vam = &vat_main;
2630 vat_json_node_t *node = NULL;
2631
2632 if (VAT_JSON_ARRAY != vam->json_tree.type)
2633 {
2634 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2635 vat_json_init_array (&vam->json_tree);
2636 }
2637 node = vat_json_array_add (&vam->json_tree);
2638 vat_json_init_object (node);
2639 vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2640}
2641
Damjan Marion7cd468a2016-12-19 23:05:39 +01002642static void
Filip Tehlar694396d2017-02-17 14:29:11 +01002643 vl_api_show_one_map_register_state_reply_t_handler
2644 (vl_api_show_one_map_register_state_reply_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002645{
2646 vat_main_t *vam = &vat_main;
2647 int retval = clib_net_to_host_u32 (mp->retval);
2648
2649 print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2650
2651 vam->retval = retval;
2652 vam->result_ready = 1;
2653}
2654
2655static void
Filip Tehlar694396d2017-02-17 14:29:11 +01002656 vl_api_show_one_map_register_state_reply_t_handler_json
2657 (vl_api_show_one_map_register_state_reply_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002658{
2659 vat_main_t *vam = &vat_main;
2660 vat_json_node_t _node, *node = &_node;
2661 int retval = clib_net_to_host_u32 (mp->retval);
2662
2663 u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2664
2665 vat_json_init_object (node);
2666 vat_json_object_add_string_copy (node, "state", s);
2667
2668 vat_json_print (vam->ofp, node);
2669 vat_json_free (node);
2670
2671 vam->retval = retval;
2672 vam->result_ready = 1;
2673 vec_free (s);
2674}
2675
2676static void
Filip Tehlar694396d2017-02-17 14:29:11 +01002677 vl_api_show_one_rloc_probe_state_reply_t_handler
2678 (vl_api_show_one_rloc_probe_state_reply_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002679{
2680 vat_main_t *vam = &vat_main;
2681 int retval = clib_net_to_host_u32 (mp->retval);
2682
2683 if (retval)
2684 goto end;
2685
2686 print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2687end:
2688 vam->retval = retval;
2689 vam->result_ready = 1;
2690}
2691
2692static void
Filip Tehlar694396d2017-02-17 14:29:11 +01002693 vl_api_show_one_rloc_probe_state_reply_t_handler_json
2694 (vl_api_show_one_rloc_probe_state_reply_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002695{
2696 vat_main_t *vam = &vat_main;
2697 vat_json_node_t _node, *node = &_node;
2698 int retval = clib_net_to_host_u32 (mp->retval);
2699
2700 u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2701 vat_json_init_object (node);
2702 vat_json_object_add_string_copy (node, "state", s);
2703
2704 vat_json_print (vam->ofp, node);
2705 vat_json_free (node);
2706
2707 vam->retval = retval;
2708 vam->result_ready = 1;
2709 vec_free (s);
2710}
2711
2712static void
Filip Tehlar82786c42017-02-20 15:20:37 +01002713api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
Filip Tehlar5fae99c2017-01-18 12:57:37 +01002714{
2715 e->dp_table = clib_net_to_host_u32 (e->dp_table);
2716 e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
2717}
2718
2719static void
Filip Tehlar82786c42017-02-20 15:20:37 +01002720 gpe_fwd_entries_get_reply_t_net_to_host
2721 (vl_api_gpe_fwd_entries_get_reply_t * mp)
Filip Tehlar5fae99c2017-01-18 12:57:37 +01002722{
2723 u32 i;
2724
2725 mp->count = clib_net_to_host_u32 (mp->count);
2726 for (i = 0; i < mp->count; i++)
2727 {
Filip Tehlar82786c42017-02-20 15:20:37 +01002728 api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
Filip Tehlar5fae99c2017-01-18 12:57:37 +01002729 }
2730}
2731
Filip Tehlar3e7b56932017-02-21 18:28:34 +01002732static u8 *
2733format_gpe_encap_mode (u8 * s, va_list * args)
2734{
2735 u32 mode = va_arg (*args, u32);
2736
2737 switch (mode)
2738 {
2739 case 0:
2740 return format (s, "lisp");
2741 case 1:
2742 return format (s, "vxlan");
2743 }
2744 return 0;
2745}
2746
2747static void
2748 vl_api_gpe_get_encap_mode_reply_t_handler
2749 (vl_api_gpe_get_encap_mode_reply_t * mp)
2750{
2751 vat_main_t *vam = &vat_main;
2752
2753 print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
2754 vam->retval = ntohl (mp->retval);
2755 vam->result_ready = 1;
2756}
2757
2758static void
2759 vl_api_gpe_get_encap_mode_reply_t_handler_json
2760 (vl_api_gpe_get_encap_mode_reply_t * mp)
2761{
2762 vat_main_t *vam = &vat_main;
2763 vat_json_node_t node;
2764
2765 u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
2766 vec_add1 (encap_mode, 0);
2767
2768 vat_json_init_object (&node);
2769 vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
2770
2771 vec_free (encap_mode);
2772 vat_json_print (vam->ofp, &node);
2773 vat_json_free (&node);
2774
2775 vam->retval = ntohl (mp->retval);
2776 vam->result_ready = 1;
2777}
2778
Filip Tehlar5fae99c2017-01-18 12:57:37 +01002779static void
Filip Tehlar82786c42017-02-20 15:20:37 +01002780 vl_api_gpe_fwd_entry_path_details_t_handler
2781 (vl_api_gpe_fwd_entry_path_details_t * mp)
Filip Tehlar5fae99c2017-01-18 12:57:37 +01002782{
2783 vat_main_t *vam = &vat_main;
2784 u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
2785
2786 if (mp->lcl_loc.is_ip4)
2787 format_ip_address_fcn = format_ip4_address;
2788 else
2789 format_ip_address_fcn = format_ip6_address;
2790
2791 print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
2792 format_ip_address_fcn, &mp->lcl_loc,
2793 format_ip_address_fcn, &mp->rmt_loc);
2794}
2795
2796static void
Filip Tehlar82786c42017-02-20 15:20:37 +01002797lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
Filip Tehlar5fae99c2017-01-18 12:57:37 +01002798{
2799 struct in6_addr ip6;
2800 struct in_addr ip4;
2801
2802 if (loc->is_ip4)
2803 {
2804 clib_memcpy (&ip4, loc->addr, sizeof (ip4));
2805 vat_json_object_add_ip4 (n, "address", ip4);
2806 }
2807 else
2808 {
2809 clib_memcpy (&ip6, loc->addr, sizeof (ip6));
2810 vat_json_object_add_ip6 (n, "address", ip6);
2811 }
2812 vat_json_object_add_uint (n, "weight", loc->weight);
2813}
2814
2815static void
Filip Tehlar82786c42017-02-20 15:20:37 +01002816 vl_api_gpe_fwd_entry_path_details_t_handler_json
2817 (vl_api_gpe_fwd_entry_path_details_t * mp)
Filip Tehlar5fae99c2017-01-18 12:57:37 +01002818{
2819 vat_main_t *vam = &vat_main;
2820 vat_json_node_t *node = NULL;
2821 vat_json_node_t *loc_node;
2822
2823 if (VAT_JSON_ARRAY != vam->json_tree.type)
2824 {
2825 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2826 vat_json_init_array (&vam->json_tree);
2827 }
2828 node = vat_json_array_add (&vam->json_tree);
2829 vat_json_init_object (node);
2830
2831 loc_node = vat_json_object_add (node, "local_locator");
2832 vat_json_init_object (loc_node);
2833 lisp_fill_locator_node (loc_node, &mp->lcl_loc);
2834
2835 loc_node = vat_json_object_add (node, "remote_locator");
2836 vat_json_init_object (loc_node);
2837 lisp_fill_locator_node (loc_node, &mp->rmt_loc);
2838}
2839
2840static void
Filip Tehlar82786c42017-02-20 15:20:37 +01002841 vl_api_gpe_fwd_entries_get_reply_t_handler
2842 (vl_api_gpe_fwd_entries_get_reply_t * mp)
Filip Tehlar5fae99c2017-01-18 12:57:37 +01002843{
2844 vat_main_t *vam = &vat_main;
2845 u32 i;
2846 int retval = clib_net_to_host_u32 (mp->retval);
Filip Tehlar82786c42017-02-20 15:20:37 +01002847 vl_api_gpe_fwd_entry_t *e;
Filip Tehlar5fae99c2017-01-18 12:57:37 +01002848
2849 if (retval)
2850 goto end;
2851
Filip Tehlar82786c42017-02-20 15:20:37 +01002852 gpe_fwd_entries_get_reply_t_net_to_host (mp);
Filip Tehlar5fae99c2017-01-18 12:57:37 +01002853
2854 for (i = 0; i < mp->count; i++)
2855 {
2856 e = &mp->entries[i];
2857 print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
2858 format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
2859 format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
2860 }
2861
2862end:
2863 vam->retval = retval;
2864 vam->result_ready = 1;
2865}
2866
2867static void
Filip Tehlar82786c42017-02-20 15:20:37 +01002868 vl_api_gpe_fwd_entries_get_reply_t_handler_json
2869 (vl_api_gpe_fwd_entries_get_reply_t * mp)
Filip Tehlar5fae99c2017-01-18 12:57:37 +01002870{
2871 u8 *s = 0;
2872 vat_main_t *vam = &vat_main;
2873 vat_json_node_t *e = 0, root;
2874 u32 i;
2875 int retval = clib_net_to_host_u32 (mp->retval);
Filip Tehlar82786c42017-02-20 15:20:37 +01002876 vl_api_gpe_fwd_entry_t *fwd;
Filip Tehlar5fae99c2017-01-18 12:57:37 +01002877
2878 if (retval)
2879 goto end;
2880
Filip Tehlar82786c42017-02-20 15:20:37 +01002881 gpe_fwd_entries_get_reply_t_net_to_host (mp);
Filip Tehlar5fae99c2017-01-18 12:57:37 +01002882 vat_json_init_array (&root);
2883
2884 for (i = 0; i < mp->count; i++)
2885 {
2886 e = vat_json_array_add (&root);
2887 fwd = &mp->entries[i];
2888
2889 vat_json_init_object (e);
2890 vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
2891 vat_json_object_add_int (e, "dp_table", fwd->dp_table);
2892
2893 s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
2894 fwd->leid_prefix_len);
2895 vec_add1 (s, 0);
2896 vat_json_object_add_string_copy (e, "leid", s);
2897 vec_free (s);
2898
2899 s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
2900 fwd->reid_prefix_len);
2901 vec_add1 (s, 0);
2902 vat_json_object_add_string_copy (e, "reid", s);
2903 vec_free (s);
2904 }
2905
2906 vat_json_print (vam->ofp, &root);
2907 vat_json_free (&root);
2908
2909end:
2910 vam->retval = retval;
2911 vam->result_ready = 1;
2912}
2913
2914static void
Filip Tehlar694396d2017-02-17 14:29:11 +01002915 vl_api_one_adjacencies_get_reply_t_handler
2916 (vl_api_one_adjacencies_get_reply_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002917{
2918 vat_main_t *vam = &vat_main;
2919 u32 i, n;
2920 int retval = clib_net_to_host_u32 (mp->retval);
Filip Tehlar694396d2017-02-17 14:29:11 +01002921 vl_api_one_adjacency_t *a;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002922
2923 if (retval)
2924 goto end;
2925
2926 n = clib_net_to_host_u32 (mp->count);
2927
2928 for (i = 0; i < n; i++)
2929 {
2930 a = &mp->adjacencies[i];
2931 print (vam->ofp, "%U %40U",
2932 format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
2933 format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
2934 }
2935
2936end:
2937 vam->retval = retval;
2938 vam->result_ready = 1;
2939}
2940
2941static void
Filip Tehlar694396d2017-02-17 14:29:11 +01002942 vl_api_one_adjacencies_get_reply_t_handler_json
2943 (vl_api_one_adjacencies_get_reply_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002944{
2945 u8 *s = 0;
2946 vat_main_t *vam = &vat_main;
2947 vat_json_node_t *e = 0, root;
2948 u32 i, n;
2949 int retval = clib_net_to_host_u32 (mp->retval);
Filip Tehlar694396d2017-02-17 14:29:11 +01002950 vl_api_one_adjacency_t *a;
Damjan Marion7cd468a2016-12-19 23:05:39 +01002951
2952 if (retval)
2953 goto end;
2954
2955 n = clib_net_to_host_u32 (mp->count);
2956 vat_json_init_array (&root);
2957
2958 for (i = 0; i < n; i++)
2959 {
2960 e = vat_json_array_add (&root);
2961 a = &mp->adjacencies[i];
2962
2963 vat_json_init_object (e);
2964 s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
2965 a->leid_prefix_len);
2966 vec_add1 (s, 0);
2967 vat_json_object_add_string_copy (e, "leid", s);
2968 vec_free (s);
2969
2970 s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
2971 a->reid_prefix_len);
2972 vec_add1 (s, 0);
2973 vat_json_object_add_string_copy (e, "reid", s);
2974 vec_free (s);
2975 }
2976
2977 vat_json_print (vam->ofp, &root);
2978 vat_json_free (&root);
2979
2980end:
2981 vam->retval = retval;
2982 vam->result_ready = 1;
2983}
2984
2985static void
Filip Tehlar694396d2017-02-17 14:29:11 +01002986vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002987{
2988 vat_main_t *vam = &vat_main;
2989
2990 print (vam->ofp, "%=20U",
2991 mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2992 mp->ip_address);
2993}
2994
2995static void
Filip Tehlar694396d2017-02-17 14:29:11 +01002996 vl_api_one_map_server_details_t_handler_json
2997 (vl_api_one_map_server_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01002998{
2999 vat_main_t *vam = &vat_main;
3000 vat_json_node_t *node = NULL;
3001 struct in6_addr ip6;
3002 struct in_addr ip4;
3003
3004 if (VAT_JSON_ARRAY != vam->json_tree.type)
3005 {
3006 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3007 vat_json_init_array (&vam->json_tree);
3008 }
3009 node = vat_json_array_add (&vam->json_tree);
3010
3011 vat_json_init_object (node);
3012 if (mp->is_ipv6)
3013 {
3014 clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3015 vat_json_object_add_ip6 (node, "map-server", ip6);
3016 }
3017 else
3018 {
3019 clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3020 vat_json_object_add_ip4 (node, "map-server", ip4);
3021 }
3022}
3023
3024static void
Filip Tehlar694396d2017-02-17 14:29:11 +01003025vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
3026 * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01003027{
3028 vat_main_t *vam = &vat_main;
3029
3030 print (vam->ofp, "%=20U",
3031 mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3032 mp->ip_address);
3033}
3034
3035static void
Filip Tehlar694396d2017-02-17 14:29:11 +01003036 vl_api_one_map_resolver_details_t_handler_json
3037 (vl_api_one_map_resolver_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01003038{
3039 vat_main_t *vam = &vat_main;
3040 vat_json_node_t *node = NULL;
3041 struct in6_addr ip6;
3042 struct in_addr ip4;
3043
3044 if (VAT_JSON_ARRAY != vam->json_tree.type)
3045 {
3046 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3047 vat_json_init_array (&vam->json_tree);
3048 }
3049 node = vat_json_array_add (&vam->json_tree);
3050
3051 vat_json_init_object (node);
3052 if (mp->is_ipv6)
3053 {
3054 clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3055 vat_json_object_add_ip6 (node, "map resolver", ip6);
3056 }
3057 else
3058 {
3059 clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3060 vat_json_object_add_ip4 (node, "map resolver", ip4);
3061 }
3062}
3063
3064static void
Filip Tehlar694396d2017-02-17 14:29:11 +01003065vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01003066{
3067 vat_main_t *vam = &vat_main;
3068 i32 retval = ntohl (mp->retval);
3069
3070 if (0 <= retval)
3071 {
3072 print (vam->ofp, "feature: %s\ngpe: %s",
3073 mp->feature_status ? "enabled" : "disabled",
3074 mp->gpe_status ? "enabled" : "disabled");
3075 }
3076
3077 vam->retval = retval;
3078 vam->result_ready = 1;
3079}
3080
3081static void
Filip Tehlar694396d2017-02-17 14:29:11 +01003082 vl_api_show_one_status_reply_t_handler_json
3083 (vl_api_show_one_status_reply_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01003084{
3085 vat_main_t *vam = &vat_main;
3086 vat_json_node_t node;
3087 u8 *gpe_status = NULL;
3088 u8 *feature_status = NULL;
3089
3090 gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
3091 feature_status = format (0, "%s",
3092 mp->feature_status ? "enabled" : "disabled");
3093 vec_add1 (gpe_status, 0);
3094 vec_add1 (feature_status, 0);
3095
3096 vat_json_init_object (&node);
3097 vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
3098 vat_json_object_add_string_copy (&node, "feature_status", feature_status);
3099
3100 vec_free (gpe_status);
3101 vec_free (feature_status);
3102
3103 vat_json_print (vam->ofp, &node);
3104 vat_json_free (&node);
3105
3106 vam->retval = ntohl (mp->retval);
3107 vam->result_ready = 1;
3108}
3109
3110static void
Filip Tehlar694396d2017-02-17 14:29:11 +01003111 vl_api_one_get_map_request_itr_rlocs_reply_t_handler
3112 (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01003113{
3114 vat_main_t *vam = &vat_main;
3115 i32 retval = ntohl (mp->retval);
3116
3117 if (retval >= 0)
3118 {
3119 print (vam->ofp, "%=20s", mp->locator_set_name);
3120 }
3121
3122 vam->retval = retval;
3123 vam->result_ready = 1;
3124}
3125
3126static void
Filip Tehlar694396d2017-02-17 14:29:11 +01003127 vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
3128 (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01003129{
3130 vat_main_t *vam = &vat_main;
3131 vat_json_node_t *node = NULL;
3132
3133 if (VAT_JSON_ARRAY != vam->json_tree.type)
3134 {
3135 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3136 vat_json_init_array (&vam->json_tree);
3137 }
3138 node = vat_json_array_add (&vam->json_tree);
3139
3140 vat_json_init_object (node);
3141 vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
3142
3143 vat_json_print (vam->ofp, node);
3144 vat_json_free (node);
3145
3146 vam->retval = ntohl (mp->retval);
3147 vam->result_ready = 1;
3148}
3149
3150static u8 *
3151format_lisp_map_request_mode (u8 * s, va_list * args)
3152{
3153 u32 mode = va_arg (*args, u32);
3154
3155 switch (mode)
3156 {
3157 case 0:
3158 return format (0, "dst-only");
3159 case 1:
3160 return format (0, "src-dst");
3161 }
3162 return 0;
3163}
3164
3165static void
Filip Tehlar694396d2017-02-17 14:29:11 +01003166 vl_api_show_one_map_request_mode_reply_t_handler
3167 (vl_api_show_one_map_request_mode_reply_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01003168{
3169 vat_main_t *vam = &vat_main;
3170 i32 retval = ntohl (mp->retval);
3171
3172 if (0 <= retval)
3173 {
3174 u32 mode = mp->mode;
3175 print (vam->ofp, "map_request_mode: %U",
3176 format_lisp_map_request_mode, mode);
3177 }
3178
3179 vam->retval = retval;
3180 vam->result_ready = 1;
3181}
3182
3183static void
Filip Tehlar694396d2017-02-17 14:29:11 +01003184 vl_api_show_one_map_request_mode_reply_t_handler_json
3185 (vl_api_show_one_map_request_mode_reply_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01003186{
3187 vat_main_t *vam = &vat_main;
3188 vat_json_node_t node;
3189 u8 *s = 0;
3190 u32 mode;
3191
3192 mode = mp->mode;
3193 s = format (0, "%U", format_lisp_map_request_mode, mode);
3194 vec_add1 (s, 0);
3195
3196 vat_json_init_object (&node);
3197 vat_json_object_add_string_copy (&node, "map_request_mode", s);
3198 vat_json_print (vam->ofp, &node);
3199 vat_json_free (&node);
3200
3201 vec_free (s);
3202 vam->retval = ntohl (mp->retval);
3203 vam->result_ready = 1;
3204}
3205
3206static void
Filip Tehlar694396d2017-02-17 14:29:11 +01003207vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01003208{
3209 vat_main_t *vam = &vat_main;
3210 i32 retval = ntohl (mp->retval);
3211
3212 if (0 <= retval)
3213 {
3214 print (vam->ofp, "%-20s%-16s",
3215 mp->status ? "enabled" : "disabled",
3216 mp->status ? (char *) mp->locator_set_name : "");
3217 }
3218
3219 vam->retval = retval;
3220 vam->result_ready = 1;
3221}
3222
3223static void
Filip Tehlar694396d2017-02-17 14:29:11 +01003224vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01003225{
3226 vat_main_t *vam = &vat_main;
3227 vat_json_node_t node;
3228 u8 *status = 0;
3229
3230 status = format (0, "%s", mp->status ? "enabled" : "disabled");
3231 vec_add1 (status, 0);
3232
3233 vat_json_init_object (&node);
3234 vat_json_object_add_string_copy (&node, "status", status);
3235 if (mp->status)
3236 {
3237 vat_json_object_add_string_copy (&node, "locator_set",
3238 mp->locator_set_name);
3239 }
3240
3241 vec_free (status);
3242
3243 vat_json_print (vam->ofp, &node);
3244 vat_json_free (&node);
3245
3246 vam->retval = ntohl (mp->retval);
3247 vam->result_ready = 1;
3248}
3249
3250static u8 *
3251format_policer_type (u8 * s, va_list * va)
3252{
3253 u32 i = va_arg (*va, u32);
3254
3255 if (i == SSE2_QOS_POLICER_TYPE_1R2C)
3256 s = format (s, "1r2c");
3257 else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
3258 s = format (s, "1r3c");
3259 else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
3260 s = format (s, "2r3c-2698");
3261 else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
3262 s = format (s, "2r3c-4115");
3263 else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
3264 s = format (s, "2r3c-mef5cf1");
3265 else
3266 s = format (s, "ILLEGAL");
3267 return s;
3268}
3269
3270static u8 *
3271format_policer_rate_type (u8 * s, va_list * va)
3272{
3273 u32 i = va_arg (*va, u32);
3274
3275 if (i == SSE2_QOS_RATE_KBPS)
3276 s = format (s, "kbps");
3277 else if (i == SSE2_QOS_RATE_PPS)
3278 s = format (s, "pps");
3279 else
3280 s = format (s, "ILLEGAL");
3281 return s;
3282}
3283
3284static u8 *
3285format_policer_round_type (u8 * s, va_list * va)
3286{
3287 u32 i = va_arg (*va, u32);
3288
3289 if (i == SSE2_QOS_ROUND_TO_CLOSEST)
3290 s = format (s, "closest");
3291 else if (i == SSE2_QOS_ROUND_TO_UP)
3292 s = format (s, "up");
3293 else if (i == SSE2_QOS_ROUND_TO_DOWN)
3294 s = format (s, "down");
3295 else
3296 s = format (s, "ILLEGAL");
3297 return s;
3298}
3299
3300static u8 *
3301format_policer_action_type (u8 * s, va_list * va)
3302{
3303 u32 i = va_arg (*va, u32);
3304
3305 if (i == SSE2_QOS_ACTION_DROP)
3306 s = format (s, "drop");
3307 else if (i == SSE2_QOS_ACTION_TRANSMIT)
3308 s = format (s, "transmit");
3309 else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3310 s = format (s, "mark-and-transmit");
3311 else
3312 s = format (s, "ILLEGAL");
3313 return s;
3314}
3315
3316static u8 *
3317format_dscp (u8 * s, va_list * va)
3318{
3319 u32 i = va_arg (*va, u32);
3320 char *t = 0;
3321
3322 switch (i)
3323 {
3324#define _(v,f,str) case VNET_DSCP_##f: t = str; break;
3325 foreach_vnet_dscp
3326#undef _
3327 default:
3328 return format (s, "ILLEGAL");
3329 }
3330 s = format (s, "%s", t);
3331 return s;
3332}
3333
3334static void
3335vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
3336{
3337 vat_main_t *vam = &vat_main;
3338 u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
3339
3340 if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3341 conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3342 else
3343 conform_dscp_str = format (0, "");
3344
3345 if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3346 exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3347 else
3348 exceed_dscp_str = format (0, "");
3349
3350 if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3351 violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3352 else
3353 violate_dscp_str = format (0, "");
3354
3355 print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
3356 "rate type %U, round type %U, %s rate, %s color-aware, "
3357 "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
3358 "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
3359 "conform action %U%s, exceed action %U%s, violate action %U%s",
3360 mp->name,
3361 format_policer_type, mp->type,
3362 ntohl (mp->cir),
3363 ntohl (mp->eir),
3364 clib_net_to_host_u64 (mp->cb),
3365 clib_net_to_host_u64 (mp->eb),
3366 format_policer_rate_type, mp->rate_type,
3367 format_policer_round_type, mp->round_type,
3368 mp->single_rate ? "single" : "dual",
3369 mp->color_aware ? "is" : "not",
3370 ntohl (mp->cir_tokens_per_period),
3371 ntohl (mp->pir_tokens_per_period),
3372 ntohl (mp->scale),
3373 ntohl (mp->current_limit),
3374 ntohl (mp->current_bucket),
3375 ntohl (mp->extended_limit),
3376 ntohl (mp->extended_bucket),
3377 clib_net_to_host_u64 (mp->last_update_time),
3378 format_policer_action_type, mp->conform_action_type,
3379 conform_dscp_str,
3380 format_policer_action_type, mp->exceed_action_type,
3381 exceed_dscp_str,
3382 format_policer_action_type, mp->violate_action_type,
3383 violate_dscp_str);
3384
3385 vec_free (conform_dscp_str);
3386 vec_free (exceed_dscp_str);
3387 vec_free (violate_dscp_str);
3388}
3389
3390static void vl_api_policer_details_t_handler_json
3391 (vl_api_policer_details_t * mp)
3392{
3393 vat_main_t *vam = &vat_main;
3394 vat_json_node_t *node;
3395 u8 *rate_type_str, *round_type_str, *type_str;
3396 u8 *conform_action_str, *exceed_action_str, *violate_action_str;
3397
3398 rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
3399 round_type_str =
3400 format (0, "%U", format_policer_round_type, mp->round_type);
3401 type_str = format (0, "%U", format_policer_type, mp->type);
3402 conform_action_str = format (0, "%U", format_policer_action_type,
3403 mp->conform_action_type);
3404 exceed_action_str = format (0, "%U", format_policer_action_type,
3405 mp->exceed_action_type);
3406 violate_action_str = format (0, "%U", format_policer_action_type,
3407 mp->violate_action_type);
3408
3409 if (VAT_JSON_ARRAY != vam->json_tree.type)
3410 {
3411 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3412 vat_json_init_array (&vam->json_tree);
3413 }
3414 node = vat_json_array_add (&vam->json_tree);
3415
3416 vat_json_init_object (node);
3417 vat_json_object_add_string_copy (node, "name", mp->name);
3418 vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3419 vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
3420 vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
3421 vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
3422 vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3423 vat_json_object_add_string_copy (node, "round_type", round_type_str);
3424 vat_json_object_add_string_copy (node, "type", type_str);
3425 vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3426 vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3427 vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3428 vat_json_object_add_uint (node, "cir_tokens_per_period",
3429 ntohl (mp->cir_tokens_per_period));
3430 vat_json_object_add_uint (node, "eir_tokens_per_period",
3431 ntohl (mp->pir_tokens_per_period));
3432 vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3433 vat_json_object_add_uint (node, "current_bucket",
3434 ntohl (mp->current_bucket));
3435 vat_json_object_add_uint (node, "extended_limit",
3436 ntohl (mp->extended_limit));
3437 vat_json_object_add_uint (node, "extended_bucket",
3438 ntohl (mp->extended_bucket));
3439 vat_json_object_add_uint (node, "last_update_time",
3440 ntohl (mp->last_update_time));
3441 vat_json_object_add_string_copy (node, "conform_action",
3442 conform_action_str);
3443 if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3444 {
3445 u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3446 vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3447 vec_free (dscp_str);
3448 }
3449 vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3450 if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3451 {
3452 u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3453 vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3454 vec_free (dscp_str);
3455 }
3456 vat_json_object_add_string_copy (node, "violate_action",
3457 violate_action_str);
3458 if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3459 {
3460 u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3461 vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3462 vec_free (dscp_str);
3463 }
3464
3465 vec_free (rate_type_str);
3466 vec_free (round_type_str);
3467 vec_free (type_str);
3468 vec_free (conform_action_str);
3469 vec_free (exceed_action_str);
3470 vec_free (violate_action_str);
3471}
3472
3473static void
3474vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3475 mp)
3476{
3477 vat_main_t *vam = &vat_main;
3478 int i, count = ntohl (mp->count);
3479
3480 if (count > 0)
3481 print (vam->ofp, "classify table ids (%d) : ", count);
3482 for (i = 0; i < count; i++)
3483 {
3484 print (vam->ofp, "%d", ntohl (mp->ids[i]));
3485 print (vam->ofp, (i < count - 1) ? "," : "");
3486 }
3487 vam->retval = ntohl (mp->retval);
3488 vam->result_ready = 1;
3489}
3490
3491static void
3492 vl_api_classify_table_ids_reply_t_handler_json
3493 (vl_api_classify_table_ids_reply_t * mp)
3494{
3495 vat_main_t *vam = &vat_main;
3496 int i, count = ntohl (mp->count);
3497
3498 if (count > 0)
3499 {
3500 vat_json_node_t node;
3501
3502 vat_json_init_object (&node);
3503 for (i = 0; i < count; i++)
3504 {
3505 vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3506 }
3507 vat_json_print (vam->ofp, &node);
3508 vat_json_free (&node);
3509 }
3510 vam->retval = ntohl (mp->retval);
3511 vam->result_ready = 1;
3512}
3513
3514static void
3515 vl_api_classify_table_by_interface_reply_t_handler
3516 (vl_api_classify_table_by_interface_reply_t * mp)
3517{
3518 vat_main_t *vam = &vat_main;
3519 u32 table_id;
3520
3521 table_id = ntohl (mp->l2_table_id);
3522 if (table_id != ~0)
3523 print (vam->ofp, "l2 table id : %d", table_id);
3524 else
3525 print (vam->ofp, "l2 table id : No input ACL tables configured");
3526 table_id = ntohl (mp->ip4_table_id);
3527 if (table_id != ~0)
3528 print (vam->ofp, "ip4 table id : %d", table_id);
3529 else
3530 print (vam->ofp, "ip4 table id : No input ACL tables configured");
3531 table_id = ntohl (mp->ip6_table_id);
3532 if (table_id != ~0)
3533 print (vam->ofp, "ip6 table id : %d", table_id);
3534 else
3535 print (vam->ofp, "ip6 table id : No input ACL tables configured");
3536 vam->retval = ntohl (mp->retval);
3537 vam->result_ready = 1;
3538}
3539
3540static void
3541 vl_api_classify_table_by_interface_reply_t_handler_json
3542 (vl_api_classify_table_by_interface_reply_t * mp)
3543{
3544 vat_main_t *vam = &vat_main;
3545 vat_json_node_t node;
3546
3547 vat_json_init_object (&node);
3548
3549 vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3550 vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3551 vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3552
3553 vat_json_print (vam->ofp, &node);
3554 vat_json_free (&node);
3555
3556 vam->retval = ntohl (mp->retval);
3557 vam->result_ready = 1;
3558}
3559
3560static void vl_api_policer_add_del_reply_t_handler
3561 (vl_api_policer_add_del_reply_t * mp)
3562{
3563 vat_main_t *vam = &vat_main;
3564 i32 retval = ntohl (mp->retval);
3565 if (vam->async_mode)
3566 {
3567 vam->async_errors += (retval < 0);
3568 }
3569 else
3570 {
3571 vam->retval = retval;
3572 vam->result_ready = 1;
3573 if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3574 /*
3575 * Note: this is just barely thread-safe, depends on
3576 * the main thread spinning waiting for an answer...
3577 */
3578 errmsg ("policer index %d", ntohl (mp->policer_index));
3579 }
3580}
3581
3582static void vl_api_policer_add_del_reply_t_handler_json
3583 (vl_api_policer_add_del_reply_t * mp)
3584{
3585 vat_main_t *vam = &vat_main;
3586 vat_json_node_t node;
3587
3588 vat_json_init_object (&node);
3589 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3590 vat_json_object_add_uint (&node, "policer_index",
3591 ntohl (mp->policer_index));
3592
3593 vat_json_print (vam->ofp, &node);
3594 vat_json_free (&node);
3595
3596 vam->retval = ntohl (mp->retval);
3597 vam->result_ready = 1;
3598}
3599
3600/* Format hex dump. */
3601u8 *
3602format_hex_bytes (u8 * s, va_list * va)
3603{
3604 u8 *bytes = va_arg (*va, u8 *);
3605 int n_bytes = va_arg (*va, int);
3606 uword i;
3607
3608 /* Print short or long form depending on byte count. */
3609 uword short_form = n_bytes <= 32;
3610 uword indent = format_get_indent (s);
3611
3612 if (n_bytes == 0)
3613 return s;
3614
3615 for (i = 0; i < n_bytes; i++)
3616 {
3617 if (!short_form && (i % 32) == 0)
3618 s = format (s, "%08x: ", i);
3619 s = format (s, "%02x", bytes[i]);
3620 if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3621 s = format (s, "\n%U", format_white_space, indent);
3622 }
3623
3624 return s;
3625}
3626
3627static void
3628vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3629 * mp)
3630{
3631 vat_main_t *vam = &vat_main;
3632 i32 retval = ntohl (mp->retval);
3633 if (retval == 0)
3634 {
3635 print (vam->ofp, "classify table info :");
3636 print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
3637 ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3638 ntohl (mp->miss_next_index));
3639 print (vam->ofp, "nbuckets: %d skip: %d match: %d",
3640 ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3641 ntohl (mp->match_n_vectors));
3642 print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
3643 ntohl (mp->mask_length));
3644 }
3645 vam->retval = retval;
3646 vam->result_ready = 1;
3647}
3648
3649static void
3650 vl_api_classify_table_info_reply_t_handler_json
3651 (vl_api_classify_table_info_reply_t * mp)
3652{
3653 vat_main_t *vam = &vat_main;
3654 vat_json_node_t node;
3655
3656 i32 retval = ntohl (mp->retval);
3657 if (retval == 0)
3658 {
3659 vat_json_init_object (&node);
3660
3661 vat_json_object_add_int (&node, "sessions",
3662 ntohl (mp->active_sessions));
3663 vat_json_object_add_int (&node, "nexttbl",
3664 ntohl (mp->next_table_index));
3665 vat_json_object_add_int (&node, "nextnode",
3666 ntohl (mp->miss_next_index));
3667 vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3668 vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3669 vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3670 u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3671 ntohl (mp->mask_length), 0);
3672 vat_json_object_add_string_copy (&node, "mask", s);
3673
3674 vat_json_print (vam->ofp, &node);
3675 vat_json_free (&node);
3676 }
3677 vam->retval = ntohl (mp->retval);
3678 vam->result_ready = 1;
3679}
3680
3681static void
3682vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3683 mp)
3684{
3685 vat_main_t *vam = &vat_main;
3686
3687 print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3688 ntohl (mp->hit_next_index), ntohl (mp->advance),
3689 ntohl (mp->opaque_index));
3690 print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
3691 ntohl (mp->match_length));
3692}
3693
3694static void
3695 vl_api_classify_session_details_t_handler_json
3696 (vl_api_classify_session_details_t * mp)
3697{
3698 vat_main_t *vam = &vat_main;
3699 vat_json_node_t *node = NULL;
3700
3701 if (VAT_JSON_ARRAY != vam->json_tree.type)
3702 {
3703 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3704 vat_json_init_array (&vam->json_tree);
3705 }
3706 node = vat_json_array_add (&vam->json_tree);
3707
3708 vat_json_init_object (node);
3709 vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3710 vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3711 vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3712 u8 *s =
3713 format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3714 0);
3715 vat_json_object_add_string_copy (node, "match", s);
3716}
3717
3718static void vl_api_pg_create_interface_reply_t_handler
3719 (vl_api_pg_create_interface_reply_t * mp)
3720{
3721 vat_main_t *vam = &vat_main;
3722
3723 vam->retval = ntohl (mp->retval);
3724 vam->result_ready = 1;
3725}
3726
3727static void vl_api_pg_create_interface_reply_t_handler_json
3728 (vl_api_pg_create_interface_reply_t * mp)
3729{
3730 vat_main_t *vam = &vat_main;
3731 vat_json_node_t node;
3732
3733 i32 retval = ntohl (mp->retval);
3734 if (retval == 0)
3735 {
3736 vat_json_init_object (&node);
3737
3738 vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3739
3740 vat_json_print (vam->ofp, &node);
3741 vat_json_free (&node);
3742 }
3743 vam->retval = ntohl (mp->retval);
3744 vam->result_ready = 1;
3745}
3746
3747static void vl_api_policer_classify_details_t_handler
3748 (vl_api_policer_classify_details_t * mp)
3749{
3750 vat_main_t *vam = &vat_main;
3751
3752 print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3753 ntohl (mp->table_index));
3754}
3755
3756static void vl_api_policer_classify_details_t_handler_json
3757 (vl_api_policer_classify_details_t * mp)
3758{
3759 vat_main_t *vam = &vat_main;
3760 vat_json_node_t *node;
3761
3762 if (VAT_JSON_ARRAY != vam->json_tree.type)
3763 {
3764 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3765 vat_json_init_array (&vam->json_tree);
3766 }
3767 node = vat_json_array_add (&vam->json_tree);
3768
3769 vat_json_init_object (node);
3770 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3771 vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3772}
3773
3774static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3775 (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3776{
3777 vat_main_t *vam = &vat_main;
3778 i32 retval = ntohl (mp->retval);
3779 if (vam->async_mode)
3780 {
3781 vam->async_errors += (retval < 0);
3782 }
3783 else
3784 {
3785 vam->retval = retval;
3786 vam->sw_if_index = ntohl (mp->sw_if_index);
3787 vam->result_ready = 1;
3788 }
3789}
3790
3791static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3792 (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3793{
3794 vat_main_t *vam = &vat_main;
3795 vat_json_node_t node;
3796
3797 vat_json_init_object (&node);
3798 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3799 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3800
3801 vat_json_print (vam->ofp, &node);
3802 vat_json_free (&node);
3803
3804 vam->retval = ntohl (mp->retval);
3805 vam->result_ready = 1;
3806}
3807
3808static void vl_api_flow_classify_details_t_handler
3809 (vl_api_flow_classify_details_t * mp)
3810{
3811 vat_main_t *vam = &vat_main;
3812
3813 print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3814 ntohl (mp->table_index));
3815}
3816
3817static void vl_api_flow_classify_details_t_handler_json
3818 (vl_api_flow_classify_details_t * mp)
3819{
3820 vat_main_t *vam = &vat_main;
3821 vat_json_node_t *node;
3822
3823 if (VAT_JSON_ARRAY != vam->json_tree.type)
3824 {
3825 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3826 vat_json_init_array (&vam->json_tree);
3827 }
3828 node = vat_json_array_add (&vam->json_tree);
3829
3830 vat_json_init_object (node);
3831 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3832 vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3833}
3834
3835
3836
3837#define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3838#define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3839#define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3840#define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
Neale Ranns044183f2017-01-24 01:34:25 -08003841#define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
3842#define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
3843#define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
3844#define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
Filip Tehlar694396d2017-02-17 14:29:11 +01003845#define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
3846#define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
Damjan Marion7cd468a2016-12-19 23:05:39 +01003847
3848/*
3849 * Generate boilerplate reply handlers, which
3850 * dig the return value out of the xxx_reply_t API message,
3851 * stick it into vam->retval, and set vam->result_ready
3852 *
3853 * Could also do this by pointing N message decode slots at
3854 * a single function, but that could break in subtle ways.
3855 */
3856
3857#define foreach_standard_reply_retval_handler \
3858_(sw_interface_set_flags_reply) \
3859_(sw_interface_add_del_address_reply) \
3860_(sw_interface_set_table_reply) \
3861_(sw_interface_set_mpls_enable_reply) \
3862_(sw_interface_set_vpath_reply) \
3863_(sw_interface_set_vxlan_bypass_reply) \
3864_(sw_interface_set_l2_bridge_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003865_(bridge_domain_add_del_reply) \
3866_(sw_interface_set_l2_xconnect_reply) \
3867_(l2fib_add_del_reply) \
3868_(ip_add_del_route_reply) \
Neale Ranns32e1c012016-11-22 17:07:28 +00003869_(ip_mroute_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003870_(mpls_route_add_del_reply) \
3871_(mpls_ip_bind_unbind_reply) \
3872_(proxy_arp_add_del_reply) \
3873_(proxy_arp_intfc_enable_disable_reply) \
3874_(sw_interface_set_unnumbered_reply) \
3875_(ip_neighbor_add_del_reply) \
3876_(reset_vrf_reply) \
3877_(oam_add_del_reply) \
3878_(reset_fib_reply) \
3879_(dhcp_proxy_config_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003880_(dhcp_proxy_set_vss_reply) \
3881_(dhcp_client_config_reply) \
3882_(set_ip_flow_hash_reply) \
3883_(sw_interface_ip6_enable_disable_reply) \
3884_(sw_interface_ip6_set_link_local_address_reply) \
3885_(sw_interface_ip6nd_ra_prefix_reply) \
3886_(sw_interface_ip6nd_ra_config_reply) \
3887_(set_arp_neighbor_limit_reply) \
3888_(l2_patch_add_del_reply) \
3889_(sr_tunnel_add_del_reply) \
3890_(sr_policy_add_del_reply) \
3891_(sr_multicast_map_add_del_reply) \
3892_(classify_add_del_session_reply) \
3893_(classify_set_interface_ip_table_reply) \
3894_(classify_set_interface_l2_tables_reply) \
3895_(l2tpv3_set_tunnel_cookies_reply) \
3896_(l2tpv3_interface_enable_disable_reply) \
3897_(l2tpv3_set_lookup_key_reply) \
3898_(l2_fib_clear_table_reply) \
3899_(l2_interface_efp_filter_reply) \
3900_(l2_interface_vlan_tag_rewrite_reply) \
3901_(modify_vhost_user_if_reply) \
3902_(delete_vhost_user_if_reply) \
3903_(want_ip4_arp_events_reply) \
3904_(want_ip6_nd_events_reply) \
3905_(input_acl_set_interface_reply) \
3906_(ipsec_spd_add_del_reply) \
3907_(ipsec_interface_add_del_spd_reply) \
3908_(ipsec_spd_add_del_entry_reply) \
3909_(ipsec_sad_add_del_entry_reply) \
3910_(ipsec_sa_set_key_reply) \
3911_(ikev2_profile_add_del_reply) \
3912_(ikev2_profile_set_auth_reply) \
3913_(ikev2_profile_set_id_reply) \
3914_(ikev2_profile_set_ts_reply) \
3915_(ikev2_set_local_key_reply) \
Radu Nicolaucb33dc22017-02-16 16:49:46 +00003916_(ikev2_set_responder_reply) \
3917_(ikev2_set_ike_transforms_reply) \
3918_(ikev2_set_esp_transforms_reply) \
3919_(ikev2_set_sa_lifetime_reply) \
3920_(ikev2_initiate_sa_init_reply) \
3921_(ikev2_initiate_del_ike_sa_reply) \
3922_(ikev2_initiate_del_child_sa_reply) \
3923_(ikev2_initiate_rekey_child_sa_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003924_(delete_loopback_reply) \
3925_(bd_ip_mac_add_del_reply) \
3926_(map_del_domain_reply) \
3927_(map_add_del_rule_reply) \
3928_(want_interface_events_reply) \
3929_(want_stats_reply) \
3930_(cop_interface_enable_disable_reply) \
3931_(cop_whitelist_enable_disable_reply) \
3932_(sw_interface_clear_stats_reply) \
3933_(ioam_enable_reply) \
3934_(ioam_disable_reply) \
Filip Tehlar694396d2017-02-17 14:29:11 +01003935_(one_add_del_locator_reply) \
3936_(one_add_del_local_eid_reply) \
3937_(one_add_del_remote_mapping_reply) \
3938_(one_add_del_adjacency_reply) \
3939_(one_add_del_map_resolver_reply) \
3940_(one_add_del_map_server_reply) \
3941_(one_enable_disable_reply) \
3942_(one_rloc_probe_enable_disable_reply) \
3943_(one_map_register_enable_disable_reply) \
3944_(one_pitr_set_locator_set_reply) \
3945_(one_map_request_mode_reply) \
3946_(one_add_del_map_request_itr_rlocs_reply) \
3947_(one_eid_table_add_del_map_reply) \
Filip Tehlar82786c42017-02-20 15:20:37 +01003948_(gpe_add_del_fwd_entry_reply) \
Filip Tehlar82786c42017-02-20 15:20:37 +01003949_(gpe_enable_disable_reply) \
Filip Tehlar3e7b56932017-02-21 18:28:34 +01003950_(gpe_set_encap_mode_reply) \
Filip Tehlar82786c42017-02-20 15:20:37 +01003951_(gpe_add_del_iface_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003952_(vxlan_gpe_add_del_tunnel_reply) \
3953_(af_packet_delete_reply) \
3954_(policer_classify_set_interface_reply) \
3955_(netmap_create_reply) \
3956_(netmap_delete_reply) \
3957_(set_ipfix_exporter_reply) \
3958_(set_ipfix_classify_stream_reply) \
3959_(ipfix_classify_table_add_del_reply) \
3960_(flow_classify_set_interface_reply) \
3961_(sw_interface_span_enable_disable_reply) \
3962_(pg_capture_reply) \
3963_(pg_enable_disable_reply) \
3964_(ip_source_and_port_range_check_add_del_reply) \
3965_(ip_source_and_port_range_check_interface_add_del_reply)\
3966_(delete_subif_reply) \
3967_(l2_interface_pbb_tag_rewrite_reply) \
3968_(punt_reply) \
3969_(feature_enable_disable_reply) \
3970_(sw_interface_tag_add_del_reply) \
3971_(sw_interface_set_mtu_reply)
3972
Pavel Kotucek738f3f22017-01-09 15:11:03 +01003973#if DPDK > 0
3974#define foreach_standard_dpdk_reply_retval_handler \
3975_(sw_interface_set_dpdk_hqos_pipe_reply) \
3976_(sw_interface_set_dpdk_hqos_subport_reply) \
3977_(sw_interface_set_dpdk_hqos_tctbl_reply)
3978#endif
3979
Damjan Marion7cd468a2016-12-19 23:05:39 +01003980#define _(n) \
3981 static void vl_api_##n##_t_handler \
3982 (vl_api_##n##_t * mp) \
3983 { \
3984 vat_main_t * vam = &vat_main; \
3985 i32 retval = ntohl(mp->retval); \
3986 if (vam->async_mode) { \
3987 vam->async_errors += (retval < 0); \
3988 } else { \
3989 vam->retval = retval; \
3990 vam->result_ready = 1; \
3991 } \
3992 }
3993foreach_standard_reply_retval_handler;
3994#undef _
3995
3996#define _(n) \
3997 static void vl_api_##n##_t_handler_json \
3998 (vl_api_##n##_t * mp) \
3999 { \
4000 vat_main_t * vam = &vat_main; \
4001 vat_json_node_t node; \
4002 vat_json_init_object(&node); \
4003 vat_json_object_add_int(&node, "retval", ntohl(mp->retval)); \
4004 vat_json_print(vam->ofp, &node); \
4005 vam->retval = ntohl(mp->retval); \
4006 vam->result_ready = 1; \
4007 }
4008foreach_standard_reply_retval_handler;
4009#undef _
4010
Pavel Kotucek738f3f22017-01-09 15:11:03 +01004011#if DPDK > 0
4012#define _(n) \
4013 static void vl_api_##n##_t_handler \
4014 (vl_api_##n##_t * mp) \
4015 { \
4016 vat_main_t * vam = &vat_main; \
4017 i32 retval = ntohl(mp->retval); \
4018 if (vam->async_mode) { \
4019 vam->async_errors += (retval < 0); \
4020 } else { \
4021 vam->retval = retval; \
4022 vam->result_ready = 1; \
4023 } \
4024 }
4025foreach_standard_dpdk_reply_retval_handler;
4026#undef _
4027
4028#define _(n) \
4029 static void vl_api_##n##_t_handler_json \
4030 (vl_api_##n##_t * mp) \
4031 { \
4032 vat_main_t * vam = &vat_main; \
4033 vat_json_node_t node; \
4034 vat_json_init_object(&node); \
4035 vat_json_object_add_int(&node, "retval", ntohl(mp->retval)); \
4036 vat_json_print(vam->ofp, &node); \
4037 vam->retval = ntohl(mp->retval); \
4038 vam->result_ready = 1; \
4039 }
4040foreach_standard_dpdk_reply_retval_handler;
4041#undef _
4042#endif
4043
Damjan Marion7cd468a2016-12-19 23:05:39 +01004044/*
4045 * Table of message reply handlers, must include boilerplate handlers
4046 * we just generated
4047 */
4048
4049#define foreach_vpe_api_reply_msg \
4050_(CREATE_LOOPBACK_REPLY, create_loopback_reply) \
4051_(SW_INTERFACE_DETAILS, sw_interface_details) \
4052_(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags) \
4053_(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply) \
4054_(CONTROL_PING_REPLY, control_ping_reply) \
4055_(CLI_REPLY, cli_reply) \
4056_(CLI_INBAND_REPLY, cli_inband_reply) \
4057_(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY, \
4058 sw_interface_add_del_address_reply) \
4059_(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply) \
4060_(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
4061_(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply) \
4062_(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
4063_(SW_INTERFACE_SET_L2_XCONNECT_REPLY, \
4064 sw_interface_set_l2_xconnect_reply) \
4065_(SW_INTERFACE_SET_L2_BRIDGE_REPLY, \
4066 sw_interface_set_l2_bridge_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01004067_(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply) \
4068_(BRIDGE_DOMAIN_DETAILS, bridge_domain_details) \
4069_(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details) \
4070_(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply) \
4071_(L2_FLAGS_REPLY, l2_flags_reply) \
4072_(BRIDGE_FLAGS_REPLY, bridge_flags_reply) \
4073_(TAP_CONNECT_REPLY, tap_connect_reply) \
4074_(TAP_MODIFY_REPLY, tap_modify_reply) \
4075_(TAP_DELETE_REPLY, tap_delete_reply) \
4076_(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details) \
4077_(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply) \
Neale Ranns32e1c012016-11-22 17:07:28 +00004078_(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01004079_(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply) \
4080_(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply) \
4081_(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply) \
4082_(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY, \
4083 proxy_arp_intfc_enable_disable_reply) \
4084_(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply) \
4085_(SW_INTERFACE_SET_UNNUMBERED_REPLY, \
4086 sw_interface_set_unnumbered_reply) \
4087_(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply) \
4088_(RESET_VRF_REPLY, reset_vrf_reply) \
4089_(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply) \
4090_(CREATE_SUBIF_REPLY, create_subif_reply) \
4091_(OAM_ADD_DEL_REPLY, oam_add_del_reply) \
4092_(RESET_FIB_REPLY, reset_fib_reply) \
4093_(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01004094_(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply) \
Neale Ranns20a175a2017-02-14 07:28:41 -08004095_(DHCP_PROXY_DETAILS, dhcp_proxy_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01004096_(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply) \
4097_(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply) \
4098_(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY, \
4099 sw_interface_ip6_enable_disable_reply) \
4100_(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY, \
4101 sw_interface_ip6_set_link_local_address_reply) \
4102_(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY, \
4103 sw_interface_ip6nd_ra_prefix_reply) \
4104_(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY, \
4105 sw_interface_ip6nd_ra_config_reply) \
4106_(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply) \
4107_(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply) \
4108_(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply) \
4109_(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply) \
4110_(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply) \
4111_(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply) \
4112_(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply) \
4113_(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY, \
4114classify_set_interface_ip_table_reply) \
4115_(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY, \
4116 classify_set_interface_l2_tables_reply) \
4117_(GET_NODE_INDEX_REPLY, get_node_index_reply) \
4118_(ADD_NODE_NEXT_REPLY, add_node_next_reply) \
4119_(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply) \
4120_(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply) \
4121_(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY, \
4122 l2tpv3_interface_enable_disable_reply) \
4123_(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply) \
4124_(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details) \
4125_(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply) \
4126_(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details) \
4127_(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply) \
4128_(GRE_TUNNEL_DETAILS, gre_tunnel_details) \
4129_(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply) \
4130_(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply) \
4131_(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
4132_(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details) \
4133_(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply) \
4134_(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply) \
4135_(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply) \
4136_(SHOW_VERSION_REPLY, show_version_reply) \
4137_(L2_FIB_TABLE_ENTRY, l2_fib_table_entry) \
4138_(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply) \
4139_(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details) \
4140_(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply) \
4141_(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply) \
4142_(IP4_ARP_EVENT, ip4_arp_event) \
4143_(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply) \
4144_(IP6_ND_EVENT, ip6_nd_event) \
4145_(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply) \
4146_(IP_ADDRESS_DETAILS, ip_address_details) \
4147_(IP_DETAILS, ip_details) \
4148_(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply) \
4149_(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
4150_(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply) \
4151_(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply) \
4152_(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply) \
4153_(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply) \
4154_(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply) \
4155_(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply) \
4156_(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply) \
4157_(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply) \
Radu Nicolaucb33dc22017-02-16 16:49:46 +00004158_(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply) \
4159_(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply) \
4160_(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply) \
4161_(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply) \
4162_(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply) \
4163_(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply) \
4164_(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
4165_(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01004166_(DELETE_LOOPBACK_REPLY, delete_loopback_reply) \
4167_(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply) \
4168_(DHCP_COMPL_EVENT, dhcp_compl_event) \
4169_(VNET_INTERFACE_COUNTERS, vnet_interface_counters) \
4170_(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters) \
4171_(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters) \
Neale Ranns044183f2017-01-24 01:34:25 -08004172_(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters) \
4173_(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01004174_(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply) \
4175_(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply) \
4176_(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply) \
4177_(MAP_DOMAIN_DETAILS, map_domain_details) \
4178_(MAP_RULE_DETAILS, map_rule_details) \
4179_(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply) \
4180_(WANT_STATS_REPLY, want_stats_reply) \
4181_(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply) \
4182_(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
4183_(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
4184_(GET_NODE_GRAPH_REPLY, get_node_graph_reply) \
4185_(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply) \
4186_(IOAM_ENABLE_REPLY, ioam_enable_reply) \
4187_(IOAM_DISABLE_REPLY, ioam_disable_reply) \
Filip Tehlar694396d2017-02-17 14:29:11 +01004188_(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply) \
4189_(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply) \
4190_(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply) \
4191_(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply) \
4192_(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply) \
4193_(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply) \
4194_(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply) \
4195_(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply) \
4196_(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY, \
4197 one_map_register_enable_disable_reply) \
4198_(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY, \
4199 one_rloc_probe_enable_disable_reply) \
4200_(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply) \
4201_(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply) \
4202_(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply) \
4203_(ONE_LOCATOR_SET_DETAILS, one_locator_set_details) \
4204_(ONE_LOCATOR_DETAILS, one_locator_details) \
4205_(ONE_EID_TABLE_DETAILS, one_eid_table_details) \
4206_(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details) \
4207_(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details) \
4208_(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details) \
4209_(ONE_MAP_SERVER_DETAILS, one_map_server_details) \
4210_(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply) \
Filip Tehlar3e7b56932017-02-21 18:28:34 +01004211_(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply) \
4212_(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply) \
Filip Tehlar82786c42017-02-20 15:20:37 +01004213_(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply) \
Filip Tehlar694396d2017-02-17 14:29:11 +01004214_(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply) \
4215_(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply) \
Filip Tehlar82786c42017-02-20 15:20:37 +01004216_(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply) \
4217_(GPE_FWD_ENTRY_PATH_DETAILS, \
4218 gpe_fwd_entry_path_details) \
Filip Tehlar694396d2017-02-17 14:29:11 +01004219_(SHOW_ONE_STATUS_REPLY, show_one_status_reply) \
4220_(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY, \
4221 one_add_del_map_request_itr_rlocs_reply) \
4222_(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY, \
4223 one_get_map_request_itr_rlocs_reply) \
4224_(SHOW_ONE_PITR_REPLY, show_one_pitr_reply) \
4225_(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply) \
4226_(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply) \
4227_(SHOW_ONE_MAP_REGISTER_STATE_REPLY, \
4228 show_one_map_register_state_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01004229_(AF_PACKET_CREATE_REPLY, af_packet_create_reply) \
4230_(AF_PACKET_DELETE_REPLY, af_packet_delete_reply) \
4231_(POLICER_ADD_DEL_REPLY, policer_add_del_reply) \
4232_(POLICER_DETAILS, policer_details) \
4233_(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
4234_(POLICER_CLASSIFY_DETAILS, policer_classify_details) \
4235_(NETMAP_CREATE_REPLY, netmap_create_reply) \
4236_(NETMAP_DELETE_REPLY, netmap_delete_reply) \
4237_(MPLS_TUNNEL_DETAILS, mpls_tunnel_details) \
4238_(MPLS_FIB_DETAILS, mpls_fib_details) \
4239_(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply) \
4240_(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
4241_(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply) \
4242_(CLASSIFY_SESSION_DETAILS, classify_session_details) \
4243_(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply) \
4244_(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details) \
4245_(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply) \
4246_(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details) \
4247_(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
4248_(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details) \
4249_(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
4250_(FLOW_CLASSIFY_DETAILS, flow_classify_details) \
4251_(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
4252_(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details) \
4253_(GET_NEXT_INDEX_REPLY, get_next_index_reply) \
4254_(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply) \
4255_(PG_CAPTURE_REPLY, pg_capture_reply) \
4256_(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply) \
4257_(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY, \
4258 ip_source_and_port_range_check_add_del_reply) \
4259_(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY, \
4260 ip_source_and_port_range_check_interface_add_del_reply) \
4261_(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply) \
4262_(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details) \
4263_(DELETE_SUBIF_REPLY, delete_subif_reply) \
4264_(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
4265_(PUNT_REPLY, punt_reply) \
4266_(IP_FIB_DETAILS, ip_fib_details) \
4267_(IP6_FIB_DETAILS, ip6_fib_details) \
4268_(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply) \
4269_(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply) \
4270_(L2_XCONNECT_DETAILS, l2_xconnect_details) \
4271_(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply) \
4272_(IP_NEIGHBOR_DETAILS, ip_neighbor_details) \
4273_(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)
4274
Pavel Kotucek738f3f22017-01-09 15:11:03 +01004275#if DPDK > 0
4276#define foreach_vpe_dpdk_api_reply_msg \
4277_(SW_INTERFACE_SET_DPDK_HQOS_PIPE_REPLY, \
4278 sw_interface_set_dpdk_hqos_pipe_reply) \
4279_(SW_INTERFACE_SET_DPDK_HQOS_SUBPORT_REPLY, \
4280 sw_interface_set_dpdk_hqos_subport_reply) \
4281_(SW_INTERFACE_SET_DPDK_HQOS_TCTBL_REPLY, \
4282 sw_interface_set_dpdk_hqos_tctbl_reply)
4283#endif
4284
Damjan Marion7cd468a2016-12-19 23:05:39 +01004285typedef struct
4286{
4287 u8 *name;
4288 u32 value;
4289} name_sort_t;
4290
4291
4292#define STR_VTR_OP_CASE(op) \
4293 case L2_VTR_ ## op: \
4294 return "" # op;
4295
4296static const char *
4297str_vtr_op (u32 vtr_op)
4298{
4299 switch (vtr_op)
4300 {
4301 STR_VTR_OP_CASE (DISABLED);
4302 STR_VTR_OP_CASE (PUSH_1);
4303 STR_VTR_OP_CASE (PUSH_2);
4304 STR_VTR_OP_CASE (POP_1);
4305 STR_VTR_OP_CASE (POP_2);
4306 STR_VTR_OP_CASE (TRANSLATE_1_1);
4307 STR_VTR_OP_CASE (TRANSLATE_1_2);
4308 STR_VTR_OP_CASE (TRANSLATE_2_1);
4309 STR_VTR_OP_CASE (TRANSLATE_2_2);
4310 }
4311
4312 return "UNKNOWN";
4313}
4314
4315static int
4316dump_sub_interface_table (vat_main_t * vam)
4317{
4318 const sw_interface_subif_t *sub = NULL;
4319
4320 if (vam->json_output)
4321 {
4322 clib_warning
4323 ("JSON output supported only for VPE API calls and dump_stats_table");
4324 return -99;
4325 }
4326
4327 print (vam->ofp,
4328 "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
4329 "Interface", "sw_if_index",
4330 "sub id", "dot1ad", "tags", "outer id",
4331 "inner id", "exact", "default", "outer any", "inner any");
4332
4333 vec_foreach (sub, vam->sw_if_subif_table)
4334 {
4335 print (vam->ofp,
4336 "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
4337 sub->interface_name,
4338 sub->sw_if_index,
4339 sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
4340 sub->sub_number_of_tags, sub->sub_outer_vlan_id,
4341 sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
4342 sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
4343 if (sub->vtr_op != L2_VTR_DISABLED)
4344 {
4345 print (vam->ofp,
4346 " vlan-tag-rewrite - op: %-14s [ dot1q: %d "
4347 "tag1: %d tag2: %d ]",
4348 str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
4349 sub->vtr_tag1, sub->vtr_tag2);
4350 }
4351 }
4352
4353 return 0;
4354}
4355
4356static int
4357name_sort_cmp (void *a1, void *a2)
4358{
4359 name_sort_t *n1 = a1;
4360 name_sort_t *n2 = a2;
4361
4362 return strcmp ((char *) n1->name, (char *) n2->name);
4363}
4364
4365static int
4366dump_interface_table (vat_main_t * vam)
4367{
4368 hash_pair_t *p;
4369 name_sort_t *nses = 0, *ns;
4370
4371 if (vam->json_output)
4372 {
4373 clib_warning
4374 ("JSON output supported only for VPE API calls and dump_stats_table");
4375 return -99;
4376 }
4377
4378 /* *INDENT-OFF* */
4379 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4380 ({
4381 vec_add2 (nses, ns, 1);
4382 ns->name = (u8 *)(p->key);
4383 ns->value = (u32) p->value[0];
4384 }));
4385 /* *INDENT-ON* */
4386
4387 vec_sort_with_function (nses, name_sort_cmp);
4388
4389 print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
4390 vec_foreach (ns, nses)
4391 {
4392 print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
4393 }
4394 vec_free (nses);
4395 return 0;
4396}
4397
4398static int
4399dump_ip_table (vat_main_t * vam, int is_ipv6)
4400{
4401 const ip_details_t *det = NULL;
4402 const ip_address_details_t *address = NULL;
4403 u32 i = ~0;
4404
4405 print (vam->ofp, "%-12s", "sw_if_index");
4406
4407 vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
4408 {
4409 i++;
4410 if (!det->present)
4411 {
4412 continue;
4413 }
4414 print (vam->ofp, "%-12d", i);
4415 print (vam->ofp, " %-30s%-13s", "Address", "Prefix length");
4416 if (!det->addr)
4417 {
4418 continue;
4419 }
4420 vec_foreach (address, det->addr)
4421 {
4422 print (vam->ofp,
4423 " %-30U%-13d",
4424 is_ipv6 ? format_ip6_address : format_ip4_address,
4425 address->ip, address->prefix_length);
4426 }
4427 }
4428
4429 return 0;
4430}
4431
4432static int
4433dump_ipv4_table (vat_main_t * vam)
4434{
4435 if (vam->json_output)
4436 {
4437 clib_warning
4438 ("JSON output supported only for VPE API calls and dump_stats_table");
4439 return -99;
4440 }
4441
4442 return dump_ip_table (vam, 0);
4443}
4444
4445static int
4446dump_ipv6_table (vat_main_t * vam)
4447{
4448 if (vam->json_output)
4449 {
4450 clib_warning
4451 ("JSON output supported only for VPE API calls and dump_stats_table");
4452 return -99;
4453 }
4454
4455 return dump_ip_table (vam, 1);
4456}
4457
4458static char *
4459counter_type_to_str (u8 counter_type, u8 is_combined)
4460{
4461 if (!is_combined)
4462 {
4463 switch (counter_type)
4464 {
4465 case VNET_INTERFACE_COUNTER_DROP:
4466 return "drop";
4467 case VNET_INTERFACE_COUNTER_PUNT:
4468 return "punt";
4469 case VNET_INTERFACE_COUNTER_IP4:
4470 return "ip4";
4471 case VNET_INTERFACE_COUNTER_IP6:
4472 return "ip6";
4473 case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4474 return "rx-no-buf";
4475 case VNET_INTERFACE_COUNTER_RX_MISS:
4476 return "rx-miss";
4477 case VNET_INTERFACE_COUNTER_RX_ERROR:
4478 return "rx-error";
4479 case VNET_INTERFACE_COUNTER_TX_ERROR:
4480 return "tx-error";
4481 default:
4482 return "INVALID-COUNTER-TYPE";
4483 }
4484 }
4485 else
4486 {
4487 switch (counter_type)
4488 {
4489 case VNET_INTERFACE_COUNTER_RX:
4490 return "rx";
4491 case VNET_INTERFACE_COUNTER_TX:
4492 return "tx";
4493 default:
4494 return "INVALID-COUNTER-TYPE";
4495 }
4496 }
4497}
4498
4499static int
4500dump_stats_table (vat_main_t * vam)
4501{
4502 vat_json_node_t node;
4503 vat_json_node_t *msg_array;
4504 vat_json_node_t *msg;
4505 vat_json_node_t *counter_array;
4506 vat_json_node_t *counter;
4507 interface_counter_t c;
4508 u64 packets;
4509 ip4_fib_counter_t *c4;
4510 ip6_fib_counter_t *c6;
Neale Ranns044183f2017-01-24 01:34:25 -08004511 ip4_nbr_counter_t *n4;
4512 ip6_nbr_counter_t *n6;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004513 int i, j;
4514
4515 if (!vam->json_output)
4516 {
4517 clib_warning ("dump_stats_table supported only in JSON format");
4518 return -99;
4519 }
4520
4521 vat_json_init_object (&node);
4522
4523 /* interface counters */
4524 msg_array = vat_json_object_add (&node, "interface_counters");
4525 vat_json_init_array (msg_array);
4526 for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4527 {
4528 msg = vat_json_array_add (msg_array);
4529 vat_json_init_object (msg);
4530 vat_json_object_add_string_copy (msg, "vnet_counter_type",
4531 (u8 *) counter_type_to_str (i, 0));
4532 vat_json_object_add_int (msg, "is_combined", 0);
4533 counter_array = vat_json_object_add (msg, "data");
4534 vat_json_init_array (counter_array);
4535 for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4536 {
4537 packets = vam->simple_interface_counters[i][j];
4538 vat_json_array_add_uint (counter_array, packets);
4539 }
4540 }
4541 for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4542 {
4543 msg = vat_json_array_add (msg_array);
4544 vat_json_init_object (msg);
4545 vat_json_object_add_string_copy (msg, "vnet_counter_type",
4546 (u8 *) counter_type_to_str (i, 1));
4547 vat_json_object_add_int (msg, "is_combined", 1);
4548 counter_array = vat_json_object_add (msg, "data");
4549 vat_json_init_array (counter_array);
4550 for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4551 {
4552 c = vam->combined_interface_counters[i][j];
4553 counter = vat_json_array_add (counter_array);
4554 vat_json_init_object (counter);
4555 vat_json_object_add_uint (counter, "packets", c.packets);
4556 vat_json_object_add_uint (counter, "bytes", c.bytes);
4557 }
4558 }
4559
4560 /* ip4 fib counters */
4561 msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4562 vat_json_init_array (msg_array);
4563 for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4564 {
4565 msg = vat_json_array_add (msg_array);
4566 vat_json_init_object (msg);
4567 vat_json_object_add_uint (msg, "vrf_id",
4568 vam->ip4_fib_counters_vrf_id_by_index[i]);
4569 counter_array = vat_json_object_add (msg, "c");
4570 vat_json_init_array (counter_array);
4571 for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4572 {
4573 counter = vat_json_array_add (counter_array);
4574 vat_json_init_object (counter);
4575 c4 = &vam->ip4_fib_counters[i][j];
4576 vat_json_object_add_ip4 (counter, "address", c4->address);
4577 vat_json_object_add_uint (counter, "address_length",
4578 c4->address_length);
4579 vat_json_object_add_uint (counter, "packets", c4->packets);
4580 vat_json_object_add_uint (counter, "bytes", c4->bytes);
4581 }
4582 }
4583
4584 /* ip6 fib counters */
4585 msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4586 vat_json_init_array (msg_array);
4587 for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4588 {
4589 msg = vat_json_array_add (msg_array);
4590 vat_json_init_object (msg);
4591 vat_json_object_add_uint (msg, "vrf_id",
4592 vam->ip6_fib_counters_vrf_id_by_index[i]);
4593 counter_array = vat_json_object_add (msg, "c");
4594 vat_json_init_array (counter_array);
4595 for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4596 {
4597 counter = vat_json_array_add (counter_array);
4598 vat_json_init_object (counter);
4599 c6 = &vam->ip6_fib_counters[i][j];
4600 vat_json_object_add_ip6 (counter, "address", c6->address);
4601 vat_json_object_add_uint (counter, "address_length",
4602 c6->address_length);
4603 vat_json_object_add_uint (counter, "packets", c6->packets);
4604 vat_json_object_add_uint (counter, "bytes", c6->bytes);
4605 }
4606 }
4607
Neale Ranns044183f2017-01-24 01:34:25 -08004608 /* ip4 nbr counters */
4609 msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
4610 vat_json_init_array (msg_array);
4611 for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
4612 {
4613 msg = vat_json_array_add (msg_array);
4614 vat_json_init_object (msg);
4615 vat_json_object_add_uint (msg, "sw_if_index", i);
4616 counter_array = vat_json_object_add (msg, "c");
4617 vat_json_init_array (counter_array);
4618 for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
4619 {
4620 counter = vat_json_array_add (counter_array);
4621 vat_json_init_object (counter);
4622 n4 = &vam->ip4_nbr_counters[i][j];
4623 vat_json_object_add_ip4 (counter, "address", n4->address);
4624 vat_json_object_add_uint (counter, "link-type", n4->linkt);
4625 vat_json_object_add_uint (counter, "packets", n4->packets);
4626 vat_json_object_add_uint (counter, "bytes", n4->bytes);
4627 }
4628 }
4629
4630 /* ip6 nbr counters */
4631 msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
4632 vat_json_init_array (msg_array);
4633 for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
4634 {
4635 msg = vat_json_array_add (msg_array);
4636 vat_json_init_object (msg);
4637 vat_json_object_add_uint (msg, "sw_if_index", i);
4638 counter_array = vat_json_object_add (msg, "c");
4639 vat_json_init_array (counter_array);
4640 for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
4641 {
4642 counter = vat_json_array_add (counter_array);
4643 vat_json_init_object (counter);
4644 n6 = &vam->ip6_nbr_counters[i][j];
4645 vat_json_object_add_ip6 (counter, "address", n6->address);
4646 vat_json_object_add_uint (counter, "packets", n6->packets);
4647 vat_json_object_add_uint (counter, "bytes", n6->bytes);
4648 }
4649 }
4650
Damjan Marion7cd468a2016-12-19 23:05:39 +01004651 vat_json_print (vam->ofp, &node);
4652 vat_json_free (&node);
4653
4654 return 0;
4655}
4656
4657int
4658exec (vat_main_t * vam)
4659{
4660 api_main_t *am = &api_main;
4661 vl_api_cli_request_t *mp;
4662 f64 timeout;
4663 void *oldheap;
4664 u8 *cmd = 0;
4665 unformat_input_t *i = vam->input;
4666
4667 if (vec_len (i->buffer) == 0)
4668 return -1;
4669
4670 if (vam->exec_mode == 0 && unformat (i, "mode"))
4671 {
4672 vam->exec_mode = 1;
4673 return 0;
4674 }
4675 if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4676 {
4677 vam->exec_mode = 0;
4678 return 0;
4679 }
4680
4681
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004682 M (CLI_REQUEST, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004683
4684 /*
4685 * Copy cmd into shared memory.
4686 * In order for the CLI command to work, it
4687 * must be a vector ending in \n, not a C-string ending
4688 * in \n\0.
4689 */
4690 pthread_mutex_lock (&am->vlib_rp->mutex);
4691 oldheap = svm_push_data_heap (am->vlib_rp);
4692
4693 vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4694 clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4695
4696 svm_pop_heap (oldheap);
4697 pthread_mutex_unlock (&am->vlib_rp->mutex);
4698
4699 mp->cmd_in_shmem = (u64) cmd;
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004700 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004701 timeout = vat_time_now (vam) + 10.0;
4702
4703 while (vat_time_now (vam) < timeout)
4704 {
4705 if (vam->result_ready == 1)
4706 {
4707 u8 *free_me;
4708 if (vam->shmem_result != NULL)
4709 print (vam->ofp, "%s", vam->shmem_result);
4710 pthread_mutex_lock (&am->vlib_rp->mutex);
4711 oldheap = svm_push_data_heap (am->vlib_rp);
4712
4713 free_me = (u8 *) vam->shmem_result;
4714 vec_free (free_me);
4715
4716 svm_pop_heap (oldheap);
4717 pthread_mutex_unlock (&am->vlib_rp->mutex);
4718 return 0;
4719 }
4720 }
4721 return -99;
4722}
4723
4724/*
4725 * Future replacement of exec() that passes CLI buffers directly in
4726 * the API messages instead of an additional shared memory area.
4727 */
4728static int
4729exec_inband (vat_main_t * vam)
4730{
4731 vl_api_cli_inband_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004732 unformat_input_t *i = vam->input;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004733 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004734
4735 if (vec_len (i->buffer) == 0)
4736 return -1;
4737
4738 if (vam->exec_mode == 0 && unformat (i, "mode"))
4739 {
4740 vam->exec_mode = 1;
4741 return 0;
4742 }
4743 if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4744 {
4745 vam->exec_mode = 0;
4746 return 0;
4747 }
4748
4749 /*
4750 * In order for the CLI command to work, it
4751 * must be a vector ending in \n, not a C-string ending
4752 * in \n\0.
4753 */
4754 u32 len = vec_len (vam->input->buffer);
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004755 M2 (CLI_INBAND, mp, len);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004756 clib_memcpy (mp->cmd, vam->input->buffer, len);
4757 mp->length = htonl (len);
4758
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004759 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06004760 W2 (ret, print (vam->ofp, "%s", vam->cmd_reply));
4761 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004762}
4763
4764static int
4765api_create_loopback (vat_main_t * vam)
4766{
4767 unformat_input_t *i = vam->input;
4768 vl_api_create_loopback_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004769 u8 mac_address[6];
4770 u8 mac_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004771 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004772
4773 memset (mac_address, 0, sizeof (mac_address));
4774
4775 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4776 {
4777 if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4778 mac_set = 1;
4779 else
4780 break;
4781 }
4782
4783 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004784 M (CREATE_LOOPBACK, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004785 if (mac_set)
4786 clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4787
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004788 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06004789 W (ret);
4790 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004791}
4792
4793static int
4794api_delete_loopback (vat_main_t * vam)
4795{
4796 unformat_input_t *i = vam->input;
4797 vl_api_delete_loopback_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004798 u32 sw_if_index = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004799 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004800
4801 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4802 {
4803 if (unformat (i, "sw_if_index %d", &sw_if_index))
4804 ;
4805 else
4806 break;
4807 }
4808
4809 if (sw_if_index == ~0)
4810 {
4811 errmsg ("missing sw_if_index");
4812 return -99;
4813 }
4814
4815 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004816 M (DELETE_LOOPBACK, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004817 mp->sw_if_index = ntohl (sw_if_index);
4818
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004819 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06004820 W (ret);
4821 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004822}
4823
4824static int
4825api_want_stats (vat_main_t * vam)
4826{
4827 unformat_input_t *i = vam->input;
4828 vl_api_want_stats_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004829 int enable = -1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004830 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004831
4832 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4833 {
4834 if (unformat (i, "enable"))
4835 enable = 1;
4836 else if (unformat (i, "disable"))
4837 enable = 0;
4838 else
4839 break;
4840 }
4841
4842 if (enable == -1)
4843 {
4844 errmsg ("missing enable|disable");
4845 return -99;
4846 }
4847
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004848 M (WANT_STATS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004849 mp->enable_disable = enable;
4850
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004851 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06004852 W (ret);
4853 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004854}
4855
4856static int
4857api_want_interface_events (vat_main_t * vam)
4858{
4859 unformat_input_t *i = vam->input;
4860 vl_api_want_interface_events_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004861 int enable = -1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004862 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004863
4864 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4865 {
4866 if (unformat (i, "enable"))
4867 enable = 1;
4868 else if (unformat (i, "disable"))
4869 enable = 0;
4870 else
4871 break;
4872 }
4873
4874 if (enable == -1)
4875 {
4876 errmsg ("missing enable|disable");
4877 return -99;
4878 }
4879
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004880 M (WANT_INTERFACE_EVENTS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004881 mp->enable_disable = enable;
4882
4883 vam->interface_event_display = enable;
4884
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004885 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06004886 W (ret);
4887 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004888}
4889
4890
4891/* Note: non-static, called once to set up the initial intfc table */
4892int
4893api_sw_interface_dump (vat_main_t * vam)
4894{
4895 vl_api_sw_interface_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -06004896 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004897 hash_pair_t *p;
4898 name_sort_t *nses = 0, *ns;
4899 sw_interface_subif_t *sub = NULL;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004900 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004901
4902 /* Toss the old name table */
4903 /* *INDENT-OFF* */
4904 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4905 ({
4906 vec_add2 (nses, ns, 1);
4907 ns->name = (u8 *)(p->key);
4908 ns->value = (u32) p->value[0];
4909 }));
4910 /* *INDENT-ON* */
4911
4912 hash_free (vam->sw_if_index_by_interface_name);
4913
4914 vec_foreach (ns, nses) vec_free (ns->name);
4915
4916 vec_free (nses);
4917
4918 vec_foreach (sub, vam->sw_if_subif_table)
4919 {
4920 vec_free (sub->interface_name);
4921 }
4922 vec_free (vam->sw_if_subif_table);
4923
4924 /* recreate the interface name hash table */
4925 vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4926
4927 /* Get list of ethernets */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004928 M (SW_INTERFACE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004929 mp->name_filter_valid = 1;
4930 strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004931 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004932
4933 /* and local / loopback interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004934 M (SW_INTERFACE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004935 mp->name_filter_valid = 1;
4936 strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004937 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004938
4939 /* and packet-generator interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004940 M (SW_INTERFACE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004941 mp->name_filter_valid = 1;
4942 strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004943 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004944
4945 /* and vxlan-gpe tunnel interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004946 M (SW_INTERFACE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004947 mp->name_filter_valid = 1;
4948 strncpy ((char *) mp->name_filter, "vxlan_gpe",
4949 sizeof (mp->name_filter) - 1);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004950 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004951
4952 /* and vxlan tunnel interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004953 M (SW_INTERFACE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004954 mp->name_filter_valid = 1;
4955 strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004956 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004957
4958 /* and host (af_packet) interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004959 M (SW_INTERFACE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004960 mp->name_filter_valid = 1;
4961 strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004962 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004963
4964 /* and l2tpv3 tunnel interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004965 M (SW_INTERFACE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004966 mp->name_filter_valid = 1;
4967 strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4968 sizeof (mp->name_filter) - 1);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004969 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004970
4971 /* and GRE tunnel interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004972 M (SW_INTERFACE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004973 mp->name_filter_valid = 1;
4974 strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004975 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004976
4977 /* and LISP-GPE interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004978 M (SW_INTERFACE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004979 mp->name_filter_valid = 1;
4980 strncpy ((char *) mp->name_filter, "lisp_gpe",
4981 sizeof (mp->name_filter) - 1);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004982 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004983
4984 /* and IPSEC tunnel interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004985 M (SW_INTERFACE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004986 mp->name_filter_valid = 1;
4987 strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004988 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004989
4990 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -06004991 M (CONTROL_PING, mp_ping);
4992 S (mp_ping);
4993
Jon Loeliger56c7b012017-02-01 12:31:41 -06004994 W (ret);
4995 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004996}
4997
4998static int
4999api_sw_interface_set_flags (vat_main_t * vam)
5000{
5001 unformat_input_t *i = vam->input;
5002 vl_api_sw_interface_set_flags_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005003 u32 sw_if_index;
5004 u8 sw_if_index_set = 0;
5005 u8 admin_up = 0, link_up = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005006 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005007
5008 /* Parse args required to build the message */
5009 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5010 {
5011 if (unformat (i, "admin-up"))
5012 admin_up = 1;
5013 else if (unformat (i, "admin-down"))
5014 admin_up = 0;
5015 else if (unformat (i, "link-up"))
5016 link_up = 1;
5017 else if (unformat (i, "link-down"))
5018 link_up = 0;
5019 else
5020 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5021 sw_if_index_set = 1;
5022 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5023 sw_if_index_set = 1;
5024 else
5025 break;
5026 }
5027
5028 if (sw_if_index_set == 0)
5029 {
5030 errmsg ("missing interface name or sw_if_index");
5031 return -99;
5032 }
5033
5034 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005035 M (SW_INTERFACE_SET_FLAGS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005036 mp->sw_if_index = ntohl (sw_if_index);
5037 mp->admin_up_down = admin_up;
5038 mp->link_up_down = link_up;
5039
5040 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005041 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005042
5043 /* Wait for a reply, return the good/bad news... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06005044 W (ret);
5045 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005046}
5047
5048static int
5049api_sw_interface_clear_stats (vat_main_t * vam)
5050{
5051 unformat_input_t *i = vam->input;
5052 vl_api_sw_interface_clear_stats_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005053 u32 sw_if_index;
5054 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005055 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005056
5057 /* Parse args required to build the message */
5058 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5059 {
5060 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5061 sw_if_index_set = 1;
5062 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5063 sw_if_index_set = 1;
5064 else
5065 break;
5066 }
5067
5068 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005069 M (SW_INTERFACE_CLEAR_STATS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005070
5071 if (sw_if_index_set == 1)
5072 mp->sw_if_index = ntohl (sw_if_index);
5073 else
5074 mp->sw_if_index = ~0;
5075
5076 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005077 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005078
5079 /* Wait for a reply, return the good/bad news... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06005080 W (ret);
5081 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005082}
5083
Pavel Kotucek738f3f22017-01-09 15:11:03 +01005084#if DPDK >0
Damjan Marion7cd468a2016-12-19 23:05:39 +01005085static int
5086api_sw_interface_set_dpdk_hqos_pipe (vat_main_t * vam)
5087{
5088 unformat_input_t *i = vam->input;
5089 vl_api_sw_interface_set_dpdk_hqos_pipe_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005090 u32 sw_if_index;
5091 u8 sw_if_index_set = 0;
5092 u32 subport;
5093 u8 subport_set = 0;
5094 u32 pipe;
5095 u8 pipe_set = 0;
5096 u32 profile;
5097 u8 profile_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005098 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005099
5100 /* Parse args required to build the message */
5101 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5102 {
5103 if (unformat (i, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
5104 sw_if_index_set = 1;
5105 else if (unformat (i, "sw_if_index %u", &sw_if_index))
5106 sw_if_index_set = 1;
5107 else if (unformat (i, "subport %u", &subport))
5108 subport_set = 1;
5109 else
5110 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5111 sw_if_index_set = 1;
5112 else if (unformat (i, "pipe %u", &pipe))
5113 pipe_set = 1;
5114 else if (unformat (i, "profile %u", &profile))
5115 profile_set = 1;
5116 else
5117 break;
5118 }
5119
5120 if (sw_if_index_set == 0)
5121 {
5122 errmsg ("missing interface name or sw_if_index");
5123 return -99;
5124 }
5125
5126 if (subport_set == 0)
5127 {
5128 errmsg ("missing subport ");
5129 return -99;
5130 }
5131
5132 if (pipe_set == 0)
5133 {
5134 errmsg ("missing pipe");
5135 return -99;
5136 }
5137
5138 if (profile_set == 0)
5139 {
5140 errmsg ("missing profile");
5141 return -99;
5142 }
5143
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005144 M (SW_INTERFACE_SET_DPDK_HQOS_PIPE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005145
5146 mp->sw_if_index = ntohl (sw_if_index);
5147 mp->subport = ntohl (subport);
5148 mp->pipe = ntohl (pipe);
5149 mp->profile = ntohl (profile);
5150
5151
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005152 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06005153 W (ret);
5154 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005155}
5156
5157static int
5158api_sw_interface_set_dpdk_hqos_subport (vat_main_t * vam)
5159{
5160 unformat_input_t *i = vam->input;
5161 vl_api_sw_interface_set_dpdk_hqos_subport_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005162 u32 sw_if_index;
5163 u8 sw_if_index_set = 0;
5164 u32 subport;
5165 u8 subport_set = 0;
5166 u32 tb_rate = 1250000000; /* 10GbE */
5167 u32 tb_size = 1000000;
5168 u32 tc_rate[] = { 1250000000, 1250000000, 1250000000, 1250000000 };
5169 u32 tc_period = 10;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005170 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005171
5172 /* Parse args required to build the message */
5173 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5174 {
5175 if (unformat (i, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
5176 sw_if_index_set = 1;
5177 else if (unformat (i, "sw_if_index %u", &sw_if_index))
5178 sw_if_index_set = 1;
5179 else if (unformat (i, "subport %u", &subport))
5180 subport_set = 1;
5181 else
5182 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5183 sw_if_index_set = 1;
5184 else if (unformat (i, "rate %u", &tb_rate))
5185 {
5186 u32 tc_id;
5187
5188 for (tc_id = 0; tc_id < (sizeof (tc_rate) / sizeof (tc_rate[0]));
5189 tc_id++)
5190 tc_rate[tc_id] = tb_rate;
5191 }
5192 else if (unformat (i, "bktsize %u", &tb_size))
5193 ;
5194 else if (unformat (i, "tc0 %u", &tc_rate[0]))
5195 ;
5196 else if (unformat (i, "tc1 %u", &tc_rate[1]))
5197 ;
5198 else if (unformat (i, "tc2 %u", &tc_rate[2]))
5199 ;
5200 else if (unformat (i, "tc3 %u", &tc_rate[3]))
5201 ;
5202 else if (unformat (i, "period %u", &tc_period))
5203 ;
5204 else
5205 break;
5206 }
5207
5208 if (sw_if_index_set == 0)
5209 {
5210 errmsg ("missing interface name or sw_if_index");
5211 return -99;
5212 }
5213
5214 if (subport_set == 0)
5215 {
5216 errmsg ("missing subport ");
5217 return -99;
5218 }
5219
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005220 M (SW_INTERFACE_SET_DPDK_HQOS_SUBPORT, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005221
5222 mp->sw_if_index = ntohl (sw_if_index);
5223 mp->subport = ntohl (subport);
5224 mp->tb_rate = ntohl (tb_rate);
5225 mp->tb_size = ntohl (tb_size);
5226 mp->tc_rate[0] = ntohl (tc_rate[0]);
5227 mp->tc_rate[1] = ntohl (tc_rate[1]);
5228 mp->tc_rate[2] = ntohl (tc_rate[2]);
5229 mp->tc_rate[3] = ntohl (tc_rate[3]);
5230 mp->tc_period = ntohl (tc_period);
5231
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005232 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06005233 W (ret);
5234 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005235}
5236
5237static int
5238api_sw_interface_set_dpdk_hqos_tctbl (vat_main_t * vam)
5239{
5240 unformat_input_t *i = vam->input;
5241 vl_api_sw_interface_set_dpdk_hqos_tctbl_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005242 u32 sw_if_index;
5243 u8 sw_if_index_set = 0;
5244 u8 entry_set = 0;
5245 u8 tc_set = 0;
5246 u8 queue_set = 0;
5247 u32 entry, tc, queue;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005248 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005249
5250 /* Parse args required to build the message */
5251 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5252 {
5253 if (unformat (i, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
5254 sw_if_index_set = 1;
5255 else if (unformat (i, "sw_if_index %u", &sw_if_index))
5256 sw_if_index_set = 1;
5257 else if (unformat (i, "entry %d", &entry))
5258 entry_set = 1;
5259 else if (unformat (i, "tc %d", &tc))
5260 tc_set = 1;
5261 else if (unformat (i, "queue %d", &queue))
5262 queue_set = 1;
5263 else
5264 break;
5265 }
5266
5267 if (sw_if_index_set == 0)
5268 {
5269 errmsg ("missing interface name or sw_if_index");
5270 return -99;
5271 }
5272
5273 if (entry_set == 0)
5274 {
5275 errmsg ("missing entry ");
5276 return -99;
5277 }
5278
5279 if (tc_set == 0)
5280 {
5281 errmsg ("missing traffic class ");
5282 return -99;
5283 }
5284
5285 if (queue_set == 0)
5286 {
5287 errmsg ("missing queue ");
5288 return -99;
5289 }
5290
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005291 M (SW_INTERFACE_SET_DPDK_HQOS_TCTBL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005292
5293 mp->sw_if_index = ntohl (sw_if_index);
5294 mp->entry = ntohl (entry);
5295 mp->tc = ntohl (tc);
5296 mp->queue = ntohl (queue);
5297
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005298 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06005299 W (ret);
5300 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005301}
Pavel Kotucek738f3f22017-01-09 15:11:03 +01005302#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +01005303
5304static int
5305api_sw_interface_add_del_address (vat_main_t * vam)
5306{
5307 unformat_input_t *i = vam->input;
5308 vl_api_sw_interface_add_del_address_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005309 u32 sw_if_index;
5310 u8 sw_if_index_set = 0;
5311 u8 is_add = 1, del_all = 0;
5312 u32 address_length = 0;
5313 u8 v4_address_set = 0;
5314 u8 v6_address_set = 0;
5315 ip4_address_t v4address;
5316 ip6_address_t v6address;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005317 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005318
5319 /* Parse args required to build the message */
5320 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5321 {
5322 if (unformat (i, "del-all"))
5323 del_all = 1;
5324 else if (unformat (i, "del"))
5325 is_add = 0;
5326 else
5327 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5328 sw_if_index_set = 1;
5329 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5330 sw_if_index_set = 1;
5331 else if (unformat (i, "%U/%d",
5332 unformat_ip4_address, &v4address, &address_length))
5333 v4_address_set = 1;
5334 else if (unformat (i, "%U/%d",
5335 unformat_ip6_address, &v6address, &address_length))
5336 v6_address_set = 1;
5337 else
5338 break;
5339 }
5340
5341 if (sw_if_index_set == 0)
5342 {
5343 errmsg ("missing interface name or sw_if_index");
5344 return -99;
5345 }
5346 if (v4_address_set && v6_address_set)
5347 {
5348 errmsg ("both v4 and v6 addresses set");
5349 return -99;
5350 }
5351 if (!v4_address_set && !v6_address_set && !del_all)
5352 {
5353 errmsg ("no addresses set");
5354 return -99;
5355 }
5356
5357 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005358 M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005359
5360 mp->sw_if_index = ntohl (sw_if_index);
5361 mp->is_add = is_add;
5362 mp->del_all = del_all;
5363 if (v6_address_set)
5364 {
5365 mp->is_ipv6 = 1;
5366 clib_memcpy (mp->address, &v6address, sizeof (v6address));
5367 }
5368 else
5369 {
5370 clib_memcpy (mp->address, &v4address, sizeof (v4address));
5371 }
5372 mp->address_length = address_length;
5373
5374 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005375 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005376
5377 /* Wait for a reply, return good/bad news */
Jon Loeliger56c7b012017-02-01 12:31:41 -06005378 W (ret);
5379 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005380}
5381
5382static int
5383api_sw_interface_set_mpls_enable (vat_main_t * vam)
5384{
5385 unformat_input_t *i = vam->input;
5386 vl_api_sw_interface_set_mpls_enable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005387 u32 sw_if_index;
5388 u8 sw_if_index_set = 0;
5389 u8 enable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005390 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005391
5392 /* Parse args required to build the message */
5393 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5394 {
5395 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5396 sw_if_index_set = 1;
5397 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5398 sw_if_index_set = 1;
5399 else if (unformat (i, "disable"))
5400 enable = 0;
5401 else if (unformat (i, "dis"))
5402 enable = 0;
5403 else
5404 break;
5405 }
5406
5407 if (sw_if_index_set == 0)
5408 {
5409 errmsg ("missing interface name or sw_if_index");
5410 return -99;
5411 }
5412
5413 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005414 M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005415
5416 mp->sw_if_index = ntohl (sw_if_index);
5417 mp->enable = enable;
5418
5419 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005420 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005421
5422 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06005423 W (ret);
5424 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005425}
5426
5427static int
5428api_sw_interface_set_table (vat_main_t * vam)
5429{
5430 unformat_input_t *i = vam->input;
5431 vl_api_sw_interface_set_table_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005432 u32 sw_if_index, vrf_id = 0;
5433 u8 sw_if_index_set = 0;
5434 u8 is_ipv6 = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005435 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005436
5437 /* Parse args required to build the message */
5438 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5439 {
5440 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5441 sw_if_index_set = 1;
5442 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5443 sw_if_index_set = 1;
5444 else if (unformat (i, "vrf %d", &vrf_id))
5445 ;
5446 else if (unformat (i, "ipv6"))
5447 is_ipv6 = 1;
5448 else
5449 break;
5450 }
5451
5452 if (sw_if_index_set == 0)
5453 {
5454 errmsg ("missing interface name or sw_if_index");
5455 return -99;
5456 }
5457
5458 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005459 M (SW_INTERFACE_SET_TABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005460
5461 mp->sw_if_index = ntohl (sw_if_index);
5462 mp->is_ipv6 = is_ipv6;
5463 mp->vrf_id = ntohl (vrf_id);
5464
5465 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005466 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005467
5468 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06005469 W (ret);
5470 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005471}
5472
5473static void vl_api_sw_interface_get_table_reply_t_handler
5474 (vl_api_sw_interface_get_table_reply_t * mp)
5475{
5476 vat_main_t *vam = &vat_main;
5477
5478 print (vam->ofp, "%d", ntohl (mp->vrf_id));
5479
5480 vam->retval = ntohl (mp->retval);
5481 vam->result_ready = 1;
5482
5483}
5484
5485static void vl_api_sw_interface_get_table_reply_t_handler_json
5486 (vl_api_sw_interface_get_table_reply_t * mp)
5487{
5488 vat_main_t *vam = &vat_main;
5489 vat_json_node_t node;
5490
5491 vat_json_init_object (&node);
5492 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5493 vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
5494
5495 vat_json_print (vam->ofp, &node);
5496 vat_json_free (&node);
5497
5498 vam->retval = ntohl (mp->retval);
5499 vam->result_ready = 1;
5500}
5501
5502static int
5503api_sw_interface_get_table (vat_main_t * vam)
5504{
5505 unformat_input_t *i = vam->input;
5506 vl_api_sw_interface_get_table_t *mp;
5507 u32 sw_if_index;
5508 u8 sw_if_index_set = 0;
5509 u8 is_ipv6 = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005510 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005511
5512 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5513 {
5514 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5515 sw_if_index_set = 1;
5516 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5517 sw_if_index_set = 1;
5518 else if (unformat (i, "ipv6"))
5519 is_ipv6 = 1;
5520 else
5521 break;
5522 }
5523
5524 if (sw_if_index_set == 0)
5525 {
5526 errmsg ("missing interface name or sw_if_index");
5527 return -99;
5528 }
5529
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005530 M (SW_INTERFACE_GET_TABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005531 mp->sw_if_index = htonl (sw_if_index);
5532 mp->is_ipv6 = is_ipv6;
5533
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005534 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06005535 W (ret);
5536 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005537}
5538
5539static int
5540api_sw_interface_set_vpath (vat_main_t * vam)
5541{
5542 unformat_input_t *i = vam->input;
5543 vl_api_sw_interface_set_vpath_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005544 u32 sw_if_index = 0;
5545 u8 sw_if_index_set = 0;
5546 u8 is_enable = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005547 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005548
5549 /* Parse args required to build the message */
5550 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5551 {
5552 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5553 sw_if_index_set = 1;
5554 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5555 sw_if_index_set = 1;
5556 else if (unformat (i, "enable"))
5557 is_enable = 1;
5558 else if (unformat (i, "disable"))
5559 is_enable = 0;
5560 else
5561 break;
5562 }
5563
5564 if (sw_if_index_set == 0)
5565 {
5566 errmsg ("missing interface name or sw_if_index");
5567 return -99;
5568 }
5569
5570 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005571 M (SW_INTERFACE_SET_VPATH, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005572
5573 mp->sw_if_index = ntohl (sw_if_index);
5574 mp->enable = is_enable;
5575
5576 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005577 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005578
5579 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06005580 W (ret);
5581 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005582}
5583
5584static int
5585api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
5586{
5587 unformat_input_t *i = vam->input;
5588 vl_api_sw_interface_set_vxlan_bypass_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005589 u32 sw_if_index = 0;
5590 u8 sw_if_index_set = 0;
John Lo2b81eb82017-01-30 13:12:10 -05005591 u8 is_enable = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005592 u8 is_ipv6 = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005593 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005594
5595 /* Parse args required to build the message */
5596 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5597 {
5598 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5599 sw_if_index_set = 1;
5600 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5601 sw_if_index_set = 1;
5602 else if (unformat (i, "enable"))
5603 is_enable = 1;
5604 else if (unformat (i, "disable"))
5605 is_enable = 0;
5606 else if (unformat (i, "ip4"))
5607 is_ipv6 = 0;
5608 else if (unformat (i, "ip6"))
5609 is_ipv6 = 1;
5610 else
5611 break;
5612 }
5613
5614 if (sw_if_index_set == 0)
5615 {
5616 errmsg ("missing interface name or sw_if_index");
5617 return -99;
5618 }
5619
5620 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005621 M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005622
5623 mp->sw_if_index = ntohl (sw_if_index);
5624 mp->enable = is_enable;
5625 mp->is_ipv6 = is_ipv6;
5626
5627 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005628 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005629
5630 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06005631 W (ret);
5632 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005633}
5634
5635static int
5636api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5637{
5638 unformat_input_t *i = vam->input;
5639 vl_api_sw_interface_set_l2_xconnect_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005640 u32 rx_sw_if_index;
5641 u8 rx_sw_if_index_set = 0;
5642 u32 tx_sw_if_index;
5643 u8 tx_sw_if_index_set = 0;
5644 u8 enable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005645 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005646
5647 /* Parse args required to build the message */
5648 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5649 {
5650 if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5651 rx_sw_if_index_set = 1;
5652 else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5653 tx_sw_if_index_set = 1;
5654 else if (unformat (i, "rx"))
5655 {
5656 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5657 {
5658 if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5659 &rx_sw_if_index))
5660 rx_sw_if_index_set = 1;
5661 }
5662 else
5663 break;
5664 }
5665 else if (unformat (i, "tx"))
5666 {
5667 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5668 {
5669 if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5670 &tx_sw_if_index))
5671 tx_sw_if_index_set = 1;
5672 }
5673 else
5674 break;
5675 }
5676 else if (unformat (i, "enable"))
5677 enable = 1;
5678 else if (unformat (i, "disable"))
5679 enable = 0;
5680 else
5681 break;
5682 }
5683
5684 if (rx_sw_if_index_set == 0)
5685 {
5686 errmsg ("missing rx interface name or rx_sw_if_index");
5687 return -99;
5688 }
5689
5690 if (enable && (tx_sw_if_index_set == 0))
5691 {
5692 errmsg ("missing tx interface name or tx_sw_if_index");
5693 return -99;
5694 }
5695
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005696 M (SW_INTERFACE_SET_L2_XCONNECT, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005697
5698 mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5699 mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5700 mp->enable = enable;
5701
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005702 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06005703 W (ret);
5704 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005705}
5706
5707static int
5708api_sw_interface_set_l2_bridge (vat_main_t * vam)
5709{
5710 unformat_input_t *i = vam->input;
5711 vl_api_sw_interface_set_l2_bridge_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005712 u32 rx_sw_if_index;
5713 u8 rx_sw_if_index_set = 0;
5714 u32 bd_id;
5715 u8 bd_id_set = 0;
5716 u8 bvi = 0;
5717 u32 shg = 0;
5718 u8 enable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005719 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005720
5721 /* Parse args required to build the message */
5722 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5723 {
5724 if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5725 rx_sw_if_index_set = 1;
5726 else if (unformat (i, "bd_id %d", &bd_id))
5727 bd_id_set = 1;
5728 else
5729 if (unformat
5730 (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
5731 rx_sw_if_index_set = 1;
5732 else if (unformat (i, "shg %d", &shg))
5733 ;
5734 else if (unformat (i, "bvi"))
5735 bvi = 1;
5736 else if (unformat (i, "enable"))
5737 enable = 1;
5738 else if (unformat (i, "disable"))
5739 enable = 0;
5740 else
5741 break;
5742 }
5743
5744 if (rx_sw_if_index_set == 0)
5745 {
5746 errmsg ("missing rx interface name or sw_if_index");
5747 return -99;
5748 }
5749
5750 if (enable && (bd_id_set == 0))
5751 {
5752 errmsg ("missing bridge domain");
5753 return -99;
5754 }
5755
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005756 M (SW_INTERFACE_SET_L2_BRIDGE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005757
5758 mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5759 mp->bd_id = ntohl (bd_id);
5760 mp->shg = (u8) shg;
5761 mp->bvi = bvi;
5762 mp->enable = enable;
5763
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005764 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06005765 W (ret);
5766 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005767}
5768
5769static int
5770api_bridge_domain_dump (vat_main_t * vam)
5771{
5772 unformat_input_t *i = vam->input;
5773 vl_api_bridge_domain_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -06005774 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005775 u32 bd_id = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005776 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005777
5778 /* Parse args required to build the message */
5779 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5780 {
5781 if (unformat (i, "bd_id %d", &bd_id))
5782 ;
5783 else
5784 break;
5785 }
5786
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005787 M (BRIDGE_DOMAIN_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005788 mp->bd_id = ntohl (bd_id);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005789 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005790
5791 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -06005792 M (CONTROL_PING, mp_ping);
5793 S (mp_ping);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005794
Jon Loeliger56c7b012017-02-01 12:31:41 -06005795 W (ret);
5796 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005797}
5798
5799static int
5800api_bridge_domain_add_del (vat_main_t * vam)
5801{
5802 unformat_input_t *i = vam->input;
5803 vl_api_bridge_domain_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005804 u32 bd_id = ~0;
5805 u8 is_add = 1;
5806 u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5807 u32 mac_age = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005808 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005809
5810 /* Parse args required to build the message */
5811 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5812 {
5813 if (unformat (i, "bd_id %d", &bd_id))
5814 ;
5815 else if (unformat (i, "flood %d", &flood))
5816 ;
5817 else if (unformat (i, "uu-flood %d", &uu_flood))
5818 ;
5819 else if (unformat (i, "forward %d", &forward))
5820 ;
5821 else if (unformat (i, "learn %d", &learn))
5822 ;
5823 else if (unformat (i, "arp-term %d", &arp_term))
5824 ;
5825 else if (unformat (i, "mac-age %d", &mac_age))
5826 ;
5827 else if (unformat (i, "del"))
5828 {
5829 is_add = 0;
5830 flood = uu_flood = forward = learn = 0;
5831 }
5832 else
5833 break;
5834 }
5835
5836 if (bd_id == ~0)
5837 {
5838 errmsg ("missing bridge domain");
5839 return -99;
5840 }
5841
5842 if (mac_age > 255)
5843 {
5844 errmsg ("mac age must be less than 256 ");
5845 return -99;
5846 }
5847
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005848 M (BRIDGE_DOMAIN_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005849
5850 mp->bd_id = ntohl (bd_id);
5851 mp->flood = flood;
5852 mp->uu_flood = uu_flood;
5853 mp->forward = forward;
5854 mp->learn = learn;
5855 mp->arp_term = arp_term;
5856 mp->is_add = is_add;
5857 mp->mac_age = (u8) mac_age;
5858
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005859 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06005860 W (ret);
5861 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005862}
5863
5864static int
5865api_l2fib_add_del (vat_main_t * vam)
5866{
5867 unformat_input_t *i = vam->input;
5868 vl_api_l2fib_add_del_t *mp;
5869 f64 timeout;
5870 u64 mac = 0;
5871 u8 mac_set = 0;
5872 u32 bd_id;
5873 u8 bd_id_set = 0;
5874 u32 sw_if_index = ~0;
5875 u8 sw_if_index_set = 0;
5876 u8 is_add = 1;
5877 u8 static_mac = 0;
5878 u8 filter_mac = 0;
5879 u8 bvi_mac = 0;
5880 int count = 1;
5881 f64 before = 0;
5882 int j;
5883
5884 /* Parse args required to build the message */
5885 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5886 {
5887 if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
5888 mac_set = 1;
5889 else if (unformat (i, "bd_id %d", &bd_id))
5890 bd_id_set = 1;
5891 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5892 sw_if_index_set = 1;
5893 else if (unformat (i, "sw_if"))
5894 {
5895 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5896 {
5897 if (unformat
5898 (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5899 sw_if_index_set = 1;
5900 }
5901 else
5902 break;
5903 }
5904 else if (unformat (i, "static"))
5905 static_mac = 1;
5906 else if (unformat (i, "filter"))
5907 {
5908 filter_mac = 1;
5909 static_mac = 1;
5910 }
5911 else if (unformat (i, "bvi"))
5912 {
5913 bvi_mac = 1;
5914 static_mac = 1;
5915 }
5916 else if (unformat (i, "del"))
5917 is_add = 0;
5918 else if (unformat (i, "count %d", &count))
5919 ;
5920 else
5921 break;
5922 }
5923
5924 if (mac_set == 0)
5925 {
5926 errmsg ("missing mac address");
5927 return -99;
5928 }
5929
5930 if (bd_id_set == 0)
5931 {
5932 errmsg ("missing bridge domain");
5933 return -99;
5934 }
5935
5936 if (is_add && sw_if_index_set == 0 && filter_mac == 0)
5937 {
5938 errmsg ("missing interface name or sw_if_index");
5939 return -99;
5940 }
5941
5942 if (count > 1)
5943 {
5944 /* Turn on async mode */
5945 vam->async_mode = 1;
5946 vam->async_errors = 0;
5947 before = vat_time_now (vam);
5948 }
5949
5950 for (j = 0; j < count; j++)
5951 {
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005952 M (L2FIB_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005953
5954 mp->mac = mac;
5955 mp->bd_id = ntohl (bd_id);
5956 mp->is_add = is_add;
5957
5958 if (is_add)
5959 {
5960 mp->sw_if_index = ntohl (sw_if_index);
5961 mp->static_mac = static_mac;
5962 mp->filter_mac = filter_mac;
5963 mp->bvi_mac = bvi_mac;
5964 }
5965 increment_mac_address (&mac);
5966 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005967 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005968 }
5969
5970 if (count > 1)
5971 {
Jon Loeliger2d23eca2017-02-01 13:09:58 -06005972 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005973 f64 after;
5974
5975 /* Shut off async mode */
5976 vam->async_mode = 0;
5977
Jon Loeliger2d23eca2017-02-01 13:09:58 -06005978 M (CONTROL_PING, mp_ping);
5979 S (mp_ping);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005980
5981 timeout = vat_time_now (vam) + 1.0;
5982 while (vat_time_now (vam) < timeout)
5983 if (vam->result_ready == 1)
5984 goto out;
5985 vam->retval = -99;
5986
5987 out:
5988 if (vam->retval == -99)
5989 errmsg ("timeout");
5990
5991 if (vam->async_errors > 0)
5992 {
5993 errmsg ("%d asynchronous errors", vam->async_errors);
5994 vam->retval = -98;
5995 }
5996 vam->async_errors = 0;
5997 after = vat_time_now (vam);
5998
5999 print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6000 count, after - before, count / (after - before));
6001 }
6002 else
6003 {
Jon Loeliger56c7b012017-02-01 12:31:41 -06006004 int ret;
6005
Damjan Marion7cd468a2016-12-19 23:05:39 +01006006 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06006007 W (ret);
6008 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006009 }
6010 /* Return the good/bad news */
6011 return (vam->retval);
6012}
6013
6014static int
6015api_l2_flags (vat_main_t * vam)
6016{
6017 unformat_input_t *i = vam->input;
6018 vl_api_l2_flags_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006019 u32 sw_if_index;
6020 u32 feature_bitmap = 0;
6021 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006022 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006023
6024 /* Parse args required to build the message */
6025 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6026 {
6027 if (unformat (i, "sw_if_index %d", &sw_if_index))
6028 sw_if_index_set = 1;
6029 else if (unformat (i, "sw_if"))
6030 {
6031 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6032 {
6033 if (unformat
6034 (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6035 sw_if_index_set = 1;
6036 }
6037 else
6038 break;
6039 }
6040 else if (unformat (i, "learn"))
6041 feature_bitmap |= L2INPUT_FEAT_LEARN;
6042 else if (unformat (i, "forward"))
6043 feature_bitmap |= L2INPUT_FEAT_FWD;
6044 else if (unformat (i, "flood"))
6045 feature_bitmap |= L2INPUT_FEAT_FLOOD;
6046 else if (unformat (i, "uu-flood"))
6047 feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
6048 else
6049 break;
6050 }
6051
6052 if (sw_if_index_set == 0)
6053 {
6054 errmsg ("missing interface name or sw_if_index");
6055 return -99;
6056 }
6057
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006058 M (L2_FLAGS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006059
6060 mp->sw_if_index = ntohl (sw_if_index);
6061 mp->feature_bitmap = ntohl (feature_bitmap);
6062
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006063 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06006064 W (ret);
6065 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006066}
6067
6068static int
6069api_bridge_flags (vat_main_t * vam)
6070{
6071 unformat_input_t *i = vam->input;
6072 vl_api_bridge_flags_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006073 u32 bd_id;
6074 u8 bd_id_set = 0;
6075 u8 is_set = 1;
6076 u32 flags = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006077 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006078
6079 /* Parse args required to build the message */
6080 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6081 {
6082 if (unformat (i, "bd_id %d", &bd_id))
6083 bd_id_set = 1;
6084 else if (unformat (i, "learn"))
6085 flags |= L2_LEARN;
6086 else if (unformat (i, "forward"))
6087 flags |= L2_FWD;
6088 else if (unformat (i, "flood"))
6089 flags |= L2_FLOOD;
6090 else if (unformat (i, "uu-flood"))
6091 flags |= L2_UU_FLOOD;
6092 else if (unformat (i, "arp-term"))
6093 flags |= L2_ARP_TERM;
6094 else if (unformat (i, "off"))
6095 is_set = 0;
6096 else if (unformat (i, "disable"))
6097 is_set = 0;
6098 else
6099 break;
6100 }
6101
6102 if (bd_id_set == 0)
6103 {
6104 errmsg ("missing bridge domain");
6105 return -99;
6106 }
6107
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006108 M (BRIDGE_FLAGS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006109
6110 mp->bd_id = ntohl (bd_id);
6111 mp->feature_bitmap = ntohl (flags);
6112 mp->is_set = is_set;
6113
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006114 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06006115 W (ret);
6116 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006117}
6118
6119static int
6120api_bd_ip_mac_add_del (vat_main_t * vam)
6121{
6122 unformat_input_t *i = vam->input;
6123 vl_api_bd_ip_mac_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006124 u32 bd_id;
6125 u8 is_ipv6 = 0;
6126 u8 is_add = 1;
6127 u8 bd_id_set = 0;
6128 u8 ip_set = 0;
6129 u8 mac_set = 0;
6130 ip4_address_t v4addr;
6131 ip6_address_t v6addr;
6132 u8 macaddr[6];
Jon Loeliger56c7b012017-02-01 12:31:41 -06006133 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006134
6135
6136 /* Parse args required to build the message */
6137 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6138 {
6139 if (unformat (i, "bd_id %d", &bd_id))
6140 {
6141 bd_id_set++;
6142 }
6143 else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
6144 {
6145 ip_set++;
6146 }
6147 else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
6148 {
6149 ip_set++;
6150 is_ipv6++;
6151 }
6152 else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
6153 {
6154 mac_set++;
6155 }
6156 else if (unformat (i, "del"))
6157 is_add = 0;
6158 else
6159 break;
6160 }
6161
6162 if (bd_id_set == 0)
6163 {
6164 errmsg ("missing bridge domain");
6165 return -99;
6166 }
6167 else if (ip_set == 0)
6168 {
6169 errmsg ("missing IP address");
6170 return -99;
6171 }
6172 else if (mac_set == 0)
6173 {
6174 errmsg ("missing MAC address");
6175 return -99;
6176 }
6177
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006178 M (BD_IP_MAC_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006179
6180 mp->bd_id = ntohl (bd_id);
6181 mp->is_ipv6 = is_ipv6;
6182 mp->is_add = is_add;
6183 if (is_ipv6)
6184 clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
6185 else
6186 clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
6187 clib_memcpy (mp->mac_address, macaddr, 6);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006188 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06006189 W (ret);
6190 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006191}
6192
6193static int
6194api_tap_connect (vat_main_t * vam)
6195{
6196 unformat_input_t *i = vam->input;
6197 vl_api_tap_connect_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006198 u8 mac_address[6];
6199 u8 random_mac = 1;
6200 u8 name_set = 0;
6201 u8 *tap_name;
6202 u8 *tag = 0;
Dave Barach2feaffc2017-01-14 10:30:50 -05006203 ip4_address_t ip4_address;
6204 u32 ip4_mask_width;
6205 int ip4_address_set = 0;
6206 ip6_address_t ip6_address;
6207 u32 ip6_mask_width;
6208 int ip6_address_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006209 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006210
6211 memset (mac_address, 0, sizeof (mac_address));
6212
6213 /* Parse args required to build the message */
6214 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6215 {
6216 if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6217 {
6218 random_mac = 0;
6219 }
6220 else if (unformat (i, "random-mac"))
6221 random_mac = 1;
6222 else if (unformat (i, "tapname %s", &tap_name))
6223 name_set = 1;
6224 else if (unformat (i, "tag %s", &tag))
6225 ;
Dave Barach2feaffc2017-01-14 10:30:50 -05006226 else if (unformat (i, "address %U/%d",
6227 unformat_ip4_address, &ip4_address, &ip4_mask_width))
6228 ip4_address_set = 1;
6229 else if (unformat (i, "address %U/%d",
6230 unformat_ip6_address, &ip6_address, &ip6_mask_width))
6231 ip6_address_set = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006232 else
6233 break;
6234 }
6235
6236 if (name_set == 0)
6237 {
6238 errmsg ("missing tap name");
6239 return -99;
6240 }
6241 if (vec_len (tap_name) > 63)
6242 {
6243 errmsg ("tap name too long");
6244 return -99;
6245 }
6246 vec_add1 (tap_name, 0);
6247
6248 if (vec_len (tag) > 63)
6249 {
6250 errmsg ("tag too long");
6251 return -99;
6252 }
6253
6254 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006255 M (TAP_CONNECT, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006256
6257 mp->use_random_mac = random_mac;
6258 clib_memcpy (mp->mac_address, mac_address, 6);
6259 clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6260 if (tag)
6261 clib_memcpy (mp->tag, tag, vec_len (tag));
6262
Dave Barach2feaffc2017-01-14 10:30:50 -05006263 if (ip4_address_set)
6264 {
6265 mp->ip4_address_set = 1;
6266 clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
6267 mp->ip4_mask_width = ip4_mask_width;
6268 }
6269 if (ip6_address_set)
6270 {
6271 mp->ip6_address_set = 1;
6272 clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
6273 mp->ip6_mask_width = ip6_mask_width;
6274 }
6275
Damjan Marion7cd468a2016-12-19 23:05:39 +01006276 vec_free (tap_name);
6277 vec_free (tag);
6278
6279 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006280 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006281
6282 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06006283 W (ret);
6284 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006285}
6286
6287static int
6288api_tap_modify (vat_main_t * vam)
6289{
6290 unformat_input_t *i = vam->input;
6291 vl_api_tap_modify_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006292 u8 mac_address[6];
6293 u8 random_mac = 1;
6294 u8 name_set = 0;
6295 u8 *tap_name;
6296 u32 sw_if_index = ~0;
6297 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006298 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006299
6300 memset (mac_address, 0, sizeof (mac_address));
6301
6302 /* Parse args required to build the message */
6303 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6304 {
6305 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6306 sw_if_index_set = 1;
6307 else if (unformat (i, "sw_if_index %d", &sw_if_index))
6308 sw_if_index_set = 1;
6309 else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6310 {
6311 random_mac = 0;
6312 }
6313 else if (unformat (i, "random-mac"))
6314 random_mac = 1;
6315 else if (unformat (i, "tapname %s", &tap_name))
6316 name_set = 1;
6317 else
6318 break;
6319 }
6320
6321 if (sw_if_index_set == 0)
6322 {
6323 errmsg ("missing vpp interface name");
6324 return -99;
6325 }
6326 if (name_set == 0)
6327 {
6328 errmsg ("missing tap name");
6329 return -99;
6330 }
6331 if (vec_len (tap_name) > 63)
6332 {
6333 errmsg ("tap name too long");
6334 }
6335 vec_add1 (tap_name, 0);
6336
6337 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006338 M (TAP_MODIFY, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006339
6340 mp->use_random_mac = random_mac;
6341 mp->sw_if_index = ntohl (sw_if_index);
6342 clib_memcpy (mp->mac_address, mac_address, 6);
6343 clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6344 vec_free (tap_name);
6345
6346 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006347 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006348
6349 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06006350 W (ret);
6351 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006352}
6353
6354static int
6355api_tap_delete (vat_main_t * vam)
6356{
6357 unformat_input_t *i = vam->input;
6358 vl_api_tap_delete_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006359 u32 sw_if_index = ~0;
6360 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006361 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006362
6363 /* Parse args required to build the message */
6364 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6365 {
6366 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6367 sw_if_index_set = 1;
6368 else if (unformat (i, "sw_if_index %d", &sw_if_index))
6369 sw_if_index_set = 1;
6370 else
6371 break;
6372 }
6373
6374 if (sw_if_index_set == 0)
6375 {
6376 errmsg ("missing vpp interface name");
6377 return -99;
6378 }
6379
6380 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006381 M (TAP_DELETE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006382
6383 mp->sw_if_index = ntohl (sw_if_index);
6384
6385 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006386 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006387
6388 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06006389 W (ret);
6390 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006391}
6392
6393static int
6394api_ip_add_del_route (vat_main_t * vam)
6395{
6396 unformat_input_t *i = vam->input;
6397 vl_api_ip_add_del_route_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006398 u32 sw_if_index = ~0, vrf_id = 0;
6399 u8 is_ipv6 = 0;
6400 u8 is_local = 0, is_drop = 0;
6401 u8 is_unreach = 0, is_prohibit = 0;
6402 u8 create_vrf_if_needed = 0;
6403 u8 is_add = 1;
6404 u32 next_hop_weight = 1;
6405 u8 not_last = 0;
6406 u8 is_multipath = 0;
6407 u8 address_set = 0;
6408 u8 address_length_set = 0;
6409 u32 next_hop_table_id = 0;
6410 u32 resolve_attempts = 0;
6411 u32 dst_address_length = 0;
6412 u8 next_hop_set = 0;
6413 ip4_address_t v4_dst_address, v4_next_hop_address;
6414 ip6_address_t v6_dst_address, v6_next_hop_address;
6415 int count = 1;
6416 int j;
6417 f64 before = 0;
6418 u32 random_add_del = 0;
6419 u32 *random_vector = 0;
6420 uword *random_hash;
6421 u32 random_seed = 0xdeaddabe;
6422 u32 classify_table_index = ~0;
6423 u8 is_classify = 0;
6424 u8 resolve_host = 0, resolve_attached = 0;
6425 mpls_label_t *next_hop_out_label_stack = NULL;
6426 mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6427 mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6428
6429 /* Parse args required to build the message */
6430 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6431 {
6432 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6433 ;
6434 else if (unformat (i, "sw_if_index %d", &sw_if_index))
6435 ;
6436 else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
6437 {
6438 address_set = 1;
6439 is_ipv6 = 0;
6440 }
6441 else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
6442 {
6443 address_set = 1;
6444 is_ipv6 = 1;
6445 }
6446 else if (unformat (i, "/%d", &dst_address_length))
6447 {
6448 address_length_set = 1;
6449 }
6450
6451 else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
6452 &v4_next_hop_address))
6453 {
6454 next_hop_set = 1;
6455 }
6456 else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
6457 &v6_next_hop_address))
6458 {
6459 next_hop_set = 1;
6460 }
6461 else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6462 ;
6463 else if (unformat (i, "weight %d", &next_hop_weight))
6464 ;
6465 else if (unformat (i, "drop"))
6466 {
6467 is_drop = 1;
6468 }
6469 else if (unformat (i, "null-send-unreach"))
6470 {
6471 is_unreach = 1;
6472 }
6473 else if (unformat (i, "null-send-prohibit"))
6474 {
6475 is_prohibit = 1;
6476 }
6477 else if (unformat (i, "local"))
6478 {
6479 is_local = 1;
6480 }
6481 else if (unformat (i, "classify %d", &classify_table_index))
6482 {
6483 is_classify = 1;
6484 }
6485 else if (unformat (i, "del"))
6486 is_add = 0;
6487 else if (unformat (i, "add"))
6488 is_add = 1;
6489 else if (unformat (i, "not-last"))
6490 not_last = 1;
6491 else if (unformat (i, "resolve-via-host"))
6492 resolve_host = 1;
6493 else if (unformat (i, "resolve-via-attached"))
6494 resolve_attached = 1;
6495 else if (unformat (i, "multipath"))
6496 is_multipath = 1;
6497 else if (unformat (i, "vrf %d", &vrf_id))
6498 ;
6499 else if (unformat (i, "create-vrf"))
6500 create_vrf_if_needed = 1;
6501 else if (unformat (i, "count %d", &count))
6502 ;
6503 else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
6504 ;
6505 else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6506 ;
6507 else if (unformat (i, "out-label %d", &next_hop_out_label))
6508 vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6509 else if (unformat (i, "via-label %d", &next_hop_via_label))
6510 ;
6511 else if (unformat (i, "random"))
6512 random_add_del = 1;
6513 else if (unformat (i, "seed %d", &random_seed))
6514 ;
6515 else
6516 {
6517 clib_warning ("parse error '%U'", format_unformat_error, i);
6518 return -99;
6519 }
6520 }
6521
6522 if (!next_hop_set && !is_drop && !is_local &&
6523 !is_classify && !is_unreach && !is_prohibit &&
6524 MPLS_LABEL_INVALID == next_hop_via_label)
6525 {
6526 errmsg
6527 ("next hop / local / drop / unreach / prohibit / classify not set");
6528 return -99;
6529 }
6530
6531 if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
6532 {
6533 errmsg ("next hop and next-hop via label set");
6534 return -99;
6535 }
6536 if (address_set == 0)
6537 {
6538 errmsg ("missing addresses");
6539 return -99;
6540 }
6541
6542 if (address_length_set == 0)
6543 {
6544 errmsg ("missing address length");
6545 return -99;
6546 }
6547
6548 /* Generate a pile of unique, random routes */
6549 if (random_add_del)
6550 {
6551 u32 this_random_address;
6552 random_hash = hash_create (count, sizeof (uword));
6553
6554 hash_set (random_hash, v4_next_hop_address.as_u32, 1);
6555 for (j = 0; j <= count; j++)
6556 {
6557 do
6558 {
6559 this_random_address = random_u32 (&random_seed);
6560 this_random_address =
6561 clib_host_to_net_u32 (this_random_address);
6562 }
6563 while (hash_get (random_hash, this_random_address));
6564 vec_add1 (random_vector, this_random_address);
6565 hash_set (random_hash, this_random_address, 1);
6566 }
6567 hash_free (random_hash);
6568 v4_dst_address.as_u32 = random_vector[0];
6569 }
6570
6571 if (count > 1)
6572 {
6573 /* Turn on async mode */
6574 vam->async_mode = 1;
6575 vam->async_errors = 0;
6576 before = vat_time_now (vam);
6577 }
6578
6579 for (j = 0; j < count; j++)
6580 {
6581 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006582 M2 (IP_ADD_DEL_ROUTE, mp,
Damjan Marion7cd468a2016-12-19 23:05:39 +01006583 sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6584
6585 mp->next_hop_sw_if_index = ntohl (sw_if_index);
6586 mp->table_id = ntohl (vrf_id);
6587 mp->create_vrf_if_needed = create_vrf_if_needed;
6588
6589 mp->is_add = is_add;
6590 mp->is_drop = is_drop;
6591 mp->is_unreach = is_unreach;
6592 mp->is_prohibit = is_prohibit;
6593 mp->is_ipv6 = is_ipv6;
6594 mp->is_local = is_local;
6595 mp->is_classify = is_classify;
6596 mp->is_multipath = is_multipath;
6597 mp->is_resolve_host = resolve_host;
6598 mp->is_resolve_attached = resolve_attached;
6599 mp->not_last = not_last;
6600 mp->next_hop_weight = next_hop_weight;
6601 mp->dst_address_length = dst_address_length;
6602 mp->next_hop_table_id = ntohl (next_hop_table_id);
6603 mp->classify_table_index = ntohl (classify_table_index);
6604 mp->next_hop_via_label = ntohl (next_hop_via_label);
6605 mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6606 if (0 != mp->next_hop_n_out_labels)
6607 {
6608 memcpy (mp->next_hop_out_label_stack,
6609 next_hop_out_label_stack,
6610 vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6611 vec_free (next_hop_out_label_stack);
6612 }
6613
6614 if (is_ipv6)
6615 {
6616 clib_memcpy (mp->dst_address, &v6_dst_address,
6617 sizeof (v6_dst_address));
6618 if (next_hop_set)
6619 clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
6620 sizeof (v6_next_hop_address));
6621 increment_v6_address (&v6_dst_address);
6622 }
6623 else
6624 {
6625 clib_memcpy (mp->dst_address, &v4_dst_address,
6626 sizeof (v4_dst_address));
6627 if (next_hop_set)
6628 clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
6629 sizeof (v4_next_hop_address));
6630 if (random_add_del)
6631 v4_dst_address.as_u32 = random_vector[j + 1];
6632 else
6633 increment_v4_address (&v4_dst_address);
6634 }
6635 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006636 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006637 /* If we receive SIGTERM, stop now... */
6638 if (vam->do_exit)
6639 break;
6640 }
6641
6642 /* When testing multiple add/del ops, use a control-ping to sync */
6643 if (count > 1)
6644 {
Jon Loeliger2d23eca2017-02-01 13:09:58 -06006645 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006646 f64 after;
Jon Loeliger1f9191f2017-01-31 15:27:19 -06006647 f64 timeout;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006648
6649 /* Shut off async mode */
6650 vam->async_mode = 0;
6651
Jon Loeliger2d23eca2017-02-01 13:09:58 -06006652 M (CONTROL_PING, mp_ping);
6653 S (mp_ping);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006654
6655 timeout = vat_time_now (vam) + 1.0;
6656 while (vat_time_now (vam) < timeout)
6657 if (vam->result_ready == 1)
6658 goto out;
6659 vam->retval = -99;
6660
6661 out:
6662 if (vam->retval == -99)
6663 errmsg ("timeout");
6664
6665 if (vam->async_errors > 0)
6666 {
6667 errmsg ("%d asynchronous errors", vam->async_errors);
6668 vam->retval = -98;
6669 }
6670 vam->async_errors = 0;
6671 after = vat_time_now (vam);
6672
6673 /* slim chance, but we might have eaten SIGTERM on the first iteration */
6674 if (j > 0)
6675 count = j;
6676
6677 print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6678 count, after - before, count / (after - before));
6679 }
6680 else
6681 {
Jon Loeliger56c7b012017-02-01 12:31:41 -06006682 int ret;
6683
Damjan Marion7cd468a2016-12-19 23:05:39 +01006684 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06006685 W (ret);
6686 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006687 }
6688
6689 /* Return the good/bad news */
6690 return (vam->retval);
6691}
6692
6693static int
Neale Ranns32e1c012016-11-22 17:07:28 +00006694api_ip_mroute_add_del (vat_main_t * vam)
6695{
6696 unformat_input_t *i = vam->input;
6697 vl_api_ip_mroute_add_del_t *mp;
Neale Ranns32e1c012016-11-22 17:07:28 +00006698 u32 sw_if_index = ~0, vrf_id = 0;
6699 u8 is_ipv6 = 0;
6700 u8 is_local = 0;
6701 u8 create_vrf_if_needed = 0;
6702 u8 is_add = 1;
6703 u8 address_set = 0;
6704 u32 grp_address_length = 0;
6705 ip4_address_t v4_grp_address, v4_src_address;
6706 ip6_address_t v6_grp_address, v6_src_address;
6707 mfib_itf_flags_t iflags = 0;
6708 mfib_entry_flags_t eflags = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006709 int ret;
Neale Ranns32e1c012016-11-22 17:07:28 +00006710
6711 /* Parse args required to build the message */
6712 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6713 {
6714 if (unformat (i, "sw_if_index %d", &sw_if_index))
6715 ;
6716 else if (unformat (i, "%U %U",
6717 unformat_ip4_address, &v4_src_address,
6718 unformat_ip4_address, &v4_grp_address))
6719 {
6720 grp_address_length = 64;
6721 address_set = 1;
6722 is_ipv6 = 0;
6723 }
6724 else if (unformat (i, "%U %U",
6725 unformat_ip6_address, &v6_src_address,
6726 unformat_ip6_address, &v6_grp_address))
6727 {
6728 grp_address_length = 256;
6729 address_set = 1;
6730 is_ipv6 = 1;
6731 }
6732 else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
6733 {
6734 memset (&v4_src_address, 0, sizeof (v4_src_address));
6735 grp_address_length = 32;
6736 address_set = 1;
6737 is_ipv6 = 0;
6738 }
6739 else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
6740 {
6741 memset (&v6_src_address, 0, sizeof (v6_src_address));
6742 grp_address_length = 128;
6743 address_set = 1;
6744 is_ipv6 = 1;
6745 }
6746 else if (unformat (i, "/%d", &grp_address_length))
6747 ;
6748 else if (unformat (i, "local"))
6749 {
6750 is_local = 1;
6751 }
6752 else if (unformat (i, "del"))
6753 is_add = 0;
6754 else if (unformat (i, "add"))
6755 is_add = 1;
6756 else if (unformat (i, "vrf %d", &vrf_id))
6757 ;
6758 else if (unformat (i, "create-vrf"))
6759 create_vrf_if_needed = 1;
6760 else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
6761 ;
6762 else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
6763 ;
6764 else
6765 {
6766 clib_warning ("parse error '%U'", format_unformat_error, i);
6767 return -99;
6768 }
6769 }
6770
6771 if (address_set == 0)
6772 {
6773 errmsg ("missing addresses\n");
6774 return -99;
6775 }
6776
6777 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006778 M (IP_MROUTE_ADD_DEL, mp);
Neale Ranns32e1c012016-11-22 17:07:28 +00006779
6780 mp->next_hop_sw_if_index = ntohl (sw_if_index);
6781 mp->table_id = ntohl (vrf_id);
6782 mp->create_vrf_if_needed = create_vrf_if_needed;
6783
6784 mp->is_add = is_add;
6785 mp->is_ipv6 = is_ipv6;
6786 mp->is_local = is_local;
6787 mp->itf_flags = ntohl (iflags);
6788 mp->entry_flags = ntohl (eflags);
6789 mp->grp_address_length = grp_address_length;
6790 mp->grp_address_length = ntohs (mp->grp_address_length);
6791
6792 if (is_ipv6)
6793 {
6794 clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
6795 clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
6796 }
6797 else
6798 {
6799 clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
6800 clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
6801
6802 }
6803
6804 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006805 S (mp);
Neale Ranns32e1c012016-11-22 17:07:28 +00006806 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06006807 W (ret);
6808 return ret;
Neale Ranns32e1c012016-11-22 17:07:28 +00006809}
6810
6811static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01006812api_mpls_route_add_del (vat_main_t * vam)
6813{
6814 unformat_input_t *i = vam->input;
6815 vl_api_mpls_route_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006816 u32 sw_if_index = ~0, table_id = 0;
6817 u8 create_table_if_needed = 0;
6818 u8 is_add = 1;
6819 u32 next_hop_weight = 1;
6820 u8 is_multipath = 0;
6821 u32 next_hop_table_id = 0;
6822 u8 next_hop_set = 0;
6823 ip4_address_t v4_next_hop_address = {
6824 .as_u32 = 0,
6825 };
6826 ip6_address_t v6_next_hop_address = { {0} };
6827 int count = 1;
6828 int j;
6829 f64 before = 0;
6830 u32 classify_table_index = ~0;
6831 u8 is_classify = 0;
6832 u8 resolve_host = 0, resolve_attached = 0;
6833 mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6834 mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6835 mpls_label_t *next_hop_out_label_stack = NULL;
6836 mpls_label_t local_label = MPLS_LABEL_INVALID;
6837 u8 is_eos = 0;
6838 u8 next_hop_proto_is_ip4 = 1;
6839
6840 /* Parse args required to build the message */
6841 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6842 {
6843 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6844 ;
6845 else if (unformat (i, "sw_if_index %d", &sw_if_index))
6846 ;
6847 else if (unformat (i, "%d", &local_label))
6848 ;
6849 else if (unformat (i, "eos"))
6850 is_eos = 1;
6851 else if (unformat (i, "non-eos"))
6852 is_eos = 0;
6853 else if (unformat (i, "via %U", unformat_ip4_address,
6854 &v4_next_hop_address))
6855 {
6856 next_hop_set = 1;
6857 next_hop_proto_is_ip4 = 1;
6858 }
6859 else if (unformat (i, "via %U", unformat_ip6_address,
6860 &v6_next_hop_address))
6861 {
6862 next_hop_set = 1;
6863 next_hop_proto_is_ip4 = 0;
6864 }
6865 else if (unformat (i, "weight %d", &next_hop_weight))
6866 ;
6867 else if (unformat (i, "create-table"))
6868 create_table_if_needed = 1;
6869 else if (unformat (i, "classify %d", &classify_table_index))
6870 {
6871 is_classify = 1;
6872 }
6873 else if (unformat (i, "del"))
6874 is_add = 0;
6875 else if (unformat (i, "add"))
6876 is_add = 1;
6877 else if (unformat (i, "resolve-via-host"))
6878 resolve_host = 1;
6879 else if (unformat (i, "resolve-via-attached"))
6880 resolve_attached = 1;
6881 else if (unformat (i, "multipath"))
6882 is_multipath = 1;
6883 else if (unformat (i, "count %d", &count))
6884 ;
6885 else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
6886 {
6887 next_hop_set = 1;
6888 next_hop_proto_is_ip4 = 1;
6889 }
6890 else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
6891 {
6892 next_hop_set = 1;
6893 next_hop_proto_is_ip4 = 0;
6894 }
6895 else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6896 ;
6897 else if (unformat (i, "via-label %d", &next_hop_via_label))
6898 ;
6899 else if (unformat (i, "out-label %d", &next_hop_out_label))
6900 vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6901 else
6902 {
6903 clib_warning ("parse error '%U'", format_unformat_error, i);
6904 return -99;
6905 }
6906 }
6907
6908 if (!next_hop_set && !is_classify)
6909 {
6910 errmsg ("next hop / classify not set");
6911 return -99;
6912 }
6913
6914 if (MPLS_LABEL_INVALID == local_label)
6915 {
6916 errmsg ("missing label");
6917 return -99;
6918 }
6919
6920 if (count > 1)
6921 {
6922 /* Turn on async mode */
6923 vam->async_mode = 1;
6924 vam->async_errors = 0;
6925 before = vat_time_now (vam);
6926 }
6927
6928 for (j = 0; j < count; j++)
6929 {
6930 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006931 M2 (MPLS_ROUTE_ADD_DEL, mp,
Damjan Marion7cd468a2016-12-19 23:05:39 +01006932 sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6933
6934 mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
6935 mp->mr_table_id = ntohl (table_id);
6936 mp->mr_create_table_if_needed = create_table_if_needed;
6937
6938 mp->mr_is_add = is_add;
6939 mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6940 mp->mr_is_classify = is_classify;
6941 mp->mr_is_multipath = is_multipath;
6942 mp->mr_is_resolve_host = resolve_host;
6943 mp->mr_is_resolve_attached = resolve_attached;
6944 mp->mr_next_hop_weight = next_hop_weight;
6945 mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
6946 mp->mr_classify_table_index = ntohl (classify_table_index);
6947 mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
6948 mp->mr_label = ntohl (local_label);
6949 mp->mr_eos = is_eos;
6950
6951 mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6952 if (0 != mp->mr_next_hop_n_out_labels)
6953 {
6954 memcpy (mp->mr_next_hop_out_label_stack,
6955 next_hop_out_label_stack,
6956 vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6957 vec_free (next_hop_out_label_stack);
6958 }
6959
6960 if (next_hop_set)
6961 {
6962 if (next_hop_proto_is_ip4)
6963 {
6964 clib_memcpy (mp->mr_next_hop,
6965 &v4_next_hop_address,
6966 sizeof (v4_next_hop_address));
6967 }
6968 else
6969 {
6970 clib_memcpy (mp->mr_next_hop,
6971 &v6_next_hop_address,
6972 sizeof (v6_next_hop_address));
6973 }
6974 }
6975 local_label++;
6976
6977 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006978 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006979 /* If we receive SIGTERM, stop now... */
6980 if (vam->do_exit)
6981 break;
6982 }
6983
6984 /* When testing multiple add/del ops, use a control-ping to sync */
6985 if (count > 1)
6986 {
Jon Loeliger2d23eca2017-02-01 13:09:58 -06006987 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006988 f64 after;
Jon Loeliger1f9191f2017-01-31 15:27:19 -06006989 f64 timeout;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006990
6991 /* Shut off async mode */
6992 vam->async_mode = 0;
6993
Jon Loeliger2d23eca2017-02-01 13:09:58 -06006994 M (CONTROL_PING, mp_ping);
6995 S (mp_ping);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006996
6997 timeout = vat_time_now (vam) + 1.0;
6998 while (vat_time_now (vam) < timeout)
6999 if (vam->result_ready == 1)
7000 goto out;
7001 vam->retval = -99;
7002
7003 out:
7004 if (vam->retval == -99)
7005 errmsg ("timeout");
7006
7007 if (vam->async_errors > 0)
7008 {
7009 errmsg ("%d asynchronous errors", vam->async_errors);
7010 vam->retval = -98;
7011 }
7012 vam->async_errors = 0;
7013 after = vat_time_now (vam);
7014
7015 /* slim chance, but we might have eaten SIGTERM on the first iteration */
7016 if (j > 0)
7017 count = j;
7018
7019 print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7020 count, after - before, count / (after - before));
7021 }
7022 else
7023 {
Jon Loeliger56c7b012017-02-01 12:31:41 -06007024 int ret;
7025
Damjan Marion7cd468a2016-12-19 23:05:39 +01007026 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06007027 W (ret);
7028 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007029 }
7030
7031 /* Return the good/bad news */
7032 return (vam->retval);
7033}
7034
7035static int
7036api_mpls_ip_bind_unbind (vat_main_t * vam)
7037{
7038 unformat_input_t *i = vam->input;
7039 vl_api_mpls_ip_bind_unbind_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007040 u32 ip_table_id = 0;
7041 u8 create_table_if_needed = 0;
7042 u8 is_bind = 1;
7043 u8 is_ip4 = 1;
7044 ip4_address_t v4_address;
7045 ip6_address_t v6_address;
7046 u32 address_length;
7047 u8 address_set = 0;
7048 mpls_label_t local_label = MPLS_LABEL_INVALID;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007049 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007050
7051 /* Parse args required to build the message */
7052 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7053 {
7054 if (unformat (i, "%U/%d", unformat_ip4_address,
7055 &v4_address, &address_length))
7056 {
7057 is_ip4 = 1;
7058 address_set = 1;
7059 }
7060 else if (unformat (i, "%U/%d", unformat_ip6_address,
7061 &v6_address, &address_length))
7062 {
7063 is_ip4 = 0;
7064 address_set = 1;
7065 }
7066 else if (unformat (i, "%d", &local_label))
7067 ;
7068 else if (unformat (i, "create-table"))
7069 create_table_if_needed = 1;
7070 else if (unformat (i, "table-id %d", &ip_table_id))
7071 ;
7072 else if (unformat (i, "unbind"))
7073 is_bind = 0;
7074 else if (unformat (i, "bind"))
7075 is_bind = 1;
7076 else
7077 {
7078 clib_warning ("parse error '%U'", format_unformat_error, i);
7079 return -99;
7080 }
7081 }
7082
7083 if (!address_set)
7084 {
7085 errmsg ("IP addres not set");
7086 return -99;
7087 }
7088
7089 if (MPLS_LABEL_INVALID == local_label)
7090 {
7091 errmsg ("missing label");
7092 return -99;
7093 }
7094
7095 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007096 M (MPLS_IP_BIND_UNBIND, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007097
7098 mp->mb_create_table_if_needed = create_table_if_needed;
7099 mp->mb_is_bind = is_bind;
7100 mp->mb_is_ip4 = is_ip4;
7101 mp->mb_ip_table_id = ntohl (ip_table_id);
7102 mp->mb_mpls_table_id = 0;
7103 mp->mb_label = ntohl (local_label);
7104 mp->mb_address_length = address_length;
7105
7106 if (is_ip4)
7107 clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
7108 else
7109 clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
7110
7111 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007112 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007113
7114 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06007115 W (ret);
7116 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007117}
7118
7119static int
7120api_proxy_arp_add_del (vat_main_t * vam)
7121{
7122 unformat_input_t *i = vam->input;
7123 vl_api_proxy_arp_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007124 u32 vrf_id = 0;
7125 u8 is_add = 1;
7126 ip4_address_t lo, hi;
7127 u8 range_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007128 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007129
7130 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7131 {
7132 if (unformat (i, "vrf %d", &vrf_id))
7133 ;
7134 else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
7135 unformat_ip4_address, &hi))
7136 range_set = 1;
7137 else if (unformat (i, "del"))
7138 is_add = 0;
7139 else
7140 {
7141 clib_warning ("parse error '%U'", format_unformat_error, i);
7142 return -99;
7143 }
7144 }
7145
7146 if (range_set == 0)
7147 {
7148 errmsg ("address range not set");
7149 return -99;
7150 }
7151
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007152 M (PROXY_ARP_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007153
7154 mp->vrf_id = ntohl (vrf_id);
7155 mp->is_add = is_add;
7156 clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
7157 clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
7158
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007159 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007160 W (ret);
7161 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007162}
7163
7164static int
7165api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
7166{
7167 unformat_input_t *i = vam->input;
7168 vl_api_proxy_arp_intfc_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007169 u32 sw_if_index;
7170 u8 enable = 1;
7171 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007172 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007173
7174 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7175 {
7176 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7177 sw_if_index_set = 1;
7178 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7179 sw_if_index_set = 1;
7180 else if (unformat (i, "enable"))
7181 enable = 1;
7182 else if (unformat (i, "disable"))
7183 enable = 0;
7184 else
7185 {
7186 clib_warning ("parse error '%U'", format_unformat_error, i);
7187 return -99;
7188 }
7189 }
7190
7191 if (sw_if_index_set == 0)
7192 {
7193 errmsg ("missing interface name or sw_if_index");
7194 return -99;
7195 }
7196
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007197 M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007198
7199 mp->sw_if_index = ntohl (sw_if_index);
7200 mp->enable_disable = enable;
7201
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007202 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007203 W (ret);
7204 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007205}
7206
7207static int
7208api_mpls_tunnel_add_del (vat_main_t * vam)
7209{
7210 unformat_input_t *i = vam->input;
7211 vl_api_mpls_tunnel_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007212
7213 u8 is_add = 1;
7214 u8 l2_only = 0;
7215 u32 sw_if_index = ~0;
7216 u32 next_hop_sw_if_index = ~0;
7217 u32 next_hop_proto_is_ip4 = 1;
7218
7219 u32 next_hop_table_id = 0;
7220 ip4_address_t v4_next_hop_address = {
7221 .as_u32 = 0,
7222 };
7223 ip6_address_t v6_next_hop_address = { {0} };
7224 mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007225 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007226
7227 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7228 {
7229 if (unformat (i, "add"))
7230 is_add = 1;
7231 else if (unformat (i, "del sw_if_index %d", &sw_if_index))
7232 is_add = 0;
7233 else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
7234 ;
7235 else if (unformat (i, "via %U",
7236 unformat_ip4_address, &v4_next_hop_address))
7237 {
7238 next_hop_proto_is_ip4 = 1;
7239 }
7240 else if (unformat (i, "via %U",
7241 unformat_ip6_address, &v6_next_hop_address))
7242 {
7243 next_hop_proto_is_ip4 = 0;
7244 }
7245 else if (unformat (i, "l2-only"))
7246 l2_only = 1;
7247 else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7248 ;
7249 else if (unformat (i, "out-label %d", &next_hop_out_label))
7250 vec_add1 (labels, ntohl (next_hop_out_label));
7251 else
7252 {
7253 clib_warning ("parse error '%U'", format_unformat_error, i);
7254 return -99;
7255 }
7256 }
7257
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007258 M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
Damjan Marion7cd468a2016-12-19 23:05:39 +01007259
7260 mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
7261 mp->mt_sw_if_index = ntohl (sw_if_index);
7262 mp->mt_is_add = is_add;
7263 mp->mt_l2_only = l2_only;
7264 mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
7265 mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7266
7267 mp->mt_next_hop_n_out_labels = vec_len (labels);
7268
7269 if (0 != mp->mt_next_hop_n_out_labels)
7270 {
7271 clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
7272 sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
7273 vec_free (labels);
7274 }
7275
7276 if (next_hop_proto_is_ip4)
7277 {
7278 clib_memcpy (mp->mt_next_hop,
7279 &v4_next_hop_address, sizeof (v4_next_hop_address));
7280 }
7281 else
7282 {
7283 clib_memcpy (mp->mt_next_hop,
7284 &v6_next_hop_address, sizeof (v6_next_hop_address));
7285 }
7286
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007287 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007288 W (ret);
7289 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007290}
7291
7292static int
7293api_sw_interface_set_unnumbered (vat_main_t * vam)
7294{
7295 unformat_input_t *i = vam->input;
7296 vl_api_sw_interface_set_unnumbered_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007297 u32 sw_if_index;
7298 u32 unnum_sw_index = ~0;
7299 u8 is_add = 1;
7300 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007301 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007302
7303 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7304 {
7305 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7306 sw_if_index_set = 1;
7307 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7308 sw_if_index_set = 1;
7309 else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
7310 ;
7311 else if (unformat (i, "del"))
7312 is_add = 0;
7313 else
7314 {
7315 clib_warning ("parse error '%U'", format_unformat_error, i);
7316 return -99;
7317 }
7318 }
7319
7320 if (sw_if_index_set == 0)
7321 {
7322 errmsg ("missing interface name or sw_if_index");
7323 return -99;
7324 }
7325
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007326 M (SW_INTERFACE_SET_UNNUMBERED, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007327
7328 mp->sw_if_index = ntohl (sw_if_index);
7329 mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
7330 mp->is_add = is_add;
7331
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007332 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007333 W (ret);
7334 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007335}
7336
7337static int
7338api_ip_neighbor_add_del (vat_main_t * vam)
7339{
7340 unformat_input_t *i = vam->input;
7341 vl_api_ip_neighbor_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007342 u32 sw_if_index;
7343 u8 sw_if_index_set = 0;
7344 u32 vrf_id = 0;
7345 u8 is_add = 1;
7346 u8 is_static = 0;
7347 u8 mac_address[6];
7348 u8 mac_set = 0;
7349 u8 v4_address_set = 0;
7350 u8 v6_address_set = 0;
7351 ip4_address_t v4address;
7352 ip6_address_t v6address;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007353 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007354
7355 memset (mac_address, 0, sizeof (mac_address));
7356
7357 /* Parse args required to build the message */
7358 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7359 {
7360 if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7361 {
7362 mac_set = 1;
7363 }
7364 else if (unformat (i, "del"))
7365 is_add = 0;
7366 else
7367 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7368 sw_if_index_set = 1;
7369 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7370 sw_if_index_set = 1;
7371 else if (unformat (i, "is_static"))
7372 is_static = 1;
7373 else if (unformat (i, "vrf %d", &vrf_id))
7374 ;
7375 else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
7376 v4_address_set = 1;
7377 else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
7378 v6_address_set = 1;
7379 else
7380 {
7381 clib_warning ("parse error '%U'", format_unformat_error, i);
7382 return -99;
7383 }
7384 }
7385
7386 if (sw_if_index_set == 0)
7387 {
7388 errmsg ("missing interface name or sw_if_index");
7389 return -99;
7390 }
7391 if (v4_address_set && v6_address_set)
7392 {
7393 errmsg ("both v4 and v6 addresses set");
7394 return -99;
7395 }
7396 if (!v4_address_set && !v6_address_set)
7397 {
7398 errmsg ("no address set");
7399 return -99;
7400 }
7401
7402 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007403 M (IP_NEIGHBOR_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007404
7405 mp->sw_if_index = ntohl (sw_if_index);
7406 mp->is_add = is_add;
7407 mp->vrf_id = ntohl (vrf_id);
7408 mp->is_static = is_static;
7409 if (mac_set)
7410 clib_memcpy (mp->mac_address, mac_address, 6);
7411 if (v6_address_set)
7412 {
7413 mp->is_ipv6 = 1;
7414 clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
7415 }
7416 else
7417 {
7418 /* mp->is_ipv6 = 0; via memset in M macro above */
7419 clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
7420 }
7421
7422 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007423 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007424
7425 /* Wait for a reply, return good/bad news */
Jon Loeliger56c7b012017-02-01 12:31:41 -06007426 W (ret);
7427 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007428}
7429
7430static int
7431api_reset_vrf (vat_main_t * vam)
7432{
7433 unformat_input_t *i = vam->input;
7434 vl_api_reset_vrf_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007435 u32 vrf_id = 0;
7436 u8 is_ipv6 = 0;
7437 u8 vrf_id_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007438 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007439
7440 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7441 {
7442 if (unformat (i, "vrf %d", &vrf_id))
7443 vrf_id_set = 1;
7444 else if (unformat (i, "ipv6"))
7445 is_ipv6 = 1;
7446 else
7447 {
7448 clib_warning ("parse error '%U'", format_unformat_error, i);
7449 return -99;
7450 }
7451 }
7452
7453 if (vrf_id_set == 0)
7454 {
7455 errmsg ("missing vrf id");
7456 return -99;
7457 }
7458
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007459 M (RESET_VRF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007460
7461 mp->vrf_id = ntohl (vrf_id);
7462 mp->is_ipv6 = is_ipv6;
7463
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007464 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007465 W (ret);
7466 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007467}
7468
7469static int
7470api_create_vlan_subif (vat_main_t * vam)
7471{
7472 unformat_input_t *i = vam->input;
7473 vl_api_create_vlan_subif_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007474 u32 sw_if_index;
7475 u8 sw_if_index_set = 0;
7476 u32 vlan_id;
7477 u8 vlan_id_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007478 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007479
7480 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7481 {
7482 if (unformat (i, "sw_if_index %d", &sw_if_index))
7483 sw_if_index_set = 1;
7484 else
7485 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7486 sw_if_index_set = 1;
7487 else if (unformat (i, "vlan %d", &vlan_id))
7488 vlan_id_set = 1;
7489 else
7490 {
7491 clib_warning ("parse error '%U'", format_unformat_error, i);
7492 return -99;
7493 }
7494 }
7495
7496 if (sw_if_index_set == 0)
7497 {
7498 errmsg ("missing interface name or sw_if_index");
7499 return -99;
7500 }
7501
7502 if (vlan_id_set == 0)
7503 {
7504 errmsg ("missing vlan_id");
7505 return -99;
7506 }
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007507 M (CREATE_VLAN_SUBIF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007508
7509 mp->sw_if_index = ntohl (sw_if_index);
7510 mp->vlan_id = ntohl (vlan_id);
7511
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007512 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007513 W (ret);
7514 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007515}
7516
7517#define foreach_create_subif_bit \
7518_(no_tags) \
7519_(one_tag) \
7520_(two_tags) \
7521_(dot1ad) \
7522_(exact_match) \
7523_(default_sub) \
7524_(outer_vlan_id_any) \
7525_(inner_vlan_id_any)
7526
7527static int
7528api_create_subif (vat_main_t * vam)
7529{
7530 unformat_input_t *i = vam->input;
7531 vl_api_create_subif_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007532 u32 sw_if_index;
7533 u8 sw_if_index_set = 0;
7534 u32 sub_id;
7535 u8 sub_id_set = 0;
7536 u32 no_tags = 0;
7537 u32 one_tag = 0;
7538 u32 two_tags = 0;
7539 u32 dot1ad = 0;
7540 u32 exact_match = 0;
7541 u32 default_sub = 0;
7542 u32 outer_vlan_id_any = 0;
7543 u32 inner_vlan_id_any = 0;
7544 u32 tmp;
7545 u16 outer_vlan_id = 0;
7546 u16 inner_vlan_id = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007547 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007548
7549 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7550 {
7551 if (unformat (i, "sw_if_index %d", &sw_if_index))
7552 sw_if_index_set = 1;
7553 else
7554 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7555 sw_if_index_set = 1;
7556 else if (unformat (i, "sub_id %d", &sub_id))
7557 sub_id_set = 1;
7558 else if (unformat (i, "outer_vlan_id %d", &tmp))
7559 outer_vlan_id = tmp;
7560 else if (unformat (i, "inner_vlan_id %d", &tmp))
7561 inner_vlan_id = tmp;
7562
7563#define _(a) else if (unformat (i, #a)) a = 1 ;
7564 foreach_create_subif_bit
7565#undef _
7566 else
7567 {
7568 clib_warning ("parse error '%U'", format_unformat_error, i);
7569 return -99;
7570 }
7571 }
7572
7573 if (sw_if_index_set == 0)
7574 {
7575 errmsg ("missing interface name or sw_if_index");
7576 return -99;
7577 }
7578
7579 if (sub_id_set == 0)
7580 {
7581 errmsg ("missing sub_id");
7582 return -99;
7583 }
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007584 M (CREATE_SUBIF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007585
7586 mp->sw_if_index = ntohl (sw_if_index);
7587 mp->sub_id = ntohl (sub_id);
7588
7589#define _(a) mp->a = a;
7590 foreach_create_subif_bit;
7591#undef _
7592
7593 mp->outer_vlan_id = ntohs (outer_vlan_id);
7594 mp->inner_vlan_id = ntohs (inner_vlan_id);
7595
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007596 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007597 W (ret);
7598 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007599}
7600
7601static int
7602api_oam_add_del (vat_main_t * vam)
7603{
7604 unformat_input_t *i = vam->input;
7605 vl_api_oam_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007606 u32 vrf_id = 0;
7607 u8 is_add = 1;
7608 ip4_address_t src, dst;
7609 u8 src_set = 0;
7610 u8 dst_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007611 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007612
7613 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7614 {
7615 if (unformat (i, "vrf %d", &vrf_id))
7616 ;
7617 else if (unformat (i, "src %U", unformat_ip4_address, &src))
7618 src_set = 1;
7619 else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
7620 dst_set = 1;
7621 else if (unformat (i, "del"))
7622 is_add = 0;
7623 else
7624 {
7625 clib_warning ("parse error '%U'", format_unformat_error, i);
7626 return -99;
7627 }
7628 }
7629
7630 if (src_set == 0)
7631 {
7632 errmsg ("missing src addr");
7633 return -99;
7634 }
7635
7636 if (dst_set == 0)
7637 {
7638 errmsg ("missing dst addr");
7639 return -99;
7640 }
7641
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007642 M (OAM_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007643
7644 mp->vrf_id = ntohl (vrf_id);
7645 mp->is_add = is_add;
7646 clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
7647 clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
7648
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007649 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007650 W (ret);
7651 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007652}
7653
7654static int
7655api_reset_fib (vat_main_t * vam)
7656{
7657 unformat_input_t *i = vam->input;
7658 vl_api_reset_fib_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007659 u32 vrf_id = 0;
7660 u8 is_ipv6 = 0;
7661 u8 vrf_id_set = 0;
7662
Jon Loeliger56c7b012017-02-01 12:31:41 -06007663 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007664 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7665 {
7666 if (unformat (i, "vrf %d", &vrf_id))
7667 vrf_id_set = 1;
7668 else if (unformat (i, "ipv6"))
7669 is_ipv6 = 1;
7670 else
7671 {
7672 clib_warning ("parse error '%U'", format_unformat_error, i);
7673 return -99;
7674 }
7675 }
7676
7677 if (vrf_id_set == 0)
7678 {
7679 errmsg ("missing vrf id");
7680 return -99;
7681 }
7682
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007683 M (RESET_FIB, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007684
7685 mp->vrf_id = ntohl (vrf_id);
7686 mp->is_ipv6 = is_ipv6;
7687
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007688 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007689 W (ret);
7690 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007691}
7692
7693static int
7694api_dhcp_proxy_config (vat_main_t * vam)
7695{
7696 unformat_input_t *i = vam->input;
7697 vl_api_dhcp_proxy_config_t *mp;
Neale Ranns20a175a2017-02-14 07:28:41 -08007698 u32 rx_vrf_id = 0;
7699 u32 server_vrf_id = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007700 u8 is_add = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007701 u8 v4_address_set = 0;
7702 u8 v6_address_set = 0;
7703 ip4_address_t v4address;
7704 ip6_address_t v6address;
7705 u8 v4_src_address_set = 0;
7706 u8 v6_src_address_set = 0;
7707 ip4_address_t v4srcaddress;
7708 ip6_address_t v6srcaddress;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007709 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007710
7711 /* Parse args required to build the message */
7712 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7713 {
7714 if (unformat (i, "del"))
7715 is_add = 0;
Neale Ranns20a175a2017-02-14 07:28:41 -08007716 else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
Damjan Marion7cd468a2016-12-19 23:05:39 +01007717 ;
Neale Ranns20a175a2017-02-14 07:28:41 -08007718 else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
Damjan Marion7cd468a2016-12-19 23:05:39 +01007719 ;
7720 else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7721 v4_address_set = 1;
7722 else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7723 v6_address_set = 1;
7724 else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7725 v4_src_address_set = 1;
7726 else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7727 v6_src_address_set = 1;
7728 else
7729 break;
7730 }
7731
7732 if (v4_address_set && v6_address_set)
7733 {
7734 errmsg ("both v4 and v6 server addresses set");
7735 return -99;
7736 }
7737 if (!v4_address_set && !v6_address_set)
7738 {
7739 errmsg ("no server addresses set");
7740 return -99;
7741 }
7742
7743 if (v4_src_address_set && v6_src_address_set)
7744 {
7745 errmsg ("both v4 and v6 src addresses set");
7746 return -99;
7747 }
7748 if (!v4_src_address_set && !v6_src_address_set)
7749 {
7750 errmsg ("no src addresses set");
7751 return -99;
7752 }
7753
7754 if (!(v4_src_address_set && v4_address_set) &&
7755 !(v6_src_address_set && v6_address_set))
7756 {
7757 errmsg ("no matching server and src addresses set");
7758 return -99;
7759 }
7760
7761 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007762 M (DHCP_PROXY_CONFIG, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007763
Damjan Marion7cd468a2016-12-19 23:05:39 +01007764 mp->is_add = is_add;
Neale Ranns20a175a2017-02-14 07:28:41 -08007765 mp->rx_vrf_id = ntohl (rx_vrf_id);
7766 mp->server_vrf_id = ntohl (server_vrf_id);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007767 if (v6_address_set)
7768 {
7769 mp->is_ipv6 = 1;
7770 clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7771 clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7772 }
7773 else
7774 {
7775 clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7776 clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7777 }
7778
7779 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007780 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007781
7782 /* Wait for a reply, return good/bad news */
Jon Loeliger56c7b012017-02-01 12:31:41 -06007783 W (ret);
7784 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007785}
7786
Neale Ranns20a175a2017-02-14 07:28:41 -08007787#define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
7788#define vl_api_dhcp_proxy_details_t_print vl_noop_handler
7789
7790static void
7791vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
Damjan Marion7cd468a2016-12-19 23:05:39 +01007792{
Neale Ranns20a175a2017-02-14 07:28:41 -08007793 vat_main_t *vam = &vat_main;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007794
Neale Ranns20a175a2017-02-14 07:28:41 -08007795 if (mp->is_ipv6)
7796 print (vam->ofp,
7797 "RX Table-ID %d, Server Table-ID %d, Server Address %U, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
7798 ntohl (mp->rx_vrf_id),
7799 ntohl (mp->server_vrf_id),
7800 format_ip6_address, mp->dhcp_server,
7801 format_ip6_address, mp->dhcp_src_address,
7802 ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
7803 else
7804 print (vam->ofp,
7805 "RX Table-ID %d, Server Table-ID %d, Server Address %U, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
7806 ntohl (mp->rx_vrf_id),
7807 ntohl (mp->server_vrf_id),
7808 format_ip4_address, mp->dhcp_server,
7809 format_ip4_address, mp->dhcp_src_address,
7810 ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
7811}
Damjan Marion7cd468a2016-12-19 23:05:39 +01007812
Neale Ranns20a175a2017-02-14 07:28:41 -08007813static void vl_api_dhcp_proxy_details_t_handler_json
7814 (vl_api_dhcp_proxy_details_t * mp)
7815{
7816 vat_main_t *vam = &vat_main;
7817 vat_json_node_t *node = NULL;
7818 struct in_addr ip4;
7819 struct in6_addr ip6;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007820
Neale Ranns20a175a2017-02-14 07:28:41 -08007821 if (VAT_JSON_ARRAY != vam->json_tree.type)
Damjan Marion7cd468a2016-12-19 23:05:39 +01007822 {
Neale Ranns20a175a2017-02-14 07:28:41 -08007823 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7824 vat_json_init_array (&vam->json_tree);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007825 }
Neale Ranns20a175a2017-02-14 07:28:41 -08007826 node = vat_json_array_add (&vam->json_tree);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007827
Neale Ranns20a175a2017-02-14 07:28:41 -08007828 vat_json_init_object (node);
7829 vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
7830 vat_json_object_add_uint (node, "server-table-id",
7831 ntohl (mp->server_vrf_id));
7832 if (mp->is_ipv6)
Damjan Marion7cd468a2016-12-19 23:05:39 +01007833 {
Neale Ranns20a175a2017-02-14 07:28:41 -08007834 clib_memcpy (&ip6, &mp->dhcp_server, sizeof (ip6));
7835 vat_json_object_add_ip6 (node, "server_address", ip6);
7836 clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
7837 vat_json_object_add_ip6 (node, "src_address", ip6);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007838 }
7839 else
7840 {
Neale Ranns20a175a2017-02-14 07:28:41 -08007841 clib_memcpy (&ip4, &mp->dhcp_server, sizeof (ip4));
7842 vat_json_object_add_ip4 (node, "server_address", ip4);
7843 clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
7844 vat_json_object_add_ip4 (node, "src_address", ip4);
7845 }
7846 vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
7847 vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
7848}
7849
7850static int
7851api_dhcp_proxy_dump (vat_main_t * vam)
7852{
7853 unformat_input_t *i = vam->input;
7854 vl_api_control_ping_t *mp_ping;
7855 vl_api_dhcp_proxy_dump_t *mp;
7856 u8 is_ipv6 = 0;
7857 int ret;
7858
7859 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7860 {
7861 if (unformat (i, "ipv6"))
7862 is_ipv6 = 1;
7863 else
7864 {
7865 clib_warning ("parse error '%U'", format_unformat_error, i);
7866 return -99;
7867 }
Damjan Marion7cd468a2016-12-19 23:05:39 +01007868 }
7869
Neale Ranns20a175a2017-02-14 07:28:41 -08007870 M (DHCP_PROXY_DUMP, mp);
7871
7872 mp->is_ip6 = is_ipv6;
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007873 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007874
Neale Ranns20a175a2017-02-14 07:28:41 -08007875 /* Use a control ping for synchronization */
7876 M (CONTROL_PING, mp_ping);
7877 S (mp_ping);
7878
Jon Loeliger56c7b012017-02-01 12:31:41 -06007879 W (ret);
7880 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007881}
7882
7883static int
7884api_dhcp_proxy_set_vss (vat_main_t * vam)
7885{
7886 unformat_input_t *i = vam->input;
7887 vl_api_dhcp_proxy_set_vss_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007888 u8 is_ipv6 = 0;
7889 u8 is_add = 1;
7890 u32 tbl_id;
7891 u8 tbl_id_set = 0;
7892 u32 oui;
7893 u8 oui_set = 0;
7894 u32 fib_id;
7895 u8 fib_id_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007896 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007897
7898 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7899 {
7900 if (unformat (i, "tbl_id %d", &tbl_id))
7901 tbl_id_set = 1;
7902 if (unformat (i, "fib_id %d", &fib_id))
7903 fib_id_set = 1;
7904 if (unformat (i, "oui %d", &oui))
7905 oui_set = 1;
7906 else if (unformat (i, "ipv6"))
7907 is_ipv6 = 1;
7908 else if (unformat (i, "del"))
7909 is_add = 0;
7910 else
7911 {
7912 clib_warning ("parse error '%U'", format_unformat_error, i);
7913 return -99;
7914 }
7915 }
7916
7917 if (tbl_id_set == 0)
7918 {
7919 errmsg ("missing tbl id");
7920 return -99;
7921 }
7922
7923 if (fib_id_set == 0)
7924 {
7925 errmsg ("missing fib id");
7926 return -99;
7927 }
7928 if (oui_set == 0)
7929 {
7930 errmsg ("missing oui");
7931 return -99;
7932 }
7933
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007934 M (DHCP_PROXY_SET_VSS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007935 mp->tbl_id = ntohl (tbl_id);
7936 mp->fib_id = ntohl (fib_id);
7937 mp->oui = ntohl (oui);
7938 mp->is_ipv6 = is_ipv6;
7939 mp->is_add = is_add;
7940
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007941 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007942 W (ret);
7943 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007944}
7945
7946static int
7947api_dhcp_client_config (vat_main_t * vam)
7948{
7949 unformat_input_t *i = vam->input;
7950 vl_api_dhcp_client_config_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007951 u32 sw_if_index;
7952 u8 sw_if_index_set = 0;
7953 u8 is_add = 1;
7954 u8 *hostname = 0;
7955 u8 disable_event = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007956 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007957
7958 /* Parse args required to build the message */
7959 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7960 {
7961 if (unformat (i, "del"))
7962 is_add = 0;
7963 else
7964 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7965 sw_if_index_set = 1;
7966 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7967 sw_if_index_set = 1;
7968 else if (unformat (i, "hostname %s", &hostname))
7969 ;
7970 else if (unformat (i, "disable_event"))
7971 disable_event = 1;
7972 else
7973 break;
7974 }
7975
7976 if (sw_if_index_set == 0)
7977 {
7978 errmsg ("missing interface name or sw_if_index");
7979 return -99;
7980 }
7981
7982 if (vec_len (hostname) > 63)
7983 {
7984 errmsg ("hostname too long");
7985 }
7986 vec_add1 (hostname, 0);
7987
7988 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007989 M (DHCP_CLIENT_CONFIG, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007990
7991 mp->sw_if_index = ntohl (sw_if_index);
7992 clib_memcpy (mp->hostname, hostname, vec_len (hostname));
7993 vec_free (hostname);
7994 mp->is_add = is_add;
7995 mp->want_dhcp_event = disable_event ? 0 : 1;
7996 mp->pid = getpid ();
7997
7998 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007999 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008000
8001 /* Wait for a reply, return good/bad news */
Jon Loeliger56c7b012017-02-01 12:31:41 -06008002 W (ret);
8003 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008004}
8005
8006static int
8007api_set_ip_flow_hash (vat_main_t * vam)
8008{
8009 unformat_input_t *i = vam->input;
8010 vl_api_set_ip_flow_hash_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008011 u32 vrf_id = 0;
8012 u8 is_ipv6 = 0;
8013 u8 vrf_id_set = 0;
8014 u8 src = 0;
8015 u8 dst = 0;
8016 u8 sport = 0;
8017 u8 dport = 0;
8018 u8 proto = 0;
8019 u8 reverse = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008020 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008021
8022 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8023 {
8024 if (unformat (i, "vrf %d", &vrf_id))
8025 vrf_id_set = 1;
8026 else if (unformat (i, "ipv6"))
8027 is_ipv6 = 1;
8028 else if (unformat (i, "src"))
8029 src = 1;
8030 else if (unformat (i, "dst"))
8031 dst = 1;
8032 else if (unformat (i, "sport"))
8033 sport = 1;
8034 else if (unformat (i, "dport"))
8035 dport = 1;
8036 else if (unformat (i, "proto"))
8037 proto = 1;
8038 else if (unformat (i, "reverse"))
8039 reverse = 1;
8040
8041 else
8042 {
8043 clib_warning ("parse error '%U'", format_unformat_error, i);
8044 return -99;
8045 }
8046 }
8047
8048 if (vrf_id_set == 0)
8049 {
8050 errmsg ("missing vrf id");
8051 return -99;
8052 }
8053
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008054 M (SET_IP_FLOW_HASH, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008055 mp->src = src;
8056 mp->dst = dst;
8057 mp->sport = sport;
8058 mp->dport = dport;
8059 mp->proto = proto;
8060 mp->reverse = reverse;
8061 mp->vrf_id = ntohl (vrf_id);
8062 mp->is_ipv6 = is_ipv6;
8063
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008064 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008065 W (ret);
8066 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008067}
8068
8069static int
8070api_sw_interface_ip6_enable_disable (vat_main_t * vam)
8071{
8072 unformat_input_t *i = vam->input;
8073 vl_api_sw_interface_ip6_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008074 u32 sw_if_index;
8075 u8 sw_if_index_set = 0;
8076 u8 enable = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008077 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008078
8079 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8080 {
8081 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8082 sw_if_index_set = 1;
8083 else if (unformat (i, "sw_if_index %d", &sw_if_index))
8084 sw_if_index_set = 1;
8085 else if (unformat (i, "enable"))
8086 enable = 1;
8087 else if (unformat (i, "disable"))
8088 enable = 0;
8089 else
8090 {
8091 clib_warning ("parse error '%U'", format_unformat_error, i);
8092 return -99;
8093 }
8094 }
8095
8096 if (sw_if_index_set == 0)
8097 {
8098 errmsg ("missing interface name or sw_if_index");
8099 return -99;
8100 }
8101
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008102 M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008103
8104 mp->sw_if_index = ntohl (sw_if_index);
8105 mp->enable = enable;
8106
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008107 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008108 W (ret);
8109 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008110}
8111
8112static int
8113api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
8114{
8115 unformat_input_t *i = vam->input;
8116 vl_api_sw_interface_ip6_set_link_local_address_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008117 u32 sw_if_index;
8118 u8 sw_if_index_set = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008119 u8 v6_address_set = 0;
8120 ip6_address_t v6address;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008121 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008122
8123 /* Parse args required to build the message */
8124 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8125 {
8126 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8127 sw_if_index_set = 1;
8128 else if (unformat (i, "sw_if_index %d", &sw_if_index))
8129 sw_if_index_set = 1;
Neale Ranns75152282017-01-09 01:00:45 -08008130 else if (unformat (i, "%U", unformat_ip6_address, &v6address))
Damjan Marion7cd468a2016-12-19 23:05:39 +01008131 v6_address_set = 1;
8132 else
8133 break;
8134 }
8135
8136 if (sw_if_index_set == 0)
8137 {
8138 errmsg ("missing interface name or sw_if_index");
8139 return -99;
8140 }
8141 if (!v6_address_set)
8142 {
8143 errmsg ("no address set");
8144 return -99;
8145 }
8146
8147 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008148 M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008149
8150 mp->sw_if_index = ntohl (sw_if_index);
8151 clib_memcpy (mp->address, &v6address, sizeof (v6address));
Damjan Marion7cd468a2016-12-19 23:05:39 +01008152
8153 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008154 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008155
8156 /* Wait for a reply, return good/bad news */
Jon Loeliger56c7b012017-02-01 12:31:41 -06008157 W (ret);
8158 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008159}
8160
8161
8162static int
8163api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
8164{
8165 unformat_input_t *i = vam->input;
8166 vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008167 u32 sw_if_index;
8168 u8 sw_if_index_set = 0;
8169 u32 address_length = 0;
8170 u8 v6_address_set = 0;
8171 ip6_address_t v6address;
8172 u8 use_default = 0;
8173 u8 no_advertise = 0;
8174 u8 off_link = 0;
8175 u8 no_autoconfig = 0;
8176 u8 no_onlink = 0;
8177 u8 is_no = 0;
8178 u32 val_lifetime = 0;
8179 u32 pref_lifetime = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008180 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008181
8182 /* Parse args required to build the message */
8183 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8184 {
8185 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8186 sw_if_index_set = 1;
8187 else if (unformat (i, "sw_if_index %d", &sw_if_index))
8188 sw_if_index_set = 1;
8189 else if (unformat (i, "%U/%d",
8190 unformat_ip6_address, &v6address, &address_length))
8191 v6_address_set = 1;
8192 else if (unformat (i, "val_life %d", &val_lifetime))
8193 ;
8194 else if (unformat (i, "pref_life %d", &pref_lifetime))
8195 ;
8196 else if (unformat (i, "def"))
8197 use_default = 1;
8198 else if (unformat (i, "noadv"))
8199 no_advertise = 1;
8200 else if (unformat (i, "offl"))
8201 off_link = 1;
8202 else if (unformat (i, "noauto"))
8203 no_autoconfig = 1;
8204 else if (unformat (i, "nolink"))
8205 no_onlink = 1;
8206 else if (unformat (i, "isno"))
8207 is_no = 1;
8208 else
8209 {
8210 clib_warning ("parse error '%U'", format_unformat_error, i);
8211 return -99;
8212 }
8213 }
8214
8215 if (sw_if_index_set == 0)
8216 {
8217 errmsg ("missing interface name or sw_if_index");
8218 return -99;
8219 }
8220 if (!v6_address_set)
8221 {
8222 errmsg ("no address set");
8223 return -99;
8224 }
8225
8226 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008227 M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008228
8229 mp->sw_if_index = ntohl (sw_if_index);
8230 clib_memcpy (mp->address, &v6address, sizeof (v6address));
8231 mp->address_length = address_length;
8232 mp->use_default = use_default;
8233 mp->no_advertise = no_advertise;
8234 mp->off_link = off_link;
8235 mp->no_autoconfig = no_autoconfig;
8236 mp->no_onlink = no_onlink;
8237 mp->is_no = is_no;
8238 mp->val_lifetime = ntohl (val_lifetime);
8239 mp->pref_lifetime = ntohl (pref_lifetime);
8240
8241 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008242 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008243
8244 /* Wait for a reply, return good/bad news */
Jon Loeliger56c7b012017-02-01 12:31:41 -06008245 W (ret);
8246 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008247}
8248
8249static int
8250api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
8251{
8252 unformat_input_t *i = vam->input;
8253 vl_api_sw_interface_ip6nd_ra_config_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008254 u32 sw_if_index;
8255 u8 sw_if_index_set = 0;
8256 u8 suppress = 0;
8257 u8 managed = 0;
8258 u8 other = 0;
8259 u8 ll_option = 0;
8260 u8 send_unicast = 0;
8261 u8 cease = 0;
8262 u8 is_no = 0;
8263 u8 default_router = 0;
8264 u32 max_interval = 0;
8265 u32 min_interval = 0;
8266 u32 lifetime = 0;
8267 u32 initial_count = 0;
8268 u32 initial_interval = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008269 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008270
8271
8272 /* Parse args required to build the message */
8273 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8274 {
8275 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8276 sw_if_index_set = 1;
8277 else if (unformat (i, "sw_if_index %d", &sw_if_index))
8278 sw_if_index_set = 1;
8279 else if (unformat (i, "maxint %d", &max_interval))
8280 ;
8281 else if (unformat (i, "minint %d", &min_interval))
8282 ;
8283 else if (unformat (i, "life %d", &lifetime))
8284 ;
8285 else if (unformat (i, "count %d", &initial_count))
8286 ;
8287 else if (unformat (i, "interval %d", &initial_interval))
8288 ;
8289 else if (unformat (i, "suppress") || unformat (i, "surpress"))
8290 suppress = 1;
8291 else if (unformat (i, "managed"))
8292 managed = 1;
8293 else if (unformat (i, "other"))
8294 other = 1;
8295 else if (unformat (i, "ll"))
8296 ll_option = 1;
8297 else if (unformat (i, "send"))
8298 send_unicast = 1;
8299 else if (unformat (i, "cease"))
8300 cease = 1;
8301 else if (unformat (i, "isno"))
8302 is_no = 1;
8303 else if (unformat (i, "def"))
8304 default_router = 1;
8305 else
8306 {
8307 clib_warning ("parse error '%U'", format_unformat_error, i);
8308 return -99;
8309 }
8310 }
8311
8312 if (sw_if_index_set == 0)
8313 {
8314 errmsg ("missing interface name or sw_if_index");
8315 return -99;
8316 }
8317
8318 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008319 M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008320
8321 mp->sw_if_index = ntohl (sw_if_index);
8322 mp->max_interval = ntohl (max_interval);
8323 mp->min_interval = ntohl (min_interval);
8324 mp->lifetime = ntohl (lifetime);
8325 mp->initial_count = ntohl (initial_count);
8326 mp->initial_interval = ntohl (initial_interval);
8327 mp->suppress = suppress;
8328 mp->managed = managed;
8329 mp->other = other;
8330 mp->ll_option = ll_option;
8331 mp->send_unicast = send_unicast;
8332 mp->cease = cease;
8333 mp->is_no = is_no;
8334 mp->default_router = default_router;
8335
8336 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008337 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008338
8339 /* Wait for a reply, return good/bad news */
Jon Loeliger56c7b012017-02-01 12:31:41 -06008340 W (ret);
8341 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008342}
8343
8344static int
8345api_set_arp_neighbor_limit (vat_main_t * vam)
8346{
8347 unformat_input_t *i = vam->input;
8348 vl_api_set_arp_neighbor_limit_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008349 u32 arp_nbr_limit;
8350 u8 limit_set = 0;
8351 u8 is_ipv6 = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008352 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008353
8354 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8355 {
8356 if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
8357 limit_set = 1;
8358 else if (unformat (i, "ipv6"))
8359 is_ipv6 = 1;
8360 else
8361 {
8362 clib_warning ("parse error '%U'", format_unformat_error, i);
8363 return -99;
8364 }
8365 }
8366
8367 if (limit_set == 0)
8368 {
8369 errmsg ("missing limit value");
8370 return -99;
8371 }
8372
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008373 M (SET_ARP_NEIGHBOR_LIMIT, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008374
8375 mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
8376 mp->is_ipv6 = is_ipv6;
8377
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008378 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008379 W (ret);
8380 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008381}
8382
8383static int
8384api_l2_patch_add_del (vat_main_t * vam)
8385{
8386 unformat_input_t *i = vam->input;
8387 vl_api_l2_patch_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008388 u32 rx_sw_if_index;
8389 u8 rx_sw_if_index_set = 0;
8390 u32 tx_sw_if_index;
8391 u8 tx_sw_if_index_set = 0;
8392 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008393 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008394
8395 /* Parse args required to build the message */
8396 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8397 {
8398 if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
8399 rx_sw_if_index_set = 1;
8400 else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
8401 tx_sw_if_index_set = 1;
8402 else if (unformat (i, "rx"))
8403 {
8404 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8405 {
8406 if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8407 &rx_sw_if_index))
8408 rx_sw_if_index_set = 1;
8409 }
8410 else
8411 break;
8412 }
8413 else if (unformat (i, "tx"))
8414 {
8415 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8416 {
8417 if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8418 &tx_sw_if_index))
8419 tx_sw_if_index_set = 1;
8420 }
8421 else
8422 break;
8423 }
8424 else if (unformat (i, "del"))
8425 is_add = 0;
8426 else
8427 break;
8428 }
8429
8430 if (rx_sw_if_index_set == 0)
8431 {
8432 errmsg ("missing rx interface name or rx_sw_if_index");
8433 return -99;
8434 }
8435
8436 if (tx_sw_if_index_set == 0)
8437 {
8438 errmsg ("missing tx interface name or tx_sw_if_index");
8439 return -99;
8440 }
8441
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008442 M (L2_PATCH_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008443
8444 mp->rx_sw_if_index = ntohl (rx_sw_if_index);
8445 mp->tx_sw_if_index = ntohl (tx_sw_if_index);
8446 mp->is_add = is_add;
8447
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008448 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008449 W (ret);
8450 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008451}
8452
8453static int
8454api_ioam_enable (vat_main_t * vam)
8455{
8456 unformat_input_t *input = vam->input;
8457 vl_api_ioam_enable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008458 u32 id = 0;
8459 int has_trace_option = 0;
8460 int has_pot_option = 0;
8461 int has_seqno_option = 0;
8462 int has_analyse_option = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008463 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008464
8465 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8466 {
8467 if (unformat (input, "trace"))
8468 has_trace_option = 1;
8469 else if (unformat (input, "pot"))
8470 has_pot_option = 1;
8471 else if (unformat (input, "seqno"))
8472 has_seqno_option = 1;
8473 else if (unformat (input, "analyse"))
8474 has_analyse_option = 1;
8475 else
8476 break;
8477 }
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008478 M (IOAM_ENABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008479 mp->id = htons (id);
8480 mp->seqno = has_seqno_option;
8481 mp->analyse = has_analyse_option;
8482 mp->pot_enable = has_pot_option;
8483 mp->trace_enable = has_trace_option;
8484
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008485 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008486 W (ret);
8487 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008488}
8489
8490
8491static int
8492api_ioam_disable (vat_main_t * vam)
8493{
8494 vl_api_ioam_disable_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008495 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008496
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008497 M (IOAM_DISABLE, mp);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008498 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008499 W (ret);
8500 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008501}
8502
8503static int
8504api_sr_tunnel_add_del (vat_main_t * vam)
8505{
8506 unformat_input_t *i = vam->input;
8507 vl_api_sr_tunnel_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008508 int is_del = 0;
8509 int pl_index;
8510 ip6_address_t src_address;
8511 int src_address_set = 0;
8512 ip6_address_t dst_address;
8513 u32 dst_mask_width;
8514 int dst_address_set = 0;
8515 u16 flags = 0;
8516 u32 rx_table_id = 0;
8517 u32 tx_table_id = 0;
8518 ip6_address_t *segments = 0;
8519 ip6_address_t *this_seg;
8520 ip6_address_t *tags = 0;
8521 ip6_address_t *this_tag;
8522 ip6_address_t next_address, tag;
8523 u8 *name = 0;
8524 u8 *policy_name = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008525 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008526
8527 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8528 {
8529 if (unformat (i, "del"))
8530 is_del = 1;
8531 else if (unformat (i, "name %s", &name))
8532 ;
8533 else if (unformat (i, "policy %s", &policy_name))
8534 ;
8535 else if (unformat (i, "rx_fib_id %d", &rx_table_id))
8536 ;
8537 else if (unformat (i, "tx_fib_id %d", &tx_table_id))
8538 ;
8539 else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
8540 src_address_set = 1;
8541 else if (unformat (i, "dst %U/%d",
8542 unformat_ip6_address, &dst_address, &dst_mask_width))
8543 dst_address_set = 1;
8544 else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
8545 {
8546 vec_add2 (segments, this_seg, 1);
8547 clib_memcpy (this_seg->as_u8, next_address.as_u8,
8548 sizeof (*this_seg));
8549 }
8550 else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
8551 {
8552 vec_add2 (tags, this_tag, 1);
8553 clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
8554 }
8555 else if (unformat (i, "clean"))
8556 flags |= IP6_SR_HEADER_FLAG_CLEANUP;
8557 else if (unformat (i, "protected"))
8558 flags |= IP6_SR_HEADER_FLAG_PROTECTED;
8559 else if (unformat (i, "InPE %d", &pl_index))
8560 {
8561 if (pl_index <= 0 || pl_index > 4)
8562 {
8563 pl_index_range_error:
8564 errmsg ("pl index %d out of range", pl_index);
8565 return -99;
8566 }
8567 flags |=
8568 IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
8569 }
8570 else if (unformat (i, "EgPE %d", &pl_index))
8571 {
8572 if (pl_index <= 0 || pl_index > 4)
8573 goto pl_index_range_error;
8574 flags |=
8575 IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
8576 }
8577 else if (unformat (i, "OrgSrc %d", &pl_index))
8578 {
8579 if (pl_index <= 0 || pl_index > 4)
8580 goto pl_index_range_error;
8581 flags |=
8582 IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
8583 }
8584 else
8585 break;
8586 }
8587
8588 if (!src_address_set)
8589 {
8590 errmsg ("src address required");
8591 return -99;
8592 }
8593
8594 if (!dst_address_set)
8595 {
8596 errmsg ("dst address required");
8597 return -99;
8598 }
8599
8600 if (!segments)
8601 {
8602 errmsg ("at least one sr segment required");
8603 return -99;
8604 }
8605
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008606 M2 (SR_TUNNEL_ADD_DEL, mp,
Damjan Marion7cd468a2016-12-19 23:05:39 +01008607 vec_len (segments) * sizeof (ip6_address_t)
8608 + vec_len (tags) * sizeof (ip6_address_t));
8609
8610 clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
8611 clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
8612 mp->dst_mask_width = dst_mask_width;
8613 mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
8614 mp->n_segments = vec_len (segments);
8615 mp->n_tags = vec_len (tags);
8616 mp->is_add = is_del == 0;
8617 clib_memcpy (mp->segs_and_tags, segments,
8618 vec_len (segments) * sizeof (ip6_address_t));
8619 clib_memcpy (mp->segs_and_tags +
8620 vec_len (segments) * sizeof (ip6_address_t), tags,
8621 vec_len (tags) * sizeof (ip6_address_t));
8622
8623 mp->outer_vrf_id = ntohl (rx_table_id);
8624 mp->inner_vrf_id = ntohl (tx_table_id);
8625 memcpy (mp->name, name, vec_len (name));
8626 memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8627
8628 vec_free (segments);
8629 vec_free (tags);
8630
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008631 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008632 W (ret);
8633 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008634}
8635
8636static int
8637api_sr_policy_add_del (vat_main_t * vam)
8638{
8639 unformat_input_t *input = vam->input;
8640 vl_api_sr_policy_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008641 int is_del = 0;
8642 u8 *name = 0;
8643 u8 *tunnel_name = 0;
8644 u8 **tunnel_names = 0;
8645
8646 int name_set = 0;
8647 int tunnel_set = 0;
8648 int j = 0;
8649 int tunnel_names_length = 1; // Init to 1 to offset the #tunnel_names counter byte
8650 int tun_name_len = 0; // Different naming convention used as confusing these would be "bad" (TM)
Jon Loeliger56c7b012017-02-01 12:31:41 -06008651 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008652
8653 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8654 {
8655 if (unformat (input, "del"))
8656 is_del = 1;
8657 else if (unformat (input, "name %s", &name))
8658 name_set = 1;
8659 else if (unformat (input, "tunnel %s", &tunnel_name))
8660 {
8661 if (tunnel_name)
8662 {
8663 vec_add1 (tunnel_names, tunnel_name);
8664 /* For serializer:
8665 - length = #bytes to store in serial vector
8666 - +1 = byte to store that length
8667 */
8668 tunnel_names_length += (vec_len (tunnel_name) + 1);
8669 tunnel_set = 1;
8670 tunnel_name = 0;
8671 }
8672 }
8673 else
8674 break;
8675 }
8676
8677 if (!name_set)
8678 {
8679 errmsg ("policy name required");
8680 return -99;
8681 }
8682
8683 if ((!tunnel_set) && (!is_del))
8684 {
8685 errmsg ("tunnel name required");
8686 return -99;
8687 }
8688
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008689 M2 (SR_POLICY_ADD_DEL, mp, tunnel_names_length);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008690
8691
8692
8693 mp->is_add = !is_del;
8694
8695 memcpy (mp->name, name, vec_len (name));
8696 // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
8697 u8 *serial_orig = 0;
8698 vec_validate (serial_orig, tunnel_names_length);
8699 *serial_orig = vec_len (tunnel_names); // Store the number of tunnels as length in first byte of serialized vector
8700 serial_orig += 1; // Move along one byte to store the length of first tunnel_name
8701
8702 for (j = 0; j < vec_len (tunnel_names); j++)
8703 {
8704 tun_name_len = vec_len (tunnel_names[j]);
8705 *serial_orig = tun_name_len; // Store length of tunnel name in first byte of Length/Value pair
8706 serial_orig += 1; // Move along one byte to store the actual tunnel name
8707 memcpy (serial_orig, tunnel_names[j], tun_name_len);
8708 serial_orig += tun_name_len; // Advance past the copy
8709 }
8710 memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length); // Regress serial_orig to head then copy fwd
8711
8712 vec_free (tunnel_names);
8713 vec_free (tunnel_name);
8714
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008715 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008716 W (ret);
8717 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008718}
8719
8720static int
8721api_sr_multicast_map_add_del (vat_main_t * vam)
8722{
8723 unformat_input_t *input = vam->input;
8724 vl_api_sr_multicast_map_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008725 int is_del = 0;
8726 ip6_address_t multicast_address;
8727 u8 *policy_name = 0;
8728 int multicast_address_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008729 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008730
8731 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8732 {
8733 if (unformat (input, "del"))
8734 is_del = 1;
8735 else
8736 if (unformat
8737 (input, "address %U", unformat_ip6_address, &multicast_address))
8738 multicast_address_set = 1;
8739 else if (unformat (input, "sr-policy %s", &policy_name))
8740 ;
8741 else
8742 break;
8743 }
8744
8745 if (!is_del && !policy_name)
8746 {
8747 errmsg ("sr-policy name required");
8748 return -99;
8749 }
8750
8751
8752 if (!multicast_address_set)
8753 {
8754 errmsg ("address required");
8755 return -99;
8756 }
8757
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008758 M (SR_MULTICAST_MAP_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008759
8760 mp->is_add = !is_del;
8761 memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8762 clib_memcpy (mp->multicast_address, &multicast_address,
8763 sizeof (mp->multicast_address));
8764
8765
8766 vec_free (policy_name);
8767
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008768 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008769 W (ret);
8770 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008771}
8772
8773
8774#define foreach_tcp_proto_field \
8775_(src_port) \
8776_(dst_port)
8777
8778#define foreach_udp_proto_field \
8779_(src_port) \
8780_(dst_port)
8781
8782#define foreach_ip4_proto_field \
8783_(src_address) \
8784_(dst_address) \
8785_(tos) \
8786_(length) \
8787_(fragment_id) \
8788_(ttl) \
8789_(protocol) \
8790_(checksum)
8791
Dave Barach4a3f69c2017-02-22 12:44:56 -05008792typedef struct
8793{
8794 u16 src_port, dst_port;
8795} tcpudp_header_t;
8796
8797#if VPP_API_TEST_BUILTIN == 0
Damjan Marion7cd468a2016-12-19 23:05:39 +01008798uword
8799unformat_tcp_mask (unformat_input_t * input, va_list * args)
8800{
8801 u8 **maskp = va_arg (*args, u8 **);
8802 u8 *mask = 0;
8803 u8 found_something = 0;
8804 tcp_header_t *tcp;
8805
8806#define _(a) u8 a=0;
8807 foreach_tcp_proto_field;
8808#undef _
8809
8810 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8811 {
8812 if (0);
8813#define _(a) else if (unformat (input, #a)) a=1;
8814 foreach_tcp_proto_field
8815#undef _
8816 else
8817 break;
8818 }
8819
8820#define _(a) found_something += a;
8821 foreach_tcp_proto_field;
8822#undef _
8823
8824 if (found_something == 0)
8825 return 0;
8826
8827 vec_validate (mask, sizeof (*tcp) - 1);
8828
8829 tcp = (tcp_header_t *) mask;
8830
8831#define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8832 foreach_tcp_proto_field;
8833#undef _
8834
8835 *maskp = mask;
8836 return 1;
8837}
8838
8839uword
8840unformat_udp_mask (unformat_input_t * input, va_list * args)
8841{
8842 u8 **maskp = va_arg (*args, u8 **);
8843 u8 *mask = 0;
8844 u8 found_something = 0;
8845 udp_header_t *udp;
8846
8847#define _(a) u8 a=0;
8848 foreach_udp_proto_field;
8849#undef _
8850
8851 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8852 {
8853 if (0);
8854#define _(a) else if (unformat (input, #a)) a=1;
8855 foreach_udp_proto_field
8856#undef _
8857 else
8858 break;
8859 }
8860
8861#define _(a) found_something += a;
8862 foreach_udp_proto_field;
8863#undef _
8864
8865 if (found_something == 0)
8866 return 0;
8867
8868 vec_validate (mask, sizeof (*udp) - 1);
8869
8870 udp = (udp_header_t *) mask;
8871
8872#define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8873 foreach_udp_proto_field;
8874#undef _
8875
8876 *maskp = mask;
8877 return 1;
8878}
8879
Damjan Marion7cd468a2016-12-19 23:05:39 +01008880uword
8881unformat_l4_mask (unformat_input_t * input, va_list * args)
8882{
8883 u8 **maskp = va_arg (*args, u8 **);
8884 u16 src_port = 0, dst_port = 0;
8885 tcpudp_header_t *tcpudp;
8886
8887 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8888 {
8889 if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
8890 return 1;
8891 else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
8892 return 1;
8893 else if (unformat (input, "src_port"))
8894 src_port = 0xFFFF;
8895 else if (unformat (input, "dst_port"))
8896 dst_port = 0xFFFF;
8897 else
8898 return 0;
8899 }
8900
8901 if (!src_port && !dst_port)
8902 return 0;
8903
8904 u8 *mask = 0;
8905 vec_validate (mask, sizeof (tcpudp_header_t) - 1);
8906
8907 tcpudp = (tcpudp_header_t *) mask;
8908 tcpudp->src_port = src_port;
8909 tcpudp->dst_port = dst_port;
8910
8911 *maskp = mask;
8912
8913 return 1;
8914}
8915
8916uword
8917unformat_ip4_mask (unformat_input_t * input, va_list * args)
8918{
8919 u8 **maskp = va_arg (*args, u8 **);
8920 u8 *mask = 0;
8921 u8 found_something = 0;
8922 ip4_header_t *ip;
8923
8924#define _(a) u8 a=0;
8925 foreach_ip4_proto_field;
8926#undef _
8927 u8 version = 0;
8928 u8 hdr_length = 0;
8929
8930
8931 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8932 {
8933 if (unformat (input, "version"))
8934 version = 1;
8935 else if (unformat (input, "hdr_length"))
8936 hdr_length = 1;
8937 else if (unformat (input, "src"))
8938 src_address = 1;
8939 else if (unformat (input, "dst"))
8940 dst_address = 1;
8941 else if (unformat (input, "proto"))
8942 protocol = 1;
8943
8944#define _(a) else if (unformat (input, #a)) a=1;
8945 foreach_ip4_proto_field
8946#undef _
8947 else
8948 break;
8949 }
8950
8951#define _(a) found_something += a;
8952 foreach_ip4_proto_field;
8953#undef _
8954
8955 if (found_something == 0)
8956 return 0;
8957
8958 vec_validate (mask, sizeof (*ip) - 1);
8959
8960 ip = (ip4_header_t *) mask;
8961
8962#define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8963 foreach_ip4_proto_field;
8964#undef _
8965
8966 ip->ip_version_and_header_length = 0;
8967
8968 if (version)
8969 ip->ip_version_and_header_length |= 0xF0;
8970
8971 if (hdr_length)
8972 ip->ip_version_and_header_length |= 0x0F;
8973
8974 *maskp = mask;
8975 return 1;
8976}
8977
8978#define foreach_ip6_proto_field \
8979_(src_address) \
8980_(dst_address) \
8981_(payload_length) \
8982_(hop_limit) \
8983_(protocol)
8984
8985uword
8986unformat_ip6_mask (unformat_input_t * input, va_list * args)
8987{
8988 u8 **maskp = va_arg (*args, u8 **);
8989 u8 *mask = 0;
8990 u8 found_something = 0;
8991 ip6_header_t *ip;
8992 u32 ip_version_traffic_class_and_flow_label;
8993
8994#define _(a) u8 a=0;
8995 foreach_ip6_proto_field;
8996#undef _
8997 u8 version = 0;
8998 u8 traffic_class = 0;
8999 u8 flow_label = 0;
9000
9001 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9002 {
9003 if (unformat (input, "version"))
9004 version = 1;
9005 else if (unformat (input, "traffic-class"))
9006 traffic_class = 1;
9007 else if (unformat (input, "flow-label"))
9008 flow_label = 1;
9009 else if (unformat (input, "src"))
9010 src_address = 1;
9011 else if (unformat (input, "dst"))
9012 dst_address = 1;
9013 else if (unformat (input, "proto"))
9014 protocol = 1;
9015
9016#define _(a) else if (unformat (input, #a)) a=1;
9017 foreach_ip6_proto_field
9018#undef _
9019 else
9020 break;
9021 }
9022
9023#define _(a) found_something += a;
9024 foreach_ip6_proto_field;
9025#undef _
9026
9027 if (found_something == 0)
9028 return 0;
9029
9030 vec_validate (mask, sizeof (*ip) - 1);
9031
9032 ip = (ip6_header_t *) mask;
9033
9034#define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
9035 foreach_ip6_proto_field;
9036#undef _
9037
9038 ip_version_traffic_class_and_flow_label = 0;
9039
9040 if (version)
9041 ip_version_traffic_class_and_flow_label |= 0xF0000000;
9042
9043 if (traffic_class)
9044 ip_version_traffic_class_and_flow_label |= 0x0FF00000;
9045
9046 if (flow_label)
9047 ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
9048
9049 ip->ip_version_traffic_class_and_flow_label =
9050 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9051
9052 *maskp = mask;
9053 return 1;
9054}
9055
9056uword
9057unformat_l3_mask (unformat_input_t * input, va_list * args)
9058{
9059 u8 **maskp = va_arg (*args, u8 **);
9060
9061 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9062 {
9063 if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
9064 return 1;
9065 else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
9066 return 1;
9067 else
9068 break;
9069 }
9070 return 0;
9071}
9072
9073uword
9074unformat_l2_mask (unformat_input_t * input, va_list * args)
9075{
9076 u8 **maskp = va_arg (*args, u8 **);
9077 u8 *mask = 0;
9078 u8 src = 0;
9079 u8 dst = 0;
9080 u8 proto = 0;
9081 u8 tag1 = 0;
9082 u8 tag2 = 0;
9083 u8 ignore_tag1 = 0;
9084 u8 ignore_tag2 = 0;
9085 u8 cos1 = 0;
9086 u8 cos2 = 0;
9087 u8 dot1q = 0;
9088 u8 dot1ad = 0;
9089 int len = 14;
9090
9091 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9092 {
9093 if (unformat (input, "src"))
9094 src = 1;
9095 else if (unformat (input, "dst"))
9096 dst = 1;
9097 else if (unformat (input, "proto"))
9098 proto = 1;
9099 else if (unformat (input, "tag1"))
9100 tag1 = 1;
9101 else if (unformat (input, "tag2"))
9102 tag2 = 1;
9103 else if (unformat (input, "ignore-tag1"))
9104 ignore_tag1 = 1;
9105 else if (unformat (input, "ignore-tag2"))
9106 ignore_tag2 = 1;
9107 else if (unformat (input, "cos1"))
9108 cos1 = 1;
9109 else if (unformat (input, "cos2"))
9110 cos2 = 1;
9111 else if (unformat (input, "dot1q"))
9112 dot1q = 1;
9113 else if (unformat (input, "dot1ad"))
9114 dot1ad = 1;
9115 else
9116 break;
9117 }
9118 if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9119 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9120 return 0;
9121
9122 if (tag1 || ignore_tag1 || cos1 || dot1q)
9123 len = 18;
9124 if (tag2 || ignore_tag2 || cos2 || dot1ad)
9125 len = 22;
9126
9127 vec_validate (mask, len - 1);
9128
9129 if (dst)
9130 memset (mask, 0xff, 6);
9131
9132 if (src)
9133 memset (mask + 6, 0xff, 6);
9134
9135 if (tag2 || dot1ad)
9136 {
9137 /* inner vlan tag */
9138 if (tag2)
9139 {
9140 mask[19] = 0xff;
9141 mask[18] = 0x0f;
9142 }
9143 if (cos2)
9144 mask[18] |= 0xe0;
9145 if (proto)
9146 mask[21] = mask[20] = 0xff;
9147 if (tag1)
9148 {
9149 mask[15] = 0xff;
9150 mask[14] = 0x0f;
9151 }
9152 if (cos1)
9153 mask[14] |= 0xe0;
9154 *maskp = mask;
9155 return 1;
9156 }
9157 if (tag1 | dot1q)
9158 {
9159 if (tag1)
9160 {
9161 mask[15] = 0xff;
9162 mask[14] = 0x0f;
9163 }
9164 if (cos1)
9165 mask[14] |= 0xe0;
9166 if (proto)
9167 mask[16] = mask[17] = 0xff;
9168
9169 *maskp = mask;
9170 return 1;
9171 }
9172 if (cos2)
9173 mask[18] |= 0xe0;
9174 if (cos1)
9175 mask[14] |= 0xe0;
9176 if (proto)
9177 mask[12] = mask[13] = 0xff;
9178
9179 *maskp = mask;
9180 return 1;
9181}
9182
9183uword
9184unformat_classify_mask (unformat_input_t * input, va_list * args)
9185{
9186 u8 **maskp = va_arg (*args, u8 **);
9187 u32 *skipp = va_arg (*args, u32 *);
9188 u32 *matchp = va_arg (*args, u32 *);
9189 u32 match;
9190 u8 *mask = 0;
9191 u8 *l2 = 0;
9192 u8 *l3 = 0;
9193 u8 *l4 = 0;
9194 int i;
9195
9196 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9197 {
9198 if (unformat (input, "hex %U", unformat_hex_string, &mask))
9199 ;
9200 else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
9201 ;
9202 else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
9203 ;
9204 else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
9205 ;
9206 else
9207 break;
9208 }
9209
9210 if (l4 && !l3)
9211 {
9212 vec_free (mask);
9213 vec_free (l2);
9214 vec_free (l4);
9215 return 0;
9216 }
9217
9218 if (mask || l2 || l3 || l4)
9219 {
9220 if (l2 || l3 || l4)
9221 {
9222 /* "With a free Ethernet header in every package" */
9223 if (l2 == 0)
9224 vec_validate (l2, 13);
9225 mask = l2;
9226 if (vec_len (l3))
9227 {
9228 vec_append (mask, l3);
9229 vec_free (l3);
9230 }
9231 if (vec_len (l4))
9232 {
9233 vec_append (mask, l4);
9234 vec_free (l4);
9235 }
9236 }
9237
9238 /* Scan forward looking for the first significant mask octet */
9239 for (i = 0; i < vec_len (mask); i++)
9240 if (mask[i])
9241 break;
9242
9243 /* compute (skip, match) params */
9244 *skipp = i / sizeof (u32x4);
9245 vec_delete (mask, *skipp * sizeof (u32x4), 0);
9246
9247 /* Pad mask to an even multiple of the vector size */
9248 while (vec_len (mask) % sizeof (u32x4))
9249 vec_add1 (mask, 0);
9250
9251 match = vec_len (mask) / sizeof (u32x4);
9252
9253 for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9254 {
9255 u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9256 if (*tmp || *(tmp + 1))
9257 break;
9258 match--;
9259 }
9260 if (match == 0)
9261 clib_warning ("BUG: match 0");
9262
9263 _vec_len (mask) = match * sizeof (u32x4);
9264
9265 *matchp = match;
9266 *maskp = mask;
9267
9268 return 1;
9269 }
9270
9271 return 0;
9272}
Dave Barach4a3f69c2017-02-22 12:44:56 -05009273#endif /* VPP_API_TEST_BUILTIN */
Damjan Marion7cd468a2016-12-19 23:05:39 +01009274
9275#define foreach_l2_next \
9276_(drop, DROP) \
9277_(ethernet, ETHERNET_INPUT) \
9278_(ip4, IP4_INPUT) \
9279_(ip6, IP6_INPUT)
9280
9281uword
9282unformat_l2_next_index (unformat_input_t * input, va_list * args)
9283{
9284 u32 *miss_next_indexp = va_arg (*args, u32 *);
9285 u32 next_index = 0;
9286 u32 tmp;
9287
9288#define _(n,N) \
9289 if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9290 foreach_l2_next;
9291#undef _
9292
9293 if (unformat (input, "%d", &tmp))
9294 {
9295 next_index = tmp;
9296 goto out;
9297 }
9298
9299 return 0;
9300
9301out:
9302 *miss_next_indexp = next_index;
9303 return 1;
9304}
9305
9306#define foreach_ip_next \
9307_(drop, DROP) \
9308_(local, LOCAL) \
9309_(rewrite, REWRITE)
9310
9311uword
Dave Barach4a3f69c2017-02-22 12:44:56 -05009312api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
Damjan Marion7cd468a2016-12-19 23:05:39 +01009313{
9314 u32 *miss_next_indexp = va_arg (*args, u32 *);
9315 u32 next_index = 0;
9316 u32 tmp;
9317
9318#define _(n,N) \
9319 if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9320 foreach_ip_next;
9321#undef _
9322
9323 if (unformat (input, "%d", &tmp))
9324 {
9325 next_index = tmp;
9326 goto out;
9327 }
9328
9329 return 0;
9330
9331out:
9332 *miss_next_indexp = next_index;
9333 return 1;
9334}
9335
9336#define foreach_acl_next \
9337_(deny, DENY)
9338
9339uword
Dave Barach4a3f69c2017-02-22 12:44:56 -05009340api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
Damjan Marion7cd468a2016-12-19 23:05:39 +01009341{
9342 u32 *miss_next_indexp = va_arg (*args, u32 *);
9343 u32 next_index = 0;
9344 u32 tmp;
9345
9346#define _(n,N) \
9347 if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
9348 foreach_acl_next;
9349#undef _
9350
9351 if (unformat (input, "permit"))
9352 {
9353 next_index = ~0;
9354 goto out;
9355 }
9356 else if (unformat (input, "%d", &tmp))
9357 {
9358 next_index = tmp;
9359 goto out;
9360 }
9361
9362 return 0;
9363
9364out:
9365 *miss_next_indexp = next_index;
9366 return 1;
9367}
9368
9369uword
9370unformat_policer_precolor (unformat_input_t * input, va_list * args)
9371{
9372 u32 *r = va_arg (*args, u32 *);
9373
9374 if (unformat (input, "conform-color"))
9375 *r = POLICE_CONFORM;
9376 else if (unformat (input, "exceed-color"))
9377 *r = POLICE_EXCEED;
9378 else
9379 return 0;
9380
9381 return 1;
9382}
9383
9384static int
9385api_classify_add_del_table (vat_main_t * vam)
9386{
9387 unformat_input_t *i = vam->input;
9388 vl_api_classify_add_del_table_t *mp;
9389
9390 u32 nbuckets = 2;
9391 u32 skip = ~0;
9392 u32 match = ~0;
9393 int is_add = 1;
9394 int del_chain = 0;
9395 u32 table_index = ~0;
9396 u32 next_table_index = ~0;
9397 u32 miss_next_index = ~0;
9398 u32 memory_size = 32 << 20;
9399 u8 *mask = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009400 u32 current_data_flag = 0;
9401 int current_data_offset = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009402 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009403
9404 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9405 {
9406 if (unformat (i, "del"))
9407 is_add = 0;
9408 else if (unformat (i, "del-chain"))
9409 {
9410 is_add = 0;
9411 del_chain = 1;
9412 }
9413 else if (unformat (i, "buckets %d", &nbuckets))
9414 ;
9415 else if (unformat (i, "memory_size %d", &memory_size))
9416 ;
9417 else if (unformat (i, "skip %d", &skip))
9418 ;
9419 else if (unformat (i, "match %d", &match))
9420 ;
9421 else if (unformat (i, "table %d", &table_index))
9422 ;
9423 else if (unformat (i, "mask %U", unformat_classify_mask,
9424 &mask, &skip, &match))
9425 ;
9426 else if (unformat (i, "next-table %d", &next_table_index))
9427 ;
Dave Barach4a3f69c2017-02-22 12:44:56 -05009428 else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
Damjan Marion7cd468a2016-12-19 23:05:39 +01009429 &miss_next_index))
9430 ;
9431 else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
9432 &miss_next_index))
9433 ;
Dave Barach4a3f69c2017-02-22 12:44:56 -05009434 else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
Damjan Marion7cd468a2016-12-19 23:05:39 +01009435 &miss_next_index))
9436 ;
9437 else if (unformat (i, "current-data-flag %d", &current_data_flag))
9438 ;
9439 else if (unformat (i, "current-data-offset %d", &current_data_offset))
9440 ;
9441 else
9442 break;
9443 }
9444
9445 if (is_add && mask == 0)
9446 {
9447 errmsg ("Mask required");
9448 return -99;
9449 }
9450
9451 if (is_add && skip == ~0)
9452 {
9453 errmsg ("skip count required");
9454 return -99;
9455 }
9456
9457 if (is_add && match == ~0)
9458 {
9459 errmsg ("match count required");
9460 return -99;
9461 }
9462
9463 if (!is_add && table_index == ~0)
9464 {
9465 errmsg ("table index required for delete");
9466 return -99;
9467 }
9468
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009469 M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
Damjan Marion7cd468a2016-12-19 23:05:39 +01009470
9471 mp->is_add = is_add;
9472 mp->del_chain = del_chain;
9473 mp->table_index = ntohl (table_index);
9474 mp->nbuckets = ntohl (nbuckets);
9475 mp->memory_size = ntohl (memory_size);
9476 mp->skip_n_vectors = ntohl (skip);
9477 mp->match_n_vectors = ntohl (match);
9478 mp->next_table_index = ntohl (next_table_index);
9479 mp->miss_next_index = ntohl (miss_next_index);
9480 mp->current_data_flag = ntohl (current_data_flag);
9481 mp->current_data_offset = ntohl (current_data_offset);
9482 clib_memcpy (mp->mask, mask, vec_len (mask));
9483
9484 vec_free (mask);
9485
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009486 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06009487 W (ret);
9488 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009489}
9490
Dave Barach4a3f69c2017-02-22 12:44:56 -05009491#if VPP_API_TEST_BUILTIN == 0
Damjan Marion7cd468a2016-12-19 23:05:39 +01009492uword
9493unformat_l4_match (unformat_input_t * input, va_list * args)
9494{
9495 u8 **matchp = va_arg (*args, u8 **);
9496
9497 u8 *proto_header = 0;
9498 int src_port = 0;
9499 int dst_port = 0;
9500
9501 tcpudp_header_t h;
9502
9503 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9504 {
9505 if (unformat (input, "src_port %d", &src_port))
9506 ;
9507 else if (unformat (input, "dst_port %d", &dst_port))
9508 ;
9509 else
9510 return 0;
9511 }
9512
9513 h.src_port = clib_host_to_net_u16 (src_port);
9514 h.dst_port = clib_host_to_net_u16 (dst_port);
9515 vec_validate (proto_header, sizeof (h) - 1);
9516 memcpy (proto_header, &h, sizeof (h));
9517
9518 *matchp = proto_header;
9519
9520 return 1;
9521}
9522
9523uword
9524unformat_ip4_match (unformat_input_t * input, va_list * args)
9525{
9526 u8 **matchp = va_arg (*args, u8 **);
9527 u8 *match = 0;
9528 ip4_header_t *ip;
9529 int version = 0;
9530 u32 version_val;
9531 int hdr_length = 0;
9532 u32 hdr_length_val;
9533 int src = 0, dst = 0;
9534 ip4_address_t src_val, dst_val;
9535 int proto = 0;
9536 u32 proto_val;
9537 int tos = 0;
9538 u32 tos_val;
9539 int length = 0;
9540 u32 length_val;
9541 int fragment_id = 0;
9542 u32 fragment_id_val;
9543 int ttl = 0;
9544 int ttl_val;
9545 int checksum = 0;
9546 u32 checksum_val;
9547
9548 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9549 {
9550 if (unformat (input, "version %d", &version_val))
9551 version = 1;
9552 else if (unformat (input, "hdr_length %d", &hdr_length_val))
9553 hdr_length = 1;
9554 else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
9555 src = 1;
9556 else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
9557 dst = 1;
9558 else if (unformat (input, "proto %d", &proto_val))
9559 proto = 1;
9560 else if (unformat (input, "tos %d", &tos_val))
9561 tos = 1;
9562 else if (unformat (input, "length %d", &length_val))
9563 length = 1;
9564 else if (unformat (input, "fragment_id %d", &fragment_id_val))
9565 fragment_id = 1;
9566 else if (unformat (input, "ttl %d", &ttl_val))
9567 ttl = 1;
9568 else if (unformat (input, "checksum %d", &checksum_val))
9569 checksum = 1;
9570 else
9571 break;
9572 }
9573
9574 if (version + hdr_length + src + dst + proto + tos + length + fragment_id
9575 + ttl + checksum == 0)
9576 return 0;
9577
9578 /*
9579 * Aligned because we use the real comparison functions
9580 */
9581 vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9582
9583 ip = (ip4_header_t *) match;
9584
9585 /* These are realistically matched in practice */
9586 if (src)
9587 ip->src_address.as_u32 = src_val.as_u32;
9588
9589 if (dst)
9590 ip->dst_address.as_u32 = dst_val.as_u32;
9591
9592 if (proto)
9593 ip->protocol = proto_val;
9594
9595
9596 /* These are not, but they're included for completeness */
9597 if (version)
9598 ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
9599
9600 if (hdr_length)
9601 ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
9602
9603 if (tos)
9604 ip->tos = tos_val;
9605
9606 if (length)
9607 ip->length = clib_host_to_net_u16 (length_val);
9608
9609 if (ttl)
9610 ip->ttl = ttl_val;
9611
9612 if (checksum)
9613 ip->checksum = clib_host_to_net_u16 (checksum_val);
9614
9615 *matchp = match;
9616 return 1;
9617}
9618
9619uword
9620unformat_ip6_match (unformat_input_t * input, va_list * args)
9621{
9622 u8 **matchp = va_arg (*args, u8 **);
9623 u8 *match = 0;
9624 ip6_header_t *ip;
9625 int version = 0;
9626 u32 version_val;
9627 u8 traffic_class = 0;
9628 u32 traffic_class_val = 0;
9629 u8 flow_label = 0;
9630 u8 flow_label_val;
9631 int src = 0, dst = 0;
9632 ip6_address_t src_val, dst_val;
9633 int proto = 0;
9634 u32 proto_val;
9635 int payload_length = 0;
9636 u32 payload_length_val;
9637 int hop_limit = 0;
9638 int hop_limit_val;
9639 u32 ip_version_traffic_class_and_flow_label;
9640
9641 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9642 {
9643 if (unformat (input, "version %d", &version_val))
9644 version = 1;
9645 else if (unformat (input, "traffic_class %d", &traffic_class_val))
9646 traffic_class = 1;
9647 else if (unformat (input, "flow_label %d", &flow_label_val))
9648 flow_label = 1;
9649 else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
9650 src = 1;
9651 else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
9652 dst = 1;
9653 else if (unformat (input, "proto %d", &proto_val))
9654 proto = 1;
9655 else if (unformat (input, "payload_length %d", &payload_length_val))
9656 payload_length = 1;
9657 else if (unformat (input, "hop_limit %d", &hop_limit_val))
9658 hop_limit = 1;
9659 else
9660 break;
9661 }
9662
9663 if (version + traffic_class + flow_label + src + dst + proto +
9664 payload_length + hop_limit == 0)
9665 return 0;
9666
9667 /*
9668 * Aligned because we use the real comparison functions
9669 */
9670 vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9671
9672 ip = (ip6_header_t *) match;
9673
9674 if (src)
9675 clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9676
9677 if (dst)
9678 clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9679
9680 if (proto)
9681 ip->protocol = proto_val;
9682
9683 ip_version_traffic_class_and_flow_label = 0;
9684
9685 if (version)
9686 ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9687
9688 if (traffic_class)
9689 ip_version_traffic_class_and_flow_label |=
9690 (traffic_class_val & 0xFF) << 20;
9691
9692 if (flow_label)
9693 ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9694
9695 ip->ip_version_traffic_class_and_flow_label =
9696 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9697
9698 if (payload_length)
9699 ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9700
9701 if (hop_limit)
9702 ip->hop_limit = hop_limit_val;
9703
9704 *matchp = match;
9705 return 1;
9706}
9707
9708uword
9709unformat_l3_match (unformat_input_t * input, va_list * args)
9710{
9711 u8 **matchp = va_arg (*args, u8 **);
9712
9713 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9714 {
9715 if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9716 return 1;
9717 else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9718 return 1;
9719 else
9720 break;
9721 }
9722 return 0;
9723}
9724
9725uword
9726unformat_vlan_tag (unformat_input_t * input, va_list * args)
9727{
9728 u8 *tagp = va_arg (*args, u8 *);
9729 u32 tag;
9730
9731 if (unformat (input, "%d", &tag))
9732 {
9733 tagp[0] = (tag >> 8) & 0x0F;
9734 tagp[1] = tag & 0xFF;
9735 return 1;
9736 }
9737
9738 return 0;
9739}
9740
9741uword
9742unformat_l2_match (unformat_input_t * input, va_list * args)
9743{
9744 u8 **matchp = va_arg (*args, u8 **);
9745 u8 *match = 0;
9746 u8 src = 0;
9747 u8 src_val[6];
9748 u8 dst = 0;
9749 u8 dst_val[6];
9750 u8 proto = 0;
9751 u16 proto_val;
9752 u8 tag1 = 0;
9753 u8 tag1_val[2];
9754 u8 tag2 = 0;
9755 u8 tag2_val[2];
9756 int len = 14;
9757 u8 ignore_tag1 = 0;
9758 u8 ignore_tag2 = 0;
9759 u8 cos1 = 0;
9760 u8 cos2 = 0;
9761 u32 cos1_val = 0;
9762 u32 cos2_val = 0;
9763
9764 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9765 {
9766 if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9767 src = 1;
9768 else
9769 if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9770 dst = 1;
9771 else if (unformat (input, "proto %U",
9772 unformat_ethernet_type_host_byte_order, &proto_val))
9773 proto = 1;
9774 else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9775 tag1 = 1;
9776 else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9777 tag2 = 1;
9778 else if (unformat (input, "ignore-tag1"))
9779 ignore_tag1 = 1;
9780 else if (unformat (input, "ignore-tag2"))
9781 ignore_tag2 = 1;
9782 else if (unformat (input, "cos1 %d", &cos1_val))
9783 cos1 = 1;
9784 else if (unformat (input, "cos2 %d", &cos2_val))
9785 cos2 = 1;
9786 else
9787 break;
9788 }
9789 if ((src + dst + proto + tag1 + tag2 +
9790 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9791 return 0;
9792
9793 if (tag1 || ignore_tag1 || cos1)
9794 len = 18;
9795 if (tag2 || ignore_tag2 || cos2)
9796 len = 22;
9797
9798 vec_validate_aligned (match, len - 1, sizeof (u32x4));
9799
9800 if (dst)
9801 clib_memcpy (match, dst_val, 6);
9802
9803 if (src)
9804 clib_memcpy (match + 6, src_val, 6);
9805
9806 if (tag2)
9807 {
9808 /* inner vlan tag */
9809 match[19] = tag2_val[1];
9810 match[18] = tag2_val[0];
9811 if (cos2)
9812 match[18] |= (cos2_val & 0x7) << 5;
9813 if (proto)
9814 {
9815 match[21] = proto_val & 0xff;
9816 match[20] = proto_val >> 8;
9817 }
9818 if (tag1)
9819 {
9820 match[15] = tag1_val[1];
9821 match[14] = tag1_val[0];
9822 }
9823 if (cos1)
9824 match[14] |= (cos1_val & 0x7) << 5;
9825 *matchp = match;
9826 return 1;
9827 }
9828 if (tag1)
9829 {
9830 match[15] = tag1_val[1];
9831 match[14] = tag1_val[0];
9832 if (proto)
9833 {
9834 match[17] = proto_val & 0xff;
9835 match[16] = proto_val >> 8;
9836 }
9837 if (cos1)
9838 match[14] |= (cos1_val & 0x7) << 5;
9839
9840 *matchp = match;
9841 return 1;
9842 }
9843 if (cos2)
9844 match[18] |= (cos2_val & 0x7) << 5;
9845 if (cos1)
9846 match[14] |= (cos1_val & 0x7) << 5;
9847 if (proto)
9848 {
9849 match[13] = proto_val & 0xff;
9850 match[12] = proto_val >> 8;
9851 }
9852
9853 *matchp = match;
9854 return 1;
9855}
Dave Barach4a3f69c2017-02-22 12:44:56 -05009856#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +01009857
9858uword
Dave Barach4a3f69c2017-02-22 12:44:56 -05009859api_unformat_classify_match (unformat_input_t * input, va_list * args)
Damjan Marion7cd468a2016-12-19 23:05:39 +01009860{
9861 u8 **matchp = va_arg (*args, u8 **);
9862 u32 skip_n_vectors = va_arg (*args, u32);
9863 u32 match_n_vectors = va_arg (*args, u32);
9864
9865 u8 *match = 0;
9866 u8 *l2 = 0;
9867 u8 *l3 = 0;
9868 u8 *l4 = 0;
9869
9870 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9871 {
9872 if (unformat (input, "hex %U", unformat_hex_string, &match))
9873 ;
9874 else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9875 ;
9876 else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9877 ;
9878 else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9879 ;
9880 else
9881 break;
9882 }
9883
9884 if (l4 && !l3)
9885 {
9886 vec_free (match);
9887 vec_free (l2);
9888 vec_free (l4);
9889 return 0;
9890 }
9891
9892 if (match || l2 || l3 || l4)
9893 {
9894 if (l2 || l3 || l4)
9895 {
9896 /* "Win a free Ethernet header in every packet" */
9897 if (l2 == 0)
9898 vec_validate_aligned (l2, 13, sizeof (u32x4));
9899 match = l2;
9900 if (vec_len (l3))
9901 {
9902 vec_append_aligned (match, l3, sizeof (u32x4));
9903 vec_free (l3);
9904 }
9905 if (vec_len (l4))
9906 {
9907 vec_append_aligned (match, l4, sizeof (u32x4));
9908 vec_free (l4);
9909 }
9910 }
9911
9912 /* Make sure the vector is big enough even if key is all 0's */
9913 vec_validate_aligned
9914 (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
9915 sizeof (u32x4));
9916
9917 /* Set size, include skipped vectors */
9918 _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
9919
9920 *matchp = match;
9921
9922 return 1;
9923 }
9924
9925 return 0;
9926}
9927
9928static int
9929api_classify_add_del_session (vat_main_t * vam)
9930{
9931 unformat_input_t *i = vam->input;
9932 vl_api_classify_add_del_session_t *mp;
9933 int is_add = 1;
9934 u32 table_index = ~0;
9935 u32 hit_next_index = ~0;
9936 u32 opaque_index = ~0;
9937 u8 *match = 0;
9938 i32 advance = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009939 u32 skip_n_vectors = 0;
9940 u32 match_n_vectors = 0;
9941 u32 action = 0;
9942 u32 metadata = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009943 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009944
9945 /*
9946 * Warning: you have to supply skip_n and match_n
9947 * because the API client cant simply look at the classify
9948 * table object.
9949 */
9950
9951 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9952 {
9953 if (unformat (i, "del"))
9954 is_add = 0;
Dave Barach4a3f69c2017-02-22 12:44:56 -05009955 else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
Damjan Marion7cd468a2016-12-19 23:05:39 +01009956 &hit_next_index))
9957 ;
9958 else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
9959 &hit_next_index))
9960 ;
Dave Barach4a3f69c2017-02-22 12:44:56 -05009961 else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
Damjan Marion7cd468a2016-12-19 23:05:39 +01009962 &hit_next_index))
9963 ;
9964 else if (unformat (i, "policer-hit-next %d", &hit_next_index))
9965 ;
9966 else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
9967 ;
9968 else if (unformat (i, "opaque-index %d", &opaque_index))
9969 ;
9970 else if (unformat (i, "skip_n %d", &skip_n_vectors))
9971 ;
9972 else if (unformat (i, "match_n %d", &match_n_vectors))
9973 ;
Dave Barach4a3f69c2017-02-22 12:44:56 -05009974 else if (unformat (i, "match %U", api_unformat_classify_match,
Damjan Marion7cd468a2016-12-19 23:05:39 +01009975 &match, skip_n_vectors, match_n_vectors))
9976 ;
9977 else if (unformat (i, "advance %d", &advance))
9978 ;
9979 else if (unformat (i, "table-index %d", &table_index))
9980 ;
9981 else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
9982 action = 1;
9983 else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
9984 action = 2;
9985 else if (unformat (i, "action %d", &action))
9986 ;
9987 else if (unformat (i, "metadata %d", &metadata))
9988 ;
9989 else
9990 break;
9991 }
9992
9993 if (table_index == ~0)
9994 {
9995 errmsg ("Table index required");
9996 return -99;
9997 }
9998
9999 if (is_add && match == 0)
10000 {
10001 errmsg ("Match value required");
10002 return -99;
10003 }
10004
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010005 M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
Damjan Marion7cd468a2016-12-19 23:05:39 +010010006
10007 mp->is_add = is_add;
10008 mp->table_index = ntohl (table_index);
10009 mp->hit_next_index = ntohl (hit_next_index);
10010 mp->opaque_index = ntohl (opaque_index);
10011 mp->advance = ntohl (advance);
10012 mp->action = action;
10013 mp->metadata = ntohl (metadata);
10014 clib_memcpy (mp->match, match, vec_len (match));
10015 vec_free (match);
10016
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010017 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010018 W (ret);
10019 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010020}
10021
10022static int
10023api_classify_set_interface_ip_table (vat_main_t * vam)
10024{
10025 unformat_input_t *i = vam->input;
10026 vl_api_classify_set_interface_ip_table_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010027 u32 sw_if_index;
10028 int sw_if_index_set;
10029 u32 table_index = ~0;
10030 u8 is_ipv6 = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010031 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010032
10033 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10034 {
10035 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10036 sw_if_index_set = 1;
10037 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10038 sw_if_index_set = 1;
10039 else if (unformat (i, "table %d", &table_index))
10040 ;
10041 else
10042 {
10043 clib_warning ("parse error '%U'", format_unformat_error, i);
10044 return -99;
10045 }
10046 }
10047
10048 if (sw_if_index_set == 0)
10049 {
10050 errmsg ("missing interface name or sw_if_index");
10051 return -99;
10052 }
10053
10054
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010055 M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010056
10057 mp->sw_if_index = ntohl (sw_if_index);
10058 mp->table_index = ntohl (table_index);
10059 mp->is_ipv6 = is_ipv6;
10060
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010061 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010062 W (ret);
10063 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010064}
10065
10066static int
10067api_classify_set_interface_l2_tables (vat_main_t * vam)
10068{
10069 unformat_input_t *i = vam->input;
10070 vl_api_classify_set_interface_l2_tables_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010071 u32 sw_if_index;
10072 int sw_if_index_set;
10073 u32 ip4_table_index = ~0;
10074 u32 ip6_table_index = ~0;
10075 u32 other_table_index = ~0;
10076 u32 is_input = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010077 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010078
10079 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10080 {
10081 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10082 sw_if_index_set = 1;
10083 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10084 sw_if_index_set = 1;
10085 else if (unformat (i, "ip4-table %d", &ip4_table_index))
10086 ;
10087 else if (unformat (i, "ip6-table %d", &ip6_table_index))
10088 ;
10089 else if (unformat (i, "other-table %d", &other_table_index))
10090 ;
10091 else if (unformat (i, "is-input %d", &is_input))
10092 ;
10093 else
10094 {
10095 clib_warning ("parse error '%U'", format_unformat_error, i);
10096 return -99;
10097 }
10098 }
10099
10100 if (sw_if_index_set == 0)
10101 {
10102 errmsg ("missing interface name or sw_if_index");
10103 return -99;
10104 }
10105
10106
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010107 M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010108
10109 mp->sw_if_index = ntohl (sw_if_index);
10110 mp->ip4_table_index = ntohl (ip4_table_index);
10111 mp->ip6_table_index = ntohl (ip6_table_index);
10112 mp->other_table_index = ntohl (other_table_index);
10113 mp->is_input = (u8) is_input;
10114
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010115 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010116 W (ret);
10117 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010118}
10119
10120static int
10121api_set_ipfix_exporter (vat_main_t * vam)
10122{
10123 unformat_input_t *i = vam->input;
10124 vl_api_set_ipfix_exporter_t *mp;
10125 ip4_address_t collector_address;
10126 u8 collector_address_set = 0;
10127 u32 collector_port = ~0;
10128 ip4_address_t src_address;
10129 u8 src_address_set = 0;
10130 u32 vrf_id = ~0;
10131 u32 path_mtu = ~0;
10132 u32 template_interval = ~0;
10133 u8 udp_checksum = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010134 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010135
10136 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10137 {
10138 if (unformat (i, "collector_address %U", unformat_ip4_address,
10139 &collector_address))
10140 collector_address_set = 1;
10141 else if (unformat (i, "collector_port %d", &collector_port))
10142 ;
10143 else if (unformat (i, "src_address %U", unformat_ip4_address,
10144 &src_address))
10145 src_address_set = 1;
10146 else if (unformat (i, "vrf_id %d", &vrf_id))
10147 ;
10148 else if (unformat (i, "path_mtu %d", &path_mtu))
10149 ;
10150 else if (unformat (i, "template_interval %d", &template_interval))
10151 ;
10152 else if (unformat (i, "udp_checksum"))
10153 udp_checksum = 1;
10154 else
10155 break;
10156 }
10157
10158 if (collector_address_set == 0)
10159 {
10160 errmsg ("collector_address required");
10161 return -99;
10162 }
10163
10164 if (src_address_set == 0)
10165 {
10166 errmsg ("src_address required");
10167 return -99;
10168 }
10169
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010170 M (SET_IPFIX_EXPORTER, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010171
10172 memcpy (mp->collector_address, collector_address.data,
10173 sizeof (collector_address.data));
10174 mp->collector_port = htons ((u16) collector_port);
10175 memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
10176 mp->vrf_id = htonl (vrf_id);
10177 mp->path_mtu = htonl (path_mtu);
10178 mp->template_interval = htonl (template_interval);
10179 mp->udp_checksum = udp_checksum;
10180
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010181 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010182 W (ret);
10183 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010184}
10185
10186static int
10187api_set_ipfix_classify_stream (vat_main_t * vam)
10188{
10189 unformat_input_t *i = vam->input;
10190 vl_api_set_ipfix_classify_stream_t *mp;
10191 u32 domain_id = 0;
10192 u32 src_port = UDP_DST_PORT_ipfix;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010193 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010194
10195 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10196 {
10197 if (unformat (i, "domain %d", &domain_id))
10198 ;
10199 else if (unformat (i, "src_port %d", &src_port))
10200 ;
10201 else
10202 {
10203 errmsg ("unknown input `%U'", format_unformat_error, i);
10204 return -99;
10205 }
10206 }
10207
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010208 M (SET_IPFIX_CLASSIFY_STREAM, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010209
10210 mp->domain_id = htonl (domain_id);
10211 mp->src_port = htons ((u16) src_port);
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_ipfix_classify_table_add_del (vat_main_t * vam)
10220{
10221 unformat_input_t *i = vam->input;
10222 vl_api_ipfix_classify_table_add_del_t *mp;
10223 int is_add = -1;
10224 u32 classify_table_index = ~0;
10225 u8 ip_version = 0;
10226 u8 transport_protocol = 255;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010227 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010228
10229 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10230 {
10231 if (unformat (i, "add"))
10232 is_add = 1;
10233 else if (unformat (i, "del"))
10234 is_add = 0;
10235 else if (unformat (i, "table %d", &classify_table_index))
10236 ;
10237 else if (unformat (i, "ip4"))
10238 ip_version = 4;
10239 else if (unformat (i, "ip6"))
10240 ip_version = 6;
10241 else if (unformat (i, "tcp"))
10242 transport_protocol = 6;
10243 else if (unformat (i, "udp"))
10244 transport_protocol = 17;
10245 else
10246 {
10247 errmsg ("unknown input `%U'", format_unformat_error, i);
10248 return -99;
10249 }
10250 }
10251
10252 if (is_add == -1)
10253 {
10254 errmsg ("expecting: add|del");
10255 return -99;
10256 }
10257 if (classify_table_index == ~0)
10258 {
10259 errmsg ("classifier table not specified");
10260 return -99;
10261 }
10262 if (ip_version == 0)
10263 {
10264 errmsg ("IP version not specified");
10265 return -99;
10266 }
10267
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010268 M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010269
10270 mp->is_add = is_add;
10271 mp->table_id = htonl (classify_table_index);
10272 mp->ip_version = ip_version;
10273 mp->transport_protocol = transport_protocol;
10274
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010275 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010276 W (ret);
10277 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010278}
10279
10280static int
10281api_get_node_index (vat_main_t * vam)
10282{
10283 unformat_input_t *i = vam->input;
10284 vl_api_get_node_index_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010285 u8 *name = 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, "node %s", &name))
10291 ;
10292 else
10293 break;
10294 }
10295 if (name == 0)
10296 {
10297 errmsg ("node name required");
10298 return -99;
10299 }
10300 if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10301 {
10302 errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10303 return -99;
10304 }
10305
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010306 M (GET_NODE_INDEX, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010307 clib_memcpy (mp->node_name, name, vec_len (name));
10308 vec_free (name);
10309
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010310 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010311 W (ret);
10312 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010313}
10314
10315static int
10316api_get_next_index (vat_main_t * vam)
10317{
10318 unformat_input_t *i = vam->input;
10319 vl_api_get_next_index_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010320 u8 *node_name = 0, *next_node_name = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010321 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010322
10323 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10324 {
10325 if (unformat (i, "node-name %s", &node_name))
10326 ;
10327 else if (unformat (i, "next-node-name %s", &next_node_name))
10328 break;
10329 }
10330
10331 if (node_name == 0)
10332 {
10333 errmsg ("node name required");
10334 return -99;
10335 }
10336 if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
10337 {
10338 errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10339 return -99;
10340 }
10341
10342 if (next_node_name == 0)
10343 {
10344 errmsg ("next node name required");
10345 return -99;
10346 }
10347 if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
10348 {
10349 errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
10350 return -99;
10351 }
10352
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010353 M (GET_NEXT_INDEX, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010354 clib_memcpy (mp->node_name, node_name, vec_len (node_name));
10355 clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
10356 vec_free (node_name);
10357 vec_free (next_node_name);
10358
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010359 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010360 W (ret);
10361 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010362}
10363
10364static int
10365api_add_node_next (vat_main_t * vam)
10366{
10367 unformat_input_t *i = vam->input;
10368 vl_api_add_node_next_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010369 u8 *name = 0;
10370 u8 *next = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010371 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010372
10373 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10374 {
10375 if (unformat (i, "node %s", &name))
10376 ;
10377 else if (unformat (i, "next %s", &next))
10378 ;
10379 else
10380 break;
10381 }
10382 if (name == 0)
10383 {
10384 errmsg ("node name required");
10385 return -99;
10386 }
10387 if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10388 {
10389 errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10390 return -99;
10391 }
10392 if (next == 0)
10393 {
10394 errmsg ("next node required");
10395 return -99;
10396 }
10397 if (vec_len (next) >= ARRAY_LEN (mp->next_name))
10398 {
10399 errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
10400 return -99;
10401 }
10402
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010403 M (ADD_NODE_NEXT, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010404 clib_memcpy (mp->node_name, name, vec_len (name));
10405 clib_memcpy (mp->next_name, next, vec_len (next));
10406 vec_free (name);
10407 vec_free (next);
10408
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010409 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010410 W (ret);
10411 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010412}
10413
10414static int
10415api_l2tpv3_create_tunnel (vat_main_t * vam)
10416{
10417 unformat_input_t *i = vam->input;
10418 ip6_address_t client_address, our_address;
10419 int client_address_set = 0;
10420 int our_address_set = 0;
10421 u32 local_session_id = 0;
10422 u32 remote_session_id = 0;
10423 u64 local_cookie = 0;
10424 u64 remote_cookie = 0;
10425 u8 l2_sublayer_present = 0;
10426 vl_api_l2tpv3_create_tunnel_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010427 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010428
10429 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10430 {
10431 if (unformat (i, "client_address %U", unformat_ip6_address,
10432 &client_address))
10433 client_address_set = 1;
10434 else if (unformat (i, "our_address %U", unformat_ip6_address,
10435 &our_address))
10436 our_address_set = 1;
10437 else if (unformat (i, "local_session_id %d", &local_session_id))
10438 ;
10439 else if (unformat (i, "remote_session_id %d", &remote_session_id))
10440 ;
10441 else if (unformat (i, "local_cookie %lld", &local_cookie))
10442 ;
10443 else if (unformat (i, "remote_cookie %lld", &remote_cookie))
10444 ;
10445 else if (unformat (i, "l2-sublayer-present"))
10446 l2_sublayer_present = 1;
10447 else
10448 break;
10449 }
10450
10451 if (client_address_set == 0)
10452 {
10453 errmsg ("client_address required");
10454 return -99;
10455 }
10456
10457 if (our_address_set == 0)
10458 {
10459 errmsg ("our_address required");
10460 return -99;
10461 }
10462
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010463 M (L2TPV3_CREATE_TUNNEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010464
10465 clib_memcpy (mp->client_address, client_address.as_u8,
10466 sizeof (mp->client_address));
10467
10468 clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
10469
10470 mp->local_session_id = ntohl (local_session_id);
10471 mp->remote_session_id = ntohl (remote_session_id);
10472 mp->local_cookie = clib_host_to_net_u64 (local_cookie);
10473 mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
10474 mp->l2_sublayer_present = l2_sublayer_present;
10475 mp->is_ipv6 = 1;
10476
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010477 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010478 W (ret);
10479 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010480}
10481
10482static int
10483api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
10484{
10485 unformat_input_t *i = vam->input;
10486 u32 sw_if_index;
10487 u8 sw_if_index_set = 0;
10488 u64 new_local_cookie = 0;
10489 u64 new_remote_cookie = 0;
10490 vl_api_l2tpv3_set_tunnel_cookies_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010491 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010492
10493 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10494 {
10495 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10496 sw_if_index_set = 1;
10497 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10498 sw_if_index_set = 1;
10499 else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
10500 ;
10501 else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
10502 ;
10503 else
10504 break;
10505 }
10506
10507 if (sw_if_index_set == 0)
10508 {
10509 errmsg ("missing interface name or sw_if_index");
10510 return -99;
10511 }
10512
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010513 M (L2TPV3_SET_TUNNEL_COOKIES, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010514
10515 mp->sw_if_index = ntohl (sw_if_index);
10516 mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
10517 mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
10518
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010519 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010520 W (ret);
10521 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010522}
10523
10524static int
10525api_l2tpv3_interface_enable_disable (vat_main_t * vam)
10526{
10527 unformat_input_t *i = vam->input;
10528 vl_api_l2tpv3_interface_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010529 u32 sw_if_index;
10530 u8 sw_if_index_set = 0;
10531 u8 enable_disable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010532 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010533
10534 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10535 {
10536 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10537 sw_if_index_set = 1;
10538 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10539 sw_if_index_set = 1;
10540 else if (unformat (i, "enable"))
10541 enable_disable = 1;
10542 else if (unformat (i, "disable"))
10543 enable_disable = 0;
10544 else
10545 break;
10546 }
10547
10548 if (sw_if_index_set == 0)
10549 {
10550 errmsg ("missing interface name or sw_if_index");
10551 return -99;
10552 }
10553
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010554 M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010555
10556 mp->sw_if_index = ntohl (sw_if_index);
10557 mp->enable_disable = enable_disable;
10558
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010559 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010560 W (ret);
10561 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010562}
10563
10564static int
10565api_l2tpv3_set_lookup_key (vat_main_t * vam)
10566{
10567 unformat_input_t *i = vam->input;
10568 vl_api_l2tpv3_set_lookup_key_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010569 u8 key = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010570 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010571
10572 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10573 {
10574 if (unformat (i, "lookup_v6_src"))
10575 key = L2T_LOOKUP_SRC_ADDRESS;
10576 else if (unformat (i, "lookup_v6_dst"))
10577 key = L2T_LOOKUP_DST_ADDRESS;
10578 else if (unformat (i, "lookup_session_id"))
10579 key = L2T_LOOKUP_SESSION_ID;
10580 else
10581 break;
10582 }
10583
10584 if (key == (u8) ~ 0)
10585 {
10586 errmsg ("l2tp session lookup key unset");
10587 return -99;
10588 }
10589
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010590 M (L2TPV3_SET_LOOKUP_KEY, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010591
10592 mp->key = key;
10593
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010594 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010595 W (ret);
10596 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010597}
10598
10599static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
10600 (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10601{
10602 vat_main_t *vam = &vat_main;
10603
10604 print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
10605 format_ip6_address, mp->our_address,
10606 format_ip6_address, mp->client_address,
10607 clib_net_to_host_u32 (mp->sw_if_index));
10608
10609 print (vam->ofp,
10610 " local cookies %016llx %016llx remote cookie %016llx",
10611 clib_net_to_host_u64 (mp->local_cookie[0]),
10612 clib_net_to_host_u64 (mp->local_cookie[1]),
10613 clib_net_to_host_u64 (mp->remote_cookie));
10614
10615 print (vam->ofp, " local session-id %d remote session-id %d",
10616 clib_net_to_host_u32 (mp->local_session_id),
10617 clib_net_to_host_u32 (mp->remote_session_id));
10618
10619 print (vam->ofp, " l2 specific sublayer %s\n",
10620 mp->l2_sublayer_present ? "preset" : "absent");
10621
10622}
10623
10624static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
10625 (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10626{
10627 vat_main_t *vam = &vat_main;
10628 vat_json_node_t *node = NULL;
10629 struct in6_addr addr;
10630
10631 if (VAT_JSON_ARRAY != vam->json_tree.type)
10632 {
10633 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10634 vat_json_init_array (&vam->json_tree);
10635 }
10636 node = vat_json_array_add (&vam->json_tree);
10637
10638 vat_json_init_object (node);
10639
10640 clib_memcpy (&addr, mp->our_address, sizeof (addr));
10641 vat_json_object_add_ip6 (node, "our_address", addr);
10642 clib_memcpy (&addr, mp->client_address, sizeof (addr));
10643 vat_json_object_add_ip6 (node, "client_address", addr);
10644
10645 vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
10646 vat_json_init_array (lc);
10647 vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
10648 vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
10649 vat_json_object_add_uint (node, "remote_cookie",
10650 clib_net_to_host_u64 (mp->remote_cookie));
10651
10652 printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
10653 vat_json_object_add_uint (node, "local_session_id",
10654 clib_net_to_host_u32 (mp->local_session_id));
10655 vat_json_object_add_uint (node, "remote_session_id",
10656 clib_net_to_host_u32 (mp->remote_session_id));
10657 vat_json_object_add_string_copy (node, "l2_sublayer",
10658 mp->l2_sublayer_present ? (u8 *) "present"
10659 : (u8 *) "absent");
10660}
10661
10662static int
10663api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
10664{
10665 vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010666 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010667 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010668
10669 /* Get list of l2tpv3-tunnel interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010670 M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010671 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010672
10673 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010674 M (CONTROL_PING, mp_ping);
10675 S (mp_ping);
10676
Jon Loeliger56c7b012017-02-01 12:31:41 -060010677 W (ret);
10678 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010679}
10680
10681
10682static void vl_api_sw_interface_tap_details_t_handler
10683 (vl_api_sw_interface_tap_details_t * mp)
10684{
10685 vat_main_t *vam = &vat_main;
10686
10687 print (vam->ofp, "%-16s %d",
10688 mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10689}
10690
10691static void vl_api_sw_interface_tap_details_t_handler_json
10692 (vl_api_sw_interface_tap_details_t * mp)
10693{
10694 vat_main_t *vam = &vat_main;
10695 vat_json_node_t *node = NULL;
10696
10697 if (VAT_JSON_ARRAY != vam->json_tree.type)
10698 {
10699 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10700 vat_json_init_array (&vam->json_tree);
10701 }
10702 node = vat_json_array_add (&vam->json_tree);
10703
10704 vat_json_init_object (node);
10705 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10706 vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10707}
10708
10709static int
10710api_sw_interface_tap_dump (vat_main_t * vam)
10711{
10712 vl_api_sw_interface_tap_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010713 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010714 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010715
10716 print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
10717 /* Get list of tap interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010718 M (SW_INTERFACE_TAP_DUMP, mp);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010719 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010720
10721 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010722 M (CONTROL_PING, mp_ping);
10723 S (mp_ping);
10724
Jon Loeliger56c7b012017-02-01 12:31:41 -060010725 W (ret);
10726 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010727}
10728
10729static uword unformat_vxlan_decap_next
10730 (unformat_input_t * input, va_list * args)
10731{
10732 u32 *result = va_arg (*args, u32 *);
10733 u32 tmp;
10734
10735 if (unformat (input, "l2"))
10736 *result = VXLAN_INPUT_NEXT_L2_INPUT;
10737 else if (unformat (input, "%d", &tmp))
10738 *result = tmp;
10739 else
10740 return 0;
10741 return 1;
10742}
10743
10744static int
10745api_vxlan_add_del_tunnel (vat_main_t * vam)
10746{
10747 unformat_input_t *line_input = vam->input;
10748 vl_api_vxlan_add_del_tunnel_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010749 ip46_address_t src, dst;
10750 u8 is_add = 1;
10751 u8 ipv4_set = 0, ipv6_set = 0;
10752 u8 src_set = 0;
10753 u8 dst_set = 0;
10754 u8 grp_set = 0;
10755 u32 mcast_sw_if_index = ~0;
10756 u32 encap_vrf_id = 0;
10757 u32 decap_next_index = ~0;
10758 u32 vni = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010759 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010760
10761 /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
10762 memset (&src, 0, sizeof src);
10763 memset (&dst, 0, sizeof dst);
10764
10765 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10766 {
10767 if (unformat (line_input, "del"))
10768 is_add = 0;
10769 else
10770 if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
10771 {
10772 ipv4_set = 1;
10773 src_set = 1;
10774 }
10775 else
10776 if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
10777 {
10778 ipv4_set = 1;
10779 dst_set = 1;
10780 }
10781 else
10782 if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
10783 {
10784 ipv6_set = 1;
10785 src_set = 1;
10786 }
10787 else
10788 if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
10789 {
10790 ipv6_set = 1;
10791 dst_set = 1;
10792 }
10793 else if (unformat (line_input, "group %U %U",
10794 unformat_ip4_address, &dst.ip4,
10795 api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10796 {
10797 grp_set = dst_set = 1;
10798 ipv4_set = 1;
10799 }
10800 else if (unformat (line_input, "group %U",
10801 unformat_ip4_address, &dst.ip4))
10802 {
10803 grp_set = dst_set = 1;
10804 ipv4_set = 1;
10805 }
10806 else if (unformat (line_input, "group %U %U",
10807 unformat_ip6_address, &dst.ip6,
10808 api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10809 {
10810 grp_set = dst_set = 1;
10811 ipv6_set = 1;
10812 }
10813 else if (unformat (line_input, "group %U",
10814 unformat_ip6_address, &dst.ip6))
10815 {
10816 grp_set = dst_set = 1;
10817 ipv6_set = 1;
10818 }
10819 else
10820 if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10821 ;
10822 else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10823 ;
10824 else if (unformat (line_input, "decap-next %U",
10825 unformat_vxlan_decap_next, &decap_next_index))
10826 ;
10827 else if (unformat (line_input, "vni %d", &vni))
10828 ;
10829 else
10830 {
10831 errmsg ("parse error '%U'", format_unformat_error, line_input);
10832 return -99;
10833 }
10834 }
10835
10836 if (src_set == 0)
10837 {
10838 errmsg ("tunnel src address not specified");
10839 return -99;
10840 }
10841 if (dst_set == 0)
10842 {
10843 errmsg ("tunnel dst address not specified");
10844 return -99;
10845 }
10846
10847 if (grp_set && !ip46_address_is_multicast (&dst))
10848 {
10849 errmsg ("tunnel group address not multicast");
10850 return -99;
10851 }
10852 if (grp_set && mcast_sw_if_index == ~0)
10853 {
10854 errmsg ("tunnel nonexistent multicast device");
10855 return -99;
10856 }
10857 if (grp_set == 0 && ip46_address_is_multicast (&dst))
10858 {
10859 errmsg ("tunnel dst address must be unicast");
10860 return -99;
10861 }
10862
10863
10864 if (ipv4_set && ipv6_set)
10865 {
10866 errmsg ("both IPv4 and IPv6 addresses specified");
10867 return -99;
10868 }
10869
10870 if ((vni == 0) || (vni >> 24))
10871 {
10872 errmsg ("vni not specified or out of range");
10873 return -99;
10874 }
10875
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010876 M (VXLAN_ADD_DEL_TUNNEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010877
10878 if (ipv6_set)
10879 {
10880 clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
10881 clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
10882 }
10883 else
10884 {
10885 clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
10886 clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
10887 }
10888 mp->encap_vrf_id = ntohl (encap_vrf_id);
10889 mp->decap_next_index = ntohl (decap_next_index);
10890 mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
10891 mp->vni = ntohl (vni);
10892 mp->is_add = is_add;
10893 mp->is_ipv6 = ipv6_set;
10894
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010895 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010896 W (ret);
10897 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010898}
10899
10900static void vl_api_vxlan_tunnel_details_t_handler
10901 (vl_api_vxlan_tunnel_details_t * mp)
10902{
10903 vat_main_t *vam = &vat_main;
10904 ip46_address_t src, dst;
10905
10906 ip46_from_addr_buf (mp->is_ipv6, mp->src_address, &src);
10907 ip46_from_addr_buf (mp->is_ipv6, mp->dst_address, &dst);
10908
10909 print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
10910 ntohl (mp->sw_if_index),
10911 format_ip46_address, &src, IP46_TYPE_ANY,
10912 format_ip46_address, &dst, IP46_TYPE_ANY,
10913 ntohl (mp->encap_vrf_id),
10914 ntohl (mp->decap_next_index), ntohl (mp->vni),
10915 ntohl (mp->mcast_sw_if_index));
10916}
10917
10918static void vl_api_vxlan_tunnel_details_t_handler_json
10919 (vl_api_vxlan_tunnel_details_t * mp)
10920{
10921 vat_main_t *vam = &vat_main;
10922 vat_json_node_t *node = NULL;
10923
10924 if (VAT_JSON_ARRAY != vam->json_tree.type)
10925 {
10926 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10927 vat_json_init_array (&vam->json_tree);
10928 }
10929 node = vat_json_array_add (&vam->json_tree);
10930
10931 vat_json_init_object (node);
10932 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10933 if (mp->is_ipv6)
10934 {
10935 struct in6_addr ip6;
10936
10937 clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
10938 vat_json_object_add_ip6 (node, "src_address", ip6);
10939 clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
10940 vat_json_object_add_ip6 (node, "dst_address", ip6);
10941 }
10942 else
10943 {
10944 struct in_addr ip4;
10945
10946 clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
10947 vat_json_object_add_ip4 (node, "src_address", ip4);
10948 clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
10949 vat_json_object_add_ip4 (node, "dst_address", ip4);
10950 }
10951 vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10952 vat_json_object_add_uint (node, "decap_next_index",
10953 ntohl (mp->decap_next_index));
10954 vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10955 vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10956 vat_json_object_add_uint (node, "mcast_sw_if_index",
10957 ntohl (mp->mcast_sw_if_index));
10958}
10959
10960static int
10961api_vxlan_tunnel_dump (vat_main_t * vam)
10962{
10963 unformat_input_t *i = vam->input;
10964 vl_api_vxlan_tunnel_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010965 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010966 u32 sw_if_index;
10967 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010968 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010969
10970 /* Parse args required to build the message */
10971 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10972 {
10973 if (unformat (i, "sw_if_index %d", &sw_if_index))
10974 sw_if_index_set = 1;
10975 else
10976 break;
10977 }
10978
10979 if (sw_if_index_set == 0)
10980 {
10981 sw_if_index = ~0;
10982 }
10983
10984 if (!vam->json_output)
10985 {
10986 print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
10987 "sw_if_index", "src_address", "dst_address",
10988 "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
10989 }
10990
10991 /* Get list of vxlan-tunnel interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010992 M (VXLAN_TUNNEL_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010993
10994 mp->sw_if_index = htonl (sw_if_index);
10995
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010996 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010997
10998 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010999 M (CONTROL_PING, mp_ping);
11000 S (mp_ping);
11001
Jon Loeliger56c7b012017-02-01 12:31:41 -060011002 W (ret);
11003 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011004}
11005
11006static int
11007api_gre_add_del_tunnel (vat_main_t * vam)
11008{
11009 unformat_input_t *line_input = vam->input;
11010 vl_api_gre_add_del_tunnel_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011011 ip4_address_t src4, dst4;
11012 u8 is_add = 1;
11013 u8 teb = 0;
11014 u8 src_set = 0;
11015 u8 dst_set = 0;
11016 u32 outer_fib_id = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011017 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011018
11019 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11020 {
11021 if (unformat (line_input, "del"))
11022 is_add = 0;
11023 else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
11024 src_set = 1;
11025 else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
11026 dst_set = 1;
11027 else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
11028 ;
11029 else if (unformat (line_input, "teb"))
11030 teb = 1;
11031 else
11032 {
11033 errmsg ("parse error '%U'", format_unformat_error, line_input);
11034 return -99;
11035 }
11036 }
11037
11038 if (src_set == 0)
11039 {
11040 errmsg ("tunnel src address not specified");
11041 return -99;
11042 }
11043 if (dst_set == 0)
11044 {
11045 errmsg ("tunnel dst address not specified");
11046 return -99;
11047 }
11048
11049
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011050 M (GRE_ADD_DEL_TUNNEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011051
11052 clib_memcpy (&mp->src_address, &src4, sizeof (src4));
11053 clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
11054 mp->outer_fib_id = ntohl (outer_fib_id);
11055 mp->is_add = is_add;
11056 mp->teb = teb;
11057
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011058 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011059 W (ret);
11060 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011061}
11062
11063static void vl_api_gre_tunnel_details_t_handler
11064 (vl_api_gre_tunnel_details_t * mp)
11065{
11066 vat_main_t *vam = &vat_main;
11067
11068 print (vam->ofp, "%11d%15U%15U%6d%14d",
11069 ntohl (mp->sw_if_index),
11070 format_ip4_address, &mp->src_address,
11071 format_ip4_address, &mp->dst_address,
11072 mp->teb, ntohl (mp->outer_fib_id));
11073}
11074
11075static void vl_api_gre_tunnel_details_t_handler_json
11076 (vl_api_gre_tunnel_details_t * mp)
11077{
11078 vat_main_t *vam = &vat_main;
11079 vat_json_node_t *node = NULL;
11080 struct in_addr ip4;
11081
11082 if (VAT_JSON_ARRAY != vam->json_tree.type)
11083 {
11084 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11085 vat_json_init_array (&vam->json_tree);
11086 }
11087 node = vat_json_array_add (&vam->json_tree);
11088
11089 vat_json_init_object (node);
11090 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11091 clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
11092 vat_json_object_add_ip4 (node, "src_address", ip4);
11093 clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
11094 vat_json_object_add_ip4 (node, "dst_address", ip4);
11095 vat_json_object_add_uint (node, "teb", mp->teb);
11096 vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
11097}
11098
11099static int
11100api_gre_tunnel_dump (vat_main_t * vam)
11101{
11102 unformat_input_t *i = vam->input;
11103 vl_api_gre_tunnel_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011104 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011105 u32 sw_if_index;
11106 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011107 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011108
11109 /* Parse args required to build the message */
11110 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11111 {
11112 if (unformat (i, "sw_if_index %d", &sw_if_index))
11113 sw_if_index_set = 1;
11114 else
11115 break;
11116 }
11117
11118 if (sw_if_index_set == 0)
11119 {
11120 sw_if_index = ~0;
11121 }
11122
11123 if (!vam->json_output)
11124 {
11125 print (vam->ofp, "%11s%15s%15s%6s%14s",
11126 "sw_if_index", "src_address", "dst_address", "teb",
11127 "outer_fib_id");
11128 }
11129
11130 /* Get list of gre-tunnel interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011131 M (GRE_TUNNEL_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011132
11133 mp->sw_if_index = htonl (sw_if_index);
11134
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011135 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011136
11137 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011138 M (CONTROL_PING, mp_ping);
11139 S (mp_ping);
11140
Jon Loeliger56c7b012017-02-01 12:31:41 -060011141 W (ret);
11142 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011143}
11144
11145static int
11146api_l2_fib_clear_table (vat_main_t * vam)
11147{
11148// unformat_input_t * i = vam->input;
11149 vl_api_l2_fib_clear_table_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011150 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011151
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011152 M (L2_FIB_CLEAR_TABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011153
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011154 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011155 W (ret);
11156 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011157}
11158
11159static int
11160api_l2_interface_efp_filter (vat_main_t * vam)
11161{
11162 unformat_input_t *i = vam->input;
11163 vl_api_l2_interface_efp_filter_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011164 u32 sw_if_index;
11165 u8 enable = 1;
11166 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011167 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011168
11169 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11170 {
11171 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11172 sw_if_index_set = 1;
11173 else if (unformat (i, "sw_if_index %d", &sw_if_index))
11174 sw_if_index_set = 1;
11175 else if (unformat (i, "enable"))
11176 enable = 1;
11177 else if (unformat (i, "disable"))
11178 enable = 0;
11179 else
11180 {
11181 clib_warning ("parse error '%U'", format_unformat_error, i);
11182 return -99;
11183 }
11184 }
11185
11186 if (sw_if_index_set == 0)
11187 {
11188 errmsg ("missing sw_if_index");
11189 return -99;
11190 }
11191
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011192 M (L2_INTERFACE_EFP_FILTER, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011193
11194 mp->sw_if_index = ntohl (sw_if_index);
11195 mp->enable_disable = enable;
11196
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011197 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011198 W (ret);
11199 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011200}
11201
11202#define foreach_vtr_op \
11203_("disable", L2_VTR_DISABLED) \
11204_("push-1", L2_VTR_PUSH_1) \
11205_("push-2", L2_VTR_PUSH_2) \
11206_("pop-1", L2_VTR_POP_1) \
11207_("pop-2", L2_VTR_POP_2) \
11208_("translate-1-1", L2_VTR_TRANSLATE_1_1) \
11209_("translate-1-2", L2_VTR_TRANSLATE_1_2) \
11210_("translate-2-1", L2_VTR_TRANSLATE_2_1) \
11211_("translate-2-2", L2_VTR_TRANSLATE_2_2)
11212
11213static int
11214api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
11215{
11216 unformat_input_t *i = vam->input;
11217 vl_api_l2_interface_vlan_tag_rewrite_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011218 u32 sw_if_index;
11219 u8 sw_if_index_set = 0;
11220 u8 vtr_op_set = 0;
11221 u32 vtr_op = 0;
11222 u32 push_dot1q = 1;
11223 u32 tag1 = ~0;
11224 u32 tag2 = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011225 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011226
11227 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11228 {
11229 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11230 sw_if_index_set = 1;
11231 else if (unformat (i, "sw_if_index %d", &sw_if_index))
11232 sw_if_index_set = 1;
11233 else if (unformat (i, "vtr_op %d", &vtr_op))
11234 vtr_op_set = 1;
11235#define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
11236 foreach_vtr_op
11237#undef _
11238 else if (unformat (i, "push_dot1q %d", &push_dot1q))
11239 ;
11240 else if (unformat (i, "tag1 %d", &tag1))
11241 ;
11242 else if (unformat (i, "tag2 %d", &tag2))
11243 ;
11244 else
11245 {
11246 clib_warning ("parse error '%U'", format_unformat_error, i);
11247 return -99;
11248 }
11249 }
11250
11251 if ((sw_if_index_set == 0) || (vtr_op_set == 0))
11252 {
11253 errmsg ("missing vtr operation or sw_if_index");
11254 return -99;
11255 }
11256
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011257 M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
11258 mp->sw_if_index = ntohl (sw_if_index);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011259 mp->vtr_op = ntohl (vtr_op);
11260 mp->push_dot1q = ntohl (push_dot1q);
11261 mp->tag1 = ntohl (tag1);
11262 mp->tag2 = ntohl (tag2);
11263
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011264 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011265 W (ret);
11266 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011267}
11268
11269static int
11270api_create_vhost_user_if (vat_main_t * vam)
11271{
11272 unformat_input_t *i = vam->input;
11273 vl_api_create_vhost_user_if_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011274 u8 *file_name;
11275 u8 is_server = 0;
11276 u8 file_name_set = 0;
11277 u32 custom_dev_instance = ~0;
11278 u8 hwaddr[6];
11279 u8 use_custom_mac = 0;
11280 u8 *tag = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011281 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011282
11283 /* Shut up coverity */
11284 memset (hwaddr, 0, sizeof (hwaddr));
11285
11286 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11287 {
11288 if (unformat (i, "socket %s", &file_name))
11289 {
11290 file_name_set = 1;
11291 }
11292 else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11293 ;
11294 else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
11295 use_custom_mac = 1;
11296 else if (unformat (i, "server"))
11297 is_server = 1;
11298 else if (unformat (i, "tag %s", &tag))
11299 ;
11300 else
11301 break;
11302 }
11303
11304 if (file_name_set == 0)
11305 {
11306 errmsg ("missing socket file name");
11307 return -99;
11308 }
11309
11310 if (vec_len (file_name) > 255)
11311 {
11312 errmsg ("socket file name too long");
11313 return -99;
11314 }
11315 vec_add1 (file_name, 0);
11316
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011317 M (CREATE_VHOST_USER_IF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011318
11319 mp->is_server = is_server;
11320 clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11321 vec_free (file_name);
11322 if (custom_dev_instance != ~0)
11323 {
11324 mp->renumber = 1;
11325 mp->custom_dev_instance = ntohl (custom_dev_instance);
11326 }
11327 mp->use_custom_mac = use_custom_mac;
11328 clib_memcpy (mp->mac_address, hwaddr, 6);
11329 if (tag)
11330 strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
11331 vec_free (tag);
11332
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011333 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011334 W (ret);
11335 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011336}
11337
11338static int
11339api_modify_vhost_user_if (vat_main_t * vam)
11340{
11341 unformat_input_t *i = vam->input;
11342 vl_api_modify_vhost_user_if_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011343 u8 *file_name;
11344 u8 is_server = 0;
11345 u8 file_name_set = 0;
11346 u32 custom_dev_instance = ~0;
11347 u8 sw_if_index_set = 0;
11348 u32 sw_if_index = (u32) ~ 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011349 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011350
11351 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11352 {
11353 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11354 sw_if_index_set = 1;
11355 else if (unformat (i, "sw_if_index %d", &sw_if_index))
11356 sw_if_index_set = 1;
11357 else if (unformat (i, "socket %s", &file_name))
11358 {
11359 file_name_set = 1;
11360 }
11361 else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11362 ;
11363 else if (unformat (i, "server"))
11364 is_server = 1;
11365 else
11366 break;
11367 }
11368
11369 if (sw_if_index_set == 0)
11370 {
11371 errmsg ("missing sw_if_index or interface name");
11372 return -99;
11373 }
11374
11375 if (file_name_set == 0)
11376 {
11377 errmsg ("missing socket file name");
11378 return -99;
11379 }
11380
11381 if (vec_len (file_name) > 255)
11382 {
11383 errmsg ("socket file name too long");
11384 return -99;
11385 }
11386 vec_add1 (file_name, 0);
11387
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011388 M (MODIFY_VHOST_USER_IF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011389
11390 mp->sw_if_index = ntohl (sw_if_index);
11391 mp->is_server = is_server;
11392 clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11393 vec_free (file_name);
11394 if (custom_dev_instance != ~0)
11395 {
11396 mp->renumber = 1;
11397 mp->custom_dev_instance = ntohl (custom_dev_instance);
11398 }
11399
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011400 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011401 W (ret);
11402 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011403}
11404
11405static int
11406api_delete_vhost_user_if (vat_main_t * vam)
11407{
11408 unformat_input_t *i = vam->input;
11409 vl_api_delete_vhost_user_if_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011410 u32 sw_if_index = ~0;
11411 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011412 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011413
11414 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11415 {
11416 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11417 sw_if_index_set = 1;
11418 else if (unformat (i, "sw_if_index %d", &sw_if_index))
11419 sw_if_index_set = 1;
11420 else
11421 break;
11422 }
11423
11424 if (sw_if_index_set == 0)
11425 {
11426 errmsg ("missing sw_if_index or interface name");
11427 return -99;
11428 }
11429
11430
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011431 M (DELETE_VHOST_USER_IF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011432
11433 mp->sw_if_index = ntohl (sw_if_index);
11434
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011435 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011436 W (ret);
11437 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011438}
11439
11440static void vl_api_sw_interface_vhost_user_details_t_handler
11441 (vl_api_sw_interface_vhost_user_details_t * mp)
11442{
11443 vat_main_t *vam = &vat_main;
11444
11445 print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
11446 (char *) mp->interface_name,
11447 ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
11448 clib_net_to_host_u64 (mp->features), mp->is_server,
11449 ntohl (mp->num_regions), (char *) mp->sock_filename);
11450 print (vam->ofp, " Status: '%s'", strerror (ntohl (mp->sock_errno)));
11451}
11452
11453static void vl_api_sw_interface_vhost_user_details_t_handler_json
11454 (vl_api_sw_interface_vhost_user_details_t * mp)
11455{
11456 vat_main_t *vam = &vat_main;
11457 vat_json_node_t *node = NULL;
11458
11459 if (VAT_JSON_ARRAY != vam->json_tree.type)
11460 {
11461 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11462 vat_json_init_array (&vam->json_tree);
11463 }
11464 node = vat_json_array_add (&vam->json_tree);
11465
11466 vat_json_init_object (node);
11467 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11468 vat_json_object_add_string_copy (node, "interface_name",
11469 mp->interface_name);
11470 vat_json_object_add_uint (node, "virtio_net_hdr_sz",
11471 ntohl (mp->virtio_net_hdr_sz));
11472 vat_json_object_add_uint (node, "features",
11473 clib_net_to_host_u64 (mp->features));
11474 vat_json_object_add_uint (node, "is_server", mp->is_server);
11475 vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
11476 vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
11477 vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
11478}
11479
11480static int
11481api_sw_interface_vhost_user_dump (vat_main_t * vam)
11482{
11483 vl_api_sw_interface_vhost_user_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011484 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011485 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011486 print (vam->ofp,
11487 "Interface name idx hdr_sz features server regions filename");
11488
11489 /* Get list of vhost-user interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011490 M (SW_INTERFACE_VHOST_USER_DUMP, mp);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011491 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011492
11493 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011494 M (CONTROL_PING, mp_ping);
11495 S (mp_ping);
11496
Jon Loeliger56c7b012017-02-01 12:31:41 -060011497 W (ret);
11498 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011499}
11500
11501static int
11502api_show_version (vat_main_t * vam)
11503{
11504 vl_api_show_version_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011505 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011506
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011507 M (SHOW_VERSION, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011508
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011509 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011510 W (ret);
11511 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011512}
11513
11514
11515static int
11516api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
11517{
11518 unformat_input_t *line_input = vam->input;
11519 vl_api_vxlan_gpe_add_del_tunnel_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011520 ip4_address_t local4, remote4;
11521 ip6_address_t local6, remote6;
11522 u8 is_add = 1;
11523 u8 ipv4_set = 0, ipv6_set = 0;
11524 u8 local_set = 0;
11525 u8 remote_set = 0;
11526 u32 encap_vrf_id = 0;
11527 u32 decap_vrf_id = 0;
11528 u8 protocol = ~0;
11529 u32 vni;
11530 u8 vni_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011531 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011532
11533 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11534 {
11535 if (unformat (line_input, "del"))
11536 is_add = 0;
11537 else if (unformat (line_input, "local %U",
11538 unformat_ip4_address, &local4))
11539 {
11540 local_set = 1;
11541 ipv4_set = 1;
11542 }
11543 else if (unformat (line_input, "remote %U",
11544 unformat_ip4_address, &remote4))
11545 {
11546 remote_set = 1;
11547 ipv4_set = 1;
11548 }
11549 else if (unformat (line_input, "local %U",
11550 unformat_ip6_address, &local6))
11551 {
11552 local_set = 1;
11553 ipv6_set = 1;
11554 }
11555 else if (unformat (line_input, "remote %U",
11556 unformat_ip6_address, &remote6))
11557 {
11558 remote_set = 1;
11559 ipv6_set = 1;
11560 }
11561 else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11562 ;
11563 else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
11564 ;
11565 else if (unformat (line_input, "vni %d", &vni))
11566 vni_set = 1;
11567 else if (unformat (line_input, "next-ip4"))
11568 protocol = 1;
11569 else if (unformat (line_input, "next-ip6"))
11570 protocol = 2;
11571 else if (unformat (line_input, "next-ethernet"))
11572 protocol = 3;
11573 else if (unformat (line_input, "next-nsh"))
11574 protocol = 4;
11575 else
11576 {
11577 errmsg ("parse error '%U'", format_unformat_error, line_input);
11578 return -99;
11579 }
11580 }
11581
11582 if (local_set == 0)
11583 {
11584 errmsg ("tunnel local address not specified");
11585 return -99;
11586 }
11587 if (remote_set == 0)
11588 {
11589 errmsg ("tunnel remote address not specified");
11590 return -99;
11591 }
11592 if (ipv4_set && ipv6_set)
11593 {
11594 errmsg ("both IPv4 and IPv6 addresses specified");
11595 return -99;
11596 }
11597
11598 if (vni_set == 0)
11599 {
11600 errmsg ("vni not specified");
11601 return -99;
11602 }
11603
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011604 M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011605
11606
11607 if (ipv6_set)
11608 {
11609 clib_memcpy (&mp->local, &local6, sizeof (local6));
11610 clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
11611 }
11612 else
11613 {
11614 clib_memcpy (&mp->local, &local4, sizeof (local4));
11615 clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
11616 }
11617
11618 mp->encap_vrf_id = ntohl (encap_vrf_id);
11619 mp->decap_vrf_id = ntohl (decap_vrf_id);
11620 mp->protocol = protocol;
11621 mp->vni = ntohl (vni);
11622 mp->is_add = is_add;
11623 mp->is_ipv6 = ipv6_set;
11624
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011625 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011626 W (ret);
11627 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011628}
11629
11630static void vl_api_vxlan_gpe_tunnel_details_t_handler
11631 (vl_api_vxlan_gpe_tunnel_details_t * mp)
11632{
11633 vat_main_t *vam = &vat_main;
11634
11635 print (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d",
11636 ntohl (mp->sw_if_index),
11637 format_ip46_address, &(mp->local[0]),
11638 format_ip46_address, &(mp->remote[0]),
11639 ntohl (mp->vni),
11640 ntohl (mp->protocol),
11641 ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
11642}
11643
11644static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
11645 (vl_api_vxlan_gpe_tunnel_details_t * mp)
11646{
11647 vat_main_t *vam = &vat_main;
11648 vat_json_node_t *node = NULL;
11649 struct in_addr ip4;
11650 struct in6_addr ip6;
11651
11652 if (VAT_JSON_ARRAY != vam->json_tree.type)
11653 {
11654 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11655 vat_json_init_array (&vam->json_tree);
11656 }
11657 node = vat_json_array_add (&vam->json_tree);
11658
11659 vat_json_init_object (node);
11660 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11661 if (mp->is_ipv6)
11662 {
11663 clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
11664 vat_json_object_add_ip6 (node, "local", ip6);
11665 clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
11666 vat_json_object_add_ip6 (node, "remote", ip6);
11667 }
11668 else
11669 {
11670 clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
11671 vat_json_object_add_ip4 (node, "local", ip4);
11672 clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
11673 vat_json_object_add_ip4 (node, "remote", ip4);
11674 }
11675 vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11676 vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
11677 vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11678 vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
11679 vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11680}
11681
11682static int
11683api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
11684{
11685 unformat_input_t *i = vam->input;
11686 vl_api_vxlan_gpe_tunnel_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011687 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011688 u32 sw_if_index;
11689 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011690 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011691
11692 /* Parse args required to build the message */
11693 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11694 {
11695 if (unformat (i, "sw_if_index %d", &sw_if_index))
11696 sw_if_index_set = 1;
11697 else
11698 break;
11699 }
11700
11701 if (sw_if_index_set == 0)
11702 {
11703 sw_if_index = ~0;
11704 }
11705
11706 if (!vam->json_output)
11707 {
11708 print (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s",
11709 "sw_if_index", "local", "remote", "vni",
11710 "protocol", "encap_vrf_id", "decap_vrf_id");
11711 }
11712
11713 /* Get list of vxlan-tunnel interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011714 M (VXLAN_GPE_TUNNEL_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011715
11716 mp->sw_if_index = htonl (sw_if_index);
11717
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011718 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011719
11720 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011721 M (CONTROL_PING, mp_ping);
11722 S (mp_ping);
11723
Jon Loeliger56c7b012017-02-01 12:31:41 -060011724 W (ret);
11725 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011726}
11727
11728u8 *
11729format_l2_fib_mac_address (u8 * s, va_list * args)
11730{
11731 u8 *a = va_arg (*args, u8 *);
11732
11733 return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11734 a[2], a[3], a[4], a[5], a[6], a[7]);
11735}
11736
11737static void vl_api_l2_fib_table_entry_t_handler
11738 (vl_api_l2_fib_table_entry_t * mp)
11739{
11740 vat_main_t *vam = &vat_main;
11741
11742 print (vam->ofp, "%3" PRIu32 " %U %3" PRIu32
11743 " %d %d %d",
11744 ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11745 ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11746 mp->bvi_mac);
11747}
11748
11749static void vl_api_l2_fib_table_entry_t_handler_json
11750 (vl_api_l2_fib_table_entry_t * mp)
11751{
11752 vat_main_t *vam = &vat_main;
11753 vat_json_node_t *node = NULL;
11754
11755 if (VAT_JSON_ARRAY != vam->json_tree.type)
11756 {
11757 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11758 vat_json_init_array (&vam->json_tree);
11759 }
11760 node = vat_json_array_add (&vam->json_tree);
11761
11762 vat_json_init_object (node);
11763 vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11764 vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11765 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11766 vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11767 vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11768 vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11769}
11770
11771static int
11772api_l2_fib_table_dump (vat_main_t * vam)
11773{
11774 unformat_input_t *i = vam->input;
11775 vl_api_l2_fib_table_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011776 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011777 u32 bd_id;
11778 u8 bd_id_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011779 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011780
11781 /* Parse args required to build the message */
11782 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11783 {
11784 if (unformat (i, "bd_id %d", &bd_id))
11785 bd_id_set = 1;
11786 else
11787 break;
11788 }
11789
11790 if (bd_id_set == 0)
11791 {
11792 errmsg ("missing bridge domain");
11793 return -99;
11794 }
11795
11796 print (vam->ofp, "BD-ID Mac Address sw-ndx Static Filter BVI");
11797
11798 /* Get list of l2 fib entries */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011799 M (L2_FIB_TABLE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011800
11801 mp->bd_id = ntohl (bd_id);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011802 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011803
11804 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011805 M (CONTROL_PING, mp_ping);
11806 S (mp_ping);
11807
Jon Loeliger56c7b012017-02-01 12:31:41 -060011808 W (ret);
11809 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011810}
11811
11812
11813static int
11814api_interface_name_renumber (vat_main_t * vam)
11815{
11816 unformat_input_t *line_input = vam->input;
11817 vl_api_interface_name_renumber_t *mp;
11818 u32 sw_if_index = ~0;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011819 u32 new_show_dev_instance = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011820 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011821
11822 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11823 {
11824 if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
11825 &sw_if_index))
11826 ;
11827 else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11828 ;
11829 else if (unformat (line_input, "new_show_dev_instance %d",
11830 &new_show_dev_instance))
11831 ;
11832 else
11833 break;
11834 }
11835
11836 if (sw_if_index == ~0)
11837 {
11838 errmsg ("missing interface name or sw_if_index");
11839 return -99;
11840 }
11841
11842 if (new_show_dev_instance == ~0)
11843 {
11844 errmsg ("missing new_show_dev_instance");
11845 return -99;
11846 }
11847
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011848 M (INTERFACE_NAME_RENUMBER, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011849
11850 mp->sw_if_index = ntohl (sw_if_index);
11851 mp->new_show_dev_instance = ntohl (new_show_dev_instance);
11852
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011853 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011854 W (ret);
11855 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011856}
11857
11858static int
11859api_want_ip4_arp_events (vat_main_t * vam)
11860{
11861 unformat_input_t *line_input = vam->input;
11862 vl_api_want_ip4_arp_events_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011863 ip4_address_t address;
11864 int address_set = 0;
11865 u32 enable_disable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011866 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011867
11868 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11869 {
11870 if (unformat (line_input, "address %U", unformat_ip4_address, &address))
11871 address_set = 1;
11872 else if (unformat (line_input, "del"))
11873 enable_disable = 0;
11874 else
11875 break;
11876 }
11877
11878 if (address_set == 0)
11879 {
11880 errmsg ("missing addresses");
11881 return -99;
11882 }
11883
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011884 M (WANT_IP4_ARP_EVENTS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011885 mp->enable_disable = enable_disable;
11886 mp->pid = getpid ();
11887 mp->address = address.as_u32;
11888
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011889 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011890 W (ret);
11891 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011892}
11893
11894static int
11895api_want_ip6_nd_events (vat_main_t * vam)
11896{
11897 unformat_input_t *line_input = vam->input;
11898 vl_api_want_ip6_nd_events_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011899 ip6_address_t address;
11900 int address_set = 0;
11901 u32 enable_disable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011902 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011903
11904 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11905 {
11906 if (unformat (line_input, "address %U", unformat_ip6_address, &address))
11907 address_set = 1;
11908 else if (unformat (line_input, "del"))
11909 enable_disable = 0;
11910 else
11911 break;
11912 }
11913
11914 if (address_set == 0)
11915 {
11916 errmsg ("missing addresses");
11917 return -99;
11918 }
11919
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011920 M (WANT_IP6_ND_EVENTS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011921 mp->enable_disable = enable_disable;
11922 mp->pid = getpid ();
11923 clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
11924
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011925 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011926 W (ret);
11927 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011928}
11929
11930static int
11931api_input_acl_set_interface (vat_main_t * vam)
11932{
11933 unformat_input_t *i = vam->input;
11934 vl_api_input_acl_set_interface_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011935 u32 sw_if_index;
11936 int sw_if_index_set;
11937 u32 ip4_table_index = ~0;
11938 u32 ip6_table_index = ~0;
11939 u32 l2_table_index = ~0;
11940 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011941 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011942
11943 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11944 {
11945 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11946 sw_if_index_set = 1;
11947 else if (unformat (i, "sw_if_index %d", &sw_if_index))
11948 sw_if_index_set = 1;
11949 else if (unformat (i, "del"))
11950 is_add = 0;
11951 else if (unformat (i, "ip4-table %d", &ip4_table_index))
11952 ;
11953 else if (unformat (i, "ip6-table %d", &ip6_table_index))
11954 ;
11955 else if (unformat (i, "l2-table %d", &l2_table_index))
11956 ;
11957 else
11958 {
11959 clib_warning ("parse error '%U'", format_unformat_error, i);
11960 return -99;
11961 }
11962 }
11963
11964 if (sw_if_index_set == 0)
11965 {
11966 errmsg ("missing interface name or sw_if_index");
11967 return -99;
11968 }
11969
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011970 M (INPUT_ACL_SET_INTERFACE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011971
11972 mp->sw_if_index = ntohl (sw_if_index);
11973 mp->ip4_table_index = ntohl (ip4_table_index);
11974 mp->ip6_table_index = ntohl (ip6_table_index);
11975 mp->l2_table_index = ntohl (l2_table_index);
11976 mp->is_add = is_add;
11977
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011978 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011979 W (ret);
11980 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011981}
11982
11983static int
11984api_ip_address_dump (vat_main_t * vam)
11985{
11986 unformat_input_t *i = vam->input;
11987 vl_api_ip_address_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011988 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011989 u32 sw_if_index = ~0;
11990 u8 sw_if_index_set = 0;
11991 u8 ipv4_set = 0;
11992 u8 ipv6_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011993 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011994
11995 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11996 {
11997 if (unformat (i, "sw_if_index %d", &sw_if_index))
11998 sw_if_index_set = 1;
11999 else
12000 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12001 sw_if_index_set = 1;
12002 else if (unformat (i, "ipv4"))
12003 ipv4_set = 1;
12004 else if (unformat (i, "ipv6"))
12005 ipv6_set = 1;
12006 else
12007 break;
12008 }
12009
12010 if (ipv4_set && ipv6_set)
12011 {
12012 errmsg ("ipv4 and ipv6 flags cannot be both set");
12013 return -99;
12014 }
12015
12016 if ((!ipv4_set) && (!ipv6_set))
12017 {
12018 errmsg ("no ipv4 nor ipv6 flag set");
12019 return -99;
12020 }
12021
12022 if (sw_if_index_set == 0)
12023 {
12024 errmsg ("missing interface name or sw_if_index");
12025 return -99;
12026 }
12027
12028 vam->current_sw_if_index = sw_if_index;
12029 vam->is_ipv6 = ipv6_set;
12030
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012031 M (IP_ADDRESS_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012032 mp->sw_if_index = ntohl (sw_if_index);
12033 mp->is_ipv6 = ipv6_set;
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012034 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012035
12036 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012037 M (CONTROL_PING, mp_ping);
12038 S (mp_ping);
12039
Jon Loeliger56c7b012017-02-01 12:31:41 -060012040 W (ret);
12041 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012042}
12043
12044static int
12045api_ip_dump (vat_main_t * vam)
12046{
12047 vl_api_ip_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012048 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012049 unformat_input_t *in = vam->input;
12050 int ipv4_set = 0;
12051 int ipv6_set = 0;
12052 int is_ipv6;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012053 int i;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012054 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012055
12056 while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
12057 {
12058 if (unformat (in, "ipv4"))
12059 ipv4_set = 1;
12060 else if (unformat (in, "ipv6"))
12061 ipv6_set = 1;
12062 else
12063 break;
12064 }
12065
12066 if (ipv4_set && ipv6_set)
12067 {
12068 errmsg ("ipv4 and ipv6 flags cannot be both set");
12069 return -99;
12070 }
12071
12072 if ((!ipv4_set) && (!ipv6_set))
12073 {
12074 errmsg ("no ipv4 nor ipv6 flag set");
12075 return -99;
12076 }
12077
12078 is_ipv6 = ipv6_set;
12079 vam->is_ipv6 = is_ipv6;
12080
12081 /* free old data */
12082 for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
12083 {
12084 vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
12085 }
12086 vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
12087
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012088 M (IP_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012089 mp->is_ipv6 = ipv6_set;
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012090 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012091
12092 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012093 M (CONTROL_PING, mp_ping);
12094 S (mp_ping);
12095
Jon Loeliger56c7b012017-02-01 12:31:41 -060012096 W (ret);
12097 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012098}
12099
12100static int
12101api_ipsec_spd_add_del (vat_main_t * vam)
12102{
12103 unformat_input_t *i = vam->input;
12104 vl_api_ipsec_spd_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012105 u32 spd_id = ~0;
12106 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012107 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012108
12109 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12110 {
12111 if (unformat (i, "spd_id %d", &spd_id))
12112 ;
12113 else if (unformat (i, "del"))
12114 is_add = 0;
12115 else
12116 {
12117 clib_warning ("parse error '%U'", format_unformat_error, i);
12118 return -99;
12119 }
12120 }
12121 if (spd_id == ~0)
12122 {
12123 errmsg ("spd_id must be set");
12124 return -99;
12125 }
12126
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012127 M (IPSEC_SPD_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012128
12129 mp->spd_id = ntohl (spd_id);
12130 mp->is_add = is_add;
12131
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012132 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012133 W (ret);
12134 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012135}
12136
12137static int
12138api_ipsec_interface_add_del_spd (vat_main_t * vam)
12139{
12140 unformat_input_t *i = vam->input;
12141 vl_api_ipsec_interface_add_del_spd_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012142 u32 sw_if_index;
12143 u8 sw_if_index_set = 0;
12144 u32 spd_id = (u32) ~ 0;
12145 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012146 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012147
12148 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12149 {
12150 if (unformat (i, "del"))
12151 is_add = 0;
12152 else if (unformat (i, "spd_id %d", &spd_id))
12153 ;
12154 else
12155 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12156 sw_if_index_set = 1;
12157 else if (unformat (i, "sw_if_index %d", &sw_if_index))
12158 sw_if_index_set = 1;
12159 else
12160 {
12161 clib_warning ("parse error '%U'", format_unformat_error, i);
12162 return -99;
12163 }
12164
12165 }
12166
12167 if (spd_id == (u32) ~ 0)
12168 {
12169 errmsg ("spd_id must be set");
12170 return -99;
12171 }
12172
12173 if (sw_if_index_set == 0)
12174 {
12175 errmsg ("missing interface name or sw_if_index");
12176 return -99;
12177 }
12178
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012179 M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012180
12181 mp->spd_id = ntohl (spd_id);
12182 mp->sw_if_index = ntohl (sw_if_index);
12183 mp->is_add = is_add;
12184
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012185 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012186 W (ret);
12187 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012188}
12189
12190static int
12191api_ipsec_spd_add_del_entry (vat_main_t * vam)
12192{
12193 unformat_input_t *i = vam->input;
12194 vl_api_ipsec_spd_add_del_entry_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012195 u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
12196 u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
12197 i32 priority = 0;
12198 u32 rport_start = 0, rport_stop = (u32) ~ 0;
12199 u32 lport_start = 0, lport_stop = (u32) ~ 0;
12200 ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
12201 ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012202 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012203
12204 laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
12205 laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
12206 laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
12207 laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
12208 laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
12209 laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
12210
12211 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12212 {
12213 if (unformat (i, "del"))
12214 is_add = 0;
12215 if (unformat (i, "outbound"))
12216 is_outbound = 1;
12217 if (unformat (i, "inbound"))
12218 is_outbound = 0;
12219 else if (unformat (i, "spd_id %d", &spd_id))
12220 ;
12221 else if (unformat (i, "sa_id %d", &sa_id))
12222 ;
12223 else if (unformat (i, "priority %d", &priority))
12224 ;
12225 else if (unformat (i, "protocol %d", &protocol))
12226 ;
12227 else if (unformat (i, "lport_start %d", &lport_start))
12228 ;
12229 else if (unformat (i, "lport_stop %d", &lport_stop))
12230 ;
12231 else if (unformat (i, "rport_start %d", &rport_start))
12232 ;
12233 else if (unformat (i, "rport_stop %d", &rport_stop))
12234 ;
12235 else
12236 if (unformat
12237 (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
12238 {
12239 is_ipv6 = 0;
12240 is_ip_any = 0;
12241 }
12242 else
12243 if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
12244 {
12245 is_ipv6 = 0;
12246 is_ip_any = 0;
12247 }
12248 else
12249 if (unformat
12250 (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
12251 {
12252 is_ipv6 = 0;
12253 is_ip_any = 0;
12254 }
12255 else
12256 if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
12257 {
12258 is_ipv6 = 0;
12259 is_ip_any = 0;
12260 }
12261 else
12262 if (unformat
12263 (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
12264 {
12265 is_ipv6 = 1;
12266 is_ip_any = 0;
12267 }
12268 else
12269 if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
12270 {
12271 is_ipv6 = 1;
12272 is_ip_any = 0;
12273 }
12274 else
12275 if (unformat
12276 (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
12277 {
12278 is_ipv6 = 1;
12279 is_ip_any = 0;
12280 }
12281 else
12282 if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
12283 {
12284 is_ipv6 = 1;
12285 is_ip_any = 0;
12286 }
12287 else
12288 if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
12289 {
12290 if (policy == IPSEC_POLICY_ACTION_RESOLVE)
12291 {
12292 clib_warning ("unsupported action: 'resolve'");
12293 return -99;
12294 }
12295 }
12296 else
12297 {
12298 clib_warning ("parse error '%U'", format_unformat_error, i);
12299 return -99;
12300 }
12301
12302 }
12303
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012304 M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012305
12306 mp->spd_id = ntohl (spd_id);
12307 mp->priority = ntohl (priority);
12308 mp->is_outbound = is_outbound;
12309
12310 mp->is_ipv6 = is_ipv6;
12311 if (is_ipv6 || is_ip_any)
12312 {
12313 clib_memcpy (mp->remote_address_start, &raddr6_start,
12314 sizeof (ip6_address_t));
12315 clib_memcpy (mp->remote_address_stop, &raddr6_stop,
12316 sizeof (ip6_address_t));
12317 clib_memcpy (mp->local_address_start, &laddr6_start,
12318 sizeof (ip6_address_t));
12319 clib_memcpy (mp->local_address_stop, &laddr6_stop,
12320 sizeof (ip6_address_t));
12321 }
12322 else
12323 {
12324 clib_memcpy (mp->remote_address_start, &raddr4_start,
12325 sizeof (ip4_address_t));
12326 clib_memcpy (mp->remote_address_stop, &raddr4_stop,
12327 sizeof (ip4_address_t));
12328 clib_memcpy (mp->local_address_start, &laddr4_start,
12329 sizeof (ip4_address_t));
12330 clib_memcpy (mp->local_address_stop, &laddr4_stop,
12331 sizeof (ip4_address_t));
12332 }
12333 mp->protocol = (u8) protocol;
12334 mp->local_port_start = ntohs ((u16) lport_start);
12335 mp->local_port_stop = ntohs ((u16) lport_stop);
12336 mp->remote_port_start = ntohs ((u16) rport_start);
12337 mp->remote_port_stop = ntohs ((u16) rport_stop);
12338 mp->policy = (u8) policy;
12339 mp->sa_id = ntohl (sa_id);
12340 mp->is_add = is_add;
12341 mp->is_ip_any = is_ip_any;
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012342 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012343 W (ret);
12344 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012345}
12346
12347static int
12348api_ipsec_sad_add_del_entry (vat_main_t * vam)
12349{
12350 unformat_input_t *i = vam->input;
12351 vl_api_ipsec_sad_add_del_entry_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012352 u32 sad_id = 0, spi = 0;
12353 u8 *ck = 0, *ik = 0;
12354 u8 is_add = 1;
12355
12356 u8 protocol = IPSEC_PROTOCOL_AH;
12357 u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
12358 u32 crypto_alg = 0, integ_alg = 0;
12359 ip4_address_t tun_src4;
12360 ip4_address_t tun_dst4;
12361 ip6_address_t tun_src6;
12362 ip6_address_t tun_dst6;
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, "sad_id %d", &sad_id))
12370 ;
12371 else if (unformat (i, "spi %d", &spi))
12372 ;
12373 else if (unformat (i, "esp"))
12374 protocol = IPSEC_PROTOCOL_ESP;
12375 else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
12376 {
12377 is_tunnel = 1;
12378 is_tunnel_ipv6 = 0;
12379 }
12380 else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
12381 {
12382 is_tunnel = 1;
12383 is_tunnel_ipv6 = 0;
12384 }
12385 else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
12386 {
12387 is_tunnel = 1;
12388 is_tunnel_ipv6 = 1;
12389 }
12390 else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
12391 {
12392 is_tunnel = 1;
12393 is_tunnel_ipv6 = 1;
12394 }
12395 else
12396 if (unformat
12397 (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
12398 {
12399 if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
12400 crypto_alg >= IPSEC_CRYPTO_N_ALG)
12401 {
12402 clib_warning ("unsupported crypto-alg: '%U'",
12403 format_ipsec_crypto_alg, crypto_alg);
12404 return -99;
12405 }
12406 }
12407 else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12408 ;
12409 else
12410 if (unformat
12411 (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
12412 {
Damjan Marion7cd468a2016-12-19 23:05:39 +010012413 if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
Damjan Marion7cd468a2016-12-19 23:05:39 +010012414 integ_alg >= IPSEC_INTEG_N_ALG)
12415 {
12416 clib_warning ("unsupported integ-alg: '%U'",
12417 format_ipsec_integ_alg, integ_alg);
12418 return -99;
12419 }
12420 }
12421 else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12422 ;
12423 else
12424 {
12425 clib_warning ("parse error '%U'", format_unformat_error, i);
12426 return -99;
12427 }
12428
12429 }
12430
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012431 M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012432
12433 mp->sad_id = ntohl (sad_id);
12434 mp->is_add = is_add;
12435 mp->protocol = protocol;
12436 mp->spi = ntohl (spi);
12437 mp->is_tunnel = is_tunnel;
12438 mp->is_tunnel_ipv6 = is_tunnel_ipv6;
12439 mp->crypto_algorithm = crypto_alg;
12440 mp->integrity_algorithm = integ_alg;
12441 mp->crypto_key_length = vec_len (ck);
12442 mp->integrity_key_length = vec_len (ik);
12443
12444 if (mp->crypto_key_length > sizeof (mp->crypto_key))
12445 mp->crypto_key_length = sizeof (mp->crypto_key);
12446
12447 if (mp->integrity_key_length > sizeof (mp->integrity_key))
12448 mp->integrity_key_length = sizeof (mp->integrity_key);
12449
12450 if (ck)
12451 clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12452 if (ik)
12453 clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12454
12455 if (is_tunnel)
12456 {
12457 if (is_tunnel_ipv6)
12458 {
12459 clib_memcpy (mp->tunnel_src_address, &tun_src6,
12460 sizeof (ip6_address_t));
12461 clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
12462 sizeof (ip6_address_t));
12463 }
12464 else
12465 {
12466 clib_memcpy (mp->tunnel_src_address, &tun_src4,
12467 sizeof (ip4_address_t));
12468 clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
12469 sizeof (ip4_address_t));
12470 }
12471 }
12472
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012473 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012474 W (ret);
12475 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012476}
12477
12478static int
12479api_ipsec_sa_set_key (vat_main_t * vam)
12480{
12481 unformat_input_t *i = vam->input;
12482 vl_api_ipsec_sa_set_key_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012483 u32 sa_id;
12484 u8 *ck = 0, *ik = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012485 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012486
12487 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12488 {
12489 if (unformat (i, "sa_id %d", &sa_id))
12490 ;
12491 else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12492 ;
12493 else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12494 ;
12495 else
12496 {
12497 clib_warning ("parse error '%U'", format_unformat_error, i);
12498 return -99;
12499 }
12500 }
12501
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012502 M (IPSEC_SA_SET_KEY, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012503
12504 mp->sa_id = ntohl (sa_id);
12505 mp->crypto_key_length = vec_len (ck);
12506 mp->integrity_key_length = vec_len (ik);
12507
12508 if (mp->crypto_key_length > sizeof (mp->crypto_key))
12509 mp->crypto_key_length = sizeof (mp->crypto_key);
12510
12511 if (mp->integrity_key_length > sizeof (mp->integrity_key))
12512 mp->integrity_key_length = sizeof (mp->integrity_key);
12513
12514 if (ck)
12515 clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12516 if (ik)
12517 clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12518
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012519 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012520 W (ret);
12521 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012522}
12523
12524static int
12525api_ikev2_profile_add_del (vat_main_t * vam)
12526{
12527 unformat_input_t *i = vam->input;
12528 vl_api_ikev2_profile_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012529 u8 is_add = 1;
12530 u8 *name = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012531 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012532
12533 const char *valid_chars = "a-zA-Z0-9_";
12534
12535 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12536 {
12537 if (unformat (i, "del"))
12538 is_add = 0;
12539 else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12540 vec_add1 (name, 0);
12541 else
12542 {
12543 errmsg ("parse error '%U'", format_unformat_error, i);
12544 return -99;
12545 }
12546 }
12547
12548 if (!vec_len (name))
12549 {
12550 errmsg ("profile name must be specified");
12551 return -99;
12552 }
12553
12554 if (vec_len (name) > 64)
12555 {
12556 errmsg ("profile name too long");
12557 return -99;
12558 }
12559
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012560 M (IKEV2_PROFILE_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012561
12562 clib_memcpy (mp->name, name, vec_len (name));
12563 mp->is_add = is_add;
12564 vec_free (name);
12565
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012566 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012567 W (ret);
12568 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012569}
12570
12571static int
12572api_ikev2_profile_set_auth (vat_main_t * vam)
12573{
12574 unformat_input_t *i = vam->input;
12575 vl_api_ikev2_profile_set_auth_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012576 u8 *name = 0;
12577 u8 *data = 0;
12578 u32 auth_method = 0;
12579 u8 is_hex = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012580 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012581
12582 const char *valid_chars = "a-zA-Z0-9_";
12583
12584 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12585 {
12586 if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12587 vec_add1 (name, 0);
12588 else if (unformat (i, "auth_method %U",
12589 unformat_ikev2_auth_method, &auth_method))
12590 ;
12591 else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
12592 is_hex = 1;
12593 else if (unformat (i, "auth_data %v", &data))
12594 ;
12595 else
12596 {
12597 errmsg ("parse error '%U'", format_unformat_error, i);
12598 return -99;
12599 }
12600 }
12601
12602 if (!vec_len (name))
12603 {
12604 errmsg ("profile name must be specified");
12605 return -99;
12606 }
12607
12608 if (vec_len (name) > 64)
12609 {
12610 errmsg ("profile name too long");
12611 return -99;
12612 }
12613
12614 if (!vec_len (data))
12615 {
12616 errmsg ("auth_data must be specified");
12617 return -99;
12618 }
12619
12620 if (!auth_method)
12621 {
12622 errmsg ("auth_method must be specified");
12623 return -99;
12624 }
12625
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012626 M (IKEV2_PROFILE_SET_AUTH, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012627
12628 mp->is_hex = is_hex;
12629 mp->auth_method = (u8) auth_method;
12630 mp->data_len = vec_len (data);
12631 clib_memcpy (mp->name, name, vec_len (name));
12632 clib_memcpy (mp->data, data, vec_len (data));
12633 vec_free (name);
12634 vec_free (data);
12635
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012636 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012637 W (ret);
12638 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012639}
12640
12641static int
12642api_ikev2_profile_set_id (vat_main_t * vam)
12643{
12644 unformat_input_t *i = vam->input;
12645 vl_api_ikev2_profile_set_id_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012646 u8 *name = 0;
12647 u8 *data = 0;
12648 u8 is_local = 0;
12649 u32 id_type = 0;
12650 ip4_address_t ip4;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012651 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012652
12653 const char *valid_chars = "a-zA-Z0-9_";
12654
12655 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12656 {
12657 if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12658 vec_add1 (name, 0);
12659 else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
12660 ;
12661 else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
12662 {
12663 data = vec_new (u8, 4);
12664 clib_memcpy (data, ip4.as_u8, 4);
12665 }
12666 else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
12667 ;
12668 else if (unformat (i, "id_data %v", &data))
12669 ;
12670 else if (unformat (i, "local"))
12671 is_local = 1;
12672 else if (unformat (i, "remote"))
12673 is_local = 0;
12674 else
12675 {
12676 errmsg ("parse error '%U'", format_unformat_error, i);
12677 return -99;
12678 }
12679 }
12680
12681 if (!vec_len (name))
12682 {
12683 errmsg ("profile name must be specified");
12684 return -99;
12685 }
12686
12687 if (vec_len (name) > 64)
12688 {
12689 errmsg ("profile name too long");
12690 return -99;
12691 }
12692
12693 if (!vec_len (data))
12694 {
12695 errmsg ("id_data must be specified");
12696 return -99;
12697 }
12698
12699 if (!id_type)
12700 {
12701 errmsg ("id_type must be specified");
12702 return -99;
12703 }
12704
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012705 M (IKEV2_PROFILE_SET_ID, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012706
12707 mp->is_local = is_local;
12708 mp->id_type = (u8) id_type;
12709 mp->data_len = vec_len (data);
12710 clib_memcpy (mp->name, name, vec_len (name));
12711 clib_memcpy (mp->data, data, vec_len (data));
12712 vec_free (name);
12713 vec_free (data);
12714
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012715 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012716 W (ret);
12717 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012718}
12719
12720static int
12721api_ikev2_profile_set_ts (vat_main_t * vam)
12722{
12723 unformat_input_t *i = vam->input;
12724 vl_api_ikev2_profile_set_ts_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012725 u8 *name = 0;
12726 u8 is_local = 0;
12727 u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
12728 ip4_address_t start_addr, end_addr;
12729
12730 const char *valid_chars = "a-zA-Z0-9_";
Jon Loeliger56c7b012017-02-01 12:31:41 -060012731 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012732
12733 start_addr.as_u32 = 0;
12734 end_addr.as_u32 = (u32) ~ 0;
12735
12736 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12737 {
12738 if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12739 vec_add1 (name, 0);
12740 else if (unformat (i, "protocol %d", &proto))
12741 ;
12742 else if (unformat (i, "start_port %d", &start_port))
12743 ;
12744 else if (unformat (i, "end_port %d", &end_port))
12745 ;
12746 else
12747 if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
12748 ;
12749 else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
12750 ;
12751 else if (unformat (i, "local"))
12752 is_local = 1;
12753 else if (unformat (i, "remote"))
12754 is_local = 0;
12755 else
12756 {
12757 errmsg ("parse error '%U'", format_unformat_error, i);
12758 return -99;
12759 }
12760 }
12761
12762 if (!vec_len (name))
12763 {
12764 errmsg ("profile name must be specified");
12765 return -99;
12766 }
12767
12768 if (vec_len (name) > 64)
12769 {
12770 errmsg ("profile name too long");
12771 return -99;
12772 }
12773
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012774 M (IKEV2_PROFILE_SET_TS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012775
12776 mp->is_local = is_local;
12777 mp->proto = (u8) proto;
12778 mp->start_port = (u16) start_port;
12779 mp->end_port = (u16) end_port;
12780 mp->start_addr = start_addr.as_u32;
12781 mp->end_addr = end_addr.as_u32;
12782 clib_memcpy (mp->name, name, vec_len (name));
12783 vec_free (name);
12784
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012785 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012786 W (ret);
12787 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012788}
12789
12790static int
12791api_ikev2_set_local_key (vat_main_t * vam)
12792{
12793 unformat_input_t *i = vam->input;
12794 vl_api_ikev2_set_local_key_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012795 u8 *file = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012796 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012797
12798 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12799 {
12800 if (unformat (i, "file %v", &file))
12801 vec_add1 (file, 0);
12802 else
12803 {
12804 errmsg ("parse error '%U'", format_unformat_error, i);
12805 return -99;
12806 }
12807 }
12808
12809 if (!vec_len (file))
12810 {
12811 errmsg ("RSA key file must be specified");
12812 return -99;
12813 }
12814
12815 if (vec_len (file) > 256)
12816 {
12817 errmsg ("file name too long");
12818 return -99;
12819 }
12820
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012821 M (IKEV2_SET_LOCAL_KEY, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012822
12823 clib_memcpy (mp->key_file, file, vec_len (file));
12824 vec_free (file);
12825
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012826 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012827 W (ret);
12828 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012829}
12830
Radu Nicolaucb33dc22017-02-16 16:49:46 +000012831static int
12832api_ikev2_set_responder (vat_main_t * vam)
12833{
12834 unformat_input_t *i = vam->input;
12835 vl_api_ikev2_set_responder_t *mp;
12836 int ret;
12837 u8 *name = 0;
12838 u32 sw_if_index = ~0;
12839 ip4_address_t address;
12840
12841 const char *valid_chars = "a-zA-Z0-9_";
12842
12843 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12844 {
12845 if (unformat
12846 (i, "%U interface %d address %U", unformat_token, valid_chars,
12847 &name, &sw_if_index, unformat_ip4_address, &address))
12848 vec_add1 (name, 0);
12849 else
12850 {
12851 errmsg ("parse error '%U'", format_unformat_error, i);
12852 return -99;
12853 }
12854 }
12855
12856 if (!vec_len (name))
12857 {
12858 errmsg ("profile name must be specified");
12859 return -99;
12860 }
12861
12862 if (vec_len (name) > 64)
12863 {
12864 errmsg ("profile name too long");
12865 return -99;
12866 }
12867
12868 M (IKEV2_SET_RESPONDER, mp);
12869
12870 clib_memcpy (mp->name, name, vec_len (name));
12871 vec_free (name);
12872
12873 mp->sw_if_index = sw_if_index;
12874 clib_memcpy (mp->address, &address, sizeof (address));
12875
12876 S (mp);
12877 W (ret);
12878 return ret;
12879}
12880
12881static int
12882api_ikev2_set_ike_transforms (vat_main_t * vam)
12883{
12884 unformat_input_t *i = vam->input;
12885 vl_api_ikev2_set_ike_transforms_t *mp;
12886 int ret;
12887 u8 *name = 0;
12888 u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
12889
12890 const char *valid_chars = "a-zA-Z0-9_";
12891
12892 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12893 {
12894 if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
12895 &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
12896 vec_add1 (name, 0);
12897 else
12898 {
12899 errmsg ("parse error '%U'", format_unformat_error, i);
12900 return -99;
12901 }
12902 }
12903
12904 if (!vec_len (name))
12905 {
12906 errmsg ("profile name must be specified");
12907 return -99;
12908 }
12909
12910 if (vec_len (name) > 64)
12911 {
12912 errmsg ("profile name too long");
12913 return -99;
12914 }
12915
12916 M (IKEV2_SET_IKE_TRANSFORMS, mp);
12917
12918 clib_memcpy (mp->name, name, vec_len (name));
12919 vec_free (name);
12920 mp->crypto_alg = crypto_alg;
12921 mp->crypto_key_size = crypto_key_size;
12922 mp->integ_alg = integ_alg;
12923 mp->dh_group = dh_group;
12924
12925 S (mp);
12926 W (ret);
12927 return ret;
12928}
12929
12930
12931static int
12932api_ikev2_set_esp_transforms (vat_main_t * vam)
12933{
12934 unformat_input_t *i = vam->input;
12935 vl_api_ikev2_set_esp_transforms_t *mp;
12936 int ret;
12937 u8 *name = 0;
12938 u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
12939
12940 const char *valid_chars = "a-zA-Z0-9_";
12941
12942 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12943 {
12944 if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
12945 &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
12946 vec_add1 (name, 0);
12947 else
12948 {
12949 errmsg ("parse error '%U'", format_unformat_error, i);
12950 return -99;
12951 }
12952 }
12953
12954 if (!vec_len (name))
12955 {
12956 errmsg ("profile name must be specified");
12957 return -99;
12958 }
12959
12960 if (vec_len (name) > 64)
12961 {
12962 errmsg ("profile name too long");
12963 return -99;
12964 }
12965
12966 M (IKEV2_SET_ESP_TRANSFORMS, mp);
12967
12968 clib_memcpy (mp->name, name, vec_len (name));
12969 vec_free (name);
12970 mp->crypto_alg = crypto_alg;
12971 mp->crypto_key_size = crypto_key_size;
12972 mp->integ_alg = integ_alg;
12973 mp->dh_group = dh_group;
12974
12975 S (mp);
12976 W (ret);
12977 return ret;
12978}
12979
12980static int
12981api_ikev2_set_sa_lifetime (vat_main_t * vam)
12982{
12983 unformat_input_t *i = vam->input;
12984 vl_api_ikev2_set_sa_lifetime_t *mp;
12985 int ret;
12986 u8 *name = 0;
12987 u64 lifetime, lifetime_maxdata;
12988 u32 lifetime_jitter, handover;
12989
12990 const char *valid_chars = "a-zA-Z0-9_";
12991
12992 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12993 {
12994 if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
12995 &lifetime, &lifetime_jitter, &handover,
12996 &lifetime_maxdata))
12997 vec_add1 (name, 0);
12998 else
12999 {
13000 errmsg ("parse error '%U'", format_unformat_error, i);
13001 return -99;
13002 }
13003 }
13004
13005 if (!vec_len (name))
13006 {
13007 errmsg ("profile name must be specified");
13008 return -99;
13009 }
13010
13011 if (vec_len (name) > 64)
13012 {
13013 errmsg ("profile name too long");
13014 return -99;
13015 }
13016
13017 M (IKEV2_SET_SA_LIFETIME, mp);
13018
13019 clib_memcpy (mp->name, name, vec_len (name));
13020 vec_free (name);
13021 mp->lifetime = lifetime;
13022 mp->lifetime_jitter = lifetime_jitter;
13023 mp->handover = handover;
13024 mp->lifetime_maxdata = lifetime_maxdata;
13025
13026 S (mp);
13027 W (ret);
13028 return ret;
13029}
13030
13031static int
13032api_ikev2_initiate_sa_init (vat_main_t * vam)
13033{
13034 unformat_input_t *i = vam->input;
13035 vl_api_ikev2_initiate_sa_init_t *mp;
13036 int ret;
13037 u8 *name = 0;
13038
13039 const char *valid_chars = "a-zA-Z0-9_";
13040
13041 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13042 {
13043 if (unformat (i, "%U", unformat_token, valid_chars, &name))
13044 vec_add1 (name, 0);
13045 else
13046 {
13047 errmsg ("parse error '%U'", format_unformat_error, i);
13048 return -99;
13049 }
13050 }
13051
13052 if (!vec_len (name))
13053 {
13054 errmsg ("profile name must be specified");
13055 return -99;
13056 }
13057
13058 if (vec_len (name) > 64)
13059 {
13060 errmsg ("profile name too long");
13061 return -99;
13062 }
13063
13064 M (IKEV2_INITIATE_SA_INIT, mp);
13065
13066 clib_memcpy (mp->name, name, vec_len (name));
13067 vec_free (name);
13068
13069 S (mp);
13070 W (ret);
13071 return ret;
13072}
13073
13074static int
13075api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
13076{
13077 unformat_input_t *i = vam->input;
13078 vl_api_ikev2_initiate_del_ike_sa_t *mp;
13079 int ret;
13080 u64 ispi;
13081
13082
13083 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13084 {
13085 if (unformat (i, "%lx", &ispi))
13086 ;
13087 else
13088 {
13089 errmsg ("parse error '%U'", format_unformat_error, i);
13090 return -99;
13091 }
13092 }
13093
13094 M (IKEV2_INITIATE_DEL_IKE_SA, mp);
13095
13096 mp->ispi = ispi;
13097
13098 S (mp);
13099 W (ret);
13100 return ret;
13101}
13102
13103static int
13104api_ikev2_initiate_del_child_sa (vat_main_t * vam)
13105{
13106 unformat_input_t *i = vam->input;
13107 vl_api_ikev2_initiate_del_child_sa_t *mp;
13108 int ret;
13109 u32 ispi;
13110
13111
13112 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13113 {
13114 if (unformat (i, "%x", &ispi))
13115 ;
13116 else
13117 {
13118 errmsg ("parse error '%U'", format_unformat_error, i);
13119 return -99;
13120 }
13121 }
13122
13123 M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
13124
13125 mp->ispi = ispi;
13126
13127 S (mp);
13128 W (ret);
13129 return ret;
13130}
13131
13132static int
13133api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
13134{
13135 unformat_input_t *i = vam->input;
13136 vl_api_ikev2_initiate_rekey_child_sa_t *mp;
13137 int ret;
13138 u32 ispi;
13139
13140
13141 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13142 {
13143 if (unformat (i, "%x", &ispi))
13144 ;
13145 else
13146 {
13147 errmsg ("parse error '%U'", format_unformat_error, i);
13148 return -99;
13149 }
13150 }
13151
13152 M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
13153
13154 mp->ispi = ispi;
13155
13156 S (mp);
13157 W (ret);
13158 return ret;
13159}
13160
Damjan Marion7cd468a2016-12-19 23:05:39 +010013161/*
13162 * MAP
13163 */
13164static int
13165api_map_add_domain (vat_main_t * vam)
13166{
13167 unformat_input_t *i = vam->input;
13168 vl_api_map_add_domain_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013169
13170 ip4_address_t ip4_prefix;
13171 ip6_address_t ip6_prefix;
13172 ip6_address_t ip6_src;
13173 u32 num_m_args = 0;
13174 u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
13175 0, psid_length = 0;
13176 u8 is_translation = 0;
13177 u32 mtu = 0;
13178 u32 ip6_src_len = 128;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013179 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013180
13181 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13182 {
13183 if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
13184 &ip4_prefix, &ip4_prefix_len))
13185 num_m_args++;
13186 else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
13187 &ip6_prefix, &ip6_prefix_len))
13188 num_m_args++;
13189 else
13190 if (unformat
13191 (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
13192 &ip6_src_len))
13193 num_m_args++;
13194 else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
13195 num_m_args++;
13196 else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
13197 num_m_args++;
13198 else if (unformat (i, "psid-offset %d", &psid_offset))
13199 num_m_args++;
13200 else if (unformat (i, "psid-len %d", &psid_length))
13201 num_m_args++;
13202 else if (unformat (i, "mtu %d", &mtu))
13203 num_m_args++;
13204 else if (unformat (i, "map-t"))
13205 is_translation = 1;
13206 else
13207 {
13208 clib_warning ("parse error '%U'", format_unformat_error, i);
13209 return -99;
13210 }
13211 }
13212
13213 if (num_m_args < 3)
13214 {
13215 errmsg ("mandatory argument(s) missing");
13216 return -99;
13217 }
13218
13219 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013220 M (MAP_ADD_DOMAIN, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013221
13222 clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
13223 mp->ip4_prefix_len = ip4_prefix_len;
13224
13225 clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
13226 mp->ip6_prefix_len = ip6_prefix_len;
13227
13228 clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
13229 mp->ip6_src_prefix_len = ip6_src_len;
13230
13231 mp->ea_bits_len = ea_bits_len;
13232 mp->psid_offset = psid_offset;
13233 mp->psid_length = psid_length;
13234 mp->is_translation = is_translation;
13235 mp->mtu = htons (mtu);
13236
13237 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013238 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013239
13240 /* Wait for a reply, return good/bad news */
Jon Loeliger56c7b012017-02-01 12:31:41 -060013241 W (ret);
13242 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013243}
13244
13245static int
13246api_map_del_domain (vat_main_t * vam)
13247{
13248 unformat_input_t *i = vam->input;
13249 vl_api_map_del_domain_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013250
13251 u32 num_m_args = 0;
13252 u32 index;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013253 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013254
13255 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13256 {
13257 if (unformat (i, "index %d", &index))
13258 num_m_args++;
13259 else
13260 {
13261 clib_warning ("parse error '%U'", format_unformat_error, i);
13262 return -99;
13263 }
13264 }
13265
13266 if (num_m_args != 1)
13267 {
13268 errmsg ("mandatory argument(s) missing");
13269 return -99;
13270 }
13271
13272 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013273 M (MAP_DEL_DOMAIN, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013274
13275 mp->index = ntohl (index);
13276
13277 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013278 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013279
13280 /* Wait for a reply, return good/bad news */
Jon Loeliger56c7b012017-02-01 12:31:41 -060013281 W (ret);
13282 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013283}
13284
13285static int
13286api_map_add_del_rule (vat_main_t * vam)
13287{
13288 unformat_input_t *i = vam->input;
13289 vl_api_map_add_del_rule_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013290 u8 is_add = 1;
13291 ip6_address_t ip6_dst;
13292 u32 num_m_args = 0, index, psid = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013293 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013294
13295 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13296 {
13297 if (unformat (i, "index %d", &index))
13298 num_m_args++;
13299 else if (unformat (i, "psid %d", &psid))
13300 num_m_args++;
13301 else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
13302 num_m_args++;
13303 else if (unformat (i, "del"))
13304 {
13305 is_add = 0;
13306 }
13307 else
13308 {
13309 clib_warning ("parse error '%U'", format_unformat_error, i);
13310 return -99;
13311 }
13312 }
13313
13314 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013315 M (MAP_ADD_DEL_RULE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013316
13317 mp->index = ntohl (index);
13318 mp->is_add = is_add;
13319 clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
13320 mp->psid = ntohs (psid);
13321
13322 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013323 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013324
13325 /* Wait for a reply, return good/bad news */
Jon Loeliger56c7b012017-02-01 12:31:41 -060013326 W (ret);
13327 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013328}
13329
13330static int
13331api_map_domain_dump (vat_main_t * vam)
13332{
13333 vl_api_map_domain_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060013334 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013335 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013336
13337 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013338 M (MAP_DOMAIN_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013339
13340 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013341 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013342
13343 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060013344 M (CONTROL_PING, mp_ping);
13345 S (mp_ping);
13346
Jon Loeliger56c7b012017-02-01 12:31:41 -060013347 W (ret);
13348 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013349}
13350
13351static int
13352api_map_rule_dump (vat_main_t * vam)
13353{
13354 unformat_input_t *i = vam->input;
13355 vl_api_map_rule_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060013356 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013357 u32 domain_index = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013358 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013359
13360 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13361 {
13362 if (unformat (i, "index %u", &domain_index))
13363 ;
13364 else
13365 break;
13366 }
13367
13368 if (domain_index == ~0)
13369 {
13370 clib_warning ("parse error: domain index expected");
13371 return -99;
13372 }
13373
13374 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013375 M (MAP_RULE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013376
13377 mp->domain_index = htonl (domain_index);
13378
13379 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013380 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013381
13382 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060013383 M (CONTROL_PING, mp_ping);
13384 S (mp_ping);
13385
Jon Loeliger56c7b012017-02-01 12:31:41 -060013386 W (ret);
13387 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013388}
13389
13390static void vl_api_map_add_domain_reply_t_handler
13391 (vl_api_map_add_domain_reply_t * mp)
13392{
13393 vat_main_t *vam = &vat_main;
13394 i32 retval = ntohl (mp->retval);
13395
13396 if (vam->async_mode)
13397 {
13398 vam->async_errors += (retval < 0);
13399 }
13400 else
13401 {
13402 vam->retval = retval;
13403 vam->result_ready = 1;
13404 }
13405}
13406
13407static void vl_api_map_add_domain_reply_t_handler_json
13408 (vl_api_map_add_domain_reply_t * mp)
13409{
13410 vat_main_t *vam = &vat_main;
13411 vat_json_node_t node;
13412
13413 vat_json_init_object (&node);
13414 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
13415 vat_json_object_add_uint (&node, "index", ntohl (mp->index));
13416
13417 vat_json_print (vam->ofp, &node);
13418 vat_json_free (&node);
13419
13420 vam->retval = ntohl (mp->retval);
13421 vam->result_ready = 1;
13422}
13423
13424static int
13425api_get_first_msg_id (vat_main_t * vam)
13426{
13427 vl_api_get_first_msg_id_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013428 unformat_input_t *i = vam->input;
13429 u8 *name;
13430 u8 name_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013431 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013432
13433 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13434 {
13435 if (unformat (i, "client %s", &name))
13436 name_set = 1;
13437 else
13438 break;
13439 }
13440
13441 if (name_set == 0)
13442 {
13443 errmsg ("missing client name");
13444 return -99;
13445 }
13446 vec_add1 (name, 0);
13447
13448 if (vec_len (name) > 63)
13449 {
13450 errmsg ("client name too long");
13451 return -99;
13452 }
13453
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013454 M (GET_FIRST_MSG_ID, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013455 clib_memcpy (mp->name, name, vec_len (name));
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013456 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013457 W (ret);
13458 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013459}
13460
13461static int
13462api_cop_interface_enable_disable (vat_main_t * vam)
13463{
13464 unformat_input_t *line_input = vam->input;
13465 vl_api_cop_interface_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013466 u32 sw_if_index = ~0;
13467 u8 enable_disable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013468 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013469
13470 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13471 {
13472 if (unformat (line_input, "disable"))
13473 enable_disable = 0;
13474 if (unformat (line_input, "enable"))
13475 enable_disable = 1;
13476 else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13477 vam, &sw_if_index))
13478 ;
13479 else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13480 ;
13481 else
13482 break;
13483 }
13484
13485 if (sw_if_index == ~0)
13486 {
13487 errmsg ("missing interface name or sw_if_index");
13488 return -99;
13489 }
13490
13491 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013492 M (COP_INTERFACE_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013493 mp->sw_if_index = ntohl (sw_if_index);
13494 mp->enable_disable = enable_disable;
13495
13496 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013497 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013498 /* Wait for the reply */
Jon Loeliger56c7b012017-02-01 12:31:41 -060013499 W (ret);
13500 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013501}
13502
13503static int
13504api_cop_whitelist_enable_disable (vat_main_t * vam)
13505{
13506 unformat_input_t *line_input = vam->input;
13507 vl_api_cop_whitelist_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013508 u32 sw_if_index = ~0;
13509 u8 ip4 = 0, ip6 = 0, default_cop = 0;
13510 u32 fib_id = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013511 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013512
13513 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13514 {
13515 if (unformat (line_input, "ip4"))
13516 ip4 = 1;
13517 else if (unformat (line_input, "ip6"))
13518 ip6 = 1;
13519 else if (unformat (line_input, "default"))
13520 default_cop = 1;
13521 else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13522 vam, &sw_if_index))
13523 ;
13524 else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13525 ;
13526 else if (unformat (line_input, "fib-id %d", &fib_id))
13527 ;
13528 else
13529 break;
13530 }
13531
13532 if (sw_if_index == ~0)
13533 {
13534 errmsg ("missing interface name or sw_if_index");
13535 return -99;
13536 }
13537
13538 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013539 M (COP_WHITELIST_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013540 mp->sw_if_index = ntohl (sw_if_index);
13541 mp->fib_id = ntohl (fib_id);
13542 mp->ip4 = ip4;
13543 mp->ip6 = ip6;
13544 mp->default_cop = default_cop;
13545
13546 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013547 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013548 /* Wait for the reply */
Jon Loeliger56c7b012017-02-01 12:31:41 -060013549 W (ret);
13550 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013551}
13552
13553static int
13554api_get_node_graph (vat_main_t * vam)
13555{
13556 vl_api_get_node_graph_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013557 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013558
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013559 M (GET_NODE_GRAPH, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013560
13561 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013562 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013563 /* Wait for the reply */
Jon Loeliger56c7b012017-02-01 12:31:41 -060013564 W (ret);
13565 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013566}
13567
13568/* *INDENT-OFF* */
13569/** Used for parsing LISP eids */
13570typedef CLIB_PACKED(struct{
13571 u8 addr[16]; /**< eid address */
13572 u32 len; /**< prefix length if IP */
13573 u8 type; /**< type of eid */
13574}) lisp_eid_vat_t;
13575/* *INDENT-ON* */
13576
13577static uword
13578unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
13579{
13580 lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
13581
13582 memset (a, 0, sizeof (a[0]));
13583
13584 if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
13585 {
13586 a->type = 0; /* ipv4 type */
13587 }
13588 else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
13589 {
13590 a->type = 1; /* ipv6 type */
13591 }
13592 else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
13593 {
13594 a->type = 2; /* mac type */
13595 }
13596 else
13597 {
13598 return 0;
13599 }
13600
13601 if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
13602 {
13603 return 0;
13604 }
13605
13606 return 1;
13607}
13608
13609static int
13610lisp_eid_size_vat (u8 type)
13611{
13612 switch (type)
13613 {
13614 case 0:
13615 return 4;
13616 case 1:
13617 return 16;
13618 case 2:
13619 return 6;
13620 }
13621 return 0;
13622}
13623
13624static void
13625lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
13626{
13627 clib_memcpy (dst, eid, lisp_eid_size_vat (type));
13628}
13629
Damjan Marion7cd468a2016-12-19 23:05:39 +010013630static int
Filip Tehlar694396d2017-02-17 14:29:11 +010013631api_one_add_del_locator_set (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010013632{
13633 unformat_input_t *input = vam->input;
Filip Tehlar694396d2017-02-17 14:29:11 +010013634 vl_api_one_add_del_locator_set_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013635 u8 is_add = 1;
13636 u8 *locator_set_name = NULL;
13637 u8 locator_set_name_set = 0;
Filip Tehlar05a057b2017-02-01 08:50:31 +010013638 vl_api_local_locator_t locator, *locators = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013639 u32 sw_if_index, priority, weight;
13640 u32 data_len = 0;
13641
Jon Loeliger56c7b012017-02-01 12:31:41 -060013642 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013643 /* Parse args required to build the message */
13644 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13645 {
13646 if (unformat (input, "del"))
13647 {
13648 is_add = 0;
13649 }
13650 else if (unformat (input, "locator-set %s", &locator_set_name))
13651 {
13652 locator_set_name_set = 1;
13653 }
13654 else if (unformat (input, "sw_if_index %u p %u w %u",
13655 &sw_if_index, &priority, &weight))
13656 {
13657 locator.sw_if_index = htonl (sw_if_index);
13658 locator.priority = priority;
13659 locator.weight = weight;
13660 vec_add1 (locators, locator);
13661 }
13662 else
13663 if (unformat
13664 (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
13665 &sw_if_index, &priority, &weight))
13666 {
13667 locator.sw_if_index = htonl (sw_if_index);
13668 locator.priority = priority;
13669 locator.weight = weight;
13670 vec_add1 (locators, locator);
13671 }
13672 else
13673 break;
13674 }
13675
13676 if (locator_set_name_set == 0)
13677 {
13678 errmsg ("missing locator-set name");
13679 vec_free (locators);
13680 return -99;
13681 }
13682
13683 if (vec_len (locator_set_name) > 64)
13684 {
13685 errmsg ("locator-set name too long");
13686 vec_free (locator_set_name);
13687 vec_free (locators);
13688 return -99;
13689 }
13690 vec_add1 (locator_set_name, 0);
13691
Filip Tehlar05a057b2017-02-01 08:50:31 +010013692 data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013693
13694 /* Construct the API message */
Filip Tehlar694396d2017-02-17 14:29:11 +010013695 M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013696
13697 mp->is_add = is_add;
13698 clib_memcpy (mp->locator_set_name, locator_set_name,
13699 vec_len (locator_set_name));
13700 vec_free (locator_set_name);
13701
13702 mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
13703 if (locators)
13704 clib_memcpy (mp->locators, locators, data_len);
13705 vec_free (locators);
13706
13707 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013708 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013709
13710 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060013711 W (ret);
13712 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013713}
13714
Filip Tehlar694396d2017-02-17 14:29:11 +010013715#define api_lisp_add_del_locator_set api_one_add_del_locator_set
13716
Damjan Marion7cd468a2016-12-19 23:05:39 +010013717static int
Filip Tehlar694396d2017-02-17 14:29:11 +010013718api_one_add_del_locator (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010013719{
13720 unformat_input_t *input = vam->input;
Filip Tehlar694396d2017-02-17 14:29:11 +010013721 vl_api_one_add_del_locator_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013722 u32 tmp_if_index = ~0;
13723 u32 sw_if_index = ~0;
13724 u8 sw_if_index_set = 0;
13725 u8 sw_if_index_if_name_set = 0;
13726 u32 priority = ~0;
13727 u8 priority_set = 0;
13728 u32 weight = ~0;
13729 u8 weight_set = 0;
13730 u8 is_add = 1;
13731 u8 *locator_set_name = NULL;
13732 u8 locator_set_name_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013733 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013734
13735 /* Parse args required to build the message */
13736 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13737 {
13738 if (unformat (input, "del"))
13739 {
13740 is_add = 0;
13741 }
13742 else if (unformat (input, "locator-set %s", &locator_set_name))
13743 {
13744 locator_set_name_set = 1;
13745 }
13746 else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
13747 &tmp_if_index))
13748 {
13749 sw_if_index_if_name_set = 1;
13750 sw_if_index = tmp_if_index;
13751 }
13752 else if (unformat (input, "sw_if_index %d", &tmp_if_index))
13753 {
13754 sw_if_index_set = 1;
13755 sw_if_index = tmp_if_index;
13756 }
13757 else if (unformat (input, "p %d", &priority))
13758 {
13759 priority_set = 1;
13760 }
13761 else if (unformat (input, "w %d", &weight))
13762 {
13763 weight_set = 1;
13764 }
13765 else
13766 break;
13767 }
13768
13769 if (locator_set_name_set == 0)
13770 {
13771 errmsg ("missing locator-set name");
13772 return -99;
13773 }
13774
13775 if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
13776 {
13777 errmsg ("missing sw_if_index");
13778 vec_free (locator_set_name);
13779 return -99;
13780 }
13781
13782 if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
13783 {
13784 errmsg ("cannot use both params interface name and sw_if_index");
13785 vec_free (locator_set_name);
13786 return -99;
13787 }
13788
13789 if (priority_set == 0)
13790 {
13791 errmsg ("missing locator-set priority");
13792 vec_free (locator_set_name);
13793 return -99;
13794 }
13795
13796 if (weight_set == 0)
13797 {
13798 errmsg ("missing locator-set weight");
13799 vec_free (locator_set_name);
13800 return -99;
13801 }
13802
13803 if (vec_len (locator_set_name) > 64)
13804 {
13805 errmsg ("locator-set name too long");
13806 vec_free (locator_set_name);
13807 return -99;
13808 }
13809 vec_add1 (locator_set_name, 0);
13810
13811 /* Construct the API message */
Filip Tehlar694396d2017-02-17 14:29:11 +010013812 M (ONE_ADD_DEL_LOCATOR, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013813
13814 mp->is_add = is_add;
13815 mp->sw_if_index = ntohl (sw_if_index);
13816 mp->priority = priority;
13817 mp->weight = weight;
13818 clib_memcpy (mp->locator_set_name, locator_set_name,
13819 vec_len (locator_set_name));
13820 vec_free (locator_set_name);
13821
13822 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013823 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013824
13825 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060013826 W (ret);
13827 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013828}
13829
Filip Tehlar694396d2017-02-17 14:29:11 +010013830#define api_lisp_add_del_locator api_one_add_del_locator
13831
Damjan Marion7cd468a2016-12-19 23:05:39 +010013832uword
13833unformat_hmac_key_id (unformat_input_t * input, va_list * args)
13834{
13835 u32 *key_id = va_arg (*args, u32 *);
13836 u8 *s = 0;
13837
13838 if (unformat (input, "%s", &s))
13839 {
13840 if (!strcmp ((char *) s, "sha1"))
13841 key_id[0] = HMAC_SHA_1_96;
13842 else if (!strcmp ((char *) s, "sha256"))
13843 key_id[0] = HMAC_SHA_256_128;
13844 else
13845 {
13846 clib_warning ("invalid key_id: '%s'", s);
13847 key_id[0] = HMAC_NO_KEY;
13848 }
13849 }
13850 else
13851 return 0;
13852
13853 vec_free (s);
13854 return 1;
13855}
13856
13857static int
Filip Tehlar694396d2017-02-17 14:29:11 +010013858api_one_add_del_local_eid (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010013859{
13860 unformat_input_t *input = vam->input;
Filip Tehlar694396d2017-02-17 14:29:11 +010013861 vl_api_one_add_del_local_eid_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013862 u8 is_add = 1;
13863 u8 eid_set = 0;
13864 lisp_eid_vat_t _eid, *eid = &_eid;
13865 u8 *locator_set_name = 0;
13866 u8 locator_set_name_set = 0;
13867 u32 vni = 0;
13868 u16 key_id = 0;
13869 u8 *key = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013870 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013871
13872 /* Parse args required to build the message */
13873 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13874 {
13875 if (unformat (input, "del"))
13876 {
13877 is_add = 0;
13878 }
13879 else if (unformat (input, "vni %d", &vni))
13880 {
13881 ;
13882 }
13883 else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13884 {
13885 eid_set = 1;
13886 }
13887 else if (unformat (input, "locator-set %s", &locator_set_name))
13888 {
13889 locator_set_name_set = 1;
13890 }
13891 else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
13892 ;
13893 else if (unformat (input, "secret-key %_%v%_", &key))
13894 ;
13895 else
13896 break;
13897 }
13898
13899 if (locator_set_name_set == 0)
13900 {
13901 errmsg ("missing locator-set name");
13902 return -99;
13903 }
13904
13905 if (0 == eid_set)
13906 {
13907 errmsg ("EID address not set!");
13908 vec_free (locator_set_name);
13909 return -99;
13910 }
13911
13912 if (key && (0 == key_id))
13913 {
13914 errmsg ("invalid key_id!");
13915 return -99;
13916 }
13917
13918 if (vec_len (key) > 64)
13919 {
13920 errmsg ("key too long");
13921 vec_free (key);
13922 return -99;
13923 }
13924
13925 if (vec_len (locator_set_name) > 64)
13926 {
13927 errmsg ("locator-set name too long");
13928 vec_free (locator_set_name);
13929 return -99;
13930 }
13931 vec_add1 (locator_set_name, 0);
13932
13933 /* Construct the API message */
Filip Tehlar694396d2017-02-17 14:29:11 +010013934 M (ONE_ADD_DEL_LOCAL_EID, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013935
13936 mp->is_add = is_add;
13937 lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13938 mp->eid_type = eid->type;
13939 mp->prefix_len = eid->len;
13940 mp->vni = clib_host_to_net_u32 (vni);
13941 mp->key_id = clib_host_to_net_u16 (key_id);
13942 clib_memcpy (mp->locator_set_name, locator_set_name,
13943 vec_len (locator_set_name));
13944 clib_memcpy (mp->key, key, vec_len (key));
13945
13946 vec_free (locator_set_name);
13947 vec_free (key);
13948
13949 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013950 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013951
13952 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060013953 W (ret);
13954 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013955}
13956
Filip Tehlar694396d2017-02-17 14:29:11 +010013957#define api_lisp_add_del_local_eid api_one_add_del_local_eid
Damjan Marion7cd468a2016-12-19 23:05:39 +010013958
13959static int
13960api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
13961{
Filip Tehlarc3af7bf2017-01-13 14:13:09 +010013962 u32 dp_table = 0, vni = 0;;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013963 unformat_input_t *input = vam->input;
Filip Tehlar82786c42017-02-20 15:20:37 +010013964 vl_api_gpe_add_del_fwd_entry_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013965 u8 is_add = 1;
13966 lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
13967 lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
13968 u8 rmt_eid_set = 0, lcl_eid_set = 0;
Filip Tehlarc3af7bf2017-01-13 14:13:09 +010013969 u32 action = ~0, w;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013970 ip4_address_t rmt_rloc4, lcl_rloc4;
13971 ip6_address_t rmt_rloc6, lcl_rloc6;
Filip Tehlar82786c42017-02-20 15:20:37 +010013972 vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013973 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013974
13975 memset (&rloc, 0, sizeof (rloc));
13976
13977 /* Parse args required to build the message */
13978 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13979 {
13980 if (unformat (input, "del"))
Filip Tehlarc3af7bf2017-01-13 14:13:09 +010013981 is_add = 0;
13982 else if (unformat (input, "add"))
13983 is_add = 1;
13984 else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
Damjan Marion7cd468a2016-12-19 23:05:39 +010013985 {
13986 rmt_eid_set = 1;
13987 }
Filip Tehlarc3af7bf2017-01-13 14:13:09 +010013988 else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
Damjan Marion7cd468a2016-12-19 23:05:39 +010013989 {
13990 lcl_eid_set = 1;
13991 }
Filip Tehlarc3af7bf2017-01-13 14:13:09 +010013992 else if (unformat (input, "vrf %d", &dp_table))
13993 ;
13994 else if (unformat (input, "bd %d", &dp_table))
13995 ;
13996 else if (unformat (input, "vni %d", &vni))
13997 ;
13998 else if (unformat (input, "w %d", &w))
Damjan Marion7cd468a2016-12-19 23:05:39 +010013999 {
14000 if (!curr_rloc)
14001 {
14002 errmsg ("No RLOC configured for setting priority/weight!");
14003 return -99;
14004 }
Damjan Marion7cd468a2016-12-19 23:05:39 +010014005 curr_rloc->weight = w;
14006 }
14007 else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
14008 &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
14009 {
14010 rloc.is_ip4 = 1;
14011
14012 clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
Filip Tehlarc3af7bf2017-01-13 14:13:09 +010014013 rloc.weight = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014014 vec_add1 (lcl_locs, rloc);
14015
14016 clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
14017 vec_add1 (rmt_locs, rloc);
Filip Tehlarc3af7bf2017-01-13 14:13:09 +010014018 /* weight saved in rmt loc */
Damjan Marion7cd468a2016-12-19 23:05:39 +010014019 curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14020 }
14021 else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
14022 &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
14023 {
14024 rloc.is_ip4 = 0;
14025 clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
Filip Tehlarc3af7bf2017-01-13 14:13:09 +010014026 rloc.weight = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014027 vec_add1 (lcl_locs, rloc);
14028
14029 clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
14030 vec_add1 (rmt_locs, rloc);
Filip Tehlarc3af7bf2017-01-13 14:13:09 +010014031 /* weight saved in rmt loc */
Damjan Marion7cd468a2016-12-19 23:05:39 +010014032 curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14033 }
14034 else if (unformat (input, "action %d", &action))
14035 {
14036 ;
14037 }
14038 else
14039 {
14040 clib_warning ("parse error '%U'", format_unformat_error, input);
14041 return -99;
14042 }
14043 }
14044
14045 if (!rmt_eid_set)
14046 {
14047 errmsg ("remote eid addresses not set");
14048 return -99;
14049 }
14050
14051 if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
14052 {
14053 errmsg ("eid types don't match");
14054 return -99;
14055 }
14056
14057 if (0 == rmt_locs && (u32) ~ 0 == action)
14058 {
14059 errmsg ("action not set for negative mapping");
14060 return -99;
14061 }
14062
14063 /* Construct the API message */
Filip Tehlar82786c42017-02-20 15:20:37 +010014064 M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
14065 sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014066
14067 mp->is_add = is_add;
14068 lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
14069 lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
14070 mp->eid_type = rmt_eid->type;
Filip Tehlarc3af7bf2017-01-13 14:13:09 +010014071 mp->dp_table = clib_host_to_net_u32 (dp_table);
14072 mp->vni = clib_host_to_net_u32 (vni);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014073 mp->rmt_len = rmt_eid->len;
14074 mp->lcl_len = lcl_eid->len;
14075 mp->action = action;
14076
14077 if (0 != rmt_locs && 0 != lcl_locs)
14078 {
Filip Tehlarc3af7bf2017-01-13 14:13:09 +010014079 mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
14080 clib_memcpy (mp->locs, lcl_locs,
Filip Tehlar82786c42017-02-20 15:20:37 +010014081 (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
Filip Tehlarc3af7bf2017-01-13 14:13:09 +010014082
Filip Tehlar82786c42017-02-20 15:20:37 +010014083 u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
Filip Tehlarc3af7bf2017-01-13 14:13:09 +010014084 clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
Filip Tehlar82786c42017-02-20 15:20:37 +010014085 (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
Damjan Marion7cd468a2016-12-19 23:05:39 +010014086 }
14087 vec_free (lcl_locs);
14088 vec_free (rmt_locs);
14089
14090 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014091 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014092
14093 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014094 W (ret);
14095 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014096}
14097
14098static int
Filip Tehlar694396d2017-02-17 14:29:11 +010014099api_one_add_del_map_server (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010014100{
14101 unformat_input_t *input = vam->input;
Filip Tehlar694396d2017-02-17 14:29:11 +010014102 vl_api_one_add_del_map_server_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014103 u8 is_add = 1;
14104 u8 ipv4_set = 0;
14105 u8 ipv6_set = 0;
14106 ip4_address_t ipv4;
14107 ip6_address_t ipv6;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014108 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014109
14110 /* Parse args required to build the message */
14111 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14112 {
14113 if (unformat (input, "del"))
14114 {
14115 is_add = 0;
14116 }
14117 else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14118 {
14119 ipv4_set = 1;
14120 }
14121 else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14122 {
14123 ipv6_set = 1;
14124 }
14125 else
14126 break;
14127 }
14128
14129 if (ipv4_set && ipv6_set)
14130 {
14131 errmsg ("both eid v4 and v6 addresses set");
14132 return -99;
14133 }
14134
14135 if (!ipv4_set && !ipv6_set)
14136 {
14137 errmsg ("eid addresses not set");
14138 return -99;
14139 }
14140
14141 /* Construct the API message */
Filip Tehlar694396d2017-02-17 14:29:11 +010014142 M (ONE_ADD_DEL_MAP_SERVER, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014143
14144 mp->is_add = is_add;
14145 if (ipv6_set)
14146 {
14147 mp->is_ipv6 = 1;
14148 clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14149 }
14150 else
14151 {
14152 mp->is_ipv6 = 0;
14153 clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14154 }
14155
14156 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014157 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014158
14159 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014160 W (ret);
14161 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014162}
14163
Filip Tehlar694396d2017-02-17 14:29:11 +010014164#define api_lisp_add_del_map_server api_one_add_del_map_server
14165
Damjan Marion7cd468a2016-12-19 23:05:39 +010014166static int
Filip Tehlar694396d2017-02-17 14:29:11 +010014167api_one_add_del_map_resolver (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010014168{
14169 unformat_input_t *input = vam->input;
Filip Tehlar694396d2017-02-17 14:29:11 +010014170 vl_api_one_add_del_map_resolver_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014171 u8 is_add = 1;
14172 u8 ipv4_set = 0;
14173 u8 ipv6_set = 0;
14174 ip4_address_t ipv4;
14175 ip6_address_t ipv6;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014176 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014177
14178 /* Parse args required to build the message */
14179 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14180 {
14181 if (unformat (input, "del"))
14182 {
14183 is_add = 0;
14184 }
14185 else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14186 {
14187 ipv4_set = 1;
14188 }
14189 else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14190 {
14191 ipv6_set = 1;
14192 }
14193 else
14194 break;
14195 }
14196
14197 if (ipv4_set && ipv6_set)
14198 {
14199 errmsg ("both eid v4 and v6 addresses set");
14200 return -99;
14201 }
14202
14203 if (!ipv4_set && !ipv6_set)
14204 {
14205 errmsg ("eid addresses not set");
14206 return -99;
14207 }
14208
14209 /* Construct the API message */
Filip Tehlar694396d2017-02-17 14:29:11 +010014210 M (ONE_ADD_DEL_MAP_RESOLVER, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014211
14212 mp->is_add = is_add;
14213 if (ipv6_set)
14214 {
14215 mp->is_ipv6 = 1;
14216 clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14217 }
14218 else
14219 {
14220 mp->is_ipv6 = 0;
14221 clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14222 }
14223
14224 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014225 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014226
14227 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014228 W (ret);
14229 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014230}
14231
Filip Tehlar694396d2017-02-17 14:29:11 +010014232#define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
14233
Damjan Marion7cd468a2016-12-19 23:05:39 +010014234static int
14235api_lisp_gpe_enable_disable (vat_main_t * vam)
14236{
14237 unformat_input_t *input = vam->input;
Filip Tehlar82786c42017-02-20 15:20:37 +010014238 vl_api_gpe_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014239 u8 is_set = 0;
14240 u8 is_en = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014241 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014242
14243 /* Parse args required to build the message */
14244 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14245 {
14246 if (unformat (input, "enable"))
14247 {
14248 is_set = 1;
14249 is_en = 1;
14250 }
14251 else if (unformat (input, "disable"))
14252 {
14253 is_set = 1;
14254 is_en = 0;
14255 }
14256 else
14257 break;
14258 }
14259
14260 if (is_set == 0)
14261 {
14262 errmsg ("Value not set");
14263 return -99;
14264 }
14265
14266 /* Construct the API message */
Filip Tehlar82786c42017-02-20 15:20:37 +010014267 M (GPE_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014268
14269 mp->is_en = is_en;
14270
14271 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014272 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014273
14274 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014275 W (ret);
14276 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014277}
14278
14279static int
Filip Tehlar694396d2017-02-17 14:29:11 +010014280api_one_rloc_probe_enable_disable (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010014281{
14282 unformat_input_t *input = vam->input;
Filip Tehlar694396d2017-02-17 14:29:11 +010014283 vl_api_one_rloc_probe_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014284 u8 is_set = 0;
14285 u8 is_en = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014286 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014287
14288 /* Parse args required to build the message */
14289 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14290 {
14291 if (unformat (input, "enable"))
14292 {
14293 is_set = 1;
14294 is_en = 1;
14295 }
14296 else if (unformat (input, "disable"))
14297 is_set = 1;
14298 else
14299 break;
14300 }
14301
14302 if (!is_set)
14303 {
14304 errmsg ("Value not set");
14305 return -99;
14306 }
14307
14308 /* Construct the API message */
Filip Tehlar694396d2017-02-17 14:29:11 +010014309 M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014310
14311 mp->is_enabled = is_en;
14312
14313 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014314 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014315
14316 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014317 W (ret);
14318 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014319}
14320
Filip Tehlar694396d2017-02-17 14:29:11 +010014321#define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
14322
Damjan Marion7cd468a2016-12-19 23:05:39 +010014323static int
Filip Tehlar694396d2017-02-17 14:29:11 +010014324api_one_map_register_enable_disable (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010014325{
14326 unformat_input_t *input = vam->input;
Filip Tehlar694396d2017-02-17 14:29:11 +010014327 vl_api_one_map_register_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014328 u8 is_set = 0;
14329 u8 is_en = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014330 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014331
14332 /* Parse args required to build the message */
14333 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14334 {
14335 if (unformat (input, "enable"))
14336 {
14337 is_set = 1;
14338 is_en = 1;
14339 }
14340 else if (unformat (input, "disable"))
14341 is_set = 1;
14342 else
14343 break;
14344 }
14345
14346 if (!is_set)
14347 {
14348 errmsg ("Value not set");
14349 return -99;
14350 }
14351
14352 /* Construct the API message */
Filip Tehlar694396d2017-02-17 14:29:11 +010014353 M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014354
14355 mp->is_enabled = is_en;
14356
14357 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014358 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014359
14360 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014361 W (ret);
14362 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014363}
14364
Filip Tehlar694396d2017-02-17 14:29:11 +010014365#define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
14366
Damjan Marion7cd468a2016-12-19 23:05:39 +010014367static int
Filip Tehlar694396d2017-02-17 14:29:11 +010014368api_one_enable_disable (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010014369{
14370 unformat_input_t *input = vam->input;
Filip Tehlar694396d2017-02-17 14:29:11 +010014371 vl_api_one_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014372 u8 is_set = 0;
14373 u8 is_en = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014374 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014375
14376 /* Parse args required to build the message */
14377 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14378 {
14379 if (unformat (input, "enable"))
14380 {
14381 is_set = 1;
14382 is_en = 1;
14383 }
14384 else if (unformat (input, "disable"))
14385 {
14386 is_set = 1;
14387 }
14388 else
14389 break;
14390 }
14391
14392 if (!is_set)
14393 {
14394 errmsg ("Value not set");
14395 return -99;
14396 }
14397
14398 /* Construct the API message */
Filip Tehlar694396d2017-02-17 14:29:11 +010014399 M (ONE_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014400
14401 mp->is_en = is_en;
14402
14403 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014404 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014405
14406 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014407 W (ret);
14408 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014409}
14410
Filip Tehlar694396d2017-02-17 14:29:11 +010014411#define api_lisp_enable_disable api_one_enable_disable
14412
Damjan Marion7cd468a2016-12-19 23:05:39 +010014413static int
Filip Tehlar694396d2017-02-17 14:29:11 +010014414api_show_one_map_register_state (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010014415{
Filip Tehlar694396d2017-02-17 14:29:11 +010014416 vl_api_show_one_map_register_state_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014417 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014418
Filip Tehlar694396d2017-02-17 14:29:11 +010014419 M (SHOW_ONE_MAP_REGISTER_STATE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014420
14421 /* send */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014422 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014423
14424 /* wait for reply */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014425 W (ret);
14426 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014427}
14428
Filip Tehlar694396d2017-02-17 14:29:11 +010014429#define api_show_lisp_map_register_state api_show_one_map_register_state
14430
Damjan Marion7cd468a2016-12-19 23:05:39 +010014431static int
Filip Tehlar694396d2017-02-17 14:29:11 +010014432api_show_one_rloc_probe_state (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010014433{
Filip Tehlar694396d2017-02-17 14:29:11 +010014434 vl_api_show_one_rloc_probe_state_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014435 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014436
Filip Tehlar694396d2017-02-17 14:29:11 +010014437 M (SHOW_ONE_RLOC_PROBE_STATE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014438
14439 /* send */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014440 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014441
14442 /* wait for reply */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014443 W (ret);
14444 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014445}
14446
Filip Tehlar694396d2017-02-17 14:29:11 +010014447#define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
14448
Damjan Marion7cd468a2016-12-19 23:05:39 +010014449static int
Filip Tehlar694396d2017-02-17 14:29:11 +010014450api_show_one_map_request_mode (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010014451{
Filip Tehlar694396d2017-02-17 14:29:11 +010014452 vl_api_show_one_map_request_mode_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014453 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014454
Filip Tehlar694396d2017-02-17 14:29:11 +010014455 M (SHOW_ONE_MAP_REQUEST_MODE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014456
14457 /* send */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014458 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014459
14460 /* wait for reply */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014461 W (ret);
14462 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014463}
14464
Filip Tehlar694396d2017-02-17 14:29:11 +010014465#define api_show_lisp_map_request_mode api_show_one_map_request_mode
14466
Damjan Marion7cd468a2016-12-19 23:05:39 +010014467static int
Filip Tehlar694396d2017-02-17 14:29:11 +010014468api_one_map_request_mode (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010014469{
Damjan Marion7cd468a2016-12-19 23:05:39 +010014470 unformat_input_t *input = vam->input;
Filip Tehlar694396d2017-02-17 14:29:11 +010014471 vl_api_one_map_request_mode_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014472 u8 mode = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014473 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014474
14475 /* Parse args required to build the message */
14476 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14477 {
14478 if (unformat (input, "dst-only"))
14479 mode = 0;
14480 else if (unformat (input, "src-dst"))
14481 mode = 1;
14482 else
14483 {
14484 errmsg ("parse error '%U'", format_unformat_error, input);
14485 return -99;
14486 }
14487 }
14488
Filip Tehlar694396d2017-02-17 14:29:11 +010014489 M (ONE_MAP_REQUEST_MODE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014490
14491 mp->mode = mode;
14492
14493 /* send */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014494 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014495
14496 /* wait for reply */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014497 W (ret);
14498 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014499}
14500
Filip Tehlar694396d2017-02-17 14:29:11 +010014501#define api_lisp_map_request_mode api_one_map_request_mode
14502
Damjan Marion7cd468a2016-12-19 23:05:39 +010014503/**
Filip Tehlar694396d2017-02-17 14:29:11 +010014504 * Enable/disable ONE proxy ITR.
Damjan Marion7cd468a2016-12-19 23:05:39 +010014505 *
14506 * @param vam vpp API test context
14507 * @return return code
14508 */
14509static int
Filip Tehlar694396d2017-02-17 14:29:11 +010014510api_one_pitr_set_locator_set (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010014511{
Damjan Marion7cd468a2016-12-19 23:05:39 +010014512 u8 ls_name_set = 0;
14513 unformat_input_t *input = vam->input;
Filip Tehlar694396d2017-02-17 14:29:11 +010014514 vl_api_one_pitr_set_locator_set_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014515 u8 is_add = 1;
14516 u8 *ls_name = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014517 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014518
14519 /* Parse args required to build the message */
14520 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14521 {
14522 if (unformat (input, "del"))
14523 is_add = 0;
14524 else if (unformat (input, "locator-set %s", &ls_name))
14525 ls_name_set = 1;
14526 else
14527 {
14528 errmsg ("parse error '%U'", format_unformat_error, input);
14529 return -99;
14530 }
14531 }
14532
14533 if (!ls_name_set)
14534 {
14535 errmsg ("locator-set name not set!");
14536 return -99;
14537 }
14538
Filip Tehlar694396d2017-02-17 14:29:11 +010014539 M (ONE_PITR_SET_LOCATOR_SET, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014540
14541 mp->is_add = is_add;
14542 clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
14543 vec_free (ls_name);
14544
14545 /* send */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014546 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014547
14548 /* wait for reply */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014549 W (ret);
14550 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014551}
14552
Filip Tehlar694396d2017-02-17 14:29:11 +010014553#define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
14554
Damjan Marion7cd468a2016-12-19 23:05:39 +010014555static int
Filip Tehlar694396d2017-02-17 14:29:11 +010014556api_show_one_pitr (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010014557{
Filip Tehlar694396d2017-02-17 14:29:11 +010014558 vl_api_show_one_pitr_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014559 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014560
14561 if (!vam->json_output)
14562 {
14563 print (vam->ofp, "%=20s", "lisp status:");
14564 }
14565
Filip Tehlar694396d2017-02-17 14:29:11 +010014566 M (SHOW_ONE_PITR, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014567 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014568 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014569
14570 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014571 W (ret);
14572 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014573}
14574
Filip Tehlar694396d2017-02-17 14:29:11 +010014575#define api_show_lisp_pitr api_show_one_pitr
14576
Damjan Marion7cd468a2016-12-19 23:05:39 +010014577/**
14578 * Add/delete mapping between vni and vrf
14579 */
14580static int
Filip Tehlar694396d2017-02-17 14:29:11 +010014581api_one_eid_table_add_del_map (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010014582{
Damjan Marion7cd468a2016-12-19 23:05:39 +010014583 unformat_input_t *input = vam->input;
Filip Tehlar694396d2017-02-17 14:29:11 +010014584 vl_api_one_eid_table_add_del_map_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014585 u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
14586 u32 vni, vrf, bd_index;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014587 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014588
14589 /* Parse args required to build the message */
14590 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14591 {
14592 if (unformat (input, "del"))
14593 is_add = 0;
14594 else if (unformat (input, "vrf %d", &vrf))
14595 vrf_set = 1;
14596 else if (unformat (input, "bd_index %d", &bd_index))
14597 bd_index_set = 1;
14598 else if (unformat (input, "vni %d", &vni))
14599 vni_set = 1;
14600 else
14601 break;
14602 }
14603
14604 if (!vni_set || (!vrf_set && !bd_index_set))
14605 {
14606 errmsg ("missing arguments!");
14607 return -99;
14608 }
14609
14610 if (vrf_set && bd_index_set)
14611 {
14612 errmsg ("error: both vrf and bd entered!");
14613 return -99;
14614 }
14615
Filip Tehlar694396d2017-02-17 14:29:11 +010014616 M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014617
14618 mp->is_add = is_add;
14619 mp->vni = htonl (vni);
14620 mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
14621 mp->is_l2 = bd_index_set;
14622
14623 /* send */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014624 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014625
14626 /* wait for reply */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014627 W (ret);
14628 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014629}
14630
Filip Tehlar694396d2017-02-17 14:29:11 +010014631#define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
14632
Damjan Marion7cd468a2016-12-19 23:05:39 +010014633uword
14634unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
14635{
14636 u32 *action = va_arg (*args, u32 *);
14637 u8 *s = 0;
14638
14639 if (unformat (input, "%s", &s))
14640 {
14641 if (!strcmp ((char *) s, "no-action"))
14642 action[0] = 0;
14643 else if (!strcmp ((char *) s, "natively-forward"))
14644 action[0] = 1;
14645 else if (!strcmp ((char *) s, "send-map-request"))
14646 action[0] = 2;
14647 else if (!strcmp ((char *) s, "drop"))
14648 action[0] = 3;
14649 else
14650 {
14651 clib_warning ("invalid action: '%s'", s);
14652 action[0] = 3;
14653 }
14654 }
14655 else
14656 return 0;
14657
14658 vec_free (s);
14659 return 1;
14660}
14661
14662/**
Filip Tehlar694396d2017-02-17 14:29:11 +010014663 * Add/del remote mapping to/from ONE control plane
Damjan Marion7cd468a2016-12-19 23:05:39 +010014664 *
14665 * @param vam vpp API test context
14666 * @return return code
14667 */
14668static int
Filip Tehlar694396d2017-02-17 14:29:11 +010014669api_one_add_del_remote_mapping (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_add_del_remote_mapping_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014673 u32 vni = 0;
14674 lisp_eid_vat_t _eid, *eid = &_eid;
14675 lisp_eid_vat_t _seid, *seid = &_seid;
14676 u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
14677 u32 action = ~0, p, w, data_len;
14678 ip4_address_t rloc4;
14679 ip6_address_t rloc6;
Filip Tehlar05a057b2017-02-01 08:50:31 +010014680 vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014681 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014682
14683 memset (&rloc, 0, sizeof (rloc));
14684
14685 /* Parse args required to build the message */
14686 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14687 {
14688 if (unformat (input, "del-all"))
14689 {
14690 del_all = 1;
14691 }
14692 else if (unformat (input, "del"))
14693 {
14694 is_add = 0;
14695 }
14696 else if (unformat (input, "add"))
14697 {
14698 is_add = 1;
14699 }
14700 else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14701 {
14702 eid_set = 1;
14703 }
14704 else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
14705 {
14706 seid_set = 1;
14707 }
14708 else if (unformat (input, "vni %d", &vni))
14709 {
14710 ;
14711 }
14712 else if (unformat (input, "p %d w %d", &p, &w))
14713 {
14714 if (!curr_rloc)
14715 {
14716 errmsg ("No RLOC configured for setting priority/weight!");
14717 return -99;
14718 }
14719 curr_rloc->priority = p;
14720 curr_rloc->weight = w;
14721 }
14722 else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
14723 {
14724 rloc.is_ip4 = 1;
14725 clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
14726 vec_add1 (rlocs, rloc);
14727 curr_rloc = &rlocs[vec_len (rlocs) - 1];
14728 }
14729 else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
14730 {
14731 rloc.is_ip4 = 0;
14732 clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
14733 vec_add1 (rlocs, rloc);
14734 curr_rloc = &rlocs[vec_len (rlocs) - 1];
14735 }
14736 else if (unformat (input, "action %U",
14737 unformat_negative_mapping_action, &action))
14738 {
14739 ;
14740 }
14741 else
14742 {
14743 clib_warning ("parse error '%U'", format_unformat_error, input);
14744 return -99;
14745 }
14746 }
14747
14748 if (0 == eid_set)
14749 {
14750 errmsg ("missing params!");
14751 return -99;
14752 }
14753
14754 if (is_add && (~0 == action) && 0 == vec_len (rlocs))
14755 {
14756 errmsg ("no action set for negative map-reply!");
14757 return -99;
14758 }
14759
Filip Tehlar05a057b2017-02-01 08:50:31 +010014760 data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014761
Filip Tehlar694396d2017-02-17 14:29:11 +010014762 M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014763 mp->is_add = is_add;
14764 mp->vni = htonl (vni);
14765 mp->action = (u8) action;
14766 mp->is_src_dst = seid_set;
14767 mp->eid_len = eid->len;
14768 mp->seid_len = seid->len;
14769 mp->del_all = del_all;
14770 mp->eid_type = eid->type;
14771 lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14772 lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
14773
14774 mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
14775 clib_memcpy (mp->rlocs, rlocs, data_len);
14776 vec_free (rlocs);
14777
14778 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014779 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014780
14781 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014782 W (ret);
14783 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014784}
14785
Filip Tehlar694396d2017-02-17 14:29:11 +010014786#define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
14787
Damjan Marion7cd468a2016-12-19 23:05:39 +010014788/**
Filip Tehlar694396d2017-02-17 14:29:11 +010014789 * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
Damjan Marion7cd468a2016-12-19 23:05:39 +010014790 * forwarding entries in data-plane accordingly.
14791 *
14792 * @param vam vpp API test context
14793 * @return return code
14794 */
14795static int
Filip Tehlar694396d2017-02-17 14:29:11 +010014796api_one_add_del_adjacency (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010014797{
14798 unformat_input_t *input = vam->input;
Filip Tehlar694396d2017-02-17 14:29:11 +010014799 vl_api_one_add_del_adjacency_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014800 u32 vni = 0;
14801 ip4_address_t leid4, reid4;
14802 ip6_address_t leid6, reid6;
14803 u8 reid_mac[6] = { 0 };
14804 u8 leid_mac[6] = { 0 };
14805 u8 reid_type, leid_type;
14806 u32 leid_len = 0, reid_len = 0, len;
14807 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014808 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014809
14810 leid_type = reid_type = (u8) ~ 0;
14811
14812 /* Parse args required to build the message */
14813 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14814 {
14815 if (unformat (input, "del"))
14816 {
14817 is_add = 0;
14818 }
14819 else if (unformat (input, "add"))
14820 {
14821 is_add = 1;
14822 }
14823 else if (unformat (input, "reid %U/%d", unformat_ip4_address,
14824 &reid4, &len))
14825 {
14826 reid_type = 0; /* ipv4 */
14827 reid_len = len;
14828 }
14829 else if (unformat (input, "reid %U/%d", unformat_ip6_address,
14830 &reid6, &len))
14831 {
14832 reid_type = 1; /* ipv6 */
14833 reid_len = len;
14834 }
14835 else if (unformat (input, "reid %U", unformat_ethernet_address,
14836 reid_mac))
14837 {
14838 reid_type = 2; /* mac */
14839 }
14840 else if (unformat (input, "leid %U/%d", unformat_ip4_address,
14841 &leid4, &len))
14842 {
14843 leid_type = 0; /* ipv4 */
14844 leid_len = len;
14845 }
14846 else if (unformat (input, "leid %U/%d", unformat_ip6_address,
14847 &leid6, &len))
14848 {
14849 leid_type = 1; /* ipv6 */
14850 leid_len = len;
14851 }
14852 else if (unformat (input, "leid %U", unformat_ethernet_address,
14853 leid_mac))
14854 {
14855 leid_type = 2; /* mac */
14856 }
14857 else if (unformat (input, "vni %d", &vni))
14858 {
14859 ;
14860 }
14861 else
14862 {
14863 errmsg ("parse error '%U'", format_unformat_error, input);
14864 return -99;
14865 }
14866 }
14867
14868 if ((u8) ~ 0 == reid_type)
14869 {
14870 errmsg ("missing params!");
14871 return -99;
14872 }
14873
14874 if (leid_type != reid_type)
14875 {
14876 errmsg ("remote and local EIDs are of different types!");
14877 return -99;
14878 }
14879
Filip Tehlar694396d2017-02-17 14:29:11 +010014880 M (ONE_ADD_DEL_ADJACENCY, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014881 mp->is_add = is_add;
14882 mp->vni = htonl (vni);
14883 mp->leid_len = leid_len;
14884 mp->reid_len = reid_len;
14885 mp->eid_type = reid_type;
14886
14887 switch (mp->eid_type)
14888 {
14889 case 0:
14890 clib_memcpy (mp->leid, &leid4, sizeof (leid4));
14891 clib_memcpy (mp->reid, &reid4, sizeof (reid4));
14892 break;
14893 case 1:
14894 clib_memcpy (mp->leid, &leid6, sizeof (leid6));
14895 clib_memcpy (mp->reid, &reid6, sizeof (reid6));
14896 break;
14897 case 2:
14898 clib_memcpy (mp->leid, leid_mac, 6);
14899 clib_memcpy (mp->reid, reid_mac, 6);
14900 break;
14901 default:
14902 errmsg ("unknown EID type %d!", mp->eid_type);
14903 return 0;
14904 }
14905
14906 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014907 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014908
14909 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014910 W (ret);
14911 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014912}
14913
Filip Tehlar694396d2017-02-17 14:29:11 +010014914#define api_lisp_add_del_adjacency api_one_add_del_adjacency
14915
Filip Tehlar3e7b56932017-02-21 18:28:34 +010014916uword
14917unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
14918{
14919 u32 *mode = va_arg (*args, u32 *);
14920
14921 if (unformat (input, "lisp"))
14922 *mode = 0;
14923 else if (unformat (input, "vxlan"))
14924 *mode = 1;
14925 else
14926 return 0;
14927
14928 return 1;
14929}
14930
14931static int
14932api_gpe_get_encap_mode (vat_main_t * vam)
14933{
14934 vl_api_gpe_get_encap_mode_t *mp;
14935 int ret;
14936
14937 /* Construct the API message */
14938 M (GPE_GET_ENCAP_MODE, mp);
14939
14940 /* send it... */
14941 S (mp);
14942
14943 /* Wait for a reply... */
14944 W (ret);
14945 return ret;
14946}
14947
14948static int
14949api_gpe_set_encap_mode (vat_main_t * vam)
14950{
14951 unformat_input_t *input = vam->input;
14952 vl_api_gpe_set_encap_mode_t *mp;
14953 int ret;
14954 u32 mode = 0;
14955
14956 /* Parse args required to build the message */
14957 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14958 {
14959 if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
14960 ;
14961 else
14962 break;
14963 }
14964
14965 /* Construct the API message */
14966 M (GPE_SET_ENCAP_MODE, mp);
14967
14968 mp->mode = mode;
14969
14970 /* send it... */
14971 S (mp);
14972
14973 /* Wait for a reply... */
14974 W (ret);
14975 return ret;
14976}
14977
Damjan Marion7cd468a2016-12-19 23:05:39 +010014978static int
14979api_lisp_gpe_add_del_iface (vat_main_t * vam)
14980{
14981 unformat_input_t *input = vam->input;
Filip Tehlar82786c42017-02-20 15:20:37 +010014982 vl_api_gpe_add_del_iface_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014983 u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
14984 u32 dp_table = 0, vni = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014985 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014986
14987 /* Parse args required to build the message */
14988 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14989 {
14990 if (unformat (input, "up"))
14991 {
14992 action_set = 1;
14993 is_add = 1;
14994 }
14995 else if (unformat (input, "down"))
14996 {
14997 action_set = 1;
14998 is_add = 0;
14999 }
15000 else if (unformat (input, "table_id %d", &dp_table))
15001 {
15002 dp_table_set = 1;
15003 }
15004 else if (unformat (input, "bd_id %d", &dp_table))
15005 {
15006 dp_table_set = 1;
15007 is_l2 = 1;
15008 }
15009 else if (unformat (input, "vni %d", &vni))
15010 {
15011 vni_set = 1;
15012 }
15013 else
15014 break;
15015 }
15016
15017 if (action_set == 0)
15018 {
15019 errmsg ("Action not set");
15020 return -99;
15021 }
15022 if (dp_table_set == 0 || vni_set == 0)
15023 {
15024 errmsg ("vni and dp_table must be set");
15025 return -99;
15026 }
15027
15028 /* Construct the API message */
Filip Tehlar82786c42017-02-20 15:20:37 +010015029 M (GPE_ADD_DEL_IFACE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015030
15031 mp->is_add = is_add;
15032 mp->dp_table = dp_table;
15033 mp->is_l2 = is_l2;
15034 mp->vni = vni;
15035
15036 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015037 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015038
15039 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060015040 W (ret);
15041 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015042}
15043
15044/**
Filip Tehlar694396d2017-02-17 14:29:11 +010015045 * Add/del map request itr rlocs from ONE control plane and updates
Damjan Marion7cd468a2016-12-19 23:05:39 +010015046 *
15047 * @param vam vpp API test context
15048 * @return return code
15049 */
15050static int
Filip Tehlar694396d2017-02-17 14:29:11 +010015051api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010015052{
15053 unformat_input_t *input = vam->input;
Filip Tehlar694396d2017-02-17 14:29:11 +010015054 vl_api_one_add_del_map_request_itr_rlocs_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015055 u8 *locator_set_name = 0;
15056 u8 locator_set_name_set = 0;
15057 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015058 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015059
15060 /* Parse args required to build the message */
15061 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15062 {
15063 if (unformat (input, "del"))
15064 {
15065 is_add = 0;
15066 }
15067 else if (unformat (input, "%_%v%_", &locator_set_name))
15068 {
15069 locator_set_name_set = 1;
15070 }
15071 else
15072 {
15073 clib_warning ("parse error '%U'", format_unformat_error, input);
15074 return -99;
15075 }
15076 }
15077
15078 if (is_add && !locator_set_name_set)
15079 {
15080 errmsg ("itr-rloc is not set!");
15081 return -99;
15082 }
15083
15084 if (is_add && vec_len (locator_set_name) > 64)
15085 {
15086 errmsg ("itr-rloc locator-set name too long");
15087 vec_free (locator_set_name);
15088 return -99;
15089 }
15090
Filip Tehlar694396d2017-02-17 14:29:11 +010015091 M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015092 mp->is_add = is_add;
15093 if (is_add)
15094 {
15095 clib_memcpy (mp->locator_set_name, locator_set_name,
15096 vec_len (locator_set_name));
15097 }
15098 else
15099 {
15100 memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
15101 }
15102 vec_free (locator_set_name);
15103
15104 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015105 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015106
15107 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060015108 W (ret);
15109 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015110}
15111
Filip Tehlar694396d2017-02-17 14:29:11 +010015112#define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
15113
Damjan Marion7cd468a2016-12-19 23:05:39 +010015114static int
Filip Tehlar694396d2017-02-17 14:29:11 +010015115api_one_locator_dump (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010015116{
15117 unformat_input_t *input = vam->input;
Filip Tehlar694396d2017-02-17 14:29:11 +010015118 vl_api_one_locator_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060015119 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015120 u8 is_index_set = 0, is_name_set = 0;
15121 u8 *ls_name = 0;
15122 u32 ls_index = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015123 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015124
15125 /* Parse args required to build the message */
15126 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15127 {
15128 if (unformat (input, "ls_name %_%v%_", &ls_name))
15129 {
15130 is_name_set = 1;
15131 }
15132 else if (unformat (input, "ls_index %d", &ls_index))
15133 {
15134 is_index_set = 1;
15135 }
15136 else
15137 {
15138 errmsg ("parse error '%U'", format_unformat_error, input);
15139 return -99;
15140 }
15141 }
15142
15143 if (!is_index_set && !is_name_set)
15144 {
15145 errmsg ("error: expected one of index or name!");
15146 return -99;
15147 }
15148
15149 if (is_index_set && is_name_set)
15150 {
15151 errmsg ("error: only one param expected!");
15152 return -99;
15153 }
15154
15155 if (vec_len (ls_name) > 62)
15156 {
15157 errmsg ("error: locator set name too long!");
15158 return -99;
15159 }
15160
15161 if (!vam->json_output)
15162 {
15163 print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
15164 }
15165
Filip Tehlar694396d2017-02-17 14:29:11 +010015166 M (ONE_LOCATOR_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015167 mp->is_index_set = is_index_set;
15168
15169 if (is_index_set)
15170 mp->ls_index = clib_host_to_net_u32 (ls_index);
15171 else
15172 {
15173 vec_add1 (ls_name, 0);
15174 strncpy ((char *) mp->ls_name, (char *) ls_name,
15175 sizeof (mp->ls_name) - 1);
15176 }
15177
15178 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015179 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015180
15181 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060015182 M (CONTROL_PING, mp_ping);
15183 S (mp_ping);
15184
Damjan Marion7cd468a2016-12-19 23:05:39 +010015185 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060015186 W (ret);
15187 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015188}
15189
Filip Tehlar694396d2017-02-17 14:29:11 +010015190#define api_lisp_locator_dump api_one_locator_dump
15191
Damjan Marion7cd468a2016-12-19 23:05:39 +010015192static int
Filip Tehlar694396d2017-02-17 14:29:11 +010015193api_one_locator_set_dump (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010015194{
Filip Tehlar694396d2017-02-17 14:29:11 +010015195 vl_api_one_locator_set_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060015196 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015197 unformat_input_t *input = vam->input;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015198 u8 filter = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015199 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015200
15201 /* Parse args required to build the message */
15202 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15203 {
15204 if (unformat (input, "local"))
15205 {
15206 filter = 1;
15207 }
15208 else if (unformat (input, "remote"))
15209 {
15210 filter = 2;
15211 }
15212 else
15213 {
15214 errmsg ("parse error '%U'", format_unformat_error, input);
15215 return -99;
15216 }
15217 }
15218
15219 if (!vam->json_output)
15220 {
15221 print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
15222 }
15223
Filip Tehlar694396d2017-02-17 14:29:11 +010015224 M (ONE_LOCATOR_SET_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015225
15226 mp->filter = filter;
15227
15228 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015229 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015230
15231 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060015232 M (CONTROL_PING, mp_ping);
15233 S (mp_ping);
15234
Damjan Marion7cd468a2016-12-19 23:05:39 +010015235 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060015236 W (ret);
15237 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015238}
15239
Filip Tehlar694396d2017-02-17 14:29:11 +010015240#define api_lisp_locator_set_dump api_one_locator_set_dump
15241
Damjan Marion7cd468a2016-12-19 23:05:39 +010015242static int
Filip Tehlar694396d2017-02-17 14:29:11 +010015243api_one_eid_table_map_dump (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010015244{
15245 u8 is_l2 = 0;
15246 u8 mode_set = 0;
15247 unformat_input_t *input = vam->input;
Filip Tehlar694396d2017-02-17 14:29:11 +010015248 vl_api_one_eid_table_map_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060015249 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015250 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015251
15252 /* Parse args required to build the message */
15253 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15254 {
15255 if (unformat (input, "l2"))
15256 {
15257 is_l2 = 1;
15258 mode_set = 1;
15259 }
15260 else if (unformat (input, "l3"))
15261 {
15262 is_l2 = 0;
15263 mode_set = 1;
15264 }
15265 else
15266 {
15267 errmsg ("parse error '%U'", format_unformat_error, input);
15268 return -99;
15269 }
15270 }
15271
15272 if (!mode_set)
15273 {
15274 errmsg ("expected one of 'l2' or 'l3' parameter!");
15275 return -99;
15276 }
15277
15278 if (!vam->json_output)
15279 {
15280 print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
15281 }
15282
Filip Tehlar694396d2017-02-17 14:29:11 +010015283 M (ONE_EID_TABLE_MAP_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015284 mp->is_l2 = is_l2;
15285
15286 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015287 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015288
15289 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060015290 M (CONTROL_PING, mp_ping);
15291 S (mp_ping);
15292
Damjan Marion7cd468a2016-12-19 23:05:39 +010015293 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060015294 W (ret);
15295 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015296}
15297
Filip Tehlar694396d2017-02-17 14:29:11 +010015298#define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
15299
Damjan Marion7cd468a2016-12-19 23:05:39 +010015300static int
Filip Tehlar694396d2017-02-17 14:29:11 +010015301api_one_eid_table_vni_dump (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010015302{
Filip Tehlar694396d2017-02-17 14:29:11 +010015303 vl_api_one_eid_table_vni_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060015304 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015305 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015306
15307 if (!vam->json_output)
15308 {
15309 print (vam->ofp, "VNI");
15310 }
15311
Filip Tehlar694396d2017-02-17 14:29:11 +010015312 M (ONE_EID_TABLE_VNI_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015313
15314 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015315 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015316
15317 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060015318 M (CONTROL_PING, mp_ping);
15319 S (mp_ping);
15320
Damjan Marion7cd468a2016-12-19 23:05:39 +010015321 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060015322 W (ret);
15323 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015324}
15325
Filip Tehlar694396d2017-02-17 14:29:11 +010015326#define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
15327
Damjan Marion7cd468a2016-12-19 23:05:39 +010015328static int
Filip Tehlar694396d2017-02-17 14:29:11 +010015329api_one_eid_table_dump (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010015330{
15331 unformat_input_t *i = vam->input;
Filip Tehlar694396d2017-02-17 14:29:11 +010015332 vl_api_one_eid_table_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060015333 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015334 struct in_addr ip4;
15335 struct in6_addr ip6;
15336 u8 mac[6];
15337 u8 eid_type = ~0, eid_set = 0;
15338 u32 prefix_length = ~0, t, vni = 0;
15339 u8 filter = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015340 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015341
15342 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15343 {
15344 if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
15345 {
15346 eid_set = 1;
15347 eid_type = 0;
15348 prefix_length = t;
15349 }
15350 else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
15351 {
15352 eid_set = 1;
15353 eid_type = 1;
15354 prefix_length = t;
15355 }
15356 else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
15357 {
15358 eid_set = 1;
15359 eid_type = 2;
15360 }
15361 else if (unformat (i, "vni %d", &t))
15362 {
15363 vni = t;
15364 }
15365 else if (unformat (i, "local"))
15366 {
15367 filter = 1;
15368 }
15369 else if (unformat (i, "remote"))
15370 {
15371 filter = 2;
15372 }
15373 else
15374 {
15375 errmsg ("parse error '%U'", format_unformat_error, i);
15376 return -99;
15377 }
15378 }
15379
15380 if (!vam->json_output)
15381 {
15382 print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
15383 "type", "ls_index", "ttl", "authoritative", "key_id", "key");
15384 }
15385
Filip Tehlar694396d2017-02-17 14:29:11 +010015386 M (ONE_EID_TABLE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015387
15388 mp->filter = filter;
15389 if (eid_set)
15390 {
15391 mp->eid_set = 1;
15392 mp->vni = htonl (vni);
15393 mp->eid_type = eid_type;
15394 switch (eid_type)
15395 {
15396 case 0:
15397 mp->prefix_length = prefix_length;
15398 clib_memcpy (mp->eid, &ip4, sizeof (ip4));
15399 break;
15400 case 1:
15401 mp->prefix_length = prefix_length;
15402 clib_memcpy (mp->eid, &ip6, sizeof (ip6));
15403 break;
15404 case 2:
15405 clib_memcpy (mp->eid, mac, sizeof (mac));
15406 break;
15407 default:
15408 errmsg ("unknown EID type %d!", eid_type);
15409 return -99;
15410 }
15411 }
15412
15413 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015414 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015415
15416 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060015417 M (CONTROL_PING, mp_ping);
15418 S (mp_ping);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015419
15420 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060015421 W (ret);
15422 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015423}
15424
Filip Tehlar694396d2017-02-17 14:29:11 +010015425#define api_lisp_eid_table_dump api_one_eid_table_dump
15426
Damjan Marion7cd468a2016-12-19 23:05:39 +010015427static int
Filip Tehlar5fae99c2017-01-18 12:57:37 +010015428api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
15429{
15430 unformat_input_t *i = vam->input;
Filip Tehlar82786c42017-02-20 15:20:37 +010015431 vl_api_gpe_fwd_entries_get_t *mp;
Filip Tehlar5fae99c2017-01-18 12:57:37 +010015432 u8 vni_set = 0;
15433 u32 vni = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015434 int ret;
Filip Tehlar5fae99c2017-01-18 12:57:37 +010015435
15436 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15437 {
15438 if (unformat (i, "vni %d", &vni))
15439 {
15440 vni_set = 1;
15441 }
15442 else
15443 {
15444 errmsg ("parse error '%U'", format_unformat_error, i);
15445 return -99;
15446 }
15447 }
15448
15449 if (!vni_set)
15450 {
15451 errmsg ("vni not set!");
15452 return -99;
15453 }
15454
15455 if (!vam->json_output)
15456 {
15457 print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
15458 "leid", "reid");
15459 }
15460
Filip Tehlar82786c42017-02-20 15:20:37 +010015461 M (GPE_FWD_ENTRIES_GET, mp);
Filip Tehlar5fae99c2017-01-18 12:57:37 +010015462 mp->vni = clib_host_to_net_u32 (vni);
15463
15464 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015465 S (mp);
Filip Tehlar5fae99c2017-01-18 12:57:37 +010015466
15467 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060015468 W (ret);
15469 return ret;
Filip Tehlar5fae99c2017-01-18 12:57:37 +010015470}
15471
Filip Tehlar82786c42017-02-20 15:20:37 +010015472#define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
15473#define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
15474#define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
15475#define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
Filip Tehlar5fae99c2017-01-18 12:57:37 +010015476
15477static int
Filip Tehlar694396d2017-02-17 14:29:11 +010015478api_one_adjacencies_get (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010015479{
15480 unformat_input_t *i = vam->input;
Filip Tehlar694396d2017-02-17 14:29:11 +010015481 vl_api_one_adjacencies_get_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015482 u8 vni_set = 0;
15483 u32 vni = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015484 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015485
15486 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15487 {
15488 if (unformat (i, "vni %d", &vni))
15489 {
15490 vni_set = 1;
15491 }
15492 else
15493 {
15494 errmsg ("parse error '%U'", format_unformat_error, i);
15495 return -99;
15496 }
15497 }
15498
15499 if (!vni_set)
15500 {
15501 errmsg ("vni not set!");
15502 return -99;
15503 }
15504
15505 if (!vam->json_output)
15506 {
15507 print (vam->ofp, "%s %40s", "leid", "reid");
15508 }
15509
Filip Tehlar694396d2017-02-17 14:29:11 +010015510 M (ONE_ADJACENCIES_GET, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015511 mp->vni = clib_host_to_net_u32 (vni);
15512
15513 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015514 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015515
15516 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060015517 W (ret);
15518 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015519}
15520
Filip Tehlar694396d2017-02-17 14:29:11 +010015521#define api_lisp_adjacencies_get api_one_adjacencies_get
15522
Damjan Marion7cd468a2016-12-19 23:05:39 +010015523static int
Filip Tehlar694396d2017-02-17 14:29:11 +010015524api_one_map_server_dump (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010015525{
Filip Tehlar694396d2017-02-17 14:29:11 +010015526 vl_api_one_map_server_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060015527 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015528 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015529
15530 if (!vam->json_output)
15531 {
15532 print (vam->ofp, "%=20s", "Map server");
15533 }
15534
Filip Tehlar694396d2017-02-17 14:29:11 +010015535 M (ONE_MAP_SERVER_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015536 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015537 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015538
15539 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060015540 M (CONTROL_PING, mp_ping);
15541 S (mp_ping);
15542
Damjan Marion7cd468a2016-12-19 23:05:39 +010015543 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060015544 W (ret);
15545 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015546}
15547
Filip Tehlar694396d2017-02-17 14:29:11 +010015548#define api_lisp_map_server_dump api_one_map_server_dump
15549
Damjan Marion7cd468a2016-12-19 23:05:39 +010015550static int
Filip Tehlar694396d2017-02-17 14:29:11 +010015551api_one_map_resolver_dump (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010015552{
Filip Tehlar694396d2017-02-17 14:29:11 +010015553 vl_api_one_map_resolver_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060015554 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015555 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015556
15557 if (!vam->json_output)
15558 {
15559 print (vam->ofp, "%=20s", "Map resolver");
15560 }
15561
Filip Tehlar694396d2017-02-17 14:29:11 +010015562 M (ONE_MAP_RESOLVER_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015563 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015564 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015565
15566 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060015567 M (CONTROL_PING, mp_ping);
15568 S (mp_ping);
15569
Damjan Marion7cd468a2016-12-19 23:05:39 +010015570 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060015571 W (ret);
15572 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015573}
15574
Filip Tehlar694396d2017-02-17 14:29:11 +010015575#define api_lisp_map_resolver_dump api_one_map_resolver_dump
15576
Damjan Marion7cd468a2016-12-19 23:05:39 +010015577static int
Filip Tehlar694396d2017-02-17 14:29:11 +010015578api_show_one_status (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010015579{
Filip Tehlar694396d2017-02-17 14:29:11 +010015580 vl_api_show_one_status_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015581 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015582
15583 if (!vam->json_output)
15584 {
Filip Tehlar694396d2017-02-17 14:29:11 +010015585 print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
Damjan Marion7cd468a2016-12-19 23:05:39 +010015586 }
15587
Filip Tehlar694396d2017-02-17 14:29:11 +010015588 M (SHOW_ONE_STATUS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015589 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015590 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015591 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060015592 W (ret);
15593 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015594}
15595
Filip Tehlar694396d2017-02-17 14:29:11 +010015596#define api_show_lisp_status api_show_one_status
15597
Damjan Marion7cd468a2016-12-19 23:05:39 +010015598static int
Filip Tehlar5fae99c2017-01-18 12:57:37 +010015599api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
15600{
Filip Tehlar82786c42017-02-20 15:20:37 +010015601 vl_api_gpe_fwd_entry_path_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060015602 vl_api_control_ping_t *mp_ping;
Filip Tehlar5fae99c2017-01-18 12:57:37 +010015603 unformat_input_t *i = vam->input;
15604 u32 fwd_entry_index = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015605 int ret;
Filip Tehlar5fae99c2017-01-18 12:57:37 +010015606
15607 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15608 {
15609 if (unformat (i, "index %d", &fwd_entry_index))
15610 ;
15611 else
15612 break;
15613 }
15614
15615 if (~0 == fwd_entry_index)
15616 {
15617 errmsg ("no index specified!");
15618 return -99;
15619 }
15620
15621 if (!vam->json_output)
15622 {
15623 print (vam->ofp, "first line");
15624 }
15625
Filip Tehlar82786c42017-02-20 15:20:37 +010015626 M (GPE_FWD_ENTRY_PATH_DUMP, mp);
Filip Tehlar5fae99c2017-01-18 12:57:37 +010015627
15628 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015629 S (mp);
Filip Tehlar5fae99c2017-01-18 12:57:37 +010015630 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060015631 M (CONTROL_PING, mp_ping);
15632 S (mp_ping);
15633
Filip Tehlar5fae99c2017-01-18 12:57:37 +010015634 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060015635 W (ret);
15636 return ret;
Filip Tehlar5fae99c2017-01-18 12:57:37 +010015637}
15638
15639static int
Filip Tehlar694396d2017-02-17 14:29:11 +010015640api_one_get_map_request_itr_rlocs (vat_main_t * vam)
Damjan Marion7cd468a2016-12-19 23:05:39 +010015641{
Filip Tehlar694396d2017-02-17 14:29:11 +010015642 vl_api_one_get_map_request_itr_rlocs_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015643 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015644
15645 if (!vam->json_output)
15646 {
15647 print (vam->ofp, "%=20s", "itr-rlocs:");
15648 }
15649
Filip Tehlar694396d2017-02-17 14:29:11 +010015650 M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015651 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015652 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015653 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060015654 W (ret);
15655 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015656}
15657
Filip Tehlar694396d2017-02-17 14:29:11 +010015658#define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
15659
Damjan Marion7cd468a2016-12-19 23:05:39 +010015660static int
15661api_af_packet_create (vat_main_t * vam)
15662{
15663 unformat_input_t *i = vam->input;
15664 vl_api_af_packet_create_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015665 u8 *host_if_name = 0;
15666 u8 hw_addr[6];
15667 u8 random_hw_addr = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015668 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015669
15670 memset (hw_addr, 0, sizeof (hw_addr));
15671
15672 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15673 {
15674 if (unformat (i, "name %s", &host_if_name))
15675 vec_add1 (host_if_name, 0);
15676 else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15677 random_hw_addr = 0;
15678 else
15679 break;
15680 }
15681
15682 if (!vec_len (host_if_name))
15683 {
15684 errmsg ("host-interface name must be specified");
15685 return -99;
15686 }
15687
15688 if (vec_len (host_if_name) > 64)
15689 {
15690 errmsg ("host-interface name too long");
15691 return -99;
15692 }
15693
Jon Loeliger8a2aea32017-01-31 13:19:40 -060015694 M (AF_PACKET_CREATE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015695
15696 clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
15697 clib_memcpy (mp->hw_addr, hw_addr, 6);
15698 mp->use_random_hw_addr = random_hw_addr;
15699 vec_free (host_if_name);
15700
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015701 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060015702 W2 (ret, fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
15703 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015704}
15705
15706static int
15707api_af_packet_delete (vat_main_t * vam)
15708{
15709 unformat_input_t *i = vam->input;
15710 vl_api_af_packet_delete_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015711 u8 *host_if_name = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015712 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015713
15714 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15715 {
15716 if (unformat (i, "name %s", &host_if_name))
15717 vec_add1 (host_if_name, 0);
15718 else
15719 break;
15720 }
15721
15722 if (!vec_len (host_if_name))
15723 {
15724 errmsg ("host-interface name must be specified");
15725 return -99;
15726 }
15727
15728 if (vec_len (host_if_name) > 64)
15729 {
15730 errmsg ("host-interface name too long");
15731 return -99;
15732 }
15733
Jon Loeliger8a2aea32017-01-31 13:19:40 -060015734 M (AF_PACKET_DELETE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015735
15736 clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
15737 vec_free (host_if_name);
15738
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015739 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060015740 W (ret);
15741 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015742}
15743
15744static int
15745api_policer_add_del (vat_main_t * vam)
15746{
15747 unformat_input_t *i = vam->input;
15748 vl_api_policer_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015749 u8 is_add = 1;
15750 u8 *name = 0;
15751 u32 cir = 0;
15752 u32 eir = 0;
15753 u64 cb = 0;
15754 u64 eb = 0;
15755 u8 rate_type = 0;
15756 u8 round_type = 0;
15757 u8 type = 0;
15758 u8 color_aware = 0;
15759 sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015760 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015761
15762 conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
15763 conform_action.dscp = 0;
15764 exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
15765 exceed_action.dscp = 0;
15766 violate_action.action_type = SSE2_QOS_ACTION_DROP;
15767 violate_action.dscp = 0;
15768
15769 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15770 {
15771 if (unformat (i, "del"))
15772 is_add = 0;
15773 else if (unformat (i, "name %s", &name))
15774 vec_add1 (name, 0);
15775 else if (unformat (i, "cir %u", &cir))
15776 ;
15777 else if (unformat (i, "eir %u", &eir))
15778 ;
15779 else if (unformat (i, "cb %u", &cb))
15780 ;
15781 else if (unformat (i, "eb %u", &eb))
15782 ;
15783 else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
15784 &rate_type))
15785 ;
15786 else if (unformat (i, "round_type %U", unformat_policer_round_type,
15787 &round_type))
15788 ;
15789 else if (unformat (i, "type %U", unformat_policer_type, &type))
15790 ;
15791 else if (unformat (i, "conform_action %U", unformat_policer_action_type,
15792 &conform_action))
15793 ;
15794 else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
15795 &exceed_action))
15796 ;
15797 else if (unformat (i, "violate_action %U", unformat_policer_action_type,
15798 &violate_action))
15799 ;
15800 else if (unformat (i, "color-aware"))
15801 color_aware = 1;
15802 else
15803 break;
15804 }
15805
15806 if (!vec_len (name))
15807 {
15808 errmsg ("policer name must be specified");
15809 return -99;
15810 }
15811
15812 if (vec_len (name) > 64)
15813 {
15814 errmsg ("policer name too long");
15815 return -99;
15816 }
15817
Jon Loeliger8a2aea32017-01-31 13:19:40 -060015818 M (POLICER_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015819
15820 clib_memcpy (mp->name, name, vec_len (name));
15821 vec_free (name);
15822 mp->is_add = is_add;
15823 mp->cir = cir;
15824 mp->eir = eir;
15825 mp->cb = cb;
15826 mp->eb = eb;
15827 mp->rate_type = rate_type;
15828 mp->round_type = round_type;
15829 mp->type = type;
15830 mp->conform_action_type = conform_action.action_type;
15831 mp->conform_dscp = conform_action.dscp;
15832 mp->exceed_action_type = exceed_action.action_type;
15833 mp->exceed_dscp = exceed_action.dscp;
15834 mp->violate_action_type = violate_action.action_type;
15835 mp->violate_dscp = violate_action.dscp;
15836 mp->color_aware = color_aware;
15837
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015838 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060015839 W (ret);
15840 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015841}
15842
15843static int
15844api_policer_dump (vat_main_t * vam)
15845{
15846 unformat_input_t *i = vam->input;
15847 vl_api_policer_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060015848 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015849 u8 *match_name = 0;
15850 u8 match_name_valid = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015851 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015852
15853 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15854 {
15855 if (unformat (i, "name %s", &match_name))
15856 {
15857 vec_add1 (match_name, 0);
15858 match_name_valid = 1;
15859 }
15860 else
15861 break;
15862 }
15863
Jon Loeliger8a2aea32017-01-31 13:19:40 -060015864 M (POLICER_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015865 mp->match_name_valid = match_name_valid;
15866 clib_memcpy (mp->match_name, match_name, vec_len (match_name));
15867 vec_free (match_name);
15868 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015869 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015870
15871 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060015872 M (CONTROL_PING, mp_ping);
15873 S (mp_ping);
15874
Damjan Marion7cd468a2016-12-19 23:05:39 +010015875 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060015876 W (ret);
15877 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015878}
15879
15880static int
15881api_policer_classify_set_interface (vat_main_t * vam)
15882{
15883 unformat_input_t *i = vam->input;
15884 vl_api_policer_classify_set_interface_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015885 u32 sw_if_index;
15886 int sw_if_index_set;
15887 u32 ip4_table_index = ~0;
15888 u32 ip6_table_index = ~0;
15889 u32 l2_table_index = ~0;
15890 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015891 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015892
15893 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15894 {
15895 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15896 sw_if_index_set = 1;
15897 else if (unformat (i, "sw_if_index %d", &sw_if_index))
15898 sw_if_index_set = 1;
15899 else if (unformat (i, "del"))
15900 is_add = 0;
15901 else if (unformat (i, "ip4-table %d", &ip4_table_index))
15902 ;
15903 else if (unformat (i, "ip6-table %d", &ip6_table_index))
15904 ;
15905 else if (unformat (i, "l2-table %d", &l2_table_index))
15906 ;
15907 else
15908 {
15909 clib_warning ("parse error '%U'", format_unformat_error, i);
15910 return -99;
15911 }
15912 }
15913
15914 if (sw_if_index_set == 0)
15915 {
15916 errmsg ("missing interface name or sw_if_index");
15917 return -99;
15918 }
15919
Jon Loeliger8a2aea32017-01-31 13:19:40 -060015920 M (POLICER_CLASSIFY_SET_INTERFACE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015921
15922 mp->sw_if_index = ntohl (sw_if_index);
15923 mp->ip4_table_index = ntohl (ip4_table_index);
15924 mp->ip6_table_index = ntohl (ip6_table_index);
15925 mp->l2_table_index = ntohl (l2_table_index);
15926 mp->is_add = is_add;
15927
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015928 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060015929 W (ret);
15930 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015931}
15932
15933static int
15934api_policer_classify_dump (vat_main_t * vam)
15935{
15936 unformat_input_t *i = vam->input;
15937 vl_api_policer_classify_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060015938 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015939 u8 type = POLICER_CLASSIFY_N_TABLES;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015940 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015941
15942 if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
15943 ;
15944 else
15945 {
15946 errmsg ("classify table type must be specified");
15947 return -99;
15948 }
15949
15950 if (!vam->json_output)
15951 {
15952 print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
15953 }
15954
Jon Loeliger8a2aea32017-01-31 13:19:40 -060015955 M (POLICER_CLASSIFY_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015956 mp->type = type;
15957 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015958 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015959
15960 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060015961 M (CONTROL_PING, mp_ping);
15962 S (mp_ping);
15963
Damjan Marion7cd468a2016-12-19 23:05:39 +010015964 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060015965 W (ret);
15966 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015967}
15968
15969static int
15970api_netmap_create (vat_main_t * vam)
15971{
15972 unformat_input_t *i = vam->input;
15973 vl_api_netmap_create_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015974 u8 *if_name = 0;
15975 u8 hw_addr[6];
15976 u8 random_hw_addr = 1;
15977 u8 is_pipe = 0;
15978 u8 is_master = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015979 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015980
15981 memset (hw_addr, 0, sizeof (hw_addr));
15982
15983 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15984 {
15985 if (unformat (i, "name %s", &if_name))
15986 vec_add1 (if_name, 0);
15987 else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15988 random_hw_addr = 0;
15989 else if (unformat (i, "pipe"))
15990 is_pipe = 1;
15991 else if (unformat (i, "master"))
15992 is_master = 1;
15993 else if (unformat (i, "slave"))
15994 is_master = 0;
15995 else
15996 break;
15997 }
15998
15999 if (!vec_len (if_name))
16000 {
16001 errmsg ("interface name must be specified");
16002 return -99;
16003 }
16004
16005 if (vec_len (if_name) > 64)
16006 {
16007 errmsg ("interface name too long");
16008 return -99;
16009 }
16010
Jon Loeliger8a2aea32017-01-31 13:19:40 -060016011 M (NETMAP_CREATE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016012
16013 clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
16014 clib_memcpy (mp->hw_addr, hw_addr, 6);
16015 mp->use_random_hw_addr = random_hw_addr;
16016 mp->is_pipe = is_pipe;
16017 mp->is_master = is_master;
16018 vec_free (if_name);
16019
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016020 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060016021 W (ret);
16022 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016023}
16024
16025static int
16026api_netmap_delete (vat_main_t * vam)
16027{
16028 unformat_input_t *i = vam->input;
16029 vl_api_netmap_delete_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016030 u8 *if_name = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016031 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016032
16033 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16034 {
16035 if (unformat (i, "name %s", &if_name))
16036 vec_add1 (if_name, 0);
16037 else
16038 break;
16039 }
16040
16041 if (!vec_len (if_name))
16042 {
16043 errmsg ("interface name must be specified");
16044 return -99;
16045 }
16046
16047 if (vec_len (if_name) > 64)
16048 {
16049 errmsg ("interface name too long");
16050 return -99;
16051 }
16052
Jon Loeliger8a2aea32017-01-31 13:19:40 -060016053 M (NETMAP_DELETE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016054
16055 clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
16056 vec_free (if_name);
16057
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016058 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060016059 W (ret);
16060 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016061}
16062
16063static void vl_api_mpls_tunnel_details_t_handler
16064 (vl_api_mpls_tunnel_details_t * mp)
16065{
16066 vat_main_t *vam = &vat_main;
16067 i32 len = mp->mt_next_hop_n_labels;
16068 i32 i;
16069
16070 print (vam->ofp, "[%d]: via %U %d labels ",
16071 mp->tunnel_index,
16072 format_ip4_address, mp->mt_next_hop,
16073 ntohl (mp->mt_next_hop_sw_if_index));
16074 for (i = 0; i < len; i++)
16075 {
16076 print (vam->ofp, "%u ", ntohl (mp->mt_next_hop_out_labels[i]));
16077 }
16078 print (vam->ofp, "");
16079}
16080
16081static void vl_api_mpls_tunnel_details_t_handler_json
16082 (vl_api_mpls_tunnel_details_t * mp)
16083{
16084 vat_main_t *vam = &vat_main;
16085 vat_json_node_t *node = NULL;
16086 struct in_addr ip4;
16087 i32 i;
16088 i32 len = mp->mt_next_hop_n_labels;
16089
16090 if (VAT_JSON_ARRAY != vam->json_tree.type)
16091 {
16092 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16093 vat_json_init_array (&vam->json_tree);
16094 }
16095 node = vat_json_array_add (&vam->json_tree);
16096
16097 vat_json_init_object (node);
16098 vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
16099 clib_memcpy (&ip4, &(mp->mt_next_hop), sizeof (ip4));
16100 vat_json_object_add_ip4 (node, "next_hop", ip4);
16101 vat_json_object_add_uint (node, "next_hop_sw_if_index",
16102 ntohl (mp->mt_next_hop_sw_if_index));
16103 vat_json_object_add_uint (node, "l2_only", ntohl (mp->mt_l2_only));
16104 vat_json_object_add_uint (node, "label_count", len);
16105 for (i = 0; i < len; i++)
16106 {
16107 vat_json_object_add_uint (node, "label",
16108 ntohl (mp->mt_next_hop_out_labels[i]));
16109 }
16110}
16111
16112static int
16113api_mpls_tunnel_dump (vat_main_t * vam)
16114{
16115 vl_api_mpls_tunnel_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016116 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016117 i32 index = -1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016118 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016119
16120 /* Parse args required to build the message */
16121 while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
16122 {
16123 if (!unformat (vam->input, "tunnel_index %d", &index))
16124 {
16125 index = -1;
16126 break;
16127 }
16128 }
16129
16130 print (vam->ofp, " tunnel_index %d", index);
16131
Jon Loeliger8a2aea32017-01-31 13:19:40 -060016132 M (MPLS_TUNNEL_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016133 mp->tunnel_index = htonl (index);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016134 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016135
16136 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016137 M (CONTROL_PING, mp_ping);
16138 S (mp_ping);
16139
Jon Loeliger56c7b012017-02-01 12:31:41 -060016140 W (ret);
16141 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016142}
16143
16144#define vl_api_mpls_fib_details_t_endian vl_noop_handler
16145#define vl_api_mpls_fib_details_t_print vl_noop_handler
16146
16147static void
16148vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
16149{
16150 vat_main_t *vam = &vat_main;
16151 int count = ntohl (mp->count);
16152 vl_api_fib_path2_t *fp;
16153 int i;
16154
16155 print (vam->ofp,
16156 "table-id %d, label %u, ess_bit %u",
16157 ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
16158 fp = mp->path;
16159 for (i = 0; i < count; i++)
16160 {
16161 if (fp->afi == IP46_TYPE_IP6)
16162 print (vam->ofp,
16163 " weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16164 "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16165 ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16166 fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16167 format_ip6_address, fp->next_hop);
16168 else if (fp->afi == IP46_TYPE_IP4)
16169 print (vam->ofp,
16170 " weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16171 "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16172 ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16173 fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16174 format_ip4_address, fp->next_hop);
16175 fp++;
16176 }
16177}
16178
16179static void vl_api_mpls_fib_details_t_handler_json
16180 (vl_api_mpls_fib_details_t * mp)
16181{
16182 vat_main_t *vam = &vat_main;
16183 int count = ntohl (mp->count);
16184 vat_json_node_t *node = NULL;
16185 struct in_addr ip4;
16186 struct in6_addr ip6;
16187 vl_api_fib_path2_t *fp;
16188 int i;
16189
16190 if (VAT_JSON_ARRAY != vam->json_tree.type)
16191 {
16192 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16193 vat_json_init_array (&vam->json_tree);
16194 }
16195 node = vat_json_array_add (&vam->json_tree);
16196
16197 vat_json_init_object (node);
16198 vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16199 vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
16200 vat_json_object_add_uint (node, "label", ntohl (mp->label));
16201 vat_json_object_add_uint (node, "path_count", count);
16202 fp = mp->path;
16203 for (i = 0; i < count; i++)
16204 {
16205 vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16206 vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16207 vat_json_object_add_uint (node, "is_local", fp->is_local);
16208 vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16209 vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16210 vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16211 vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16212 if (fp->afi == IP46_TYPE_IP4)
16213 {
16214 clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16215 vat_json_object_add_ip4 (node, "next_hop", ip4);
16216 }
16217 else if (fp->afi == IP46_TYPE_IP6)
16218 {
16219 clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16220 vat_json_object_add_ip6 (node, "next_hop", ip6);
16221 }
16222 }
16223}
16224
16225static int
16226api_mpls_fib_dump (vat_main_t * vam)
16227{
16228 vl_api_mpls_fib_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016229 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016230 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016231
Jon Loeliger8a2aea32017-01-31 13:19:40 -060016232 M (MPLS_FIB_DUMP, mp);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016233 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016234
16235 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016236 M (CONTROL_PING, mp_ping);
16237 S (mp_ping);
16238
Jon Loeliger56c7b012017-02-01 12:31:41 -060016239 W (ret);
16240 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016241}
16242
16243#define vl_api_ip_fib_details_t_endian vl_noop_handler
16244#define vl_api_ip_fib_details_t_print vl_noop_handler
16245
16246static void
16247vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
16248{
16249 vat_main_t *vam = &vat_main;
16250 int count = ntohl (mp->count);
16251 vl_api_fib_path_t *fp;
16252 int i;
16253
16254 print (vam->ofp,
16255 "table-id %d, prefix %U/%d",
16256 ntohl (mp->table_id), format_ip4_address, mp->address,
16257 mp->address_length);
16258 fp = mp->path;
16259 for (i = 0; i < count; i++)
16260 {
16261 if (fp->afi == IP46_TYPE_IP6)
16262 print (vam->ofp,
16263 " weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16264 "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16265 ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16266 fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16267 format_ip6_address, fp->next_hop);
16268 else if (fp->afi == IP46_TYPE_IP4)
16269 print (vam->ofp,
16270 " weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16271 "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16272 ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16273 fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16274 format_ip4_address, fp->next_hop);
16275 fp++;
16276 }
16277}
16278
16279static void vl_api_ip_fib_details_t_handler_json
16280 (vl_api_ip_fib_details_t * mp)
16281{
16282 vat_main_t *vam = &vat_main;
16283 int count = ntohl (mp->count);
16284 vat_json_node_t *node = NULL;
16285 struct in_addr ip4;
16286 struct in6_addr ip6;
16287 vl_api_fib_path_t *fp;
16288 int i;
16289
16290 if (VAT_JSON_ARRAY != vam->json_tree.type)
16291 {
16292 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16293 vat_json_init_array (&vam->json_tree);
16294 }
16295 node = vat_json_array_add (&vam->json_tree);
16296
16297 vat_json_init_object (node);
16298 vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16299 clib_memcpy (&ip4, &mp->address, sizeof (ip4));
16300 vat_json_object_add_ip4 (node, "prefix", ip4);
16301 vat_json_object_add_uint (node, "mask_length", mp->address_length);
16302 vat_json_object_add_uint (node, "path_count", count);
16303 fp = mp->path;
16304 for (i = 0; i < count; i++)
16305 {
16306 vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16307 vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16308 vat_json_object_add_uint (node, "is_local", fp->is_local);
16309 vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16310 vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16311 vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16312 vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16313 if (fp->afi == IP46_TYPE_IP4)
16314 {
16315 clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16316 vat_json_object_add_ip4 (node, "next_hop", ip4);
16317 }
16318 else if (fp->afi == IP46_TYPE_IP6)
16319 {
16320 clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16321 vat_json_object_add_ip6 (node, "next_hop", ip6);
16322 }
16323 }
16324}
16325
16326static int
16327api_ip_fib_dump (vat_main_t * vam)
16328{
16329 vl_api_ip_fib_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016330 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016331 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016332
Jon Loeliger8a2aea32017-01-31 13:19:40 -060016333 M (IP_FIB_DUMP, mp);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016334 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016335
16336 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016337 M (CONTROL_PING, mp_ping);
16338 S (mp_ping);
16339
Jon Loeliger56c7b012017-02-01 12:31:41 -060016340 W (ret);
16341 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016342}
16343
Neale Ranns5a8123b2017-01-26 01:18:23 -080016344static int
16345api_ip_mfib_dump (vat_main_t * vam)
16346{
16347 vl_api_ip_mfib_dump_t *mp;
16348 vl_api_control_ping_t *mp_ping;
16349 int ret;
16350
16351 M (IP_MFIB_DUMP, mp);
16352 S (mp);
16353
16354 /* Use a control ping for synchronization */
16355 M (CONTROL_PING, mp_ping);
16356 S (mp_ping);
16357
16358 W (ret);
16359 return ret;
16360}
16361
Damjan Marion7cd468a2016-12-19 23:05:39 +010016362static void vl_api_ip_neighbor_details_t_handler
16363 (vl_api_ip_neighbor_details_t * mp)
16364{
16365 vat_main_t *vam = &vat_main;
16366
16367 print (vam->ofp, "%c %U %U",
16368 (mp->is_static) ? 'S' : 'D',
16369 format_ethernet_address, &mp->mac_address,
16370 (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
16371 &mp->ip_address);
16372}
16373
16374static void vl_api_ip_neighbor_details_t_handler_json
16375 (vl_api_ip_neighbor_details_t * mp)
16376{
16377
16378 vat_main_t *vam = &vat_main;
16379 vat_json_node_t *node;
16380 struct in_addr ip4;
16381 struct in6_addr ip6;
16382
16383 if (VAT_JSON_ARRAY != vam->json_tree.type)
16384 {
16385 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16386 vat_json_init_array (&vam->json_tree);
16387 }
16388 node = vat_json_array_add (&vam->json_tree);
16389
16390 vat_json_init_object (node);
16391 vat_json_object_add_string_copy (node, "flag",
16392 (mp->is_static) ? (u8 *) "static" : (u8 *)
16393 "dynamic");
16394
16395 vat_json_object_add_string_copy (node, "link_layer",
16396 format (0, "%U", format_ethernet_address,
16397 &mp->mac_address));
16398
16399 if (mp->is_ipv6)
16400 {
16401 clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
16402 vat_json_object_add_ip6 (node, "ip_address", ip6);
16403 }
16404 else
16405 {
16406 clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
16407 vat_json_object_add_ip4 (node, "ip_address", ip4);
16408 }
16409}
16410
16411static int
16412api_ip_neighbor_dump (vat_main_t * vam)
16413{
16414 unformat_input_t *i = vam->input;
16415 vl_api_ip_neighbor_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016416 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016417 u8 is_ipv6 = 0;
16418 u32 sw_if_index = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016419 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016420
16421 /* Parse args required to build the message */
16422 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16423 {
16424 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16425 ;
16426 else if (unformat (i, "sw_if_index %d", &sw_if_index))
16427 ;
16428 else if (unformat (i, "ip6"))
16429 is_ipv6 = 1;
16430 else
16431 break;
16432 }
16433
16434 if (sw_if_index == ~0)
16435 {
16436 errmsg ("missing interface name or sw_if_index");
16437 return -99;
16438 }
16439
Jon Loeliger8a2aea32017-01-31 13:19:40 -060016440 M (IP_NEIGHBOR_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016441 mp->is_ipv6 = (u8) is_ipv6;
16442 mp->sw_if_index = ntohl (sw_if_index);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016443 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016444
16445 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016446 M (CONTROL_PING, mp_ping);
16447 S (mp_ping);
16448
Jon Loeliger56c7b012017-02-01 12:31:41 -060016449 W (ret);
16450 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016451}
16452
16453#define vl_api_ip6_fib_details_t_endian vl_noop_handler
16454#define vl_api_ip6_fib_details_t_print vl_noop_handler
16455
16456static void
16457vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
16458{
16459 vat_main_t *vam = &vat_main;
16460 int count = ntohl (mp->count);
16461 vl_api_fib_path_t *fp;
16462 int i;
16463
16464 print (vam->ofp,
16465 "table-id %d, prefix %U/%d",
16466 ntohl (mp->table_id), format_ip6_address, mp->address,
16467 mp->address_length);
16468 fp = mp->path;
16469 for (i = 0; i < count; i++)
16470 {
16471 if (fp->afi == IP46_TYPE_IP6)
16472 print (vam->ofp,
16473 " weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16474 "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16475 ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16476 fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16477 format_ip6_address, fp->next_hop);
16478 else if (fp->afi == IP46_TYPE_IP4)
16479 print (vam->ofp,
16480 " weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16481 "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16482 ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16483 fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16484 format_ip4_address, fp->next_hop);
16485 fp++;
16486 }
16487}
16488
16489static void vl_api_ip6_fib_details_t_handler_json
16490 (vl_api_ip6_fib_details_t * mp)
16491{
16492 vat_main_t *vam = &vat_main;
16493 int count = ntohl (mp->count);
16494 vat_json_node_t *node = NULL;
16495 struct in_addr ip4;
16496 struct in6_addr ip6;
16497 vl_api_fib_path_t *fp;
16498 int i;
16499
16500 if (VAT_JSON_ARRAY != vam->json_tree.type)
16501 {
16502 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16503 vat_json_init_array (&vam->json_tree);
16504 }
16505 node = vat_json_array_add (&vam->json_tree);
16506
16507 vat_json_init_object (node);
16508 vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16509 clib_memcpy (&ip6, &mp->address, sizeof (ip6));
16510 vat_json_object_add_ip6 (node, "prefix", ip6);
16511 vat_json_object_add_uint (node, "mask_length", mp->address_length);
16512 vat_json_object_add_uint (node, "path_count", count);
16513 fp = mp->path;
16514 for (i = 0; i < count; i++)
16515 {
16516 vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16517 vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16518 vat_json_object_add_uint (node, "is_local", fp->is_local);
16519 vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16520 vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16521 vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16522 vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16523 if (fp->afi == IP46_TYPE_IP4)
16524 {
16525 clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16526 vat_json_object_add_ip4 (node, "next_hop", ip4);
16527 }
16528 else if (fp->afi == IP46_TYPE_IP6)
16529 {
16530 clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16531 vat_json_object_add_ip6 (node, "next_hop", ip6);
16532 }
16533 }
16534}
16535
16536static int
16537api_ip6_fib_dump (vat_main_t * vam)
16538{
16539 vl_api_ip6_fib_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016540 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016541 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016542
Jon Loeliger8a2aea32017-01-31 13:19:40 -060016543 M (IP6_FIB_DUMP, mp);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016544 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016545
16546 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016547 M (CONTROL_PING, mp_ping);
16548 S (mp_ping);
16549
Jon Loeliger56c7b012017-02-01 12:31:41 -060016550 W (ret);
16551 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016552}
16553
Neale Ranns5a8123b2017-01-26 01:18:23 -080016554static int
16555api_ip6_mfib_dump (vat_main_t * vam)
16556{
16557 vl_api_ip6_mfib_dump_t *mp;
16558 vl_api_control_ping_t *mp_ping;
16559 int ret;
16560
16561 M (IP6_MFIB_DUMP, mp);
16562 S (mp);
16563
16564 /* Use a control ping for synchronization */
16565 M (CONTROL_PING, mp_ping);
16566 S (mp_ping);
16567
16568 W (ret);
16569 return ret;
16570}
16571
Damjan Marion7cd468a2016-12-19 23:05:39 +010016572int
16573api_classify_table_ids (vat_main_t * vam)
16574{
16575 vl_api_classify_table_ids_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016576 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016577
16578 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060016579 M (CLASSIFY_TABLE_IDS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016580 mp->context = 0;
16581
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016582 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060016583 W (ret);
16584 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016585}
16586
16587int
16588api_classify_table_by_interface (vat_main_t * vam)
16589{
16590 unformat_input_t *input = vam->input;
16591 vl_api_classify_table_by_interface_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016592
16593 u32 sw_if_index = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016594 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016595 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16596 {
16597 if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16598 ;
16599 else if (unformat (input, "sw_if_index %d", &sw_if_index))
16600 ;
16601 else
16602 break;
16603 }
16604 if (sw_if_index == ~0)
16605 {
16606 errmsg ("missing interface name or sw_if_index");
16607 return -99;
16608 }
16609
16610 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060016611 M (CLASSIFY_TABLE_BY_INTERFACE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016612 mp->context = 0;
16613 mp->sw_if_index = ntohl (sw_if_index);
16614
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016615 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060016616 W (ret);
16617 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016618}
16619
16620int
16621api_classify_table_info (vat_main_t * vam)
16622{
16623 unformat_input_t *input = vam->input;
16624 vl_api_classify_table_info_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016625
16626 u32 table_id = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016627 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016628 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16629 {
16630 if (unformat (input, "table_id %d", &table_id))
16631 ;
16632 else
16633 break;
16634 }
16635 if (table_id == ~0)
16636 {
16637 errmsg ("missing table id");
16638 return -99;
16639 }
16640
16641 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060016642 M (CLASSIFY_TABLE_INFO, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016643 mp->context = 0;
16644 mp->table_id = ntohl (table_id);
16645
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016646 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060016647 W (ret);
16648 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016649}
16650
16651int
16652api_classify_session_dump (vat_main_t * vam)
16653{
16654 unformat_input_t *input = vam->input;
16655 vl_api_classify_session_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016656 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016657
16658 u32 table_id = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016659 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016660 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16661 {
16662 if (unformat (input, "table_id %d", &table_id))
16663 ;
16664 else
16665 break;
16666 }
16667 if (table_id == ~0)
16668 {
16669 errmsg ("missing table id");
16670 return -99;
16671 }
16672
16673 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060016674 M (CLASSIFY_SESSION_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016675 mp->context = 0;
16676 mp->table_id = ntohl (table_id);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016677 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016678
16679 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016680 M (CONTROL_PING, mp_ping);
16681 S (mp_ping);
16682
Jon Loeliger56c7b012017-02-01 12:31:41 -060016683 W (ret);
16684 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016685}
16686
16687static void
16688vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
16689{
16690 vat_main_t *vam = &vat_main;
16691
16692 print (vam->ofp, "collector_address %U, collector_port %d, "
16693 "src_address %U, vrf_id %d, path_mtu %u, "
16694 "template_interval %u, udp_checksum %d",
16695 format_ip4_address, mp->collector_address,
16696 ntohs (mp->collector_port),
16697 format_ip4_address, mp->src_address,
16698 ntohl (mp->vrf_id), ntohl (mp->path_mtu),
16699 ntohl (mp->template_interval), mp->udp_checksum);
16700
16701 vam->retval = 0;
16702 vam->result_ready = 1;
16703}
16704
16705static void
16706 vl_api_ipfix_exporter_details_t_handler_json
16707 (vl_api_ipfix_exporter_details_t * mp)
16708{
16709 vat_main_t *vam = &vat_main;
16710 vat_json_node_t node;
16711 struct in_addr collector_address;
16712 struct in_addr src_address;
16713
16714 vat_json_init_object (&node);
16715 clib_memcpy (&collector_address, &mp->collector_address,
16716 sizeof (collector_address));
16717 vat_json_object_add_ip4 (&node, "collector_address", collector_address);
16718 vat_json_object_add_uint (&node, "collector_port",
16719 ntohs (mp->collector_port));
16720 clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
16721 vat_json_object_add_ip4 (&node, "src_address", src_address);
16722 vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
16723 vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
16724 vat_json_object_add_uint (&node, "template_interval",
16725 ntohl (mp->template_interval));
16726 vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
16727
16728 vat_json_print (vam->ofp, &node);
16729 vat_json_free (&node);
16730 vam->retval = 0;
16731 vam->result_ready = 1;
16732}
16733
16734int
16735api_ipfix_exporter_dump (vat_main_t * vam)
16736{
16737 vl_api_ipfix_exporter_dump_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016738 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016739
16740 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060016741 M (IPFIX_EXPORTER_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016742 mp->context = 0;
16743
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016744 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060016745 W (ret);
16746 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016747}
16748
16749static int
16750api_ipfix_classify_stream_dump (vat_main_t * vam)
16751{
16752 vl_api_ipfix_classify_stream_dump_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016753 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016754
16755 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060016756 M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016757 mp->context = 0;
16758
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016759 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060016760 W (ret);
16761 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016762 /* NOTREACHED */
16763 return 0;
16764}
16765
16766static void
16767 vl_api_ipfix_classify_stream_details_t_handler
16768 (vl_api_ipfix_classify_stream_details_t * mp)
16769{
16770 vat_main_t *vam = &vat_main;
16771 print (vam->ofp, "domain_id %d, src_port %d",
16772 ntohl (mp->domain_id), ntohs (mp->src_port));
16773 vam->retval = 0;
16774 vam->result_ready = 1;
16775}
16776
16777static void
16778 vl_api_ipfix_classify_stream_details_t_handler_json
16779 (vl_api_ipfix_classify_stream_details_t * mp)
16780{
16781 vat_main_t *vam = &vat_main;
16782 vat_json_node_t node;
16783
16784 vat_json_init_object (&node);
16785 vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
16786 vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
16787
16788 vat_json_print (vam->ofp, &node);
16789 vat_json_free (&node);
16790 vam->retval = 0;
16791 vam->result_ready = 1;
16792}
16793
16794static int
16795api_ipfix_classify_table_dump (vat_main_t * vam)
16796{
16797 vl_api_ipfix_classify_table_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016798 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016799 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016800
16801 if (!vam->json_output)
16802 {
16803 print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
16804 "transport_protocol");
16805 }
16806
16807 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060016808 M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016809
16810 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016811 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016812
16813 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016814 M (CONTROL_PING, mp_ping);
16815 S (mp_ping);
16816
Jon Loeliger56c7b012017-02-01 12:31:41 -060016817 W (ret);
16818 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016819}
16820
16821static void
16822 vl_api_ipfix_classify_table_details_t_handler
16823 (vl_api_ipfix_classify_table_details_t * mp)
16824{
16825 vat_main_t *vam = &vat_main;
16826 print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
16827 mp->transport_protocol);
16828}
16829
16830static void
16831 vl_api_ipfix_classify_table_details_t_handler_json
16832 (vl_api_ipfix_classify_table_details_t * mp)
16833{
16834 vat_json_node_t *node = NULL;
16835 vat_main_t *vam = &vat_main;
16836
16837 if (VAT_JSON_ARRAY != vam->json_tree.type)
16838 {
16839 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16840 vat_json_init_array (&vam->json_tree);
16841 }
16842
16843 node = vat_json_array_add (&vam->json_tree);
16844 vat_json_init_object (node);
16845
16846 vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
16847 vat_json_object_add_uint (node, "ip_version", mp->ip_version);
16848 vat_json_object_add_uint (node, "transport_protocol",
16849 mp->transport_protocol);
16850}
16851
16852static int
16853api_sw_interface_span_enable_disable (vat_main_t * vam)
16854{
16855 unformat_input_t *i = vam->input;
16856 vl_api_sw_interface_span_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016857 u32 src_sw_if_index = ~0;
16858 u32 dst_sw_if_index = ~0;
16859 u8 state = 3;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016860 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016861
16862 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16863 {
16864 if (unformat
16865 (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
16866 ;
16867 else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
16868 ;
16869 else
16870 if (unformat
16871 (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
16872 ;
16873 else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
16874 ;
16875 else if (unformat (i, "disable"))
16876 state = 0;
16877 else if (unformat (i, "rx"))
16878 state = 1;
16879 else if (unformat (i, "tx"))
16880 state = 2;
16881 else if (unformat (i, "both"))
16882 state = 3;
16883 else
16884 break;
16885 }
16886
Jon Loeliger8a2aea32017-01-31 13:19:40 -060016887 M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016888
16889 mp->sw_if_index_from = htonl (src_sw_if_index);
16890 mp->sw_if_index_to = htonl (dst_sw_if_index);
16891 mp->state = state;
16892
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016893 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060016894 W (ret);
16895 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016896}
16897
16898static void
16899vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
16900 * mp)
16901{
16902 vat_main_t *vam = &vat_main;
16903 u8 *sw_if_from_name = 0;
16904 u8 *sw_if_to_name = 0;
16905 u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16906 u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16907 char *states[] = { "none", "rx", "tx", "both" };
16908 hash_pair_t *p;
16909
16910 /* *INDENT-OFF* */
16911 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16912 ({
16913 if ((u32) p->value[0] == sw_if_index_from)
16914 {
16915 sw_if_from_name = (u8 *)(p->key);
16916 if (sw_if_to_name)
16917 break;
16918 }
16919 if ((u32) p->value[0] == sw_if_index_to)
16920 {
16921 sw_if_to_name = (u8 *)(p->key);
16922 if (sw_if_from_name)
16923 break;
16924 }
16925 }));
16926 /* *INDENT-ON* */
16927 print (vam->ofp, "%20s => %20s (%s)",
16928 sw_if_from_name, sw_if_to_name, states[mp->state]);
16929}
16930
16931static void
16932 vl_api_sw_interface_span_details_t_handler_json
16933 (vl_api_sw_interface_span_details_t * mp)
16934{
16935 vat_main_t *vam = &vat_main;
16936 vat_json_node_t *node = NULL;
16937 u8 *sw_if_from_name = 0;
16938 u8 *sw_if_to_name = 0;
16939 u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16940 u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16941 hash_pair_t *p;
16942
16943 /* *INDENT-OFF* */
16944 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16945 ({
16946 if ((u32) p->value[0] == sw_if_index_from)
16947 {
16948 sw_if_from_name = (u8 *)(p->key);
16949 if (sw_if_to_name)
16950 break;
16951 }
16952 if ((u32) p->value[0] == sw_if_index_to)
16953 {
16954 sw_if_to_name = (u8 *)(p->key);
16955 if (sw_if_from_name)
16956 break;
16957 }
16958 }));
16959 /* *INDENT-ON* */
16960
16961 if (VAT_JSON_ARRAY != vam->json_tree.type)
16962 {
16963 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16964 vat_json_init_array (&vam->json_tree);
16965 }
16966 node = vat_json_array_add (&vam->json_tree);
16967
16968 vat_json_init_object (node);
16969 vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
16970 vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
16971 vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
Neale Ranns05b2bf22017-01-30 06:44:58 -080016972 if (0 != sw_if_to_name)
16973 {
16974 vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
16975 }
Damjan Marion7cd468a2016-12-19 23:05:39 +010016976 vat_json_object_add_uint (node, "state", mp->state);
16977}
16978
16979static int
16980api_sw_interface_span_dump (vat_main_t * vam)
16981{
16982 vl_api_sw_interface_span_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016983 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016984 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016985
Jon Loeliger8a2aea32017-01-31 13:19:40 -060016986 M (SW_INTERFACE_SPAN_DUMP, mp);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016987 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016988
16989 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016990 M (CONTROL_PING, mp_ping);
16991 S (mp_ping);
16992
Jon Loeliger56c7b012017-02-01 12:31:41 -060016993 W (ret);
16994 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016995}
16996
16997int
16998api_pg_create_interface (vat_main_t * vam)
16999{
17000 unformat_input_t *input = vam->input;
17001 vl_api_pg_create_interface_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017002
17003 u32 if_id = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017004 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017005 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17006 {
17007 if (unformat (input, "if_id %d", &if_id))
17008 ;
17009 else
17010 break;
17011 }
17012 if (if_id == ~0)
17013 {
17014 errmsg ("missing pg interface index");
17015 return -99;
17016 }
17017
17018 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017019 M (PG_CREATE_INTERFACE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017020 mp->context = 0;
17021 mp->interface_id = ntohl (if_id);
17022
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017023 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060017024 W (ret);
17025 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017026}
17027
17028int
17029api_pg_capture (vat_main_t * vam)
17030{
17031 unformat_input_t *input = vam->input;
17032 vl_api_pg_capture_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017033
17034 u32 if_id = ~0;
17035 u8 enable = 1;
17036 u32 count = 1;
17037 u8 pcap_file_set = 0;
17038 u8 *pcap_file = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017039 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017040 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17041 {
17042 if (unformat (input, "if_id %d", &if_id))
17043 ;
17044 else if (unformat (input, "pcap %s", &pcap_file))
17045 pcap_file_set = 1;
17046 else if (unformat (input, "count %d", &count))
17047 ;
17048 else if (unformat (input, "disable"))
17049 enable = 0;
17050 else
17051 break;
17052 }
17053 if (if_id == ~0)
17054 {
17055 errmsg ("missing pg interface index");
17056 return -99;
17057 }
17058 if (pcap_file_set > 0)
17059 {
17060 if (vec_len (pcap_file) > 255)
17061 {
17062 errmsg ("pcap file name is too long");
17063 return -99;
17064 }
17065 }
17066
17067 u32 name_len = vec_len (pcap_file);
17068 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017069 M (PG_CAPTURE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017070 mp->context = 0;
17071 mp->interface_id = ntohl (if_id);
17072 mp->is_enabled = enable;
17073 mp->count = ntohl (count);
17074 mp->pcap_name_length = ntohl (name_len);
17075 if (pcap_file_set != 0)
17076 {
17077 clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
17078 }
17079 vec_free (pcap_file);
17080
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017081 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060017082 W (ret);
17083 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017084}
17085
17086int
17087api_pg_enable_disable (vat_main_t * vam)
17088{
17089 unformat_input_t *input = vam->input;
17090 vl_api_pg_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017091
17092 u8 enable = 1;
17093 u8 stream_name_set = 0;
17094 u8 *stream_name = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017095 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017096 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17097 {
17098 if (unformat (input, "stream %s", &stream_name))
17099 stream_name_set = 1;
17100 else if (unformat (input, "disable"))
17101 enable = 0;
17102 else
17103 break;
17104 }
17105
17106 if (stream_name_set > 0)
17107 {
17108 if (vec_len (stream_name) > 255)
17109 {
17110 errmsg ("stream name too long");
17111 return -99;
17112 }
17113 }
17114
17115 u32 name_len = vec_len (stream_name);
17116 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017117 M (PG_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017118 mp->context = 0;
17119 mp->is_enabled = enable;
17120 if (stream_name_set != 0)
17121 {
17122 mp->stream_name_length = ntohl (name_len);
17123 clib_memcpy (mp->stream_name, stream_name, name_len);
17124 }
17125 vec_free (stream_name);
17126
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017127 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060017128 W (ret);
17129 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017130}
17131
17132int
17133api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
17134{
17135 unformat_input_t *input = vam->input;
17136 vl_api_ip_source_and_port_range_check_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017137
17138 u16 *low_ports = 0;
17139 u16 *high_ports = 0;
17140 u16 this_low;
17141 u16 this_hi;
17142 ip4_address_t ip4_addr;
17143 ip6_address_t ip6_addr;
17144 u32 length;
17145 u32 tmp, tmp2;
17146 u8 prefix_set = 0;
17147 u32 vrf_id = ~0;
17148 u8 is_add = 1;
17149 u8 is_ipv6 = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017150 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017151
17152 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17153 {
17154 if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
17155 {
17156 prefix_set = 1;
17157 }
17158 else
17159 if (unformat
17160 (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
17161 {
17162 prefix_set = 1;
17163 is_ipv6 = 1;
17164 }
17165 else if (unformat (input, "vrf %d", &vrf_id))
17166 ;
17167 else if (unformat (input, "del"))
17168 is_add = 0;
17169 else if (unformat (input, "port %d", &tmp))
17170 {
17171 if (tmp == 0 || tmp > 65535)
17172 {
17173 errmsg ("port %d out of range", tmp);
17174 return -99;
17175 }
17176 this_low = tmp;
17177 this_hi = this_low + 1;
17178 vec_add1 (low_ports, this_low);
17179 vec_add1 (high_ports, this_hi);
17180 }
17181 else if (unformat (input, "range %d - %d", &tmp, &tmp2))
17182 {
17183 if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
17184 {
17185 errmsg ("incorrect range parameters");
17186 return -99;
17187 }
17188 this_low = tmp;
17189 /* Note: in debug CLI +1 is added to high before
17190 passing to real fn that does "the work"
17191 (ip_source_and_port_range_check_add_del).
17192 This fn is a wrapper around the binary API fn a
17193 control plane will call, which expects this increment
17194 to have occurred. Hence letting the binary API control
17195 plane fn do the increment for consistency between VAT
17196 and other control planes.
17197 */
17198 this_hi = tmp2;
17199 vec_add1 (low_ports, this_low);
17200 vec_add1 (high_ports, this_hi);
17201 }
17202 else
17203 break;
17204 }
17205
17206 if (prefix_set == 0)
17207 {
17208 errmsg ("<address>/<mask> not specified");
17209 return -99;
17210 }
17211
17212 if (vrf_id == ~0)
17213 {
17214 errmsg ("VRF ID required, not specified");
17215 return -99;
17216 }
17217
17218 if (vrf_id == 0)
17219 {
17220 errmsg
17221 ("VRF ID should not be default. Should be distinct VRF for this purpose.");
17222 return -99;
17223 }
17224
17225 if (vec_len (low_ports) == 0)
17226 {
17227 errmsg ("At least one port or port range required");
17228 return -99;
17229 }
17230
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017231 M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017232
17233 mp->is_add = is_add;
17234
17235 if (is_ipv6)
17236 {
17237 mp->is_ipv6 = 1;
17238 clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
17239 }
17240 else
17241 {
17242 mp->is_ipv6 = 0;
17243 clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
17244 }
17245
17246 mp->mask_length = length;
17247 mp->number_of_ranges = vec_len (low_ports);
17248
17249 clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
17250 vec_free (low_ports);
17251
17252 clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
17253 vec_free (high_ports);
17254
17255 mp->vrf_id = ntohl (vrf_id);
17256
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017257 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060017258 W (ret);
17259 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017260}
17261
17262int
17263api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
17264{
17265 unformat_input_t *input = vam->input;
17266 vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017267 u32 sw_if_index = ~0;
17268 int vrf_set = 0;
17269 u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
17270 u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
17271 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017272 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017273
17274 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17275 {
17276 if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17277 ;
17278 else if (unformat (input, "sw_if_index %d", &sw_if_index))
17279 ;
17280 else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
17281 vrf_set = 1;
17282 else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
17283 vrf_set = 1;
17284 else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
17285 vrf_set = 1;
17286 else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
17287 vrf_set = 1;
17288 else if (unformat (input, "del"))
17289 is_add = 0;
17290 else
17291 break;
17292 }
17293
17294 if (sw_if_index == ~0)
17295 {
17296 errmsg ("Interface required but not specified");
17297 return -99;
17298 }
17299
17300 if (vrf_set == 0)
17301 {
17302 errmsg ("VRF ID required but not specified");
17303 return -99;
17304 }
17305
17306 if (tcp_out_vrf_id == 0
17307 || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
17308 {
17309 errmsg
17310 ("VRF ID should not be default. Should be distinct VRF for this purpose.");
17311 return -99;
17312 }
17313
17314 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017315 M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017316
17317 mp->sw_if_index = ntohl (sw_if_index);
17318 mp->is_add = is_add;
17319 mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
17320 mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
17321 mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
17322 mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
17323
17324 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017325 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017326
17327 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060017328 W (ret);
17329 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017330}
17331
17332static int
17333api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
17334{
17335 unformat_input_t *i = vam->input;
17336 vl_api_ipsec_gre_add_del_tunnel_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017337 u32 local_sa_id = 0;
17338 u32 remote_sa_id = 0;
17339 ip4_address_t src_address;
17340 ip4_address_t dst_address;
17341 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017342 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017343
17344 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17345 {
17346 if (unformat (i, "local_sa %d", &local_sa_id))
17347 ;
17348 else if (unformat (i, "remote_sa %d", &remote_sa_id))
17349 ;
17350 else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
17351 ;
17352 else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
17353 ;
17354 else if (unformat (i, "del"))
17355 is_add = 0;
17356 else
17357 {
17358 clib_warning ("parse error '%U'", format_unformat_error, i);
17359 return -99;
17360 }
17361 }
17362
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017363 M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017364
17365 mp->local_sa_id = ntohl (local_sa_id);
17366 mp->remote_sa_id = ntohl (remote_sa_id);
17367 clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
17368 clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
17369 mp->is_add = is_add;
17370
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017371 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060017372 W (ret);
17373 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017374}
17375
17376static int
17377api_punt (vat_main_t * vam)
17378{
17379 unformat_input_t *i = vam->input;
17380 vl_api_punt_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017381 u32 ipv = ~0;
17382 u32 protocol = ~0;
17383 u32 port = ~0;
17384 int is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017385 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017386
17387 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17388 {
17389 if (unformat (i, "ip %d", &ipv))
17390 ;
17391 else if (unformat (i, "protocol %d", &protocol))
17392 ;
17393 else if (unformat (i, "port %d", &port))
17394 ;
17395 else if (unformat (i, "del"))
17396 is_add = 0;
17397 else
17398 {
17399 clib_warning ("parse error '%U'", format_unformat_error, i);
17400 return -99;
17401 }
17402 }
17403
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017404 M (PUNT, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017405
17406 mp->is_add = (u8) is_add;
17407 mp->ipv = (u8) ipv;
17408 mp->l4_protocol = (u8) protocol;
17409 mp->l4_port = htons ((u16) port);
17410
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017411 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060017412 W (ret);
17413 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017414}
17415
17416static void vl_api_ipsec_gre_tunnel_details_t_handler
17417 (vl_api_ipsec_gre_tunnel_details_t * mp)
17418{
17419 vat_main_t *vam = &vat_main;
17420
17421 print (vam->ofp, "%11d%15U%15U%14d%14d",
17422 ntohl (mp->sw_if_index),
17423 format_ip4_address, &mp->src_address,
17424 format_ip4_address, &mp->dst_address,
17425 ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
17426}
17427
17428static void vl_api_ipsec_gre_tunnel_details_t_handler_json
17429 (vl_api_ipsec_gre_tunnel_details_t * mp)
17430{
17431 vat_main_t *vam = &vat_main;
17432 vat_json_node_t *node = NULL;
17433 struct in_addr ip4;
17434
17435 if (VAT_JSON_ARRAY != vam->json_tree.type)
17436 {
17437 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17438 vat_json_init_array (&vam->json_tree);
17439 }
17440 node = vat_json_array_add (&vam->json_tree);
17441
17442 vat_json_init_object (node);
17443 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17444 clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
17445 vat_json_object_add_ip4 (node, "src_address", ip4);
17446 clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
17447 vat_json_object_add_ip4 (node, "dst_address", ip4);
17448 vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
17449 vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
17450}
17451
17452static int
17453api_ipsec_gre_tunnel_dump (vat_main_t * vam)
17454{
17455 unformat_input_t *i = vam->input;
17456 vl_api_ipsec_gre_tunnel_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060017457 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017458 u32 sw_if_index;
17459 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017460 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017461
17462 /* Parse args required to build the message */
17463 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17464 {
17465 if (unformat (i, "sw_if_index %d", &sw_if_index))
17466 sw_if_index_set = 1;
17467 else
17468 break;
17469 }
17470
17471 if (sw_if_index_set == 0)
17472 {
17473 sw_if_index = ~0;
17474 }
17475
17476 if (!vam->json_output)
17477 {
17478 print (vam->ofp, "%11s%15s%15s%14s%14s",
17479 "sw_if_index", "src_address", "dst_address",
17480 "local_sa_id", "remote_sa_id");
17481 }
17482
17483 /* Get list of gre-tunnel interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017484 M (IPSEC_GRE_TUNNEL_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017485
17486 mp->sw_if_index = htonl (sw_if_index);
17487
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017488 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017489
17490 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060017491 M (CONTROL_PING, mp_ping);
17492 S (mp_ping);
17493
Jon Loeliger56c7b012017-02-01 12:31:41 -060017494 W (ret);
17495 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017496}
17497
17498static int
17499api_delete_subif (vat_main_t * vam)
17500{
17501 unformat_input_t *i = vam->input;
17502 vl_api_delete_subif_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017503 u32 sw_if_index = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017504 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017505
17506 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17507 {
17508 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17509 ;
17510 if (unformat (i, "sw_if_index %d", &sw_if_index))
17511 ;
17512 else
17513 break;
17514 }
17515
17516 if (sw_if_index == ~0)
17517 {
17518 errmsg ("missing sw_if_index");
17519 return -99;
17520 }
17521
17522 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017523 M (DELETE_SUBIF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017524 mp->sw_if_index = ntohl (sw_if_index);
17525
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017526 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060017527 W (ret);
17528 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017529}
17530
17531#define foreach_pbb_vtr_op \
17532_("disable", L2_VTR_DISABLED) \
17533_("pop", L2_VTR_POP_2) \
17534_("push", L2_VTR_PUSH_2)
17535
17536static int
17537api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
17538{
17539 unformat_input_t *i = vam->input;
17540 vl_api_l2_interface_pbb_tag_rewrite_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017541 u32 sw_if_index = ~0, vtr_op = ~0;
17542 u16 outer_tag = ~0;
17543 u8 dmac[6], smac[6];
17544 u8 dmac_set = 0, smac_set = 0;
17545 u16 vlanid = 0;
17546 u32 sid = ~0;
17547 u32 tmp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017548 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017549
17550 /* Shut up coverity */
17551 memset (dmac, 0, sizeof (dmac));
17552 memset (smac, 0, sizeof (smac));
17553
17554 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17555 {
17556 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17557 ;
17558 else if (unformat (i, "sw_if_index %d", &sw_if_index))
17559 ;
17560 else if (unformat (i, "vtr_op %d", &vtr_op))
17561 ;
17562#define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
17563 foreach_pbb_vtr_op
17564#undef _
17565 else if (unformat (i, "translate_pbb_stag"))
17566 {
17567 if (unformat (i, "%d", &tmp))
17568 {
17569 vtr_op = L2_VTR_TRANSLATE_2_1;
17570 outer_tag = tmp;
17571 }
17572 else
17573 {
17574 errmsg
17575 ("translate_pbb_stag operation requires outer tag definition");
17576 return -99;
17577 }
17578 }
17579 else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
17580 dmac_set++;
17581 else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
17582 smac_set++;
17583 else if (unformat (i, "sid %d", &sid))
17584 ;
17585 else if (unformat (i, "vlanid %d", &tmp))
17586 vlanid = tmp;
17587 else
17588 {
17589 clib_warning ("parse error '%U'", format_unformat_error, i);
17590 return -99;
17591 }
17592 }
17593
17594 if ((sw_if_index == ~0) || (vtr_op == ~0))
17595 {
17596 errmsg ("missing sw_if_index or vtr operation");
17597 return -99;
17598 }
17599 if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
17600 && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
17601 {
17602 errmsg
17603 ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
17604 return -99;
17605 }
17606
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017607 M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017608 mp->sw_if_index = ntohl (sw_if_index);
17609 mp->vtr_op = ntohl (vtr_op);
17610 mp->outer_tag = ntohs (outer_tag);
17611 clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
17612 clib_memcpy (mp->b_smac, smac, sizeof (smac));
17613 mp->b_vlanid = ntohs (vlanid);
17614 mp->i_sid = ntohl (sid);
17615
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017616 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060017617 W (ret);
17618 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017619}
17620
17621static int
17622api_flow_classify_set_interface (vat_main_t * vam)
17623{
17624 unformat_input_t *i = vam->input;
17625 vl_api_flow_classify_set_interface_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017626 u32 sw_if_index;
17627 int sw_if_index_set;
17628 u32 ip4_table_index = ~0;
17629 u32 ip6_table_index = ~0;
17630 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017631 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017632
17633 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17634 {
17635 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17636 sw_if_index_set = 1;
17637 else if (unformat (i, "sw_if_index %d", &sw_if_index))
17638 sw_if_index_set = 1;
17639 else if (unformat (i, "del"))
17640 is_add = 0;
17641 else if (unformat (i, "ip4-table %d", &ip4_table_index))
17642 ;
17643 else if (unformat (i, "ip6-table %d", &ip6_table_index))
17644 ;
17645 else
17646 {
17647 clib_warning ("parse error '%U'", format_unformat_error, i);
17648 return -99;
17649 }
17650 }
17651
17652 if (sw_if_index_set == 0)
17653 {
17654 errmsg ("missing interface name or sw_if_index");
17655 return -99;
17656 }
17657
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017658 M (FLOW_CLASSIFY_SET_INTERFACE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017659
17660 mp->sw_if_index = ntohl (sw_if_index);
17661 mp->ip4_table_index = ntohl (ip4_table_index);
17662 mp->ip6_table_index = ntohl (ip6_table_index);
17663 mp->is_add = is_add;
17664
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017665 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060017666 W (ret);
17667 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017668}
17669
17670static int
17671api_flow_classify_dump (vat_main_t * vam)
17672{
17673 unformat_input_t *i = vam->input;
17674 vl_api_flow_classify_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060017675 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017676 u8 type = FLOW_CLASSIFY_N_TABLES;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017677 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017678
17679 if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
17680 ;
17681 else
17682 {
17683 errmsg ("classify table type must be specified");
17684 return -99;
17685 }
17686
17687 if (!vam->json_output)
17688 {
17689 print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17690 }
17691
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017692 M (FLOW_CLASSIFY_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017693 mp->type = type;
17694 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017695 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017696
17697 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060017698 M (CONTROL_PING, mp_ping);
17699 S (mp_ping);
17700
Damjan Marion7cd468a2016-12-19 23:05:39 +010017701 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060017702 W (ret);
17703 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017704}
17705
17706static int
17707api_feature_enable_disable (vat_main_t * vam)
17708{
17709 unformat_input_t *i = vam->input;
17710 vl_api_feature_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017711 u8 *arc_name = 0;
17712 u8 *feature_name = 0;
17713 u32 sw_if_index = ~0;
17714 u8 enable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017715 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017716
17717 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17718 {
17719 if (unformat (i, "arc_name %s", &arc_name))
17720 ;
17721 else if (unformat (i, "feature_name %s", &feature_name))
17722 ;
17723 else
17724 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17725 ;
17726 else if (unformat (i, "sw_if_index %d", &sw_if_index))
17727 ;
17728 else if (unformat (i, "disable"))
17729 enable = 0;
17730 else
17731 break;
17732 }
17733
17734 if (arc_name == 0)
17735 {
17736 errmsg ("missing arc name");
17737 return -99;
17738 }
17739 if (vec_len (arc_name) > 63)
17740 {
17741 errmsg ("arc name too long");
17742 }
17743
17744 if (feature_name == 0)
17745 {
17746 errmsg ("missing feature name");
17747 return -99;
17748 }
17749 if (vec_len (feature_name) > 63)
17750 {
17751 errmsg ("feature name too long");
17752 }
17753
17754 if (sw_if_index == ~0)
17755 {
17756 errmsg ("missing interface name or sw_if_index");
17757 return -99;
17758 }
17759
17760 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017761 M (FEATURE_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017762 mp->sw_if_index = ntohl (sw_if_index);
17763 mp->enable = enable;
17764 clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
17765 clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
17766 vec_free (arc_name);
17767 vec_free (feature_name);
17768
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017769 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060017770 W (ret);
17771 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017772}
17773
17774static int
17775api_sw_interface_tag_add_del (vat_main_t * vam)
17776{
17777 unformat_input_t *i = vam->input;
17778 vl_api_sw_interface_tag_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017779 u32 sw_if_index = ~0;
17780 u8 *tag = 0;
17781 u8 enable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017782 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017783
17784 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17785 {
17786 if (unformat (i, "tag %s", &tag))
17787 ;
17788 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17789 ;
17790 else if (unformat (i, "sw_if_index %d", &sw_if_index))
17791 ;
17792 else if (unformat (i, "del"))
17793 enable = 0;
17794 else
17795 break;
17796 }
17797
17798 if (sw_if_index == ~0)
17799 {
17800 errmsg ("missing interface name or sw_if_index");
17801 return -99;
17802 }
17803
17804 if (enable && (tag == 0))
17805 {
17806 errmsg ("no tag specified");
17807 return -99;
17808 }
17809
17810 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017811 M (SW_INTERFACE_TAG_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017812 mp->sw_if_index = ntohl (sw_if_index);
17813 mp->is_add = enable;
17814 if (enable)
17815 strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
17816 vec_free (tag);
17817
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017818 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060017819 W (ret);
17820 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017821}
17822
17823static void vl_api_l2_xconnect_details_t_handler
17824 (vl_api_l2_xconnect_details_t * mp)
17825{
17826 vat_main_t *vam = &vat_main;
17827
17828 print (vam->ofp, "%15d%15d",
17829 ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
17830}
17831
17832static void vl_api_l2_xconnect_details_t_handler_json
17833 (vl_api_l2_xconnect_details_t * mp)
17834{
17835 vat_main_t *vam = &vat_main;
17836 vat_json_node_t *node = NULL;
17837
17838 if (VAT_JSON_ARRAY != vam->json_tree.type)
17839 {
17840 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17841 vat_json_init_array (&vam->json_tree);
17842 }
17843 node = vat_json_array_add (&vam->json_tree);
17844
17845 vat_json_init_object (node);
17846 vat_json_object_add_uint (node, "rx_sw_if_index",
17847 ntohl (mp->rx_sw_if_index));
17848 vat_json_object_add_uint (node, "tx_sw_if_index",
17849 ntohl (mp->tx_sw_if_index));
17850}
17851
17852static int
17853api_l2_xconnect_dump (vat_main_t * vam)
17854{
17855 vl_api_l2_xconnect_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060017856 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017857 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017858
17859 if (!vam->json_output)
17860 {
17861 print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
17862 }
17863
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017864 M (L2_XCONNECT_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017865
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017866 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017867
17868 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060017869 M (CONTROL_PING, mp_ping);
17870 S (mp_ping);
17871
Jon Loeliger56c7b012017-02-01 12:31:41 -060017872 W (ret);
17873 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017874}
17875
17876static int
17877api_sw_interface_set_mtu (vat_main_t * vam)
17878{
17879 unformat_input_t *i = vam->input;
17880 vl_api_sw_interface_set_mtu_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017881 u32 sw_if_index = ~0;
17882 u32 mtu = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017883 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017884
17885 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17886 {
17887 if (unformat (i, "mtu %d", &mtu))
17888 ;
17889 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17890 ;
17891 else if (unformat (i, "sw_if_index %d", &sw_if_index))
17892 ;
17893 else
17894 break;
17895 }
17896
17897 if (sw_if_index == ~0)
17898 {
17899 errmsg ("missing interface name or sw_if_index");
17900 return -99;
17901 }
17902
17903 if (mtu == 0)
17904 {
17905 errmsg ("no mtu specified");
17906 return -99;
17907 }
17908
17909 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017910 M (SW_INTERFACE_SET_MTU, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017911 mp->sw_if_index = ntohl (sw_if_index);
17912 mp->mtu = ntohs ((u16) mtu);
17913
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017914 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060017915 W (ret);
17916 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017917}
17918
17919
17920static int
17921q_or_quit (vat_main_t * vam)
17922{
Dave Barachdef19da2017-02-22 17:29:20 -050017923#if VPP_API_TEST_BUILTIN == 0
Damjan Marion7cd468a2016-12-19 23:05:39 +010017924 longjmp (vam->jump_buf, 1);
Dave Barachdef19da2017-02-22 17:29:20 -050017925#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +010017926 return 0; /* not so much */
17927}
17928
17929static int
17930q (vat_main_t * vam)
17931{
17932 return q_or_quit (vam);
17933}
17934
17935static int
17936quit (vat_main_t * vam)
17937{
17938 return q_or_quit (vam);
17939}
17940
17941static int
17942comment (vat_main_t * vam)
17943{
17944 return 0;
17945}
17946
17947static int
17948cmd_cmp (void *a1, void *a2)
17949{
17950 u8 **c1 = a1;
17951 u8 **c2 = a2;
17952
17953 return strcmp ((char *) (c1[0]), (char *) (c2[0]));
17954}
17955
17956static int
17957help (vat_main_t * vam)
17958{
17959 u8 **cmds = 0;
17960 u8 *name = 0;
17961 hash_pair_t *p;
17962 unformat_input_t *i = vam->input;
17963 int j;
17964
17965 if (unformat (i, "%s", &name))
17966 {
17967 uword *hs;
17968
17969 vec_add1 (name, 0);
17970
17971 hs = hash_get_mem (vam->help_by_name, name);
17972 if (hs)
17973 print (vam->ofp, "usage: %s %s", name, hs[0]);
17974 else
17975 print (vam->ofp, "No such msg / command '%s'", name);
17976 vec_free (name);
17977 return 0;
17978 }
17979
17980 print (vam->ofp, "Help is available for the following:");
17981
17982 /* *INDENT-OFF* */
17983 hash_foreach_pair (p, vam->function_by_name,
17984 ({
17985 vec_add1 (cmds, (u8 *)(p->key));
17986 }));
17987 /* *INDENT-ON* */
17988
17989 vec_sort_with_function (cmds, cmd_cmp);
17990
17991 for (j = 0; j < vec_len (cmds); j++)
17992 print (vam->ofp, "%s", cmds[j]);
17993
17994 vec_free (cmds);
17995 return 0;
17996}
17997
17998static int
17999set (vat_main_t * vam)
18000{
18001 u8 *name = 0, *value = 0;
18002 unformat_input_t *i = vam->input;
18003
18004 if (unformat (i, "%s", &name))
18005 {
18006 /* The input buffer is a vector, not a string. */
18007 value = vec_dup (i->buffer);
18008 vec_delete (value, i->index, 0);
18009 /* Almost certainly has a trailing newline */
18010 if (value[vec_len (value) - 1] == '\n')
18011 value[vec_len (value) - 1] = 0;
18012 /* Make sure it's a proper string, one way or the other */
18013 vec_add1 (value, 0);
18014 (void) clib_macro_set_value (&vam->macro_main,
18015 (char *) name, (char *) value);
18016 }
18017 else
18018 errmsg ("usage: set <name> <value>");
18019
18020 vec_free (name);
18021 vec_free (value);
18022 return 0;
18023}
18024
18025static int
18026unset (vat_main_t * vam)
18027{
18028 u8 *name = 0;
18029
18030 if (unformat (vam->input, "%s", &name))
18031 if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
18032 errmsg ("unset: %s wasn't set", name);
18033 vec_free (name);
18034 return 0;
18035}
18036
18037typedef struct
18038{
18039 u8 *name;
18040 u8 *value;
18041} macro_sort_t;
18042
18043
18044static int
18045macro_sort_cmp (void *a1, void *a2)
18046{
18047 macro_sort_t *s1 = a1;
18048 macro_sort_t *s2 = a2;
18049
18050 return strcmp ((char *) (s1->name), (char *) (s2->name));
18051}
18052
18053static int
18054dump_macro_table (vat_main_t * vam)
18055{
18056 macro_sort_t *sort_me = 0, *sm;
18057 int i;
18058 hash_pair_t *p;
18059
18060 /* *INDENT-OFF* */
18061 hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
18062 ({
18063 vec_add2 (sort_me, sm, 1);
18064 sm->name = (u8 *)(p->key);
18065 sm->value = (u8 *) (p->value[0]);
18066 }));
18067 /* *INDENT-ON* */
18068
18069 vec_sort_with_function (sort_me, macro_sort_cmp);
18070
18071 if (vec_len (sort_me))
18072 print (vam->ofp, "%-15s%s", "Name", "Value");
18073 else
18074 print (vam->ofp, "The macro table is empty...");
18075
18076 for (i = 0; i < vec_len (sort_me); i++)
18077 print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
18078 return 0;
18079}
18080
18081static int
18082dump_node_table (vat_main_t * vam)
18083{
18084 int i, j;
18085 vlib_node_t *node, *next_node;
18086
18087 if (vec_len (vam->graph_nodes) == 0)
18088 {
18089 print (vam->ofp, "Node table empty, issue get_node_graph...");
18090 return 0;
18091 }
18092
18093 for (i = 0; i < vec_len (vam->graph_nodes); i++)
18094 {
18095 node = vam->graph_nodes[i];
18096 print (vam->ofp, "[%d] %s", i, node->name);
18097 for (j = 0; j < vec_len (node->next_nodes); j++)
18098 {
18099 if (node->next_nodes[j] != ~0)
18100 {
18101 next_node = vam->graph_nodes[node->next_nodes[j]];
18102 print (vam->ofp, " [%d] %s", j, next_node->name);
18103 }
18104 }
18105 }
18106 return 0;
18107}
18108
18109static int
18110value_sort_cmp (void *a1, void *a2)
18111{
18112 name_sort_t *n1 = a1;
18113 name_sort_t *n2 = a2;
18114
18115 if (n1->value < n2->value)
18116 return -1;
18117 if (n1->value > n2->value)
18118 return 1;
18119 return 0;
18120}
18121
18122
18123static int
18124dump_msg_api_table (vat_main_t * vam)
18125{
18126 api_main_t *am = &api_main;
18127 name_sort_t *nses = 0, *ns;
18128 hash_pair_t *hp;
18129 int i;
18130
18131 /* *INDENT-OFF* */
18132 hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
18133 ({
18134 vec_add2 (nses, ns, 1);
18135 ns->name = (u8 *)(hp->key);
18136 ns->value = (u32) hp->value[0];
18137 }));
18138 /* *INDENT-ON* */
18139
18140 vec_sort_with_function (nses, value_sort_cmp);
18141
18142 for (i = 0; i < vec_len (nses); i++)
18143 print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
18144 vec_free (nses);
18145 return 0;
18146}
18147
18148static int
18149get_msg_id (vat_main_t * vam)
18150{
18151 u8 *name_and_crc;
18152 u32 message_index;
18153
18154 if (unformat (vam->input, "%s", &name_and_crc))
18155 {
18156 message_index = vl_api_get_msg_index (name_and_crc);
18157 if (message_index == ~0)
18158 {
18159 print (vam->ofp, " '%s' not found", name_and_crc);
18160 return 0;
18161 }
18162 print (vam->ofp, " '%s' has message index %d",
18163 name_and_crc, message_index);
18164 return 0;
18165 }
18166 errmsg ("name_and_crc required...");
18167 return 0;
18168}
18169
18170static int
18171search_node_table (vat_main_t * vam)
18172{
18173 unformat_input_t *line_input = vam->input;
18174 u8 *node_to_find;
18175 int j;
18176 vlib_node_t *node, *next_node;
18177 uword *p;
18178
18179 if (vam->graph_node_index_by_name == 0)
18180 {
18181 print (vam->ofp, "Node table empty, issue get_node_graph...");
18182 return 0;
18183 }
18184
18185 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
18186 {
18187 if (unformat (line_input, "%s", &node_to_find))
18188 {
18189 vec_add1 (node_to_find, 0);
18190 p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
18191 if (p == 0)
18192 {
18193 print (vam->ofp, "%s not found...", node_to_find);
18194 goto out;
18195 }
18196 node = vam->graph_nodes[p[0]];
18197 print (vam->ofp, "[%d] %s", p[0], node->name);
18198 for (j = 0; j < vec_len (node->next_nodes); j++)
18199 {
18200 if (node->next_nodes[j] != ~0)
18201 {
18202 next_node = vam->graph_nodes[node->next_nodes[j]];
18203 print (vam->ofp, " [%d] %s", j, next_node->name);
18204 }
18205 }
18206 }
18207
18208 else
18209 {
18210 clib_warning ("parse error '%U'", format_unformat_error,
18211 line_input);
18212 return -99;
18213 }
18214
18215 out:
18216 vec_free (node_to_find);
18217
18218 }
18219
18220 return 0;
18221}
18222
18223
18224static int
18225script (vat_main_t * vam)
18226{
18227#if (VPP_API_TEST_BUILTIN==0)
18228 u8 *s = 0;
18229 char *save_current_file;
18230 unformat_input_t save_input;
18231 jmp_buf save_jump_buf;
18232 u32 save_line_number;
18233
18234 FILE *new_fp, *save_ifp;
18235
18236 if (unformat (vam->input, "%s", &s))
18237 {
18238 new_fp = fopen ((char *) s, "r");
18239 if (new_fp == 0)
18240 {
18241 errmsg ("Couldn't open script file %s", s);
18242 vec_free (s);
18243 return -99;
18244 }
18245 }
18246 else
18247 {
18248 errmsg ("Missing script name");
18249 return -99;
18250 }
18251
18252 clib_memcpy (&save_input, &vam->input, sizeof (save_input));
18253 clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
18254 save_ifp = vam->ifp;
18255 save_line_number = vam->input_line_number;
18256 save_current_file = (char *) vam->current_file;
18257
18258 vam->input_line_number = 0;
18259 vam->ifp = new_fp;
18260 vam->current_file = s;
18261 do_one_file (vam);
18262
18263 clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
18264 clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
18265 vam->ifp = save_ifp;
18266 vam->input_line_number = save_line_number;
18267 vam->current_file = (u8 *) save_current_file;
18268 vec_free (s);
18269
18270 return 0;
18271#else
18272 clib_warning ("use the exec command...");
18273 return -99;
18274#endif
18275}
18276
18277static int
18278echo (vat_main_t * vam)
18279{
18280 print (vam->ofp, "%v", vam->input->buffer);
18281 return 0;
18282}
18283
18284/* List of API message constructors, CLI names map to api_xxx */
18285#define foreach_vpe_api_msg \
18286_(create_loopback,"[mac <mac-addr>]") \
18287_(sw_interface_dump,"") \
18288_(sw_interface_set_flags, \
18289 "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
18290_(sw_interface_add_del_address, \
18291 "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
18292_(sw_interface_set_table, \
18293 "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]") \
18294_(sw_interface_set_mpls_enable, \
18295 "<intfc> | sw_if_index [disable | dis]") \
18296_(sw_interface_set_vpath, \
18297 "<intfc> | sw_if_index <id> enable | disable") \
18298_(sw_interface_set_vxlan_bypass, \
John Lo2b81eb82017-01-30 13:12:10 -050018299 "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010018300_(sw_interface_set_l2_xconnect, \
18301 "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
18302 "enable | disable") \
18303_(sw_interface_set_l2_bridge, \
18304 "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n" \
18305 "[shg <split-horizon-group>] [bvi]\n" \
18306 "enable | disable") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010018307_(bridge_domain_add_del, \
18308 "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n") \
18309_(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n") \
18310_(l2fib_add_del, \
18311 "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
18312_(l2_flags, \
18313 "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n") \
18314_(bridge_flags, \
18315 "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
18316_(tap_connect, \
18317 "tapname <name> mac <mac-addr> | random-mac [tag <string>]") \
18318_(tap_modify, \
18319 "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
18320_(tap_delete, \
18321 "<vpp-if-name> | sw_if_index <id>") \
18322_(sw_interface_tap_dump, "") \
18323_(ip_add_del_route, \
18324 "<addr>/<mask> via <addr> [table-id <n>]\n" \
18325 "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n" \
18326 "[weight <n>] [drop] [local] [classify <n>] [del]\n" \
18327 "[multipath] [count <n>]") \
Neale Ranns32e1c012016-11-22 17:07:28 +000018328_(ip_mroute_add_del, \
18329 "<src> <grp>/<mask> [table-id <n>]\n" \
18330 "[<intfc> | sw_if_index <id>] [local] [del]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010018331_(mpls_route_add_del, \
18332 "<label> <eos> via <addr> [table-id <n>]\n" \
18333 "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n" \
18334 "[weight <n>] [drop] [local] [classify <n>] [del]\n" \
18335 "[multipath] [count <n>]") \
18336_(mpls_ip_bind_unbind, \
18337 "<label> <addr/len>") \
18338_(mpls_tunnel_add_del, \
18339 " via <addr> [table-id <n>]\n" \
18340 "sw_if_index <id>] [l2] [del]") \
18341_(proxy_arp_add_del, \
18342 "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]") \
18343_(proxy_arp_intfc_enable_disable, \
18344 "<intfc> | sw_if_index <id> enable | disable") \
18345_(sw_interface_set_unnumbered, \
18346 "<intfc> | sw_if_index <id> unnum_if_index <id> [del]") \
18347_(ip_neighbor_add_del, \
18348 "(<intfc> | sw_if_index <id>) dst <ip46-address> " \
18349 "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]") \
18350_(reset_vrf, "vrf <id> [ipv6]") \
18351_(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>") \
18352_(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n" \
18353 "[outer_vlan_id <n>][inner_vlan_id <n>]\n" \
18354 "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n" \
18355 "[outer_vlan_id_any][inner_vlan_id_any]") \
18356_(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]") \
18357_(reset_fib, "vrf <n> [ipv6]") \
18358_(dhcp_proxy_config, \
18359 "svr <v46-address> src <v46-address>\n" \
Neale Ranns20a175a2017-02-14 07:28:41 -080018360 "rx_vrf_id <nn> server_vrf_id <nn> [del]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010018361_(dhcp_proxy_set_vss, \
18362 "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]") \
Neale Ranns20a175a2017-02-14 07:28:41 -080018363_(dhcp_proxy_dump, "ip6") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010018364_(dhcp_client_config, \
18365 "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
18366_(set_ip_flow_hash, \
18367 "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]") \
18368_(sw_interface_ip6_enable_disable, \
18369 "<intfc> | sw_if_index <id> enable | disable") \
18370_(sw_interface_ip6_set_link_local_address, \
18371 "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>") \
18372_(sw_interface_ip6nd_ra_prefix, \
18373 "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n" \
18374 "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n" \
18375 "[nolink] [isno]") \
18376_(sw_interface_ip6nd_ra_config, \
18377 "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n" \
18378 "[life <n>] [count <n>] [interval <n>] [suppress]\n" \
18379 "[managed] [other] [ll] [send] [cease] [isno] [def]") \
18380_(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]") \
18381_(l2_patch_add_del, \
18382 "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
18383 "enable | disable") \
18384_(sr_tunnel_add_del, \
18385 "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n" \
18386 "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n" \
18387 "[policy <policy_name>]") \
18388_(sr_policy_add_del, \
18389 "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]") \
18390_(sr_multicast_map_add_del, \
18391 "address [ip6 multicast address] sr-policy [policy name] [del]") \
18392_(classify_add_del_table, \
18393 "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n" \
18394 " [del] [del-chain] mask <mask-value>\n" \
18395 " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n" \
18396 " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]") \
18397_(classify_add_del_session, \
18398 "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n" \
18399 " table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n" \
18400 " [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n" \
18401 " [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]") \
18402_(classify_set_interface_ip_table, \
18403 "<intfc> | sw_if_index <nn> table <nn>") \
18404_(classify_set_interface_l2_tables, \
18405 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
18406 " [other-table <nn>]") \
18407_(get_node_index, "node <node-name") \
18408_(add_node_next, "node <node-name> next <next-node-name>") \
18409_(l2tpv3_create_tunnel, \
18410 "client_address <ip6-addr> our_address <ip6-addr>\n" \
18411 "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
18412 "[remote_cookie <nn>]\n[l2-sublayer-preset]\n") \
18413_(l2tpv3_set_tunnel_cookies, \
18414 "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n" \
18415 "[new_remote_cookie <nn>]\n") \
18416_(l2tpv3_interface_enable_disable, \
18417 "<intfc> | sw_if_index <nn> enable | disable") \
18418_(l2tpv3_set_lookup_key, \
18419 "lookup_v6_src | lookup_v6_dst | lookup_session_id") \
18420_(sw_if_l2tpv3_tunnel_dump, "") \
18421_(vxlan_add_del_tunnel, \
18422 "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n" \
18423 "{ <intfc> | mcast_sw_if_index <nn> } }\n" \
18424 "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]") \
18425_(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]") \
18426_(gre_add_del_tunnel, \
18427 "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n") \
18428_(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]") \
18429_(l2_fib_clear_table, "") \
18430_(l2_interface_efp_filter, "sw_if_index <nn> enable | disable") \
18431_(l2_interface_vlan_tag_rewrite, \
18432 "<intfc> | sw_if_index <nn> \n" \
18433 "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n" \
18434 "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>") \
18435_(create_vhost_user_if, \
18436 "socket <filename> [server] [renumber <dev_instance>] " \
18437 "[mac <mac_address>]") \
18438_(modify_vhost_user_if, \
18439 "<intfc> | sw_if_index <nn> socket <filename>\n" \
18440 "[server] [renumber <dev_instance>]") \
18441_(delete_vhost_user_if, "<intfc> | sw_if_index <nn>") \
18442_(sw_interface_vhost_user_dump, "") \
18443_(show_version, "") \
18444_(vxlan_gpe_add_del_tunnel, \
18445 "local <addr> remote <addr> vni <nn>\n" \
18446 "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]" \
18447 "[next-ethernet] [next-nsh]\n") \
18448_(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]") \
18449_(l2_fib_table_dump, "bd_id <bridge-domain-id>") \
18450_(interface_name_renumber, \
18451 "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>") \
18452_(input_acl_set_interface, \
18453 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
18454 " [l2-table <nn>] [del]") \
18455_(want_ip4_arp_events, "address <ip4-address> [del]") \
18456_(want_ip6_nd_events, "address <ip6-address> [del]") \
18457_(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)") \
18458_(ip_dump, "ipv4 | ipv6") \
18459_(ipsec_spd_add_del, "spd_id <n> [del]") \
18460_(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n" \
18461 " spid_id <n> ") \
18462_(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n" \
18463 " crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n" \
18464 " integ_alg <alg> integ_key <hex>") \
18465_(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n" \
18466 " (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n" \
18467 " laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
18468 " [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
18469_(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>") \
18470_(ikev2_profile_add_del, "name <profile_name> [del]") \
18471_(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n" \
18472 "(auth_data 0x<data> | auth_data <data>)") \
18473_(ikev2_profile_set_id, "name <profile_name> id_type <type>\n" \
18474 "(id_data 0x<data> | id_data <data>) (local|remote)") \
18475_(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n" \
18476 "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
18477 "(local|remote)") \
18478_(ikev2_set_local_key, "file <absolute_file_path>") \
Radu Nicolaucb33dc22017-02-16 16:49:46 +000018479_(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
18480_(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
18481_(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
18482_(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
18483_(ikev2_initiate_sa_init, "<profile_name>") \
18484_(ikev2_initiate_del_ike_sa, "<ispi>") \
18485_(ikev2_initiate_del_child_sa, "<ispi>") \
18486_(ikev2_initiate_rekey_child_sa, "<ispi>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010018487_(delete_loopback,"sw_if_index <nn>") \
18488_(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
18489_(map_add_domain, \
18490 "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> " \
18491 "ip6-src <ip6addr> " \
18492 "ea-bits-len <n> psid-offset <n> psid-len <n>") \
18493_(map_del_domain, "index <n>") \
18494_(map_add_del_rule, \
18495 "index <n> psid <n> dst <ip6addr> [del]") \
18496_(map_domain_dump, "") \
18497_(map_rule_dump, "index <map-domain>") \
18498_(want_interface_events, "enable|disable") \
18499_(want_stats,"enable|disable") \
18500_(get_first_msg_id, "client <name>") \
18501_(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
18502_(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n" \
18503 "fib-id <nn> [ip4][ip6][default]") \
18504_(get_node_graph, " ") \
18505_(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>") \
18506_(ioam_enable, "[trace] [pow] [ppc <encap|decap>]") \
18507_(ioam_disable, "") \
Filip Tehlar694396d2017-02-17 14:29:11 +010018508_(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
18509 " sw_if_index <sw_if_index> p <priority> " \
18510 "w <weight>] [del]") \
18511_(one_add_del_locator, "locator-set <locator_name> " \
18512 "iface <intf> | sw_if_index <sw_if_index> " \
18513 "p <priority> w <weight> [del]") \
18514_(one_add_del_local_eid,"vni <vni> eid " \
18515 "<ipv4|ipv6>/<prefix> | <L2 address> " \
18516 "locator-set <locator_name> [del]" \
18517 "[key-id sha1|sha256 secret-key <secret-key>]")\
18518_(one_add_del_map_resolver, "<ip4|6-addr> [del]") \
18519_(one_add_del_map_server, "<ip4|6-addr> [del]") \
18520_(one_enable_disable, "enable|disable") \
18521_(one_map_register_enable_disable, "enable|disable") \
18522_(one_rloc_probe_enable_disable, "enable|disable") \
18523_(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> " \
18524 "[seid <seid>] " \
18525 "rloc <locator> p <prio> " \
18526 "w <weight> [rloc <loc> ... ] " \
18527 "action <action> [del-all]") \
18528_(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid " \
18529 "<local-eid>") \
18530_(one_pitr_set_locator_set, "locator-set <loc-set-name> | del") \
18531_(one_map_request_mode, "src-dst|dst-only") \
18532_(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]") \
18533_(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>") \
18534_(one_locator_set_dump, "[local | remote]") \
18535_(one_locator_dump, "ls_index <index> | ls_name <name>") \
18536_(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] " \
18537 "[local] | [remote]") \
18538_(one_eid_table_vni_dump, "") \
18539_(one_eid_table_map_dump, "l2|l3") \
18540_(one_map_resolver_dump, "") \
18541_(one_map_server_dump, "") \
18542_(one_adjacencies_get, "vni <vni>") \
18543_(show_one_rloc_probe_state, "") \
18544_(show_one_map_register_state, "") \
18545_(show_one_status, "") \
18546_(one_get_map_request_itr_rlocs, "") \
18547_(show_one_pitr, "") \
18548_(show_one_map_request_mode, "") \
18549_(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
Damjan Marion7cd468a2016-12-19 23:05:39 +010018550 " sw_if_index <sw_if_index> p <priority> " \
18551 "w <weight>] [del]") \
18552_(lisp_add_del_locator, "locator-set <locator_name> " \
18553 "iface <intf> | sw_if_index <sw_if_index> " \
18554 "p <priority> w <weight> [del]") \
18555_(lisp_add_del_local_eid,"vni <vni> eid " \
18556 "<ipv4|ipv6>/<prefix> | <L2 address> " \
18557 "locator-set <locator_name> [del]" \
18558 "[key-id sha1|sha256 secret-key <secret-key>]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010018559_(lisp_add_del_map_resolver, "<ip4|6-addr> [del]") \
18560_(lisp_add_del_map_server, "<ip4|6-addr> [del]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010018561_(lisp_enable_disable, "enable|disable") \
18562_(lisp_map_register_enable_disable, "enable|disable") \
18563_(lisp_rloc_probe_enable_disable, "enable|disable") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010018564_(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> " \
18565 "[seid <seid>] " \
18566 "rloc <locator> p <prio> " \
18567 "w <weight> [rloc <loc> ... ] " \
18568 "action <action> [del-all]") \
18569_(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid " \
18570 "<local-eid>") \
18571_(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del") \
18572_(lisp_map_request_mode, "src-dst|dst-only") \
18573_(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]") \
18574_(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>") \
18575_(lisp_locator_set_dump, "[local | remote]") \
18576_(lisp_locator_dump, "ls_index <index> | ls_name <name>") \
18577_(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] " \
18578 "[local] | [remote]") \
18579_(lisp_eid_table_vni_dump, "") \
18580_(lisp_eid_table_map_dump, "l2|l3") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010018581_(lisp_map_resolver_dump, "") \
18582_(lisp_map_server_dump, "") \
18583_(lisp_adjacencies_get, "vni <vni>") \
Filip Tehlar5fae99c2017-01-18 12:57:37 +010018584_(lisp_gpe_fwd_entries_get, "vni <vni>") \
18585_(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>") \
Filip Tehlar3e7b56932017-02-21 18:28:34 +010018586_(gpe_set_encap_mode, "lisp|vxlan") \
18587_(gpe_get_encap_mode, "") \
Filip Tehlar82786c42017-02-20 15:20:37 +010018588_(lisp_gpe_add_del_iface, "up|down") \
18589_(lisp_gpe_enable_disable, "enable|disable") \
18590_(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>" \
18591 "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010018592_(show_lisp_rloc_probe_state, "") \
18593_(show_lisp_map_register_state, "") \
18594_(show_lisp_status, "") \
18595_(lisp_get_map_request_itr_rlocs, "") \
18596_(show_lisp_pitr, "") \
18597_(show_lisp_map_request_mode, "") \
18598_(af_packet_create, "name <host interface name> [hw_addr <mac>]") \
18599_(af_packet_delete, "name <host interface name>") \
18600_(policer_add_del, "name <policer name> <params> [del]") \
18601_(policer_dump, "[name <policer name>]") \
18602_(policer_classify_set_interface, \
18603 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
18604 " [l2-table <nn>] [del]") \
18605_(policer_classify_dump, "type [ip4|ip6|l2]") \
18606_(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] " \
18607 "[master|slave]") \
18608_(netmap_delete, "name <interface name>") \
18609_(mpls_tunnel_dump, "tunnel_index <tunnel-id>") \
18610_(mpls_fib_dump, "") \
18611_(classify_table_ids, "") \
18612_(classify_table_by_interface, "sw_if_index <sw_if_index>") \
18613_(classify_table_info, "table_id <nn>") \
18614_(classify_session_dump, "table_id <nn>") \
18615_(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] " \
18616 "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] " \
18617 "[template_interval <nn>] [udp_checksum]") \
18618_(ipfix_exporter_dump, "") \
18619_(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
18620_(ipfix_classify_stream_dump, "") \
18621_(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
18622_(ipfix_classify_table_dump, "") \
18623_(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
18624_(sw_interface_span_dump, "") \
18625_(get_next_index, "node-name <node-name> next-node-name <node-name>") \
18626_(pg_create_interface, "if_id <nn>") \
18627_(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]") \
18628_(pg_enable_disable, "[stream <id>] disable") \
18629_(ip_source_and_port_range_check_add_del, \
18630 "<ip-addr>/<mask> range <nn>-<nn> vrf <id>") \
18631_(ip_source_and_port_range_check_interface_add_del, \
18632 "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]" \
18633 "[udp-in-vrf <id>] [udp-out-vrf <id>]") \
18634_(ipsec_gre_add_del_tunnel, \
18635 "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]") \
18636_(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]") \
18637_(delete_subif,"<intfc> | sw_if_index <nn>") \
18638_(l2_interface_pbb_tag_rewrite, \
18639 "<intfc> | sw_if_index <nn> \n" \
18640 "[disable | push | pop | translate_pbb_stag <outer_tag>] \n" \
18641 "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]") \
18642_(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]") \
18643_(flow_classify_set_interface, \
18644 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
18645_(flow_classify_dump, "type [ip4|ip6]") \
18646_(ip_fib_dump, "") \
Neale Ranns5a8123b2017-01-26 01:18:23 -080018647_(ip_mfib_dump, "") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010018648_(ip6_fib_dump, "") \
Neale Ranns5a8123b2017-01-26 01:18:23 -080018649_(ip6_mfib_dump, "") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010018650_(feature_enable_disable, "arc_name <arc_name> " \
18651 "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]") \
18652_(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>" \
18653"[disable]") \
18654_(l2_xconnect_dump, "") \
18655_(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>") \
18656_(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>") \
18657_(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")
18658
Pavel Kotucek738f3f22017-01-09 15:11:03 +010018659#if DPDK > 0
18660#define foreach_vpe_dpdk_api_msg \
18661_(sw_interface_set_dpdk_hqos_pipe, \
18662 "rx <intfc> | sw_if_index <id> subport <subport-id> pipe <pipe-id>\n" \
18663 "profile <profile-id>\n") \
18664_(sw_interface_set_dpdk_hqos_subport, \
18665 "rx <intfc> | sw_if_index <id> subport <subport-id> [rate <n>]\n" \
18666 "[bktsize <n>] [tc0 <n>] [tc1 <n>] [tc2 <n>] [tc3 <n>] [period <n>]\n") \
18667_(sw_interface_set_dpdk_hqos_tctbl, \
18668 "rx <intfc> | sw_if_index <id> entry <n> tc <n> queue <n>\n")
18669#endif
18670
Damjan Marion7cd468a2016-12-19 23:05:39 +010018671/* List of command functions, CLI names map directly to functions */
18672#define foreach_cli_function \
18673_(comment, "usage: comment <ignore-rest-of-line>") \
18674_(dump_interface_table, "usage: dump_interface_table") \
18675_(dump_sub_interface_table, "usage: dump_sub_interface_table") \
18676_(dump_ipv4_table, "usage: dump_ipv4_table") \
18677_(dump_ipv6_table, "usage: dump_ipv6_table") \
18678_(dump_stats_table, "usage: dump_stats_table") \
18679_(dump_macro_table, "usage: dump_macro_table ") \
18680_(dump_node_table, "usage: dump_node_table") \
18681_(dump_msg_api_table, "usage: dump_msg_api_table") \
18682_(get_msg_id, "usage: get_msg_id name_and_crc") \
18683_(echo, "usage: echo <message>") \
18684_(exec, "usage: exec <vpe-debug-CLI-command>") \
18685_(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>") \
18686_(help, "usage: help") \
18687_(q, "usage: quit") \
18688_(quit, "usage: quit") \
18689_(search_node_table, "usage: search_node_table <name>...") \
18690_(set, "usage: set <variable-name> <value>") \
18691_(script, "usage: script <file-name>") \
18692_(unset, "usage: unset <variable-name>")
18693
18694#define _(N,n) \
18695 static void vl_api_##n##_t_handler_uni \
18696 (vl_api_##n##_t * mp) \
18697 { \
18698 vat_main_t * vam = &vat_main; \
18699 if (vam->json_output) { \
18700 vl_api_##n##_t_handler_json(mp); \
18701 } else { \
18702 vl_api_##n##_t_handler(mp); \
18703 } \
18704 }
18705foreach_vpe_api_reply_msg;
18706#undef _
18707
Pavel Kotucek738f3f22017-01-09 15:11:03 +010018708#if DPDK > 0
18709#define _(N,n) \
18710 static void vl_api_##n##_t_handler_uni \
18711 (vl_api_##n##_t * mp) \
18712 { \
18713 vat_main_t * vam = &vat_main; \
18714 if (vam->json_output) { \
18715 vl_api_##n##_t_handler_json(mp); \
18716 } else { \
18717 vl_api_##n##_t_handler(mp); \
18718 } \
18719 }
18720foreach_vpe_dpdk_api_reply_msg;
18721#undef _
18722#endif
18723
Damjan Marion7cd468a2016-12-19 23:05:39 +010018724void
18725vat_api_hookup (vat_main_t * vam)
18726{
18727#define _(N,n) \
18728 vl_msg_api_set_handlers(VL_API_##N, #n, \
18729 vl_api_##n##_t_handler_uni, \
18730 vl_noop_handler, \
18731 vl_api_##n##_t_endian, \
18732 vl_api_##n##_t_print, \
18733 sizeof(vl_api_##n##_t), 1);
18734 foreach_vpe_api_reply_msg;
18735#undef _
18736
Pavel Kotucek738f3f22017-01-09 15:11:03 +010018737#if DPDK > 0
18738#define _(N,n) \
18739 vl_msg_api_set_handlers(VL_API_##N, #n, \
18740 vl_api_##n##_t_handler_uni, \
18741 vl_noop_handler, \
18742 vl_api_##n##_t_endian, \
18743 vl_api_##n##_t_print, \
18744 sizeof(vl_api_##n##_t), 1);
18745 foreach_vpe_dpdk_api_reply_msg;
18746#undef _
18747#endif
18748
Damjan Marion7cd468a2016-12-19 23:05:39 +010018749#if (VPP_API_TEST_BUILTIN==0)
18750 vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
18751#endif
18752
18753 vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
18754
18755 vam->function_by_name = hash_create_string (0, sizeof (uword));
18756
18757 vam->help_by_name = hash_create_string (0, sizeof (uword));
18758
18759 /* API messages we can send */
18760#define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
18761 foreach_vpe_api_msg;
18762#undef _
Pavel Kotucek738f3f22017-01-09 15:11:03 +010018763#if DPDK >0
18764#define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
18765 foreach_vpe_dpdk_api_msg;
18766#undef _
18767#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +010018768
18769 /* Help strings */
18770#define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18771 foreach_vpe_api_msg;
18772#undef _
Pavel Kotucek738f3f22017-01-09 15:11:03 +010018773#if DPDK >0
18774#define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18775 foreach_vpe_dpdk_api_msg;
18776#undef _
18777#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +010018778
18779 /* CLI functions */
18780#define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
18781 foreach_cli_function;
18782#undef _
18783
18784 /* Help strings */
18785#define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18786 foreach_cli_function;
18787#undef _
18788}
18789
18790/*
18791 * fd.io coding-style-patch-verification: ON
18792 *
18793 * Local Variables:
18794 * eval: (c-set-style "gnu")
18795 * End:
18796 */