blob: e3d8ab48eb9c86badc67f569be03e3664ba20959 [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
Damjan Marion7cd468a2016-12-19 23:05:39 +0100115static uword
116api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
117{
118 vat_main_t *vam = va_arg (*args, vat_main_t *);
119 u32 *result = va_arg (*args, u32 *);
120 u8 *if_name;
121 uword *p;
122
123 if (!unformat (input, "%s", &if_name))
124 return 0;
125
126 p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
127 if (p == 0)
128 return 0;
129 *result = p[0];
130 return 1;
131}
132
Damjan Marion7cd468a2016-12-19 23:05:39 +0100133#if VPP_API_TEST_BUILTIN == 0
134/* 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}
390#endif /* VPP_API_TEST_BUILTIN */
391
392static uword
393unformat_policer_rate_type (unformat_input_t * input, va_list * args)
394{
395 u8 *r = va_arg (*args, u8 *);
396
397 if (unformat (input, "kbps"))
398 *r = SSE2_QOS_RATE_KBPS;
399 else if (unformat (input, "pps"))
400 *r = SSE2_QOS_RATE_PPS;
401 else
402 return 0;
403 return 1;
404}
405
406static uword
407unformat_policer_round_type (unformat_input_t * input, va_list * args)
408{
409 u8 *r = va_arg (*args, u8 *);
410
411 if (unformat (input, "closest"))
412 *r = SSE2_QOS_ROUND_TO_CLOSEST;
413 else if (unformat (input, "up"))
414 *r = SSE2_QOS_ROUND_TO_UP;
415 else if (unformat (input, "down"))
416 *r = SSE2_QOS_ROUND_TO_DOWN;
417 else
418 return 0;
419 return 1;
420}
421
422static uword
423unformat_policer_type (unformat_input_t * input, va_list * args)
424{
425 u8 *r = va_arg (*args, u8 *);
426
427 if (unformat (input, "1r2c"))
428 *r = SSE2_QOS_POLICER_TYPE_1R2C;
429 else if (unformat (input, "1r3c"))
430 *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
431 else if (unformat (input, "2r3c-2698"))
432 *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
433 else if (unformat (input, "2r3c-4115"))
434 *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
435 else if (unformat (input, "2r3c-mef5cf1"))
436 *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
437 else
438 return 0;
439 return 1;
440}
441
442static uword
443unformat_dscp (unformat_input_t * input, va_list * va)
444{
445 u8 *r = va_arg (*va, u8 *);
446
447 if (0);
448#define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
449 foreach_vnet_dscp
450#undef _
451 else
452 return 0;
453 return 1;
454}
455
456static uword
457unformat_policer_action_type (unformat_input_t * input, va_list * va)
458{
459 sse2_qos_pol_action_params_st *a
460 = va_arg (*va, sse2_qos_pol_action_params_st *);
461
462 if (unformat (input, "drop"))
463 a->action_type = SSE2_QOS_ACTION_DROP;
464 else if (unformat (input, "transmit"))
465 a->action_type = SSE2_QOS_ACTION_TRANSMIT;
466 else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
467 a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
468 else
469 return 0;
470 return 1;
471}
472
473static uword
474unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
475{
476 u32 *r = va_arg (*va, u32 *);
477 u32 tid;
478
479 if (unformat (input, "ip4"))
480 tid = POLICER_CLASSIFY_TABLE_IP4;
481 else if (unformat (input, "ip6"))
482 tid = POLICER_CLASSIFY_TABLE_IP6;
483 else if (unformat (input, "l2"))
484 tid = POLICER_CLASSIFY_TABLE_L2;
485 else
486 return 0;
487
488 *r = tid;
489 return 1;
490}
491
492static uword
493unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
494{
495 u32 *r = va_arg (*va, u32 *);
496 u32 tid;
497
498 if (unformat (input, "ip4"))
499 tid = FLOW_CLASSIFY_TABLE_IP4;
500 else if (unformat (input, "ip6"))
501 tid = FLOW_CLASSIFY_TABLE_IP6;
502 else
503 return 0;
504
505 *r = tid;
506 return 1;
507}
508
Neale Ranns32e1c012016-11-22 17:07:28 +0000509static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
510static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
511static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
512static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
513
514uword
515unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
516{
517 mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
518 mfib_itf_attribute_t attr;
519
520 old = *iflags;
521 FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
522 {
523 if (unformat (input, mfib_itf_flag_long_names[attr]))
524 *iflags |= (1 << attr);
525 }
526 FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
527 {
528 if (unformat (input, mfib_itf_flag_names[attr]))
529 *iflags |= (1 << attr);
530 }
531
532 return (old == *iflags ? 0 : 1);
533}
534
535uword
536unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
537{
538 mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
539 mfib_entry_attribute_t attr;
540
541 old = *eflags;
542 FOR_EACH_MFIB_ATTRIBUTE (attr)
543 {
544 if (unformat (input, mfib_flag_long_names[attr]))
545 *eflags |= (1 << attr);
546 }
547 FOR_EACH_MFIB_ATTRIBUTE (attr)
548 {
549 if (unformat (input, mfib_flag_names[attr]))
550 *eflags |= (1 << attr);
551 }
552
553 return (old == *eflags ? 0 : 1);
554}
555
Damjan Marion7cd468a2016-12-19 23:05:39 +0100556#if (VPP_API_TEST_BUILTIN==0)
557u8 *
558format_ip4_address (u8 * s, va_list * args)
559{
560 u8 *a = va_arg (*args, u8 *);
561 return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
562}
563
564u8 *
565format_ip6_address (u8 * s, va_list * args)
566{
567 ip6_address_t *a = va_arg (*args, ip6_address_t *);
568 u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
569
570 i_max_n_zero = ARRAY_LEN (a->as_u16);
571 max_n_zeros = 0;
572 i_first_zero = i_max_n_zero;
573 n_zeros = 0;
574 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
575 {
576 u32 is_zero = a->as_u16[i] == 0;
577 if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
578 {
579 i_first_zero = i;
580 n_zeros = 0;
581 }
582 n_zeros += is_zero;
583 if ((!is_zero && n_zeros > max_n_zeros)
584 || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
585 {
586 i_max_n_zero = i_first_zero;
587 max_n_zeros = n_zeros;
588 i_first_zero = ARRAY_LEN (a->as_u16);
589 n_zeros = 0;
590 }
591 }
592
593 last_double_colon = 0;
594 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
595 {
596 if (i == i_max_n_zero && max_n_zeros > 1)
597 {
598 s = format (s, "::");
599 i += max_n_zeros - 1;
600 last_double_colon = 1;
601 }
602 else
603 {
604 s = format (s, "%s%x",
605 (last_double_colon || i == 0) ? "" : ":",
606 clib_net_to_host_u16 (a->as_u16[i]));
607 last_double_colon = 0;
608 }
609 }
610
611 return s;
612}
613
614/* Format an IP46 address. */
615u8 *
616format_ip46_address (u8 * s, va_list * args)
617{
618 ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
619 ip46_type_t type = va_arg (*args, ip46_type_t);
620 int is_ip4 = 1;
621
622 switch (type)
623 {
624 case IP46_TYPE_ANY:
625 is_ip4 = ip46_address_is_ip4 (ip46);
626 break;
627 case IP46_TYPE_IP4:
628 is_ip4 = 1;
629 break;
630 case IP46_TYPE_IP6:
631 is_ip4 = 0;
632 break;
633 }
634
635 return is_ip4 ?
636 format (s, "%U", format_ip4_address, &ip46->ip4) :
637 format (s, "%U", format_ip6_address, &ip46->ip6);
638}
639
640u8 *
641format_ethernet_address (u8 * s, va_list * args)
642{
643 u8 *a = va_arg (*args, u8 *);
644
645 return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
646 a[0], a[1], a[2], a[3], a[4], a[5]);
647}
648#endif
649
650static void
651increment_v4_address (ip4_address_t * a)
652{
653 u32 v;
654
655 v = ntohl (a->as_u32) + 1;
656 a->as_u32 = ntohl (v);
657}
658
659static void
660increment_v6_address (ip6_address_t * a)
661{
662 u64 v0, v1;
663
664 v0 = clib_net_to_host_u64 (a->as_u64[0]);
665 v1 = clib_net_to_host_u64 (a->as_u64[1]);
666
667 v1 += 1;
668 if (v1 == 0)
669 v0 += 1;
670 a->as_u64[0] = clib_net_to_host_u64 (v0);
671 a->as_u64[1] = clib_net_to_host_u64 (v1);
672}
673
674static void
675increment_mac_address (u64 * mac)
676{
677 u64 tmp = *mac;
678
679 tmp = clib_net_to_host_u64 (tmp);
680 tmp += 1 << 16; /* skip unused (least significant) octets */
681 tmp = clib_host_to_net_u64 (tmp);
682 *mac = tmp;
683}
684
685static void vl_api_create_loopback_reply_t_handler
686 (vl_api_create_loopback_reply_t * mp)
687{
688 vat_main_t *vam = &vat_main;
689 i32 retval = ntohl (mp->retval);
690
691 vam->retval = retval;
692 vam->regenerate_interface_table = 1;
693 vam->sw_if_index = ntohl (mp->sw_if_index);
694 vam->result_ready = 1;
695}
696
697static void vl_api_create_loopback_reply_t_handler_json
698 (vl_api_create_loopback_reply_t * mp)
699{
700 vat_main_t *vam = &vat_main;
701 vat_json_node_t node;
702
703 vat_json_init_object (&node);
704 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
705 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
706
707 vat_json_print (vam->ofp, &node);
708 vat_json_free (&node);
709 vam->retval = ntohl (mp->retval);
710 vam->result_ready = 1;
711}
712
713static void vl_api_af_packet_create_reply_t_handler
714 (vl_api_af_packet_create_reply_t * mp)
715{
716 vat_main_t *vam = &vat_main;
717 i32 retval = ntohl (mp->retval);
718
719 vam->retval = retval;
720 vam->regenerate_interface_table = 1;
721 vam->sw_if_index = ntohl (mp->sw_if_index);
722 vam->result_ready = 1;
723}
724
725static void vl_api_af_packet_create_reply_t_handler_json
726 (vl_api_af_packet_create_reply_t * mp)
727{
728 vat_main_t *vam = &vat_main;
729 vat_json_node_t node;
730
731 vat_json_init_object (&node);
732 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
733 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
734
735 vat_json_print (vam->ofp, &node);
736 vat_json_free (&node);
737
738 vam->retval = ntohl (mp->retval);
739 vam->result_ready = 1;
740}
741
742static void vl_api_create_vlan_subif_reply_t_handler
743 (vl_api_create_vlan_subif_reply_t * mp)
744{
745 vat_main_t *vam = &vat_main;
746 i32 retval = ntohl (mp->retval);
747
748 vam->retval = retval;
749 vam->regenerate_interface_table = 1;
750 vam->sw_if_index = ntohl (mp->sw_if_index);
751 vam->result_ready = 1;
752}
753
754static void vl_api_create_vlan_subif_reply_t_handler_json
755 (vl_api_create_vlan_subif_reply_t * mp)
756{
757 vat_main_t *vam = &vat_main;
758 vat_json_node_t node;
759
760 vat_json_init_object (&node);
761 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
762 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
763
764 vat_json_print (vam->ofp, &node);
765 vat_json_free (&node);
766
767 vam->retval = ntohl (mp->retval);
768 vam->result_ready = 1;
769}
770
771static void vl_api_create_subif_reply_t_handler
772 (vl_api_create_subif_reply_t * mp)
773{
774 vat_main_t *vam = &vat_main;
775 i32 retval = ntohl (mp->retval);
776
777 vam->retval = retval;
778 vam->regenerate_interface_table = 1;
779 vam->sw_if_index = ntohl (mp->sw_if_index);
780 vam->result_ready = 1;
781}
782
783static void vl_api_create_subif_reply_t_handler_json
784 (vl_api_create_subif_reply_t * mp)
785{
786 vat_main_t *vam = &vat_main;
787 vat_json_node_t node;
788
789 vat_json_init_object (&node);
790 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
791 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
792
793 vat_json_print (vam->ofp, &node);
794 vat_json_free (&node);
795
796 vam->retval = ntohl (mp->retval);
797 vam->result_ready = 1;
798}
799
800static void vl_api_interface_name_renumber_reply_t_handler
801 (vl_api_interface_name_renumber_reply_t * mp)
802{
803 vat_main_t *vam = &vat_main;
804 i32 retval = ntohl (mp->retval);
805
806 vam->retval = retval;
807 vam->regenerate_interface_table = 1;
808 vam->result_ready = 1;
809}
810
811static void vl_api_interface_name_renumber_reply_t_handler_json
812 (vl_api_interface_name_renumber_reply_t * mp)
813{
814 vat_main_t *vam = &vat_main;
815 vat_json_node_t node;
816
817 vat_json_init_object (&node);
818 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
819
820 vat_json_print (vam->ofp, &node);
821 vat_json_free (&node);
822
823 vam->retval = ntohl (mp->retval);
824 vam->result_ready = 1;
825}
826
827/*
828 * Special-case: build the interface table, maintain
829 * the next loopback sw_if_index vbl.
830 */
831static void vl_api_sw_interface_details_t_handler
832 (vl_api_sw_interface_details_t * mp)
833{
834 vat_main_t *vam = &vat_main;
835 u8 *s = format (0, "%s%c", mp->interface_name, 0);
836
837 hash_set_mem (vam->sw_if_index_by_interface_name, s,
838 ntohl (mp->sw_if_index));
839
840 /* In sub interface case, fill the sub interface table entry */
841 if (mp->sw_if_index != mp->sup_sw_if_index)
842 {
843 sw_interface_subif_t *sub = NULL;
844
845 vec_add2 (vam->sw_if_subif_table, sub, 1);
846
847 vec_validate (sub->interface_name, strlen ((char *) s) + 1);
848 strncpy ((char *) sub->interface_name, (char *) s,
849 vec_len (sub->interface_name));
850 sub->sw_if_index = ntohl (mp->sw_if_index);
851 sub->sub_id = ntohl (mp->sub_id);
852
853 sub->sub_dot1ad = mp->sub_dot1ad;
854 sub->sub_number_of_tags = mp->sub_number_of_tags;
855 sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
856 sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
857 sub->sub_exact_match = mp->sub_exact_match;
858 sub->sub_default = mp->sub_default;
859 sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
860 sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
861
862 /* vlan tag rewrite */
863 sub->vtr_op = ntohl (mp->vtr_op);
864 sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
865 sub->vtr_tag1 = ntohl (mp->vtr_tag1);
866 sub->vtr_tag2 = ntohl (mp->vtr_tag2);
867 }
868}
869
870static void vl_api_sw_interface_details_t_handler_json
871 (vl_api_sw_interface_details_t * mp)
872{
873 vat_main_t *vam = &vat_main;
874 vat_json_node_t *node = NULL;
875
876 if (VAT_JSON_ARRAY != vam->json_tree.type)
877 {
878 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
879 vat_json_init_array (&vam->json_tree);
880 }
881 node = vat_json_array_add (&vam->json_tree);
882
883 vat_json_init_object (node);
884 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
885 vat_json_object_add_uint (node, "sup_sw_if_index",
886 ntohl (mp->sup_sw_if_index));
887 vat_json_object_add_uint (node, "l2_address_length",
888 ntohl (mp->l2_address_length));
889 vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
890 sizeof (mp->l2_address));
891 vat_json_object_add_string_copy (node, "interface_name",
892 mp->interface_name);
893 vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
894 vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
895 vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
896 vat_json_object_add_uint (node, "link_speed", mp->link_speed);
897 vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
898 vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
899 vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
900 vat_json_object_add_uint (node, "sub_number_of_tags",
901 mp->sub_number_of_tags);
902 vat_json_object_add_uint (node, "sub_outer_vlan_id",
903 ntohs (mp->sub_outer_vlan_id));
904 vat_json_object_add_uint (node, "sub_inner_vlan_id",
905 ntohs (mp->sub_inner_vlan_id));
906 vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
907 vat_json_object_add_uint (node, "sub_default", mp->sub_default);
908 vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
909 mp->sub_outer_vlan_id_any);
910 vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
911 mp->sub_inner_vlan_id_any);
912 vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
913 vat_json_object_add_uint (node, "vtr_push_dot1q",
914 ntohl (mp->vtr_push_dot1q));
915 vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
916 vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
917}
918
919static void vl_api_sw_interface_set_flags_t_handler
920 (vl_api_sw_interface_set_flags_t * mp)
921{
922 vat_main_t *vam = &vat_main;
923 if (vam->interface_event_display)
924 errmsg ("interface flags: sw_if_index %d %s %s",
925 ntohl (mp->sw_if_index),
926 mp->admin_up_down ? "admin-up" : "admin-down",
927 mp->link_up_down ? "link-up" : "link-down");
928}
929
930static void vl_api_sw_interface_set_flags_t_handler_json
931 (vl_api_sw_interface_set_flags_t * mp)
932{
933 /* JSON output not supported */
934}
935
936static void
937vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
938{
939 vat_main_t *vam = &vat_main;
940 i32 retval = ntohl (mp->retval);
941
942 vam->retval = retval;
943 vam->shmem_result = (u8 *) mp->reply_in_shmem;
944 vam->result_ready = 1;
945}
946
947static void
948vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
949{
950 vat_main_t *vam = &vat_main;
951 vat_json_node_t node;
952 api_main_t *am = &api_main;
953 void *oldheap;
954 u8 *reply;
955
956 vat_json_init_object (&node);
957 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
958 vat_json_object_add_uint (&node, "reply_in_shmem",
959 ntohl (mp->reply_in_shmem));
960 /* Toss the shared-memory original... */
961 pthread_mutex_lock (&am->vlib_rp->mutex);
962 oldheap = svm_push_data_heap (am->vlib_rp);
963
964 reply = (u8 *) (mp->reply_in_shmem);
965 vec_free (reply);
966
967 svm_pop_heap (oldheap);
968 pthread_mutex_unlock (&am->vlib_rp->mutex);
969
970 vat_json_print (vam->ofp, &node);
971 vat_json_free (&node);
972
973 vam->retval = ntohl (mp->retval);
974 vam->result_ready = 1;
975}
976
977static void
978vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
979{
980 vat_main_t *vam = &vat_main;
981 i32 retval = ntohl (mp->retval);
982
983 vam->retval = retval;
984 vam->cmd_reply = mp->reply;
985 vam->result_ready = 1;
986}
987
988static void
989vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
990{
991 vat_main_t *vam = &vat_main;
992 vat_json_node_t node;
993
994 vat_json_init_object (&node);
995 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
996 vat_json_object_add_string_copy (&node, "reply", mp->reply);
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 vl_api_classify_add_del_table_reply_t_handler
1006 (vl_api_classify_add_del_table_reply_t * mp)
1007{
1008 vat_main_t *vam = &vat_main;
1009 i32 retval = ntohl (mp->retval);
1010 if (vam->async_mode)
1011 {
1012 vam->async_errors += (retval < 0);
1013 }
1014 else
1015 {
1016 vam->retval = retval;
1017 if (retval == 0 &&
1018 ((mp->new_table_index != 0xFFFFFFFF) ||
1019 (mp->skip_n_vectors != 0xFFFFFFFF) ||
1020 (mp->match_n_vectors != 0xFFFFFFFF)))
1021 /*
1022 * Note: this is just barely thread-safe, depends on
1023 * the main thread spinning waiting for an answer...
1024 */
1025 errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1026 ntohl (mp->new_table_index),
1027 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1028 vam->result_ready = 1;
1029 }
1030}
1031
1032static void vl_api_classify_add_del_table_reply_t_handler_json
1033 (vl_api_classify_add_del_table_reply_t * mp)
1034{
1035 vat_main_t *vam = &vat_main;
1036 vat_json_node_t node;
1037
1038 vat_json_init_object (&node);
1039 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1040 vat_json_object_add_uint (&node, "new_table_index",
1041 ntohl (mp->new_table_index));
1042 vat_json_object_add_uint (&node, "skip_n_vectors",
1043 ntohl (mp->skip_n_vectors));
1044 vat_json_object_add_uint (&node, "match_n_vectors",
1045 ntohl (mp->match_n_vectors));
1046
1047 vat_json_print (vam->ofp, &node);
1048 vat_json_free (&node);
1049
1050 vam->retval = ntohl (mp->retval);
1051 vam->result_ready = 1;
1052}
1053
1054static void vl_api_get_node_index_reply_t_handler
1055 (vl_api_get_node_index_reply_t * mp)
1056{
1057 vat_main_t *vam = &vat_main;
1058 i32 retval = ntohl (mp->retval);
1059 if (vam->async_mode)
1060 {
1061 vam->async_errors += (retval < 0);
1062 }
1063 else
1064 {
1065 vam->retval = retval;
1066 if (retval == 0)
1067 errmsg ("node index %d", ntohl (mp->node_index));
1068 vam->result_ready = 1;
1069 }
1070}
1071
1072static void vl_api_get_node_index_reply_t_handler_json
1073 (vl_api_get_node_index_reply_t * mp)
1074{
1075 vat_main_t *vam = &vat_main;
1076 vat_json_node_t node;
1077
1078 vat_json_init_object (&node);
1079 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1080 vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1081
1082 vat_json_print (vam->ofp, &node);
1083 vat_json_free (&node);
1084
1085 vam->retval = ntohl (mp->retval);
1086 vam->result_ready = 1;
1087}
1088
1089static void vl_api_get_next_index_reply_t_handler
1090 (vl_api_get_next_index_reply_t * mp)
1091{
1092 vat_main_t *vam = &vat_main;
1093 i32 retval = ntohl (mp->retval);
1094 if (vam->async_mode)
1095 {
1096 vam->async_errors += (retval < 0);
1097 }
1098 else
1099 {
1100 vam->retval = retval;
1101 if (retval == 0)
1102 errmsg ("next node index %d", ntohl (mp->next_index));
1103 vam->result_ready = 1;
1104 }
1105}
1106
1107static void vl_api_get_next_index_reply_t_handler_json
1108 (vl_api_get_next_index_reply_t * mp)
1109{
1110 vat_main_t *vam = &vat_main;
1111 vat_json_node_t node;
1112
1113 vat_json_init_object (&node);
1114 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1115 vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1116
1117 vat_json_print (vam->ofp, &node);
1118 vat_json_free (&node);
1119
1120 vam->retval = ntohl (mp->retval);
1121 vam->result_ready = 1;
1122}
1123
1124static void vl_api_add_node_next_reply_t_handler
1125 (vl_api_add_node_next_reply_t * mp)
1126{
1127 vat_main_t *vam = &vat_main;
1128 i32 retval = ntohl (mp->retval);
1129 if (vam->async_mode)
1130 {
1131 vam->async_errors += (retval < 0);
1132 }
1133 else
1134 {
1135 vam->retval = retval;
1136 if (retval == 0)
1137 errmsg ("next index %d", ntohl (mp->next_index));
1138 vam->result_ready = 1;
1139 }
1140}
1141
1142static void vl_api_add_node_next_reply_t_handler_json
1143 (vl_api_add_node_next_reply_t * mp)
1144{
1145 vat_main_t *vam = &vat_main;
1146 vat_json_node_t node;
1147
1148 vat_json_init_object (&node);
1149 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1150 vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1151
1152 vat_json_print (vam->ofp, &node);
1153 vat_json_free (&node);
1154
1155 vam->retval = ntohl (mp->retval);
1156 vam->result_ready = 1;
1157}
1158
1159static void vl_api_show_version_reply_t_handler
1160 (vl_api_show_version_reply_t * mp)
1161{
1162 vat_main_t *vam = &vat_main;
1163 i32 retval = ntohl (mp->retval);
1164
1165 if (retval >= 0)
1166 {
1167 errmsg (" program: %s", mp->program);
1168 errmsg (" version: %s", mp->version);
1169 errmsg (" build date: %s", mp->build_date);
1170 errmsg ("build directory: %s", mp->build_directory);
1171 }
1172 vam->retval = retval;
1173 vam->result_ready = 1;
1174}
1175
1176static void vl_api_show_version_reply_t_handler_json
1177 (vl_api_show_version_reply_t * mp)
1178{
1179 vat_main_t *vam = &vat_main;
1180 vat_json_node_t node;
1181
1182 vat_json_init_object (&node);
1183 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1184 vat_json_object_add_string_copy (&node, "program", mp->program);
1185 vat_json_object_add_string_copy (&node, "version", mp->version);
1186 vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1187 vat_json_object_add_string_copy (&node, "build_directory",
1188 mp->build_directory);
1189
1190 vat_json_print (vam->ofp, &node);
1191 vat_json_free (&node);
1192
1193 vam->retval = ntohl (mp->retval);
1194 vam->result_ready = 1;
1195}
1196
1197static void
1198vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1199{
1200 errmsg ("arp %s event: address %U new mac %U sw_if_index %d",
1201 mp->mac_ip ? "mac/ip binding" : "address resolution",
1202 format_ip4_address, &mp->address,
1203 format_ethernet_address, mp->new_mac, mp->sw_if_index);
1204}
1205
1206static void
1207vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1208{
1209 /* JSON output not supported */
1210}
1211
1212static void
1213vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1214{
1215 errmsg ("ip6 nd %s event: address %U new mac %U sw_if_index %d",
1216 mp->mac_ip ? "mac/ip binding" : "address resolution",
1217 format_ip6_address, mp->address,
1218 format_ethernet_address, mp->new_mac, mp->sw_if_index);
1219}
1220
1221static void
1222vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1223{
1224 /* JSON output not supported */
1225}
1226
1227/*
1228 * Special-case: build the bridge domain table, maintain
1229 * the next bd id vbl.
1230 */
1231static void vl_api_bridge_domain_details_t_handler
1232 (vl_api_bridge_domain_details_t * mp)
1233{
1234 vat_main_t *vam = &vat_main;
1235 u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1236
1237 print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1238 " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1239
1240 print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1241 ntohl (mp->bd_id), mp->learn, mp->forward,
1242 mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1243
1244 if (n_sw_ifs)
1245 print (vam->ofp, "\n\n%s %s %s", "sw_if_index", "SHG", "Interface Name");
1246}
1247
1248static void vl_api_bridge_domain_details_t_handler_json
1249 (vl_api_bridge_domain_details_t * mp)
1250{
1251 vat_main_t *vam = &vat_main;
1252 vat_json_node_t *node, *array = NULL;
1253
1254 if (VAT_JSON_ARRAY != vam->json_tree.type)
1255 {
1256 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1257 vat_json_init_array (&vam->json_tree);
1258 }
1259 node = vat_json_array_add (&vam->json_tree);
1260
1261 vat_json_init_object (node);
1262 vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1263 vat_json_object_add_uint (node, "flood", mp->flood);
1264 vat_json_object_add_uint (node, "forward", mp->forward);
1265 vat_json_object_add_uint (node, "learn", mp->learn);
1266 vat_json_object_add_uint (node, "bvi_sw_if_index",
1267 ntohl (mp->bvi_sw_if_index));
1268 vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1269 array = vat_json_object_add (node, "sw_if");
1270 vat_json_init_array (array);
1271}
1272
1273/*
1274 * Special-case: build the bridge domain sw if table.
1275 */
1276static void vl_api_bridge_domain_sw_if_details_t_handler
1277 (vl_api_bridge_domain_sw_if_details_t * mp)
1278{
1279 vat_main_t *vam = &vat_main;
1280 hash_pair_t *p;
1281 u8 *sw_if_name = 0;
1282 u32 sw_if_index;
1283
1284 sw_if_index = ntohl (mp->sw_if_index);
1285 /* *INDENT-OFF* */
1286 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1287 ({
1288 if ((u32) p->value[0] == sw_if_index)
1289 {
1290 sw_if_name = (u8 *)(p->key);
1291 break;
1292 }
1293 }));
1294 /* *INDENT-ON* */
1295
1296 print (vam->ofp, "%7d %3d %s", sw_if_index,
1297 mp->shg, sw_if_name ? (char *) sw_if_name :
1298 "sw_if_index not found!");
1299}
1300
1301static void vl_api_bridge_domain_sw_if_details_t_handler_json
1302 (vl_api_bridge_domain_sw_if_details_t * mp)
1303{
1304 vat_main_t *vam = &vat_main;
1305 vat_json_node_t *node = NULL;
1306 uword last_index = 0;
1307
1308 ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1309 ASSERT (vec_len (vam->json_tree.array) >= 1);
1310 last_index = vec_len (vam->json_tree.array) - 1;
1311 node = &vam->json_tree.array[last_index];
1312 node = vat_json_object_get_element (node, "sw_if");
1313 ASSERT (NULL != node);
1314 node = vat_json_array_add (node);
1315
1316 vat_json_init_object (node);
1317 vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1318 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1319 vat_json_object_add_uint (node, "shg", mp->shg);
1320}
1321
1322static void vl_api_control_ping_reply_t_handler
1323 (vl_api_control_ping_reply_t * mp)
1324{
1325 vat_main_t *vam = &vat_main;
1326 i32 retval = ntohl (mp->retval);
1327 if (vam->async_mode)
1328 {
1329 vam->async_errors += (retval < 0);
1330 }
1331 else
1332 {
1333 vam->retval = retval;
1334 vam->result_ready = 1;
1335 }
1336}
1337
1338static void vl_api_control_ping_reply_t_handler_json
1339 (vl_api_control_ping_reply_t * mp)
1340{
1341 vat_main_t *vam = &vat_main;
1342 i32 retval = ntohl (mp->retval);
1343
1344 if (VAT_JSON_NONE != vam->json_tree.type)
1345 {
1346 vat_json_print (vam->ofp, &vam->json_tree);
1347 vat_json_free (&vam->json_tree);
1348 vam->json_tree.type = VAT_JSON_NONE;
1349 }
1350 else
1351 {
1352 /* just print [] */
1353 vat_json_init_array (&vam->json_tree);
1354 vat_json_print (vam->ofp, &vam->json_tree);
1355 vam->json_tree.type = VAT_JSON_NONE;
1356 }
1357
1358 vam->retval = retval;
1359 vam->result_ready = 1;
1360}
1361
1362static void
1363vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1364{
1365 vat_main_t *vam = &vat_main;
1366 i32 retval = ntohl (mp->retval);
1367 if (vam->async_mode)
1368 {
1369 vam->async_errors += (retval < 0);
1370 }
1371 else
1372 {
1373 vam->retval = retval;
1374 vam->result_ready = 1;
1375 }
1376}
1377
1378static void vl_api_l2_flags_reply_t_handler_json
1379 (vl_api_l2_flags_reply_t * mp)
1380{
1381 vat_main_t *vam = &vat_main;
1382 vat_json_node_t node;
1383
1384 vat_json_init_object (&node);
1385 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1386 vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1387 ntohl (mp->resulting_feature_bitmap));
1388
1389 vat_json_print (vam->ofp, &node);
1390 vat_json_free (&node);
1391
1392 vam->retval = ntohl (mp->retval);
1393 vam->result_ready = 1;
1394}
1395
1396static void vl_api_bridge_flags_reply_t_handler
1397 (vl_api_bridge_flags_reply_t * mp)
1398{
1399 vat_main_t *vam = &vat_main;
1400 i32 retval = ntohl (mp->retval);
1401 if (vam->async_mode)
1402 {
1403 vam->async_errors += (retval < 0);
1404 }
1405 else
1406 {
1407 vam->retval = retval;
1408 vam->result_ready = 1;
1409 }
1410}
1411
1412static void vl_api_bridge_flags_reply_t_handler_json
1413 (vl_api_bridge_flags_reply_t * mp)
1414{
1415 vat_main_t *vam = &vat_main;
1416 vat_json_node_t node;
1417
1418 vat_json_init_object (&node);
1419 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1420 vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1421 ntohl (mp->resulting_feature_bitmap));
1422
1423 vat_json_print (vam->ofp, &node);
1424 vat_json_free (&node);
1425
1426 vam->retval = ntohl (mp->retval);
1427 vam->result_ready = 1;
1428}
1429
1430static void vl_api_tap_connect_reply_t_handler
1431 (vl_api_tap_connect_reply_t * mp)
1432{
1433 vat_main_t *vam = &vat_main;
1434 i32 retval = ntohl (mp->retval);
1435 if (vam->async_mode)
1436 {
1437 vam->async_errors += (retval < 0);
1438 }
1439 else
1440 {
1441 vam->retval = retval;
1442 vam->sw_if_index = ntohl (mp->sw_if_index);
1443 vam->result_ready = 1;
1444 }
1445
1446}
1447
1448static void vl_api_tap_connect_reply_t_handler_json
1449 (vl_api_tap_connect_reply_t * mp)
1450{
1451 vat_main_t *vam = &vat_main;
1452 vat_json_node_t node;
1453
1454 vat_json_init_object (&node);
1455 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1456 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1457
1458 vat_json_print (vam->ofp, &node);
1459 vat_json_free (&node);
1460
1461 vam->retval = ntohl (mp->retval);
1462 vam->result_ready = 1;
1463
1464}
1465
1466static void
1467vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1468{
1469 vat_main_t *vam = &vat_main;
1470 i32 retval = ntohl (mp->retval);
1471 if (vam->async_mode)
1472 {
1473 vam->async_errors += (retval < 0);
1474 }
1475 else
1476 {
1477 vam->retval = retval;
1478 vam->sw_if_index = ntohl (mp->sw_if_index);
1479 vam->result_ready = 1;
1480 }
1481}
1482
1483static void vl_api_tap_modify_reply_t_handler_json
1484 (vl_api_tap_modify_reply_t * mp)
1485{
1486 vat_main_t *vam = &vat_main;
1487 vat_json_node_t node;
1488
1489 vat_json_init_object (&node);
1490 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1491 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1492
1493 vat_json_print (vam->ofp, &node);
1494 vat_json_free (&node);
1495
1496 vam->retval = ntohl (mp->retval);
1497 vam->result_ready = 1;
1498}
1499
1500static void
1501vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1502{
1503 vat_main_t *vam = &vat_main;
1504 i32 retval = ntohl (mp->retval);
1505 if (vam->async_mode)
1506 {
1507 vam->async_errors += (retval < 0);
1508 }
1509 else
1510 {
1511 vam->retval = retval;
1512 vam->result_ready = 1;
1513 }
1514}
1515
1516static void vl_api_tap_delete_reply_t_handler_json
1517 (vl_api_tap_delete_reply_t * mp)
1518{
1519 vat_main_t *vam = &vat_main;
1520 vat_json_node_t node;
1521
1522 vat_json_init_object (&node);
1523 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1524
1525 vat_json_print (vam->ofp, &node);
1526 vat_json_free (&node);
1527
1528 vam->retval = ntohl (mp->retval);
1529 vam->result_ready = 1;
1530}
1531
1532static void vl_api_mpls_tunnel_add_del_reply_t_handler
1533 (vl_api_mpls_tunnel_add_del_reply_t * mp)
1534{
1535 vat_main_t *vam = &vat_main;
1536 i32 retval = ntohl (mp->retval);
1537 if (vam->async_mode)
1538 {
1539 vam->async_errors += (retval < 0);
1540 }
1541 else
1542 {
1543 vam->retval = retval;
1544 vam->result_ready = 1;
1545 }
1546}
1547
1548static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1549 (vl_api_mpls_tunnel_add_del_reply_t * mp)
1550{
1551 vat_main_t *vam = &vat_main;
1552 vat_json_node_t node;
1553
1554 vat_json_init_object (&node);
1555 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1556 vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1557 ntohl (mp->sw_if_index));
1558
1559 vat_json_print (vam->ofp, &node);
1560 vat_json_free (&node);
1561
1562 vam->retval = ntohl (mp->retval);
1563 vam->result_ready = 1;
1564}
1565
1566static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1567 (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1568{
1569 vat_main_t *vam = &vat_main;
1570 i32 retval = ntohl (mp->retval);
1571 if (vam->async_mode)
1572 {
1573 vam->async_errors += (retval < 0);
1574 }
1575 else
1576 {
1577 vam->retval = retval;
1578 vam->sw_if_index = ntohl (mp->sw_if_index);
1579 vam->result_ready = 1;
1580 }
1581}
1582
1583static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1584 (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1585{
1586 vat_main_t *vam = &vat_main;
1587 vat_json_node_t node;
1588
1589 vat_json_init_object (&node);
1590 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1591 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1592
1593 vat_json_print (vam->ofp, &node);
1594 vat_json_free (&node);
1595
1596 vam->retval = ntohl (mp->retval);
1597 vam->result_ready = 1;
1598}
1599
1600
1601static void vl_api_lisp_add_del_locator_set_reply_t_handler
1602 (vl_api_lisp_add_del_locator_set_reply_t * mp)
1603{
1604 vat_main_t *vam = &vat_main;
1605 i32 retval = ntohl (mp->retval);
1606 if (vam->async_mode)
1607 {
1608 vam->async_errors += (retval < 0);
1609 }
1610 else
1611 {
1612 vam->retval = retval;
1613 vam->result_ready = 1;
1614 }
1615}
1616
1617static void vl_api_lisp_add_del_locator_set_reply_t_handler_json
1618 (vl_api_lisp_add_del_locator_set_reply_t * mp)
1619{
1620 vat_main_t *vam = &vat_main;
1621 vat_json_node_t node;
1622
1623 vat_json_init_object (&node);
1624 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1625 vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1626
1627 vat_json_print (vam->ofp, &node);
1628 vat_json_free (&node);
1629
1630 vam->retval = ntohl (mp->retval);
1631 vam->result_ready = 1;
1632}
1633
1634static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1635 (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1636{
1637 vat_main_t *vam = &vat_main;
1638 i32 retval = ntohl (mp->retval);
1639 if (vam->async_mode)
1640 {
1641 vam->async_errors += (retval < 0);
1642 }
1643 else
1644 {
1645 vam->retval = retval;
1646 vam->sw_if_index = ntohl (mp->sw_if_index);
1647 vam->result_ready = 1;
1648 }
1649}
1650
1651static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1652 (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1653{
1654 vat_main_t *vam = &vat_main;
1655 vat_json_node_t node;
1656
1657 vat_json_init_object (&node);
1658 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1659 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1660
1661 vat_json_print (vam->ofp, &node);
1662 vat_json_free (&node);
1663
1664 vam->retval = ntohl (mp->retval);
1665 vam->result_ready = 1;
1666}
1667
1668static void vl_api_gre_add_del_tunnel_reply_t_handler
1669 (vl_api_gre_add_del_tunnel_reply_t * mp)
1670{
1671 vat_main_t *vam = &vat_main;
1672 i32 retval = ntohl (mp->retval);
1673 if (vam->async_mode)
1674 {
1675 vam->async_errors += (retval < 0);
1676 }
1677 else
1678 {
1679 vam->retval = retval;
1680 vam->sw_if_index = ntohl (mp->sw_if_index);
1681 vam->result_ready = 1;
1682 }
1683}
1684
1685static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1686 (vl_api_gre_add_del_tunnel_reply_t * mp)
1687{
1688 vat_main_t *vam = &vat_main;
1689 vat_json_node_t node;
1690
1691 vat_json_init_object (&node);
1692 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1693 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1694
1695 vat_json_print (vam->ofp, &node);
1696 vat_json_free (&node);
1697
1698 vam->retval = ntohl (mp->retval);
1699 vam->result_ready = 1;
1700}
1701
1702static void vl_api_create_vhost_user_if_reply_t_handler
1703 (vl_api_create_vhost_user_if_reply_t * mp)
1704{
1705 vat_main_t *vam = &vat_main;
1706 i32 retval = ntohl (mp->retval);
1707 if (vam->async_mode)
1708 {
1709 vam->async_errors += (retval < 0);
1710 }
1711 else
1712 {
1713 vam->retval = retval;
1714 vam->sw_if_index = ntohl (mp->sw_if_index);
1715 vam->result_ready = 1;
1716 }
1717}
1718
1719static void vl_api_create_vhost_user_if_reply_t_handler_json
1720 (vl_api_create_vhost_user_if_reply_t * mp)
1721{
1722 vat_main_t *vam = &vat_main;
1723 vat_json_node_t node;
1724
1725 vat_json_init_object (&node);
1726 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1727 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1728
1729 vat_json_print (vam->ofp, &node);
1730 vat_json_free (&node);
1731
1732 vam->retval = ntohl (mp->retval);
1733 vam->result_ready = 1;
1734}
1735
1736static void vl_api_ip_address_details_t_handler
1737 (vl_api_ip_address_details_t * mp)
1738{
1739 vat_main_t *vam = &vat_main;
1740 static ip_address_details_t empty_ip_address_details = { {0} };
1741 ip_address_details_t *address = NULL;
1742 ip_details_t *current_ip_details = NULL;
1743 ip_details_t *details = NULL;
1744
1745 details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1746
1747 if (!details || vam->current_sw_if_index >= vec_len (details)
1748 || !details[vam->current_sw_if_index].present)
1749 {
1750 errmsg ("ip address details arrived but not stored");
1751 errmsg ("ip_dump should be called first");
1752 return;
1753 }
1754
1755 current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1756
1757#define addresses (current_ip_details->addr)
1758
1759 vec_validate_init_empty (addresses, vec_len (addresses),
1760 empty_ip_address_details);
1761
1762 address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1763
1764 clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1765 address->prefix_length = mp->prefix_length;
1766#undef addresses
1767}
1768
1769static void vl_api_ip_address_details_t_handler_json
1770 (vl_api_ip_address_details_t * mp)
1771{
1772 vat_main_t *vam = &vat_main;
1773 vat_json_node_t *node = NULL;
1774 struct in6_addr ip6;
1775 struct in_addr ip4;
1776
1777 if (VAT_JSON_ARRAY != vam->json_tree.type)
1778 {
1779 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1780 vat_json_init_array (&vam->json_tree);
1781 }
1782 node = vat_json_array_add (&vam->json_tree);
1783
1784 vat_json_init_object (node);
1785 if (vam->is_ipv6)
1786 {
1787 clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1788 vat_json_object_add_ip6 (node, "ip", ip6);
1789 }
1790 else
1791 {
1792 clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1793 vat_json_object_add_ip4 (node, "ip", ip4);
1794 }
1795 vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1796}
1797
1798static void
1799vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1800{
1801 vat_main_t *vam = &vat_main;
1802 static ip_details_t empty_ip_details = { 0 };
1803 ip_details_t *ip = NULL;
1804 u32 sw_if_index = ~0;
1805
1806 sw_if_index = ntohl (mp->sw_if_index);
1807
1808 vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1809 sw_if_index, empty_ip_details);
1810
1811 ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1812 sw_if_index);
1813
1814 ip->present = 1;
1815}
1816
1817static void
1818vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1819{
1820 vat_main_t *vam = &vat_main;
1821
1822 if (VAT_JSON_ARRAY != vam->json_tree.type)
1823 {
1824 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1825 vat_json_init_array (&vam->json_tree);
1826 }
1827 vat_json_array_add_uint (&vam->json_tree,
1828 clib_net_to_host_u32 (mp->sw_if_index));
1829}
1830
1831static void vl_api_map_domain_details_t_handler_json
1832 (vl_api_map_domain_details_t * mp)
1833{
1834 vat_json_node_t *node = NULL;
1835 vat_main_t *vam = &vat_main;
1836 struct in6_addr ip6;
1837 struct in_addr ip4;
1838
1839 if (VAT_JSON_ARRAY != vam->json_tree.type)
1840 {
1841 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1842 vat_json_init_array (&vam->json_tree);
1843 }
1844
1845 node = vat_json_array_add (&vam->json_tree);
1846 vat_json_init_object (node);
1847
1848 vat_json_object_add_uint (node, "domain_index",
1849 clib_net_to_host_u32 (mp->domain_index));
1850 clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1851 vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1852 clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1853 vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1854 clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1855 vat_json_object_add_ip6 (node, "ip6_src", ip6);
1856 vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1857 vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1858 vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1859 vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1860 vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1861 vat_json_object_add_int (node, "psid_length", mp->psid_length);
1862 vat_json_object_add_uint (node, "flags", mp->flags);
1863 vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1864 vat_json_object_add_int (node, "is_translation", mp->is_translation);
1865}
1866
1867static void vl_api_map_domain_details_t_handler
1868 (vl_api_map_domain_details_t * mp)
1869{
1870 vat_main_t *vam = &vat_main;
1871
1872 if (mp->is_translation)
1873 {
1874 print (vam->ofp,
1875 "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
1876 format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1877 format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1878 format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1879 clib_net_to_host_u32 (mp->domain_index));
1880 }
1881 else
1882 {
1883 print (vam->ofp,
1884 "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
1885 format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1886 format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1887 format_ip6_address, mp->ip6_src,
1888 clib_net_to_host_u32 (mp->domain_index));
1889 }
1890 print (vam->ofp, " ea-len %d psid-offset %d psid-len %d mtu %d %s",
1891 mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1892 mp->is_translation ? "map-t" : "");
1893}
1894
1895static void vl_api_map_rule_details_t_handler_json
1896 (vl_api_map_rule_details_t * mp)
1897{
1898 struct in6_addr ip6;
1899 vat_json_node_t *node = NULL;
1900 vat_main_t *vam = &vat_main;
1901
1902 if (VAT_JSON_ARRAY != vam->json_tree.type)
1903 {
1904 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1905 vat_json_init_array (&vam->json_tree);
1906 }
1907
1908 node = vat_json_array_add (&vam->json_tree);
1909 vat_json_init_object (node);
1910
1911 vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1912 clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1913 vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1914}
1915
1916static void
1917vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1918{
1919 vat_main_t *vam = &vat_main;
1920 print (vam->ofp, " %d (psid) %U (ip6-dst)",
1921 clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1922}
1923
1924static void
1925vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1926{
1927 errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1928 "router_addr %U host_mac %U",
1929 mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1930 format_ip4_address, &mp->host_address,
1931 format_ip4_address, &mp->router_address,
1932 format_ethernet_address, mp->host_mac);
1933}
1934
1935static void vl_api_dhcp_compl_event_t_handler_json
1936 (vl_api_dhcp_compl_event_t * mp)
1937{
1938 /* JSON output not supported */
1939}
1940
1941static void
1942set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1943 u32 counter)
1944{
1945 vat_main_t *vam = &vat_main;
1946 static u64 default_counter = 0;
1947
1948 vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
1949 NULL);
1950 vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
1951 sw_if_index, default_counter);
1952 vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1953}
1954
1955static void
1956set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1957 interface_counter_t counter)
1958{
1959 vat_main_t *vam = &vat_main;
1960 static interface_counter_t default_counter = { 0, };
1961
1962 vec_validate_init_empty (vam->combined_interface_counters,
1963 vnet_counter_type, NULL);
1964 vec_validate_init_empty (vam->combined_interface_counters
1965 [vnet_counter_type], sw_if_index, default_counter);
1966 vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1967}
1968
1969static void vl_api_vnet_interface_counters_t_handler
1970 (vl_api_vnet_interface_counters_t * mp)
1971{
1972 /* not supported */
1973}
1974
1975static void vl_api_vnet_interface_counters_t_handler_json
1976 (vl_api_vnet_interface_counters_t * mp)
1977{
1978 interface_counter_t counter;
1979 vlib_counter_t *v;
1980 u64 *v_packets;
1981 u64 packets;
1982 u32 count;
1983 u32 first_sw_if_index;
1984 int i;
1985
1986 count = ntohl (mp->count);
1987 first_sw_if_index = ntohl (mp->first_sw_if_index);
1988
1989 if (!mp->is_combined)
1990 {
1991 v_packets = (u64 *) & mp->data;
1992 for (i = 0; i < count; i++)
1993 {
1994 packets =
1995 clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
1996 set_simple_interface_counter (mp->vnet_counter_type,
1997 first_sw_if_index + i, packets);
1998 v_packets++;
1999 }
2000 }
2001 else
2002 {
2003 v = (vlib_counter_t *) & mp->data;
2004 for (i = 0; i < count; i++)
2005 {
2006 counter.packets =
2007 clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2008 counter.bytes =
2009 clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2010 set_combined_interface_counter (mp->vnet_counter_type,
2011 first_sw_if_index + i, counter);
2012 v++;
2013 }
2014 }
2015}
2016
2017static u32
2018ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2019{
2020 vat_main_t *vam = &vat_main;
2021 u32 i;
2022
2023 for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2024 {
2025 if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2026 {
2027 return i;
2028 }
2029 }
2030 return ~0;
2031}
2032
2033static u32
2034ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2035{
2036 vat_main_t *vam = &vat_main;
2037 u32 i;
2038
2039 for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2040 {
2041 if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2042 {
2043 return i;
2044 }
2045 }
2046 return ~0;
2047}
2048
2049static void vl_api_vnet_ip4_fib_counters_t_handler
2050 (vl_api_vnet_ip4_fib_counters_t * mp)
2051{
2052 /* not supported */
2053}
2054
2055static void vl_api_vnet_ip4_fib_counters_t_handler_json
2056 (vl_api_vnet_ip4_fib_counters_t * mp)
2057{
2058 vat_main_t *vam = &vat_main;
2059 vl_api_ip4_fib_counter_t *v;
2060 ip4_fib_counter_t *counter;
2061 struct in_addr ip4;
2062 u32 vrf_id;
2063 u32 vrf_index;
2064 u32 count;
2065 int i;
2066
2067 vrf_id = ntohl (mp->vrf_id);
2068 vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2069 if (~0 == vrf_index)
2070 {
2071 vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2072 vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2073 vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2074 vec_validate (vam->ip4_fib_counters, vrf_index);
2075 vam->ip4_fib_counters[vrf_index] = NULL;
2076 }
2077
2078 vec_free (vam->ip4_fib_counters[vrf_index]);
2079 v = (vl_api_ip4_fib_counter_t *) & mp->c;
2080 count = ntohl (mp->count);
2081 for (i = 0; i < count; i++)
2082 {
2083 vec_validate (vam->ip4_fib_counters[vrf_index], i);
2084 counter = &vam->ip4_fib_counters[vrf_index][i];
2085 clib_memcpy (&ip4, &v->address, sizeof (ip4));
2086 counter->address = ip4;
2087 counter->address_length = v->address_length;
2088 counter->packets = clib_net_to_host_u64 (v->packets);
2089 counter->bytes = clib_net_to_host_u64 (v->bytes);
2090 v++;
2091 }
2092}
2093
Neale Ranns044183f2017-01-24 01:34:25 -08002094static void vl_api_vnet_ip4_nbr_counters_t_handler
2095 (vl_api_vnet_ip4_nbr_counters_t * mp)
2096{
2097 /* not supported */
2098}
2099
2100static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2101 (vl_api_vnet_ip4_nbr_counters_t * mp)
2102{
2103 vat_main_t *vam = &vat_main;
2104 vl_api_ip4_nbr_counter_t *v;
2105 ip4_nbr_counter_t *counter;
2106 u32 sw_if_index;
2107 u32 count;
2108 int i;
2109
2110 sw_if_index = ntohl (mp->sw_if_index);
2111 count = ntohl (mp->count);
2112 vec_validate (vam->ip4_nbr_counters, sw_if_index);
2113
2114 if (mp->begin)
2115 vec_free (vam->ip4_nbr_counters[sw_if_index]);
2116
2117 v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2118 for (i = 0; i < count; i++)
2119 {
2120 vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2121 counter = &vam->ip4_nbr_counters[sw_if_index][i];
2122 counter->address.s_addr = v->address;
2123 counter->packets = clib_net_to_host_u64 (v->packets);
2124 counter->bytes = clib_net_to_host_u64 (v->bytes);
2125 counter->linkt = v->link_type;
2126 v++;
2127 }
2128}
2129
Damjan Marion7cd468a2016-12-19 23:05:39 +01002130static void vl_api_vnet_ip6_fib_counters_t_handler
2131 (vl_api_vnet_ip6_fib_counters_t * mp)
2132{
2133 /* not supported */
2134}
2135
2136static void vl_api_vnet_ip6_fib_counters_t_handler_json
2137 (vl_api_vnet_ip6_fib_counters_t * mp)
2138{
2139 vat_main_t *vam = &vat_main;
2140 vl_api_ip6_fib_counter_t *v;
2141 ip6_fib_counter_t *counter;
2142 struct in6_addr ip6;
2143 u32 vrf_id;
2144 u32 vrf_index;
2145 u32 count;
2146 int i;
2147
2148 vrf_id = ntohl (mp->vrf_id);
2149 vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2150 if (~0 == vrf_index)
2151 {
2152 vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2153 vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2154 vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2155 vec_validate (vam->ip6_fib_counters, vrf_index);
2156 vam->ip6_fib_counters[vrf_index] = NULL;
2157 }
2158
2159 vec_free (vam->ip6_fib_counters[vrf_index]);
2160 v = (vl_api_ip6_fib_counter_t *) & mp->c;
2161 count = ntohl (mp->count);
2162 for (i = 0; i < count; i++)
2163 {
2164 vec_validate (vam->ip6_fib_counters[vrf_index], i);
2165 counter = &vam->ip6_fib_counters[vrf_index][i];
2166 clib_memcpy (&ip6, &v->address, sizeof (ip6));
2167 counter->address = ip6;
2168 counter->address_length = v->address_length;
2169 counter->packets = clib_net_to_host_u64 (v->packets);
2170 counter->bytes = clib_net_to_host_u64 (v->bytes);
2171 v++;
2172 }
2173}
2174
Neale Ranns044183f2017-01-24 01:34:25 -08002175static void vl_api_vnet_ip6_nbr_counters_t_handler
2176 (vl_api_vnet_ip6_nbr_counters_t * mp)
2177{
2178 /* not supported */
2179}
2180
2181static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2182 (vl_api_vnet_ip6_nbr_counters_t * mp)
2183{
2184 vat_main_t *vam = &vat_main;
2185 vl_api_ip6_nbr_counter_t *v;
2186 ip6_nbr_counter_t *counter;
2187 struct in6_addr ip6;
2188 u32 sw_if_index;
2189 u32 count;
2190 int i;
2191
2192 sw_if_index = ntohl (mp->sw_if_index);
2193 count = ntohl (mp->count);
2194 vec_validate (vam->ip6_nbr_counters, sw_if_index);
2195
2196 if (mp->begin)
2197 vec_free (vam->ip6_nbr_counters[sw_if_index]);
2198
2199 v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2200 for (i = 0; i < count; i++)
2201 {
2202 vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2203 counter = &vam->ip6_nbr_counters[sw_if_index][i];
2204 clib_memcpy (&ip6, &v->address, sizeof (ip6));
2205 counter->address = ip6;
2206 counter->packets = clib_net_to_host_u64 (v->packets);
2207 counter->bytes = clib_net_to_host_u64 (v->bytes);
2208 v++;
2209 }
2210}
2211
Damjan Marion7cd468a2016-12-19 23:05:39 +01002212static void vl_api_get_first_msg_id_reply_t_handler
2213 (vl_api_get_first_msg_id_reply_t * mp)
2214{
2215 vat_main_t *vam = &vat_main;
2216 i32 retval = ntohl (mp->retval);
2217
2218 if (vam->async_mode)
2219 {
2220 vam->async_errors += (retval < 0);
2221 }
2222 else
2223 {
2224 vam->retval = retval;
2225 vam->result_ready = 1;
2226 }
2227 if (retval >= 0)
2228 {
2229 errmsg ("first message id %d", ntohs (mp->first_msg_id));
2230 }
2231}
2232
2233static void vl_api_get_first_msg_id_reply_t_handler_json
2234 (vl_api_get_first_msg_id_reply_t * mp)
2235{
2236 vat_main_t *vam = &vat_main;
2237 vat_json_node_t node;
2238
2239 vat_json_init_object (&node);
2240 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2241 vat_json_object_add_uint (&node, "first_msg_id",
2242 (uint) ntohs (mp->first_msg_id));
2243
2244 vat_json_print (vam->ofp, &node);
2245 vat_json_free (&node);
2246
2247 vam->retval = ntohl (mp->retval);
2248 vam->result_ready = 1;
2249}
2250
2251static void vl_api_get_node_graph_reply_t_handler
2252 (vl_api_get_node_graph_reply_t * mp)
2253{
2254 vat_main_t *vam = &vat_main;
2255 api_main_t *am = &api_main;
2256 i32 retval = ntohl (mp->retval);
2257 u8 *pvt_copy, *reply;
2258 void *oldheap;
2259 vlib_node_t *node;
2260 int i;
2261
2262 if (vam->async_mode)
2263 {
2264 vam->async_errors += (retval < 0);
2265 }
2266 else
2267 {
2268 vam->retval = retval;
2269 vam->result_ready = 1;
2270 }
2271
2272 /* "Should never happen..." */
2273 if (retval != 0)
2274 return;
2275
2276 reply = (u8 *) (mp->reply_in_shmem);
2277 pvt_copy = vec_dup (reply);
2278
2279 /* Toss the shared-memory original... */
2280 pthread_mutex_lock (&am->vlib_rp->mutex);
2281 oldheap = svm_push_data_heap (am->vlib_rp);
2282
2283 vec_free (reply);
2284
2285 svm_pop_heap (oldheap);
2286 pthread_mutex_unlock (&am->vlib_rp->mutex);
2287
2288 if (vam->graph_nodes)
2289 {
2290 hash_free (vam->graph_node_index_by_name);
2291
2292 for (i = 0; i < vec_len (vam->graph_nodes); i++)
2293 {
2294 node = vam->graph_nodes[i];
2295 vec_free (node->name);
2296 vec_free (node->next_nodes);
2297 vec_free (node);
2298 }
2299 vec_free (vam->graph_nodes);
2300 }
2301
2302 vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2303 vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2304 vec_free (pvt_copy);
2305
2306 for (i = 0; i < vec_len (vam->graph_nodes); i++)
2307 {
2308 node = vam->graph_nodes[i];
2309 hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2310 }
2311}
2312
2313static void vl_api_get_node_graph_reply_t_handler_json
2314 (vl_api_get_node_graph_reply_t * mp)
2315{
2316 vat_main_t *vam = &vat_main;
2317 api_main_t *am = &api_main;
2318 void *oldheap;
2319 vat_json_node_t node;
2320 u8 *reply;
2321
2322 /* $$$$ make this real? */
2323 vat_json_init_object (&node);
2324 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2325 vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2326
2327 reply = (u8 *) (mp->reply_in_shmem);
2328
2329 /* Toss the shared-memory original... */
2330 pthread_mutex_lock (&am->vlib_rp->mutex);
2331 oldheap = svm_push_data_heap (am->vlib_rp);
2332
2333 vec_free (reply);
2334
2335 svm_pop_heap (oldheap);
2336 pthread_mutex_unlock (&am->vlib_rp->mutex);
2337
2338 vat_json_print (vam->ofp, &node);
2339 vat_json_free (&node);
2340
2341 vam->retval = ntohl (mp->retval);
2342 vam->result_ready = 1;
2343}
2344
2345static void
2346vl_api_lisp_locator_details_t_handler (vl_api_lisp_locator_details_t * mp)
2347{
2348 vat_main_t *vam = &vat_main;
2349 u8 *s = 0;
2350
2351 if (mp->local)
2352 {
2353 s = format (s, "%=16d%=16d%=16d",
2354 ntohl (mp->sw_if_index), mp->priority, mp->weight);
2355 }
2356 else
2357 {
2358 s = format (s, "%=16U%=16d%=16d",
2359 mp->is_ipv6 ? format_ip6_address :
2360 format_ip4_address,
2361 mp->ip_address, mp->priority, mp->weight);
2362 }
2363
2364 print (vam->ofp, "%v", s);
2365 vec_free (s);
2366}
2367
2368static void
2369vl_api_lisp_locator_details_t_handler_json (vl_api_lisp_locator_details_t *
2370 mp)
2371{
2372 vat_main_t *vam = &vat_main;
2373 vat_json_node_t *node = NULL;
2374 struct in6_addr ip6;
2375 struct in_addr ip4;
2376
2377 if (VAT_JSON_ARRAY != vam->json_tree.type)
2378 {
2379 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2380 vat_json_init_array (&vam->json_tree);
2381 }
2382 node = vat_json_array_add (&vam->json_tree);
2383 vat_json_init_object (node);
2384
2385 vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2386 vat_json_object_add_uint (node, "priority", mp->priority);
2387 vat_json_object_add_uint (node, "weight", mp->weight);
2388
2389 if (mp->local)
2390 vat_json_object_add_uint (node, "sw_if_index",
2391 clib_net_to_host_u32 (mp->sw_if_index));
2392 else
2393 {
2394 if (mp->is_ipv6)
2395 {
2396 clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2397 vat_json_object_add_ip6 (node, "address", ip6);
2398 }
2399 else
2400 {
2401 clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2402 vat_json_object_add_ip4 (node, "address", ip4);
2403 }
2404 }
2405}
2406
2407static void
2408vl_api_lisp_locator_set_details_t_handler (vl_api_lisp_locator_set_details_t *
2409 mp)
2410{
2411 vat_main_t *vam = &vat_main;
2412 u8 *ls_name = 0;
2413
2414 ls_name = format (0, "%s", mp->ls_name);
2415
2416 print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2417 ls_name);
2418 vec_free (ls_name);
2419}
2420
2421static void
2422 vl_api_lisp_locator_set_details_t_handler_json
2423 (vl_api_lisp_locator_set_details_t * mp)
2424{
2425 vat_main_t *vam = &vat_main;
2426 vat_json_node_t *node = 0;
2427 u8 *ls_name = 0;
2428
2429 ls_name = format (0, "%s", mp->ls_name);
2430 vec_add1 (ls_name, 0);
2431
2432 if (VAT_JSON_ARRAY != vam->json_tree.type)
2433 {
2434 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2435 vat_json_init_array (&vam->json_tree);
2436 }
2437 node = vat_json_array_add (&vam->json_tree);
2438
2439 vat_json_init_object (node);
2440 vat_json_object_add_string_copy (node, "ls_name", ls_name);
2441 vat_json_object_add_uint (node, "ls_index",
2442 clib_net_to_host_u32 (mp->ls_index));
2443 vec_free (ls_name);
2444}
2445
2446static u8 *
2447format_lisp_flat_eid (u8 * s, va_list * args)
2448{
2449 u32 type = va_arg (*args, u32);
2450 u8 *eid = va_arg (*args, u8 *);
2451 u32 eid_len = va_arg (*args, u32);
2452
2453 switch (type)
2454 {
2455 case 0:
2456 return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2457 case 1:
2458 return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2459 case 2:
2460 return format (s, "%U", format_ethernet_address, eid);
2461 }
2462 return 0;
2463}
2464
2465static u8 *
2466format_lisp_eid_vat (u8 * s, va_list * args)
2467{
2468 u32 type = va_arg (*args, u32);
2469 u8 *eid = va_arg (*args, u8 *);
2470 u32 eid_len = va_arg (*args, u32);
2471 u8 *seid = va_arg (*args, u8 *);
2472 u32 seid_len = va_arg (*args, u32);
2473 u32 is_src_dst = va_arg (*args, u32);
2474
2475 if (is_src_dst)
2476 s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2477
2478 s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2479
2480 return s;
2481}
2482
2483static void
2484vl_api_lisp_eid_table_details_t_handler (vl_api_lisp_eid_table_details_t * mp)
2485{
2486 vat_main_t *vam = &vat_main;
2487 u8 *s = 0, *eid = 0;
2488
2489 if (~0 == mp->locator_set_index)
2490 s = format (0, "action: %d", mp->action);
2491 else
2492 s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2493
2494 eid = format (0, "%U", format_lisp_eid_vat,
2495 mp->eid_type,
2496 mp->eid,
2497 mp->eid_prefix_len,
2498 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2499 vec_add1 (eid, 0);
2500
2501 print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2502 clib_net_to_host_u32 (mp->vni),
2503 eid,
2504 mp->is_local ? "local" : "remote",
2505 s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2506 clib_net_to_host_u16 (mp->key_id), mp->key);
2507
2508 vec_free (s);
2509 vec_free (eid);
2510}
2511
2512static void
2513vl_api_lisp_eid_table_details_t_handler_json (vl_api_lisp_eid_table_details_t
2514 * mp)
2515{
2516 vat_main_t *vam = &vat_main;
2517 vat_json_node_t *node = 0;
2518 u8 *eid = 0;
2519
2520 if (VAT_JSON_ARRAY != vam->json_tree.type)
2521 {
2522 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2523 vat_json_init_array (&vam->json_tree);
2524 }
2525 node = vat_json_array_add (&vam->json_tree);
2526
2527 vat_json_init_object (node);
2528 if (~0 == mp->locator_set_index)
2529 vat_json_object_add_uint (node, "action", mp->action);
2530 else
2531 vat_json_object_add_uint (node, "locator_set_index",
2532 clib_net_to_host_u32 (mp->locator_set_index));
2533
2534 vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2535 eid = format (0, "%U", format_lisp_eid_vat,
2536 mp->eid_type,
2537 mp->eid,
2538 mp->eid_prefix_len,
2539 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2540 vec_add1 (eid, 0);
2541 vat_json_object_add_string_copy (node, "eid", eid);
2542 vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2543 vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2544 vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2545
2546 if (mp->key_id)
2547 {
2548 vat_json_object_add_uint (node, "key_id",
2549 clib_net_to_host_u16 (mp->key_id));
2550 vat_json_object_add_string_copy (node, "key", mp->key);
2551 }
2552 vec_free (eid);
2553}
2554
2555static void
2556 vl_api_lisp_eid_table_map_details_t_handler
2557 (vl_api_lisp_eid_table_map_details_t * mp)
2558{
2559 vat_main_t *vam = &vat_main;
2560
2561 u8 *line = format (0, "%=10d%=10d",
2562 clib_net_to_host_u32 (mp->vni),
2563 clib_net_to_host_u32 (mp->dp_table));
2564 print (vam->ofp, "%v", line);
2565 vec_free (line);
2566}
2567
2568static void
2569 vl_api_lisp_eid_table_map_details_t_handler_json
2570 (vl_api_lisp_eid_table_map_details_t * mp)
2571{
2572 vat_main_t *vam = &vat_main;
2573 vat_json_node_t *node = NULL;
2574
2575 if (VAT_JSON_ARRAY != vam->json_tree.type)
2576 {
2577 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2578 vat_json_init_array (&vam->json_tree);
2579 }
2580 node = vat_json_array_add (&vam->json_tree);
2581 vat_json_init_object (node);
2582 vat_json_object_add_uint (node, "dp_table",
2583 clib_net_to_host_u32 (mp->dp_table));
2584 vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2585}
2586
2587static void
2588 vl_api_lisp_eid_table_vni_details_t_handler
2589 (vl_api_lisp_eid_table_vni_details_t * mp)
2590{
2591 vat_main_t *vam = &vat_main;
2592
2593 u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2594 print (vam->ofp, "%v", line);
2595 vec_free (line);
2596}
2597
2598static void
2599 vl_api_lisp_eid_table_vni_details_t_handler_json
2600 (vl_api_lisp_eid_table_vni_details_t * mp)
2601{
2602 vat_main_t *vam = &vat_main;
2603 vat_json_node_t *node = NULL;
2604
2605 if (VAT_JSON_ARRAY != vam->json_tree.type)
2606 {
2607 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2608 vat_json_init_array (&vam->json_tree);
2609 }
2610 node = vat_json_array_add (&vam->json_tree);
2611 vat_json_init_object (node);
2612 vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2613}
2614
Damjan Marion7cd468a2016-12-19 23:05:39 +01002615static void
2616 vl_api_show_lisp_map_register_state_reply_t_handler
2617 (vl_api_show_lisp_map_register_state_reply_t * mp)
2618{
2619 vat_main_t *vam = &vat_main;
2620 int retval = clib_net_to_host_u32 (mp->retval);
2621
2622 print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2623
2624 vam->retval = retval;
2625 vam->result_ready = 1;
2626}
2627
2628static void
2629 vl_api_show_lisp_map_register_state_reply_t_handler_json
2630 (vl_api_show_lisp_map_register_state_reply_t * mp)
2631{
2632 vat_main_t *vam = &vat_main;
2633 vat_json_node_t _node, *node = &_node;
2634 int retval = clib_net_to_host_u32 (mp->retval);
2635
2636 u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2637
2638 vat_json_init_object (node);
2639 vat_json_object_add_string_copy (node, "state", s);
2640
2641 vat_json_print (vam->ofp, node);
2642 vat_json_free (node);
2643
2644 vam->retval = retval;
2645 vam->result_ready = 1;
2646 vec_free (s);
2647}
2648
2649static void
2650 vl_api_show_lisp_rloc_probe_state_reply_t_handler
2651 (vl_api_show_lisp_rloc_probe_state_reply_t * mp)
2652{
2653 vat_main_t *vam = &vat_main;
2654 int retval = clib_net_to_host_u32 (mp->retval);
2655
2656 if (retval)
2657 goto end;
2658
2659 print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2660end:
2661 vam->retval = retval;
2662 vam->result_ready = 1;
2663}
2664
2665static void
2666 vl_api_show_lisp_rloc_probe_state_reply_t_handler_json
2667 (vl_api_show_lisp_rloc_probe_state_reply_t * mp)
2668{
2669 vat_main_t *vam = &vat_main;
2670 vat_json_node_t _node, *node = &_node;
2671 int retval = clib_net_to_host_u32 (mp->retval);
2672
2673 u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2674 vat_json_init_object (node);
2675 vat_json_object_add_string_copy (node, "state", s);
2676
2677 vat_json_print (vam->ofp, node);
2678 vat_json_free (node);
2679
2680 vam->retval = retval;
2681 vam->result_ready = 1;
2682 vec_free (s);
2683}
2684
2685static void
Filip Tehlar5fae99c2017-01-18 12:57:37 +01002686api_lisp_gpe_fwd_entry_net_to_host (vl_api_lisp_gpe_fwd_entry_t * e)
2687{
2688 e->dp_table = clib_net_to_host_u32 (e->dp_table);
2689 e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
2690}
2691
2692static void
2693 lisp_gpe_fwd_entries_get_reply_t_net_to_host
2694 (vl_api_lisp_gpe_fwd_entries_get_reply_t * mp)
2695{
2696 u32 i;
2697
2698 mp->count = clib_net_to_host_u32 (mp->count);
2699 for (i = 0; i < mp->count; i++)
2700 {
2701 api_lisp_gpe_fwd_entry_net_to_host (&mp->entries[i]);
2702 }
2703}
2704
2705static void
2706 vl_api_lisp_gpe_fwd_entry_path_details_t_handler
2707 (vl_api_lisp_gpe_fwd_entry_path_details_t * mp)
2708{
2709 vat_main_t *vam = &vat_main;
2710 u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
2711
2712 if (mp->lcl_loc.is_ip4)
2713 format_ip_address_fcn = format_ip4_address;
2714 else
2715 format_ip_address_fcn = format_ip6_address;
2716
2717 print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
2718 format_ip_address_fcn, &mp->lcl_loc,
2719 format_ip_address_fcn, &mp->rmt_loc);
2720}
2721
2722static void
2723lisp_fill_locator_node (vat_json_node_t * n, vl_api_lisp_gpe_locator_t * loc)
2724{
2725 struct in6_addr ip6;
2726 struct in_addr ip4;
2727
2728 if (loc->is_ip4)
2729 {
2730 clib_memcpy (&ip4, loc->addr, sizeof (ip4));
2731 vat_json_object_add_ip4 (n, "address", ip4);
2732 }
2733 else
2734 {
2735 clib_memcpy (&ip6, loc->addr, sizeof (ip6));
2736 vat_json_object_add_ip6 (n, "address", ip6);
2737 }
2738 vat_json_object_add_uint (n, "weight", loc->weight);
2739}
2740
2741static void
2742 vl_api_lisp_gpe_fwd_entry_path_details_t_handler_json
2743 (vl_api_lisp_gpe_fwd_entry_path_details_t * mp)
2744{
2745 vat_main_t *vam = &vat_main;
2746 vat_json_node_t *node = NULL;
2747 vat_json_node_t *loc_node;
2748
2749 if (VAT_JSON_ARRAY != vam->json_tree.type)
2750 {
2751 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2752 vat_json_init_array (&vam->json_tree);
2753 }
2754 node = vat_json_array_add (&vam->json_tree);
2755 vat_json_init_object (node);
2756
2757 loc_node = vat_json_object_add (node, "local_locator");
2758 vat_json_init_object (loc_node);
2759 lisp_fill_locator_node (loc_node, &mp->lcl_loc);
2760
2761 loc_node = vat_json_object_add (node, "remote_locator");
2762 vat_json_init_object (loc_node);
2763 lisp_fill_locator_node (loc_node, &mp->rmt_loc);
2764}
2765
2766static void
2767 vl_api_lisp_gpe_fwd_entries_get_reply_t_handler
2768 (vl_api_lisp_gpe_fwd_entries_get_reply_t * mp)
2769{
2770 vat_main_t *vam = &vat_main;
2771 u32 i;
2772 int retval = clib_net_to_host_u32 (mp->retval);
2773 vl_api_lisp_gpe_fwd_entry_t *e;
2774
2775 if (retval)
2776 goto end;
2777
2778 lisp_gpe_fwd_entries_get_reply_t_net_to_host (mp);
2779
2780 for (i = 0; i < mp->count; i++)
2781 {
2782 e = &mp->entries[i];
2783 print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
2784 format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
2785 format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
2786 }
2787
2788end:
2789 vam->retval = retval;
2790 vam->result_ready = 1;
2791}
2792
2793static void
2794 vl_api_lisp_gpe_fwd_entries_get_reply_t_handler_json
2795 (vl_api_lisp_gpe_fwd_entries_get_reply_t * mp)
2796{
2797 u8 *s = 0;
2798 vat_main_t *vam = &vat_main;
2799 vat_json_node_t *e = 0, root;
2800 u32 i;
2801 int retval = clib_net_to_host_u32 (mp->retval);
2802 vl_api_lisp_gpe_fwd_entry_t *fwd;
2803
2804 if (retval)
2805 goto end;
2806
2807 lisp_gpe_fwd_entries_get_reply_t_net_to_host (mp);
2808 vat_json_init_array (&root);
2809
2810 for (i = 0; i < mp->count; i++)
2811 {
2812 e = vat_json_array_add (&root);
2813 fwd = &mp->entries[i];
2814
2815 vat_json_init_object (e);
2816 vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
2817 vat_json_object_add_int (e, "dp_table", fwd->dp_table);
2818
2819 s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
2820 fwd->leid_prefix_len);
2821 vec_add1 (s, 0);
2822 vat_json_object_add_string_copy (e, "leid", s);
2823 vec_free (s);
2824
2825 s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
2826 fwd->reid_prefix_len);
2827 vec_add1 (s, 0);
2828 vat_json_object_add_string_copy (e, "reid", s);
2829 vec_free (s);
2830 }
2831
2832 vat_json_print (vam->ofp, &root);
2833 vat_json_free (&root);
2834
2835end:
2836 vam->retval = retval;
2837 vam->result_ready = 1;
2838}
2839
2840static void
Damjan Marion7cd468a2016-12-19 23:05:39 +01002841 vl_api_lisp_adjacencies_get_reply_t_handler
2842 (vl_api_lisp_adjacencies_get_reply_t * mp)
2843{
2844 vat_main_t *vam = &vat_main;
2845 u32 i, n;
2846 int retval = clib_net_to_host_u32 (mp->retval);
2847 vl_api_lisp_adjacency_t *a;
2848
2849 if (retval)
2850 goto end;
2851
2852 n = clib_net_to_host_u32 (mp->count);
2853
2854 for (i = 0; i < n; i++)
2855 {
2856 a = &mp->adjacencies[i];
2857 print (vam->ofp, "%U %40U",
2858 format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
2859 format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
2860 }
2861
2862end:
2863 vam->retval = retval;
2864 vam->result_ready = 1;
2865}
2866
2867static void
2868 vl_api_lisp_adjacencies_get_reply_t_handler_json
2869 (vl_api_lisp_adjacencies_get_reply_t * mp)
2870{
2871 u8 *s = 0;
2872 vat_main_t *vam = &vat_main;
2873 vat_json_node_t *e = 0, root;
2874 u32 i, n;
2875 int retval = clib_net_to_host_u32 (mp->retval);
2876 vl_api_lisp_adjacency_t *a;
2877
2878 if (retval)
2879 goto end;
2880
2881 n = clib_net_to_host_u32 (mp->count);
2882 vat_json_init_array (&root);
2883
2884 for (i = 0; i < n; i++)
2885 {
2886 e = vat_json_array_add (&root);
2887 a = &mp->adjacencies[i];
2888
2889 vat_json_init_object (e);
2890 s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
2891 a->leid_prefix_len);
2892 vec_add1 (s, 0);
2893 vat_json_object_add_string_copy (e, "leid", s);
2894 vec_free (s);
2895
2896 s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
2897 a->reid_prefix_len);
2898 vec_add1 (s, 0);
2899 vat_json_object_add_string_copy (e, "reid", s);
2900 vec_free (s);
2901 }
2902
2903 vat_json_print (vam->ofp, &root);
2904 vat_json_free (&root);
2905
2906end:
2907 vam->retval = retval;
2908 vam->result_ready = 1;
2909}
2910
2911static void
2912vl_api_lisp_map_server_details_t_handler (vl_api_lisp_map_server_details_t
2913 * mp)
2914{
2915 vat_main_t *vam = &vat_main;
2916
2917 print (vam->ofp, "%=20U",
2918 mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2919 mp->ip_address);
2920}
2921
2922static void
2923 vl_api_lisp_map_server_details_t_handler_json
2924 (vl_api_lisp_map_server_details_t * mp)
2925{
2926 vat_main_t *vam = &vat_main;
2927 vat_json_node_t *node = NULL;
2928 struct in6_addr ip6;
2929 struct in_addr ip4;
2930
2931 if (VAT_JSON_ARRAY != vam->json_tree.type)
2932 {
2933 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2934 vat_json_init_array (&vam->json_tree);
2935 }
2936 node = vat_json_array_add (&vam->json_tree);
2937
2938 vat_json_init_object (node);
2939 if (mp->is_ipv6)
2940 {
2941 clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2942 vat_json_object_add_ip6 (node, "map-server", ip6);
2943 }
2944 else
2945 {
2946 clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2947 vat_json_object_add_ip4 (node, "map-server", ip4);
2948 }
2949}
2950
2951static void
2952vl_api_lisp_map_resolver_details_t_handler (vl_api_lisp_map_resolver_details_t
2953 * mp)
2954{
2955 vat_main_t *vam = &vat_main;
2956
2957 print (vam->ofp, "%=20U",
2958 mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2959 mp->ip_address);
2960}
2961
2962static void
2963 vl_api_lisp_map_resolver_details_t_handler_json
2964 (vl_api_lisp_map_resolver_details_t * mp)
2965{
2966 vat_main_t *vam = &vat_main;
2967 vat_json_node_t *node = NULL;
2968 struct in6_addr ip6;
2969 struct in_addr ip4;
2970
2971 if (VAT_JSON_ARRAY != vam->json_tree.type)
2972 {
2973 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2974 vat_json_init_array (&vam->json_tree);
2975 }
2976 node = vat_json_array_add (&vam->json_tree);
2977
2978 vat_json_init_object (node);
2979 if (mp->is_ipv6)
2980 {
2981 clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2982 vat_json_object_add_ip6 (node, "map resolver", ip6);
2983 }
2984 else
2985 {
2986 clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2987 vat_json_object_add_ip4 (node, "map resolver", ip4);
2988 }
2989}
2990
2991static void
2992 vl_api_show_lisp_status_reply_t_handler
2993 (vl_api_show_lisp_status_reply_t * mp)
2994{
2995 vat_main_t *vam = &vat_main;
2996 i32 retval = ntohl (mp->retval);
2997
2998 if (0 <= retval)
2999 {
3000 print (vam->ofp, "feature: %s\ngpe: %s",
3001 mp->feature_status ? "enabled" : "disabled",
3002 mp->gpe_status ? "enabled" : "disabled");
3003 }
3004
3005 vam->retval = retval;
3006 vam->result_ready = 1;
3007}
3008
3009static void
3010 vl_api_show_lisp_status_reply_t_handler_json
3011 (vl_api_show_lisp_status_reply_t * mp)
3012{
3013 vat_main_t *vam = &vat_main;
3014 vat_json_node_t node;
3015 u8 *gpe_status = NULL;
3016 u8 *feature_status = NULL;
3017
3018 gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
3019 feature_status = format (0, "%s",
3020 mp->feature_status ? "enabled" : "disabled");
3021 vec_add1 (gpe_status, 0);
3022 vec_add1 (feature_status, 0);
3023
3024 vat_json_init_object (&node);
3025 vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
3026 vat_json_object_add_string_copy (&node, "feature_status", feature_status);
3027
3028 vec_free (gpe_status);
3029 vec_free (feature_status);
3030
3031 vat_json_print (vam->ofp, &node);
3032 vat_json_free (&node);
3033
3034 vam->retval = ntohl (mp->retval);
3035 vam->result_ready = 1;
3036}
3037
3038static void
3039 vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler
3040 (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
3041{
3042 vat_main_t *vam = &vat_main;
3043 i32 retval = ntohl (mp->retval);
3044
3045 if (retval >= 0)
3046 {
3047 print (vam->ofp, "%=20s", mp->locator_set_name);
3048 }
3049
3050 vam->retval = retval;
3051 vam->result_ready = 1;
3052}
3053
3054static void
3055 vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler_json
3056 (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
3057{
3058 vat_main_t *vam = &vat_main;
3059 vat_json_node_t *node = NULL;
3060
3061 if (VAT_JSON_ARRAY != vam->json_tree.type)
3062 {
3063 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3064 vat_json_init_array (&vam->json_tree);
3065 }
3066 node = vat_json_array_add (&vam->json_tree);
3067
3068 vat_json_init_object (node);
3069 vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
3070
3071 vat_json_print (vam->ofp, node);
3072 vat_json_free (node);
3073
3074 vam->retval = ntohl (mp->retval);
3075 vam->result_ready = 1;
3076}
3077
3078static u8 *
3079format_lisp_map_request_mode (u8 * s, va_list * args)
3080{
3081 u32 mode = va_arg (*args, u32);
3082
3083 switch (mode)
3084 {
3085 case 0:
3086 return format (0, "dst-only");
3087 case 1:
3088 return format (0, "src-dst");
3089 }
3090 return 0;
3091}
3092
3093static void
3094 vl_api_show_lisp_map_request_mode_reply_t_handler
3095 (vl_api_show_lisp_map_request_mode_reply_t * mp)
3096{
3097 vat_main_t *vam = &vat_main;
3098 i32 retval = ntohl (mp->retval);
3099
3100 if (0 <= retval)
3101 {
3102 u32 mode = mp->mode;
3103 print (vam->ofp, "map_request_mode: %U",
3104 format_lisp_map_request_mode, mode);
3105 }
3106
3107 vam->retval = retval;
3108 vam->result_ready = 1;
3109}
3110
3111static void
3112 vl_api_show_lisp_map_request_mode_reply_t_handler_json
3113 (vl_api_show_lisp_map_request_mode_reply_t * mp)
3114{
3115 vat_main_t *vam = &vat_main;
3116 vat_json_node_t node;
3117 u8 *s = 0;
3118 u32 mode;
3119
3120 mode = mp->mode;
3121 s = format (0, "%U", format_lisp_map_request_mode, mode);
3122 vec_add1 (s, 0);
3123
3124 vat_json_init_object (&node);
3125 vat_json_object_add_string_copy (&node, "map_request_mode", s);
3126 vat_json_print (vam->ofp, &node);
3127 vat_json_free (&node);
3128
3129 vec_free (s);
3130 vam->retval = ntohl (mp->retval);
3131 vam->result_ready = 1;
3132}
3133
3134static void
3135vl_api_show_lisp_pitr_reply_t_handler (vl_api_show_lisp_pitr_reply_t * mp)
3136{
3137 vat_main_t *vam = &vat_main;
3138 i32 retval = ntohl (mp->retval);
3139
3140 if (0 <= retval)
3141 {
3142 print (vam->ofp, "%-20s%-16s",
3143 mp->status ? "enabled" : "disabled",
3144 mp->status ? (char *) mp->locator_set_name : "");
3145 }
3146
3147 vam->retval = retval;
3148 vam->result_ready = 1;
3149}
3150
3151static void
3152vl_api_show_lisp_pitr_reply_t_handler_json (vl_api_show_lisp_pitr_reply_t *
3153 mp)
3154{
3155 vat_main_t *vam = &vat_main;
3156 vat_json_node_t node;
3157 u8 *status = 0;
3158
3159 status = format (0, "%s", mp->status ? "enabled" : "disabled");
3160 vec_add1 (status, 0);
3161
3162 vat_json_init_object (&node);
3163 vat_json_object_add_string_copy (&node, "status", status);
3164 if (mp->status)
3165 {
3166 vat_json_object_add_string_copy (&node, "locator_set",
3167 mp->locator_set_name);
3168 }
3169
3170 vec_free (status);
3171
3172 vat_json_print (vam->ofp, &node);
3173 vat_json_free (&node);
3174
3175 vam->retval = ntohl (mp->retval);
3176 vam->result_ready = 1;
3177}
3178
3179static u8 *
3180format_policer_type (u8 * s, va_list * va)
3181{
3182 u32 i = va_arg (*va, u32);
3183
3184 if (i == SSE2_QOS_POLICER_TYPE_1R2C)
3185 s = format (s, "1r2c");
3186 else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
3187 s = format (s, "1r3c");
3188 else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
3189 s = format (s, "2r3c-2698");
3190 else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
3191 s = format (s, "2r3c-4115");
3192 else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
3193 s = format (s, "2r3c-mef5cf1");
3194 else
3195 s = format (s, "ILLEGAL");
3196 return s;
3197}
3198
3199static u8 *
3200format_policer_rate_type (u8 * s, va_list * va)
3201{
3202 u32 i = va_arg (*va, u32);
3203
3204 if (i == SSE2_QOS_RATE_KBPS)
3205 s = format (s, "kbps");
3206 else if (i == SSE2_QOS_RATE_PPS)
3207 s = format (s, "pps");
3208 else
3209 s = format (s, "ILLEGAL");
3210 return s;
3211}
3212
3213static u8 *
3214format_policer_round_type (u8 * s, va_list * va)
3215{
3216 u32 i = va_arg (*va, u32);
3217
3218 if (i == SSE2_QOS_ROUND_TO_CLOSEST)
3219 s = format (s, "closest");
3220 else if (i == SSE2_QOS_ROUND_TO_UP)
3221 s = format (s, "up");
3222 else if (i == SSE2_QOS_ROUND_TO_DOWN)
3223 s = format (s, "down");
3224 else
3225 s = format (s, "ILLEGAL");
3226 return s;
3227}
3228
3229static u8 *
3230format_policer_action_type (u8 * s, va_list * va)
3231{
3232 u32 i = va_arg (*va, u32);
3233
3234 if (i == SSE2_QOS_ACTION_DROP)
3235 s = format (s, "drop");
3236 else if (i == SSE2_QOS_ACTION_TRANSMIT)
3237 s = format (s, "transmit");
3238 else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3239 s = format (s, "mark-and-transmit");
3240 else
3241 s = format (s, "ILLEGAL");
3242 return s;
3243}
3244
3245static u8 *
3246format_dscp (u8 * s, va_list * va)
3247{
3248 u32 i = va_arg (*va, u32);
3249 char *t = 0;
3250
3251 switch (i)
3252 {
3253#define _(v,f,str) case VNET_DSCP_##f: t = str; break;
3254 foreach_vnet_dscp
3255#undef _
3256 default:
3257 return format (s, "ILLEGAL");
3258 }
3259 s = format (s, "%s", t);
3260 return s;
3261}
3262
3263static void
3264vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
3265{
3266 vat_main_t *vam = &vat_main;
3267 u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
3268
3269 if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3270 conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3271 else
3272 conform_dscp_str = format (0, "");
3273
3274 if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3275 exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3276 else
3277 exceed_dscp_str = format (0, "");
3278
3279 if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3280 violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3281 else
3282 violate_dscp_str = format (0, "");
3283
3284 print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
3285 "rate type %U, round type %U, %s rate, %s color-aware, "
3286 "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
3287 "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
3288 "conform action %U%s, exceed action %U%s, violate action %U%s",
3289 mp->name,
3290 format_policer_type, mp->type,
3291 ntohl (mp->cir),
3292 ntohl (mp->eir),
3293 clib_net_to_host_u64 (mp->cb),
3294 clib_net_to_host_u64 (mp->eb),
3295 format_policer_rate_type, mp->rate_type,
3296 format_policer_round_type, mp->round_type,
3297 mp->single_rate ? "single" : "dual",
3298 mp->color_aware ? "is" : "not",
3299 ntohl (mp->cir_tokens_per_period),
3300 ntohl (mp->pir_tokens_per_period),
3301 ntohl (mp->scale),
3302 ntohl (mp->current_limit),
3303 ntohl (mp->current_bucket),
3304 ntohl (mp->extended_limit),
3305 ntohl (mp->extended_bucket),
3306 clib_net_to_host_u64 (mp->last_update_time),
3307 format_policer_action_type, mp->conform_action_type,
3308 conform_dscp_str,
3309 format_policer_action_type, mp->exceed_action_type,
3310 exceed_dscp_str,
3311 format_policer_action_type, mp->violate_action_type,
3312 violate_dscp_str);
3313
3314 vec_free (conform_dscp_str);
3315 vec_free (exceed_dscp_str);
3316 vec_free (violate_dscp_str);
3317}
3318
3319static void vl_api_policer_details_t_handler_json
3320 (vl_api_policer_details_t * mp)
3321{
3322 vat_main_t *vam = &vat_main;
3323 vat_json_node_t *node;
3324 u8 *rate_type_str, *round_type_str, *type_str;
3325 u8 *conform_action_str, *exceed_action_str, *violate_action_str;
3326
3327 rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
3328 round_type_str =
3329 format (0, "%U", format_policer_round_type, mp->round_type);
3330 type_str = format (0, "%U", format_policer_type, mp->type);
3331 conform_action_str = format (0, "%U", format_policer_action_type,
3332 mp->conform_action_type);
3333 exceed_action_str = format (0, "%U", format_policer_action_type,
3334 mp->exceed_action_type);
3335 violate_action_str = format (0, "%U", format_policer_action_type,
3336 mp->violate_action_type);
3337
3338 if (VAT_JSON_ARRAY != vam->json_tree.type)
3339 {
3340 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3341 vat_json_init_array (&vam->json_tree);
3342 }
3343 node = vat_json_array_add (&vam->json_tree);
3344
3345 vat_json_init_object (node);
3346 vat_json_object_add_string_copy (node, "name", mp->name);
3347 vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3348 vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
3349 vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
3350 vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
3351 vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3352 vat_json_object_add_string_copy (node, "round_type", round_type_str);
3353 vat_json_object_add_string_copy (node, "type", type_str);
3354 vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3355 vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3356 vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3357 vat_json_object_add_uint (node, "cir_tokens_per_period",
3358 ntohl (mp->cir_tokens_per_period));
3359 vat_json_object_add_uint (node, "eir_tokens_per_period",
3360 ntohl (mp->pir_tokens_per_period));
3361 vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3362 vat_json_object_add_uint (node, "current_bucket",
3363 ntohl (mp->current_bucket));
3364 vat_json_object_add_uint (node, "extended_limit",
3365 ntohl (mp->extended_limit));
3366 vat_json_object_add_uint (node, "extended_bucket",
3367 ntohl (mp->extended_bucket));
3368 vat_json_object_add_uint (node, "last_update_time",
3369 ntohl (mp->last_update_time));
3370 vat_json_object_add_string_copy (node, "conform_action",
3371 conform_action_str);
3372 if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3373 {
3374 u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3375 vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3376 vec_free (dscp_str);
3377 }
3378 vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3379 if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3380 {
3381 u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3382 vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3383 vec_free (dscp_str);
3384 }
3385 vat_json_object_add_string_copy (node, "violate_action",
3386 violate_action_str);
3387 if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3388 {
3389 u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3390 vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3391 vec_free (dscp_str);
3392 }
3393
3394 vec_free (rate_type_str);
3395 vec_free (round_type_str);
3396 vec_free (type_str);
3397 vec_free (conform_action_str);
3398 vec_free (exceed_action_str);
3399 vec_free (violate_action_str);
3400}
3401
3402static void
3403vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3404 mp)
3405{
3406 vat_main_t *vam = &vat_main;
3407 int i, count = ntohl (mp->count);
3408
3409 if (count > 0)
3410 print (vam->ofp, "classify table ids (%d) : ", count);
3411 for (i = 0; i < count; i++)
3412 {
3413 print (vam->ofp, "%d", ntohl (mp->ids[i]));
3414 print (vam->ofp, (i < count - 1) ? "," : "");
3415 }
3416 vam->retval = ntohl (mp->retval);
3417 vam->result_ready = 1;
3418}
3419
3420static void
3421 vl_api_classify_table_ids_reply_t_handler_json
3422 (vl_api_classify_table_ids_reply_t * mp)
3423{
3424 vat_main_t *vam = &vat_main;
3425 int i, count = ntohl (mp->count);
3426
3427 if (count > 0)
3428 {
3429 vat_json_node_t node;
3430
3431 vat_json_init_object (&node);
3432 for (i = 0; i < count; i++)
3433 {
3434 vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3435 }
3436 vat_json_print (vam->ofp, &node);
3437 vat_json_free (&node);
3438 }
3439 vam->retval = ntohl (mp->retval);
3440 vam->result_ready = 1;
3441}
3442
3443static void
3444 vl_api_classify_table_by_interface_reply_t_handler
3445 (vl_api_classify_table_by_interface_reply_t * mp)
3446{
3447 vat_main_t *vam = &vat_main;
3448 u32 table_id;
3449
3450 table_id = ntohl (mp->l2_table_id);
3451 if (table_id != ~0)
3452 print (vam->ofp, "l2 table id : %d", table_id);
3453 else
3454 print (vam->ofp, "l2 table id : No input ACL tables configured");
3455 table_id = ntohl (mp->ip4_table_id);
3456 if (table_id != ~0)
3457 print (vam->ofp, "ip4 table id : %d", table_id);
3458 else
3459 print (vam->ofp, "ip4 table id : No input ACL tables configured");
3460 table_id = ntohl (mp->ip6_table_id);
3461 if (table_id != ~0)
3462 print (vam->ofp, "ip6 table id : %d", table_id);
3463 else
3464 print (vam->ofp, "ip6 table id : No input ACL tables configured");
3465 vam->retval = ntohl (mp->retval);
3466 vam->result_ready = 1;
3467}
3468
3469static void
3470 vl_api_classify_table_by_interface_reply_t_handler_json
3471 (vl_api_classify_table_by_interface_reply_t * mp)
3472{
3473 vat_main_t *vam = &vat_main;
3474 vat_json_node_t node;
3475
3476 vat_json_init_object (&node);
3477
3478 vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3479 vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3480 vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3481
3482 vat_json_print (vam->ofp, &node);
3483 vat_json_free (&node);
3484
3485 vam->retval = ntohl (mp->retval);
3486 vam->result_ready = 1;
3487}
3488
3489static void vl_api_policer_add_del_reply_t_handler
3490 (vl_api_policer_add_del_reply_t * mp)
3491{
3492 vat_main_t *vam = &vat_main;
3493 i32 retval = ntohl (mp->retval);
3494 if (vam->async_mode)
3495 {
3496 vam->async_errors += (retval < 0);
3497 }
3498 else
3499 {
3500 vam->retval = retval;
3501 vam->result_ready = 1;
3502 if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3503 /*
3504 * Note: this is just barely thread-safe, depends on
3505 * the main thread spinning waiting for an answer...
3506 */
3507 errmsg ("policer index %d", ntohl (mp->policer_index));
3508 }
3509}
3510
3511static void vl_api_policer_add_del_reply_t_handler_json
3512 (vl_api_policer_add_del_reply_t * mp)
3513{
3514 vat_main_t *vam = &vat_main;
3515 vat_json_node_t node;
3516
3517 vat_json_init_object (&node);
3518 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3519 vat_json_object_add_uint (&node, "policer_index",
3520 ntohl (mp->policer_index));
3521
3522 vat_json_print (vam->ofp, &node);
3523 vat_json_free (&node);
3524
3525 vam->retval = ntohl (mp->retval);
3526 vam->result_ready = 1;
3527}
3528
3529/* Format hex dump. */
3530u8 *
3531format_hex_bytes (u8 * s, va_list * va)
3532{
3533 u8 *bytes = va_arg (*va, u8 *);
3534 int n_bytes = va_arg (*va, int);
3535 uword i;
3536
3537 /* Print short or long form depending on byte count. */
3538 uword short_form = n_bytes <= 32;
3539 uword indent = format_get_indent (s);
3540
3541 if (n_bytes == 0)
3542 return s;
3543
3544 for (i = 0; i < n_bytes; i++)
3545 {
3546 if (!short_form && (i % 32) == 0)
3547 s = format (s, "%08x: ", i);
3548 s = format (s, "%02x", bytes[i]);
3549 if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3550 s = format (s, "\n%U", format_white_space, indent);
3551 }
3552
3553 return s;
3554}
3555
3556static void
3557vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3558 * mp)
3559{
3560 vat_main_t *vam = &vat_main;
3561 i32 retval = ntohl (mp->retval);
3562 if (retval == 0)
3563 {
3564 print (vam->ofp, "classify table info :");
3565 print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
3566 ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3567 ntohl (mp->miss_next_index));
3568 print (vam->ofp, "nbuckets: %d skip: %d match: %d",
3569 ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3570 ntohl (mp->match_n_vectors));
3571 print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
3572 ntohl (mp->mask_length));
3573 }
3574 vam->retval = retval;
3575 vam->result_ready = 1;
3576}
3577
3578static void
3579 vl_api_classify_table_info_reply_t_handler_json
3580 (vl_api_classify_table_info_reply_t * mp)
3581{
3582 vat_main_t *vam = &vat_main;
3583 vat_json_node_t node;
3584
3585 i32 retval = ntohl (mp->retval);
3586 if (retval == 0)
3587 {
3588 vat_json_init_object (&node);
3589
3590 vat_json_object_add_int (&node, "sessions",
3591 ntohl (mp->active_sessions));
3592 vat_json_object_add_int (&node, "nexttbl",
3593 ntohl (mp->next_table_index));
3594 vat_json_object_add_int (&node, "nextnode",
3595 ntohl (mp->miss_next_index));
3596 vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3597 vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3598 vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3599 u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3600 ntohl (mp->mask_length), 0);
3601 vat_json_object_add_string_copy (&node, "mask", s);
3602
3603 vat_json_print (vam->ofp, &node);
3604 vat_json_free (&node);
3605 }
3606 vam->retval = ntohl (mp->retval);
3607 vam->result_ready = 1;
3608}
3609
3610static void
3611vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3612 mp)
3613{
3614 vat_main_t *vam = &vat_main;
3615
3616 print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3617 ntohl (mp->hit_next_index), ntohl (mp->advance),
3618 ntohl (mp->opaque_index));
3619 print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
3620 ntohl (mp->match_length));
3621}
3622
3623static void
3624 vl_api_classify_session_details_t_handler_json
3625 (vl_api_classify_session_details_t * mp)
3626{
3627 vat_main_t *vam = &vat_main;
3628 vat_json_node_t *node = NULL;
3629
3630 if (VAT_JSON_ARRAY != vam->json_tree.type)
3631 {
3632 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3633 vat_json_init_array (&vam->json_tree);
3634 }
3635 node = vat_json_array_add (&vam->json_tree);
3636
3637 vat_json_init_object (node);
3638 vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3639 vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3640 vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3641 u8 *s =
3642 format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3643 0);
3644 vat_json_object_add_string_copy (node, "match", s);
3645}
3646
3647static void vl_api_pg_create_interface_reply_t_handler
3648 (vl_api_pg_create_interface_reply_t * mp)
3649{
3650 vat_main_t *vam = &vat_main;
3651
3652 vam->retval = ntohl (mp->retval);
3653 vam->result_ready = 1;
3654}
3655
3656static void vl_api_pg_create_interface_reply_t_handler_json
3657 (vl_api_pg_create_interface_reply_t * mp)
3658{
3659 vat_main_t *vam = &vat_main;
3660 vat_json_node_t node;
3661
3662 i32 retval = ntohl (mp->retval);
3663 if (retval == 0)
3664 {
3665 vat_json_init_object (&node);
3666
3667 vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3668
3669 vat_json_print (vam->ofp, &node);
3670 vat_json_free (&node);
3671 }
3672 vam->retval = ntohl (mp->retval);
3673 vam->result_ready = 1;
3674}
3675
3676static void vl_api_policer_classify_details_t_handler
3677 (vl_api_policer_classify_details_t * mp)
3678{
3679 vat_main_t *vam = &vat_main;
3680
3681 print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3682 ntohl (mp->table_index));
3683}
3684
3685static void vl_api_policer_classify_details_t_handler_json
3686 (vl_api_policer_classify_details_t * mp)
3687{
3688 vat_main_t *vam = &vat_main;
3689 vat_json_node_t *node;
3690
3691 if (VAT_JSON_ARRAY != vam->json_tree.type)
3692 {
3693 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3694 vat_json_init_array (&vam->json_tree);
3695 }
3696 node = vat_json_array_add (&vam->json_tree);
3697
3698 vat_json_init_object (node);
3699 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3700 vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3701}
3702
3703static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3704 (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3705{
3706 vat_main_t *vam = &vat_main;
3707 i32 retval = ntohl (mp->retval);
3708 if (vam->async_mode)
3709 {
3710 vam->async_errors += (retval < 0);
3711 }
3712 else
3713 {
3714 vam->retval = retval;
3715 vam->sw_if_index = ntohl (mp->sw_if_index);
3716 vam->result_ready = 1;
3717 }
3718}
3719
3720static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3721 (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3722{
3723 vat_main_t *vam = &vat_main;
3724 vat_json_node_t node;
3725
3726 vat_json_init_object (&node);
3727 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3728 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3729
3730 vat_json_print (vam->ofp, &node);
3731 vat_json_free (&node);
3732
3733 vam->retval = ntohl (mp->retval);
3734 vam->result_ready = 1;
3735}
3736
3737static void vl_api_flow_classify_details_t_handler
3738 (vl_api_flow_classify_details_t * mp)
3739{
3740 vat_main_t *vam = &vat_main;
3741
3742 print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3743 ntohl (mp->table_index));
3744}
3745
3746static void vl_api_flow_classify_details_t_handler_json
3747 (vl_api_flow_classify_details_t * mp)
3748{
3749 vat_main_t *vam = &vat_main;
3750 vat_json_node_t *node;
3751
3752 if (VAT_JSON_ARRAY != vam->json_tree.type)
3753 {
3754 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3755 vat_json_init_array (&vam->json_tree);
3756 }
3757 node = vat_json_array_add (&vam->json_tree);
3758
3759 vat_json_init_object (node);
3760 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3761 vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3762}
3763
3764
3765
3766#define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3767#define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3768#define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3769#define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
Neale Ranns044183f2017-01-24 01:34:25 -08003770#define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
3771#define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
3772#define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
3773#define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
Damjan Marion7cd468a2016-12-19 23:05:39 +01003774#define vl_api_lisp_adjacencies_get_reply_t_endian vl_noop_handler
3775#define vl_api_lisp_adjacencies_get_reply_t_print vl_noop_handler
3776
3777/*
3778 * Generate boilerplate reply handlers, which
3779 * dig the return value out of the xxx_reply_t API message,
3780 * stick it into vam->retval, and set vam->result_ready
3781 *
3782 * Could also do this by pointing N message decode slots at
3783 * a single function, but that could break in subtle ways.
3784 */
3785
3786#define foreach_standard_reply_retval_handler \
3787_(sw_interface_set_flags_reply) \
3788_(sw_interface_add_del_address_reply) \
3789_(sw_interface_set_table_reply) \
3790_(sw_interface_set_mpls_enable_reply) \
3791_(sw_interface_set_vpath_reply) \
3792_(sw_interface_set_vxlan_bypass_reply) \
3793_(sw_interface_set_l2_bridge_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003794_(bridge_domain_add_del_reply) \
3795_(sw_interface_set_l2_xconnect_reply) \
3796_(l2fib_add_del_reply) \
3797_(ip_add_del_route_reply) \
Neale Ranns32e1c012016-11-22 17:07:28 +00003798_(ip_mroute_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003799_(mpls_route_add_del_reply) \
3800_(mpls_ip_bind_unbind_reply) \
3801_(proxy_arp_add_del_reply) \
3802_(proxy_arp_intfc_enable_disable_reply) \
3803_(sw_interface_set_unnumbered_reply) \
3804_(ip_neighbor_add_del_reply) \
3805_(reset_vrf_reply) \
3806_(oam_add_del_reply) \
3807_(reset_fib_reply) \
3808_(dhcp_proxy_config_reply) \
3809_(dhcp_proxy_config_2_reply) \
3810_(dhcp_proxy_set_vss_reply) \
3811_(dhcp_client_config_reply) \
3812_(set_ip_flow_hash_reply) \
3813_(sw_interface_ip6_enable_disable_reply) \
3814_(sw_interface_ip6_set_link_local_address_reply) \
3815_(sw_interface_ip6nd_ra_prefix_reply) \
3816_(sw_interface_ip6nd_ra_config_reply) \
3817_(set_arp_neighbor_limit_reply) \
3818_(l2_patch_add_del_reply) \
3819_(sr_tunnel_add_del_reply) \
3820_(sr_policy_add_del_reply) \
3821_(sr_multicast_map_add_del_reply) \
3822_(classify_add_del_session_reply) \
3823_(classify_set_interface_ip_table_reply) \
3824_(classify_set_interface_l2_tables_reply) \
3825_(l2tpv3_set_tunnel_cookies_reply) \
3826_(l2tpv3_interface_enable_disable_reply) \
3827_(l2tpv3_set_lookup_key_reply) \
3828_(l2_fib_clear_table_reply) \
3829_(l2_interface_efp_filter_reply) \
3830_(l2_interface_vlan_tag_rewrite_reply) \
3831_(modify_vhost_user_if_reply) \
3832_(delete_vhost_user_if_reply) \
3833_(want_ip4_arp_events_reply) \
3834_(want_ip6_nd_events_reply) \
3835_(input_acl_set_interface_reply) \
3836_(ipsec_spd_add_del_reply) \
3837_(ipsec_interface_add_del_spd_reply) \
3838_(ipsec_spd_add_del_entry_reply) \
3839_(ipsec_sad_add_del_entry_reply) \
3840_(ipsec_sa_set_key_reply) \
3841_(ikev2_profile_add_del_reply) \
3842_(ikev2_profile_set_auth_reply) \
3843_(ikev2_profile_set_id_reply) \
3844_(ikev2_profile_set_ts_reply) \
3845_(ikev2_set_local_key_reply) \
Radu Nicolaucb33dc22017-02-16 16:49:46 +00003846_(ikev2_set_responder_reply) \
3847_(ikev2_set_ike_transforms_reply) \
3848_(ikev2_set_esp_transforms_reply) \
3849_(ikev2_set_sa_lifetime_reply) \
3850_(ikev2_initiate_sa_init_reply) \
3851_(ikev2_initiate_del_ike_sa_reply) \
3852_(ikev2_initiate_del_child_sa_reply) \
3853_(ikev2_initiate_rekey_child_sa_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003854_(delete_loopback_reply) \
3855_(bd_ip_mac_add_del_reply) \
3856_(map_del_domain_reply) \
3857_(map_add_del_rule_reply) \
3858_(want_interface_events_reply) \
3859_(want_stats_reply) \
3860_(cop_interface_enable_disable_reply) \
3861_(cop_whitelist_enable_disable_reply) \
3862_(sw_interface_clear_stats_reply) \
3863_(ioam_enable_reply) \
3864_(ioam_disable_reply) \
3865_(lisp_add_del_locator_reply) \
3866_(lisp_add_del_local_eid_reply) \
3867_(lisp_add_del_remote_mapping_reply) \
3868_(lisp_add_del_adjacency_reply) \
3869_(lisp_gpe_add_del_fwd_entry_reply) \
3870_(lisp_add_del_map_resolver_reply) \
3871_(lisp_add_del_map_server_reply) \
3872_(lisp_gpe_enable_disable_reply) \
3873_(lisp_gpe_add_del_iface_reply) \
3874_(lisp_enable_disable_reply) \
3875_(lisp_rloc_probe_enable_disable_reply) \
3876_(lisp_map_register_enable_disable_reply) \
3877_(lisp_pitr_set_locator_set_reply) \
3878_(lisp_map_request_mode_reply) \
3879_(lisp_add_del_map_request_itr_rlocs_reply) \
3880_(lisp_eid_table_add_del_map_reply) \
3881_(vxlan_gpe_add_del_tunnel_reply) \
3882_(af_packet_delete_reply) \
3883_(policer_classify_set_interface_reply) \
3884_(netmap_create_reply) \
3885_(netmap_delete_reply) \
3886_(set_ipfix_exporter_reply) \
3887_(set_ipfix_classify_stream_reply) \
3888_(ipfix_classify_table_add_del_reply) \
3889_(flow_classify_set_interface_reply) \
3890_(sw_interface_span_enable_disable_reply) \
3891_(pg_capture_reply) \
3892_(pg_enable_disable_reply) \
3893_(ip_source_and_port_range_check_add_del_reply) \
3894_(ip_source_and_port_range_check_interface_add_del_reply)\
3895_(delete_subif_reply) \
3896_(l2_interface_pbb_tag_rewrite_reply) \
3897_(punt_reply) \
3898_(feature_enable_disable_reply) \
3899_(sw_interface_tag_add_del_reply) \
3900_(sw_interface_set_mtu_reply)
3901
Pavel Kotucek738f3f22017-01-09 15:11:03 +01003902#if DPDK > 0
3903#define foreach_standard_dpdk_reply_retval_handler \
3904_(sw_interface_set_dpdk_hqos_pipe_reply) \
3905_(sw_interface_set_dpdk_hqos_subport_reply) \
3906_(sw_interface_set_dpdk_hqos_tctbl_reply)
3907#endif
3908
Damjan Marion7cd468a2016-12-19 23:05:39 +01003909#define _(n) \
3910 static void vl_api_##n##_t_handler \
3911 (vl_api_##n##_t * mp) \
3912 { \
3913 vat_main_t * vam = &vat_main; \
3914 i32 retval = ntohl(mp->retval); \
3915 if (vam->async_mode) { \
3916 vam->async_errors += (retval < 0); \
3917 } else { \
3918 vam->retval = retval; \
3919 vam->result_ready = 1; \
3920 } \
3921 }
3922foreach_standard_reply_retval_handler;
3923#undef _
3924
3925#define _(n) \
3926 static void vl_api_##n##_t_handler_json \
3927 (vl_api_##n##_t * mp) \
3928 { \
3929 vat_main_t * vam = &vat_main; \
3930 vat_json_node_t node; \
3931 vat_json_init_object(&node); \
3932 vat_json_object_add_int(&node, "retval", ntohl(mp->retval)); \
3933 vat_json_print(vam->ofp, &node); \
3934 vam->retval = ntohl(mp->retval); \
3935 vam->result_ready = 1; \
3936 }
3937foreach_standard_reply_retval_handler;
3938#undef _
3939
Pavel Kotucek738f3f22017-01-09 15:11:03 +01003940#if DPDK > 0
3941#define _(n) \
3942 static void vl_api_##n##_t_handler \
3943 (vl_api_##n##_t * mp) \
3944 { \
3945 vat_main_t * vam = &vat_main; \
3946 i32 retval = ntohl(mp->retval); \
3947 if (vam->async_mode) { \
3948 vam->async_errors += (retval < 0); \
3949 } else { \
3950 vam->retval = retval; \
3951 vam->result_ready = 1; \
3952 } \
3953 }
3954foreach_standard_dpdk_reply_retval_handler;
3955#undef _
3956
3957#define _(n) \
3958 static void vl_api_##n##_t_handler_json \
3959 (vl_api_##n##_t * mp) \
3960 { \
3961 vat_main_t * vam = &vat_main; \
3962 vat_json_node_t node; \
3963 vat_json_init_object(&node); \
3964 vat_json_object_add_int(&node, "retval", ntohl(mp->retval)); \
3965 vat_json_print(vam->ofp, &node); \
3966 vam->retval = ntohl(mp->retval); \
3967 vam->result_ready = 1; \
3968 }
3969foreach_standard_dpdk_reply_retval_handler;
3970#undef _
3971#endif
3972
Damjan Marion7cd468a2016-12-19 23:05:39 +01003973/*
3974 * Table of message reply handlers, must include boilerplate handlers
3975 * we just generated
3976 */
3977
3978#define foreach_vpe_api_reply_msg \
3979_(CREATE_LOOPBACK_REPLY, create_loopback_reply) \
3980_(SW_INTERFACE_DETAILS, sw_interface_details) \
3981_(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags) \
3982_(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply) \
3983_(CONTROL_PING_REPLY, control_ping_reply) \
3984_(CLI_REPLY, cli_reply) \
3985_(CLI_INBAND_REPLY, cli_inband_reply) \
3986_(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY, \
3987 sw_interface_add_del_address_reply) \
3988_(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply) \
3989_(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
3990_(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply) \
3991_(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
3992_(SW_INTERFACE_SET_L2_XCONNECT_REPLY, \
3993 sw_interface_set_l2_xconnect_reply) \
3994_(SW_INTERFACE_SET_L2_BRIDGE_REPLY, \
3995 sw_interface_set_l2_bridge_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01003996_(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply) \
3997_(BRIDGE_DOMAIN_DETAILS, bridge_domain_details) \
3998_(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details) \
3999_(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply) \
4000_(L2_FLAGS_REPLY, l2_flags_reply) \
4001_(BRIDGE_FLAGS_REPLY, bridge_flags_reply) \
4002_(TAP_CONNECT_REPLY, tap_connect_reply) \
4003_(TAP_MODIFY_REPLY, tap_modify_reply) \
4004_(TAP_DELETE_REPLY, tap_delete_reply) \
4005_(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details) \
4006_(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply) \
Neale Ranns32e1c012016-11-22 17:07:28 +00004007_(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01004008_(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply) \
4009_(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply) \
4010_(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply) \
4011_(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY, \
4012 proxy_arp_intfc_enable_disable_reply) \
4013_(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply) \
4014_(SW_INTERFACE_SET_UNNUMBERED_REPLY, \
4015 sw_interface_set_unnumbered_reply) \
4016_(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply) \
4017_(RESET_VRF_REPLY, reset_vrf_reply) \
4018_(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply) \
4019_(CREATE_SUBIF_REPLY, create_subif_reply) \
4020_(OAM_ADD_DEL_REPLY, oam_add_del_reply) \
4021_(RESET_FIB_REPLY, reset_fib_reply) \
4022_(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply) \
4023_(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply) \
4024_(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply) \
4025_(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply) \
4026_(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply) \
4027_(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY, \
4028 sw_interface_ip6_enable_disable_reply) \
4029_(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY, \
4030 sw_interface_ip6_set_link_local_address_reply) \
4031_(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY, \
4032 sw_interface_ip6nd_ra_prefix_reply) \
4033_(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY, \
4034 sw_interface_ip6nd_ra_config_reply) \
4035_(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply) \
4036_(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply) \
4037_(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply) \
4038_(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply) \
4039_(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply) \
4040_(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply) \
4041_(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply) \
4042_(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY, \
4043classify_set_interface_ip_table_reply) \
4044_(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY, \
4045 classify_set_interface_l2_tables_reply) \
4046_(GET_NODE_INDEX_REPLY, get_node_index_reply) \
4047_(ADD_NODE_NEXT_REPLY, add_node_next_reply) \
4048_(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply) \
4049_(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply) \
4050_(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY, \
4051 l2tpv3_interface_enable_disable_reply) \
4052_(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply) \
4053_(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details) \
4054_(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply) \
4055_(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details) \
4056_(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply) \
4057_(GRE_TUNNEL_DETAILS, gre_tunnel_details) \
4058_(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply) \
4059_(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply) \
4060_(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
4061_(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details) \
4062_(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply) \
4063_(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply) \
4064_(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply) \
4065_(SHOW_VERSION_REPLY, show_version_reply) \
4066_(L2_FIB_TABLE_ENTRY, l2_fib_table_entry) \
4067_(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply) \
4068_(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details) \
4069_(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply) \
4070_(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply) \
4071_(IP4_ARP_EVENT, ip4_arp_event) \
4072_(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply) \
4073_(IP6_ND_EVENT, ip6_nd_event) \
4074_(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply) \
4075_(IP_ADDRESS_DETAILS, ip_address_details) \
4076_(IP_DETAILS, ip_details) \
4077_(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply) \
4078_(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
4079_(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply) \
4080_(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply) \
4081_(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply) \
4082_(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply) \
4083_(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply) \
4084_(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply) \
4085_(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply) \
4086_(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply) \
Radu Nicolaucb33dc22017-02-16 16:49:46 +00004087_(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply) \
4088_(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply) \
4089_(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply) \
4090_(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply) \
4091_(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply) \
4092_(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply) \
4093_(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
4094_(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01004095_(DELETE_LOOPBACK_REPLY, delete_loopback_reply) \
4096_(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply) \
4097_(DHCP_COMPL_EVENT, dhcp_compl_event) \
4098_(VNET_INTERFACE_COUNTERS, vnet_interface_counters) \
4099_(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters) \
4100_(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters) \
Neale Ranns044183f2017-01-24 01:34:25 -08004101_(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters) \
4102_(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01004103_(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply) \
4104_(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply) \
4105_(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply) \
4106_(MAP_DOMAIN_DETAILS, map_domain_details) \
4107_(MAP_RULE_DETAILS, map_rule_details) \
4108_(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply) \
4109_(WANT_STATS_REPLY, want_stats_reply) \
4110_(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply) \
4111_(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
4112_(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
4113_(GET_NODE_GRAPH_REPLY, get_node_graph_reply) \
4114_(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply) \
4115_(IOAM_ENABLE_REPLY, ioam_enable_reply) \
4116_(IOAM_DISABLE_REPLY, ioam_disable_reply) \
4117_(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply) \
4118_(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply) \
4119_(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply) \
4120_(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \
4121_(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply) \
4122_(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply) \
4123_(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply) \
4124_(LISP_ADD_DEL_MAP_SERVER_REPLY, lisp_add_del_map_server_reply) \
4125_(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply) \
4126_(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply) \
4127_(LISP_MAP_REGISTER_ENABLE_DISABLE_REPLY, \
4128 lisp_map_register_enable_disable_reply) \
4129_(LISP_RLOC_PROBE_ENABLE_DISABLE_REPLY, \
4130 lisp_rloc_probe_enable_disable_reply) \
4131_(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply) \
4132_(LISP_MAP_REQUEST_MODE_REPLY, lisp_map_request_mode_reply) \
4133_(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply) \
4134_(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply) \
4135_(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details) \
4136_(LISP_LOCATOR_DETAILS, lisp_locator_details) \
4137_(LISP_EID_TABLE_DETAILS, lisp_eid_table_details) \
4138_(LISP_EID_TABLE_MAP_DETAILS, lisp_eid_table_map_details) \
4139_(LISP_EID_TABLE_VNI_DETAILS, lisp_eid_table_vni_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01004140_(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details) \
4141_(LISP_MAP_SERVER_DETAILS, lisp_map_server_details) \
4142_(LISP_ADJACENCIES_GET_REPLY, lisp_adjacencies_get_reply) \
Filip Tehlar5fae99c2017-01-18 12:57:37 +01004143_(LISP_GPE_FWD_ENTRIES_GET_REPLY, lisp_gpe_fwd_entries_get_reply) \
4144_(LISP_GPE_FWD_ENTRY_PATH_DETAILS, \
4145 lisp_gpe_fwd_entry_path_details) \
Damjan Marion7cd468a2016-12-19 23:05:39 +01004146_(SHOW_LISP_STATUS_REPLY, show_lisp_status_reply) \
4147_(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY, \
4148 lisp_add_del_map_request_itr_rlocs_reply) \
4149_(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY, \
4150 lisp_get_map_request_itr_rlocs_reply) \
4151_(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply) \
4152_(SHOW_LISP_MAP_REQUEST_MODE_REPLY, show_lisp_map_request_mode_reply) \
4153_(SHOW_LISP_RLOC_PROBE_STATE_REPLY, show_lisp_rloc_probe_state_reply) \
4154_(SHOW_LISP_MAP_REGISTER_STATE_REPLY, \
4155 show_lisp_map_register_state_reply) \
4156_(AF_PACKET_CREATE_REPLY, af_packet_create_reply) \
4157_(AF_PACKET_DELETE_REPLY, af_packet_delete_reply) \
4158_(POLICER_ADD_DEL_REPLY, policer_add_del_reply) \
4159_(POLICER_DETAILS, policer_details) \
4160_(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
4161_(POLICER_CLASSIFY_DETAILS, policer_classify_details) \
4162_(NETMAP_CREATE_REPLY, netmap_create_reply) \
4163_(NETMAP_DELETE_REPLY, netmap_delete_reply) \
4164_(MPLS_TUNNEL_DETAILS, mpls_tunnel_details) \
4165_(MPLS_FIB_DETAILS, mpls_fib_details) \
4166_(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply) \
4167_(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
4168_(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply) \
4169_(CLASSIFY_SESSION_DETAILS, classify_session_details) \
4170_(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply) \
4171_(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details) \
4172_(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply) \
4173_(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details) \
4174_(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
4175_(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details) \
4176_(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
4177_(FLOW_CLASSIFY_DETAILS, flow_classify_details) \
4178_(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
4179_(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details) \
4180_(GET_NEXT_INDEX_REPLY, get_next_index_reply) \
4181_(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply) \
4182_(PG_CAPTURE_REPLY, pg_capture_reply) \
4183_(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply) \
4184_(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY, \
4185 ip_source_and_port_range_check_add_del_reply) \
4186_(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY, \
4187 ip_source_and_port_range_check_interface_add_del_reply) \
4188_(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply) \
4189_(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details) \
4190_(DELETE_SUBIF_REPLY, delete_subif_reply) \
4191_(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
4192_(PUNT_REPLY, punt_reply) \
4193_(IP_FIB_DETAILS, ip_fib_details) \
4194_(IP6_FIB_DETAILS, ip6_fib_details) \
4195_(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply) \
4196_(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply) \
4197_(L2_XCONNECT_DETAILS, l2_xconnect_details) \
4198_(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply) \
4199_(IP_NEIGHBOR_DETAILS, ip_neighbor_details) \
4200_(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)
4201
Pavel Kotucek738f3f22017-01-09 15:11:03 +01004202#if DPDK > 0
4203#define foreach_vpe_dpdk_api_reply_msg \
4204_(SW_INTERFACE_SET_DPDK_HQOS_PIPE_REPLY, \
4205 sw_interface_set_dpdk_hqos_pipe_reply) \
4206_(SW_INTERFACE_SET_DPDK_HQOS_SUBPORT_REPLY, \
4207 sw_interface_set_dpdk_hqos_subport_reply) \
4208_(SW_INTERFACE_SET_DPDK_HQOS_TCTBL_REPLY, \
4209 sw_interface_set_dpdk_hqos_tctbl_reply)
4210#endif
4211
Damjan Marion7cd468a2016-12-19 23:05:39 +01004212typedef struct
4213{
4214 u8 *name;
4215 u32 value;
4216} name_sort_t;
4217
4218
4219#define STR_VTR_OP_CASE(op) \
4220 case L2_VTR_ ## op: \
4221 return "" # op;
4222
4223static const char *
4224str_vtr_op (u32 vtr_op)
4225{
4226 switch (vtr_op)
4227 {
4228 STR_VTR_OP_CASE (DISABLED);
4229 STR_VTR_OP_CASE (PUSH_1);
4230 STR_VTR_OP_CASE (PUSH_2);
4231 STR_VTR_OP_CASE (POP_1);
4232 STR_VTR_OP_CASE (POP_2);
4233 STR_VTR_OP_CASE (TRANSLATE_1_1);
4234 STR_VTR_OP_CASE (TRANSLATE_1_2);
4235 STR_VTR_OP_CASE (TRANSLATE_2_1);
4236 STR_VTR_OP_CASE (TRANSLATE_2_2);
4237 }
4238
4239 return "UNKNOWN";
4240}
4241
4242static int
4243dump_sub_interface_table (vat_main_t * vam)
4244{
4245 const sw_interface_subif_t *sub = NULL;
4246
4247 if (vam->json_output)
4248 {
4249 clib_warning
4250 ("JSON output supported only for VPE API calls and dump_stats_table");
4251 return -99;
4252 }
4253
4254 print (vam->ofp,
4255 "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
4256 "Interface", "sw_if_index",
4257 "sub id", "dot1ad", "tags", "outer id",
4258 "inner id", "exact", "default", "outer any", "inner any");
4259
4260 vec_foreach (sub, vam->sw_if_subif_table)
4261 {
4262 print (vam->ofp,
4263 "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
4264 sub->interface_name,
4265 sub->sw_if_index,
4266 sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
4267 sub->sub_number_of_tags, sub->sub_outer_vlan_id,
4268 sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
4269 sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
4270 if (sub->vtr_op != L2_VTR_DISABLED)
4271 {
4272 print (vam->ofp,
4273 " vlan-tag-rewrite - op: %-14s [ dot1q: %d "
4274 "tag1: %d tag2: %d ]",
4275 str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
4276 sub->vtr_tag1, sub->vtr_tag2);
4277 }
4278 }
4279
4280 return 0;
4281}
4282
4283static int
4284name_sort_cmp (void *a1, void *a2)
4285{
4286 name_sort_t *n1 = a1;
4287 name_sort_t *n2 = a2;
4288
4289 return strcmp ((char *) n1->name, (char *) n2->name);
4290}
4291
4292static int
4293dump_interface_table (vat_main_t * vam)
4294{
4295 hash_pair_t *p;
4296 name_sort_t *nses = 0, *ns;
4297
4298 if (vam->json_output)
4299 {
4300 clib_warning
4301 ("JSON output supported only for VPE API calls and dump_stats_table");
4302 return -99;
4303 }
4304
4305 /* *INDENT-OFF* */
4306 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4307 ({
4308 vec_add2 (nses, ns, 1);
4309 ns->name = (u8 *)(p->key);
4310 ns->value = (u32) p->value[0];
4311 }));
4312 /* *INDENT-ON* */
4313
4314 vec_sort_with_function (nses, name_sort_cmp);
4315
4316 print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
4317 vec_foreach (ns, nses)
4318 {
4319 print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
4320 }
4321 vec_free (nses);
4322 return 0;
4323}
4324
4325static int
4326dump_ip_table (vat_main_t * vam, int is_ipv6)
4327{
4328 const ip_details_t *det = NULL;
4329 const ip_address_details_t *address = NULL;
4330 u32 i = ~0;
4331
4332 print (vam->ofp, "%-12s", "sw_if_index");
4333
4334 vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
4335 {
4336 i++;
4337 if (!det->present)
4338 {
4339 continue;
4340 }
4341 print (vam->ofp, "%-12d", i);
4342 print (vam->ofp, " %-30s%-13s", "Address", "Prefix length");
4343 if (!det->addr)
4344 {
4345 continue;
4346 }
4347 vec_foreach (address, det->addr)
4348 {
4349 print (vam->ofp,
4350 " %-30U%-13d",
4351 is_ipv6 ? format_ip6_address : format_ip4_address,
4352 address->ip, address->prefix_length);
4353 }
4354 }
4355
4356 return 0;
4357}
4358
4359static int
4360dump_ipv4_table (vat_main_t * vam)
4361{
4362 if (vam->json_output)
4363 {
4364 clib_warning
4365 ("JSON output supported only for VPE API calls and dump_stats_table");
4366 return -99;
4367 }
4368
4369 return dump_ip_table (vam, 0);
4370}
4371
4372static int
4373dump_ipv6_table (vat_main_t * vam)
4374{
4375 if (vam->json_output)
4376 {
4377 clib_warning
4378 ("JSON output supported only for VPE API calls and dump_stats_table");
4379 return -99;
4380 }
4381
4382 return dump_ip_table (vam, 1);
4383}
4384
4385static char *
4386counter_type_to_str (u8 counter_type, u8 is_combined)
4387{
4388 if (!is_combined)
4389 {
4390 switch (counter_type)
4391 {
4392 case VNET_INTERFACE_COUNTER_DROP:
4393 return "drop";
4394 case VNET_INTERFACE_COUNTER_PUNT:
4395 return "punt";
4396 case VNET_INTERFACE_COUNTER_IP4:
4397 return "ip4";
4398 case VNET_INTERFACE_COUNTER_IP6:
4399 return "ip6";
4400 case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4401 return "rx-no-buf";
4402 case VNET_INTERFACE_COUNTER_RX_MISS:
4403 return "rx-miss";
4404 case VNET_INTERFACE_COUNTER_RX_ERROR:
4405 return "rx-error";
4406 case VNET_INTERFACE_COUNTER_TX_ERROR:
4407 return "tx-error";
4408 default:
4409 return "INVALID-COUNTER-TYPE";
4410 }
4411 }
4412 else
4413 {
4414 switch (counter_type)
4415 {
4416 case VNET_INTERFACE_COUNTER_RX:
4417 return "rx";
4418 case VNET_INTERFACE_COUNTER_TX:
4419 return "tx";
4420 default:
4421 return "INVALID-COUNTER-TYPE";
4422 }
4423 }
4424}
4425
4426static int
4427dump_stats_table (vat_main_t * vam)
4428{
4429 vat_json_node_t node;
4430 vat_json_node_t *msg_array;
4431 vat_json_node_t *msg;
4432 vat_json_node_t *counter_array;
4433 vat_json_node_t *counter;
4434 interface_counter_t c;
4435 u64 packets;
4436 ip4_fib_counter_t *c4;
4437 ip6_fib_counter_t *c6;
Neale Ranns044183f2017-01-24 01:34:25 -08004438 ip4_nbr_counter_t *n4;
4439 ip6_nbr_counter_t *n6;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004440 int i, j;
4441
4442 if (!vam->json_output)
4443 {
4444 clib_warning ("dump_stats_table supported only in JSON format");
4445 return -99;
4446 }
4447
4448 vat_json_init_object (&node);
4449
4450 /* interface counters */
4451 msg_array = vat_json_object_add (&node, "interface_counters");
4452 vat_json_init_array (msg_array);
4453 for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4454 {
4455 msg = vat_json_array_add (msg_array);
4456 vat_json_init_object (msg);
4457 vat_json_object_add_string_copy (msg, "vnet_counter_type",
4458 (u8 *) counter_type_to_str (i, 0));
4459 vat_json_object_add_int (msg, "is_combined", 0);
4460 counter_array = vat_json_object_add (msg, "data");
4461 vat_json_init_array (counter_array);
4462 for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4463 {
4464 packets = vam->simple_interface_counters[i][j];
4465 vat_json_array_add_uint (counter_array, packets);
4466 }
4467 }
4468 for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4469 {
4470 msg = vat_json_array_add (msg_array);
4471 vat_json_init_object (msg);
4472 vat_json_object_add_string_copy (msg, "vnet_counter_type",
4473 (u8 *) counter_type_to_str (i, 1));
4474 vat_json_object_add_int (msg, "is_combined", 1);
4475 counter_array = vat_json_object_add (msg, "data");
4476 vat_json_init_array (counter_array);
4477 for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4478 {
4479 c = vam->combined_interface_counters[i][j];
4480 counter = vat_json_array_add (counter_array);
4481 vat_json_init_object (counter);
4482 vat_json_object_add_uint (counter, "packets", c.packets);
4483 vat_json_object_add_uint (counter, "bytes", c.bytes);
4484 }
4485 }
4486
4487 /* ip4 fib counters */
4488 msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4489 vat_json_init_array (msg_array);
4490 for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4491 {
4492 msg = vat_json_array_add (msg_array);
4493 vat_json_init_object (msg);
4494 vat_json_object_add_uint (msg, "vrf_id",
4495 vam->ip4_fib_counters_vrf_id_by_index[i]);
4496 counter_array = vat_json_object_add (msg, "c");
4497 vat_json_init_array (counter_array);
4498 for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4499 {
4500 counter = vat_json_array_add (counter_array);
4501 vat_json_init_object (counter);
4502 c4 = &vam->ip4_fib_counters[i][j];
4503 vat_json_object_add_ip4 (counter, "address", c4->address);
4504 vat_json_object_add_uint (counter, "address_length",
4505 c4->address_length);
4506 vat_json_object_add_uint (counter, "packets", c4->packets);
4507 vat_json_object_add_uint (counter, "bytes", c4->bytes);
4508 }
4509 }
4510
4511 /* ip6 fib counters */
4512 msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4513 vat_json_init_array (msg_array);
4514 for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4515 {
4516 msg = vat_json_array_add (msg_array);
4517 vat_json_init_object (msg);
4518 vat_json_object_add_uint (msg, "vrf_id",
4519 vam->ip6_fib_counters_vrf_id_by_index[i]);
4520 counter_array = vat_json_object_add (msg, "c");
4521 vat_json_init_array (counter_array);
4522 for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4523 {
4524 counter = vat_json_array_add (counter_array);
4525 vat_json_init_object (counter);
4526 c6 = &vam->ip6_fib_counters[i][j];
4527 vat_json_object_add_ip6 (counter, "address", c6->address);
4528 vat_json_object_add_uint (counter, "address_length",
4529 c6->address_length);
4530 vat_json_object_add_uint (counter, "packets", c6->packets);
4531 vat_json_object_add_uint (counter, "bytes", c6->bytes);
4532 }
4533 }
4534
Neale Ranns044183f2017-01-24 01:34:25 -08004535 /* ip4 nbr counters */
4536 msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
4537 vat_json_init_array (msg_array);
4538 for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
4539 {
4540 msg = vat_json_array_add (msg_array);
4541 vat_json_init_object (msg);
4542 vat_json_object_add_uint (msg, "sw_if_index", i);
4543 counter_array = vat_json_object_add (msg, "c");
4544 vat_json_init_array (counter_array);
4545 for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
4546 {
4547 counter = vat_json_array_add (counter_array);
4548 vat_json_init_object (counter);
4549 n4 = &vam->ip4_nbr_counters[i][j];
4550 vat_json_object_add_ip4 (counter, "address", n4->address);
4551 vat_json_object_add_uint (counter, "link-type", n4->linkt);
4552 vat_json_object_add_uint (counter, "packets", n4->packets);
4553 vat_json_object_add_uint (counter, "bytes", n4->bytes);
4554 }
4555 }
4556
4557 /* ip6 nbr counters */
4558 msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
4559 vat_json_init_array (msg_array);
4560 for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
4561 {
4562 msg = vat_json_array_add (msg_array);
4563 vat_json_init_object (msg);
4564 vat_json_object_add_uint (msg, "sw_if_index", i);
4565 counter_array = vat_json_object_add (msg, "c");
4566 vat_json_init_array (counter_array);
4567 for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
4568 {
4569 counter = vat_json_array_add (counter_array);
4570 vat_json_init_object (counter);
4571 n6 = &vam->ip6_nbr_counters[i][j];
4572 vat_json_object_add_ip6 (counter, "address", n6->address);
4573 vat_json_object_add_uint (counter, "packets", n6->packets);
4574 vat_json_object_add_uint (counter, "bytes", n6->bytes);
4575 }
4576 }
4577
Damjan Marion7cd468a2016-12-19 23:05:39 +01004578 vat_json_print (vam->ofp, &node);
4579 vat_json_free (&node);
4580
4581 return 0;
4582}
4583
4584int
4585exec (vat_main_t * vam)
4586{
4587 api_main_t *am = &api_main;
4588 vl_api_cli_request_t *mp;
4589 f64 timeout;
4590 void *oldheap;
4591 u8 *cmd = 0;
4592 unformat_input_t *i = vam->input;
4593
4594 if (vec_len (i->buffer) == 0)
4595 return -1;
4596
4597 if (vam->exec_mode == 0 && unformat (i, "mode"))
4598 {
4599 vam->exec_mode = 1;
4600 return 0;
4601 }
4602 if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4603 {
4604 vam->exec_mode = 0;
4605 return 0;
4606 }
4607
4608
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004609 M (CLI_REQUEST, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004610
4611 /*
4612 * Copy cmd into shared memory.
4613 * In order for the CLI command to work, it
4614 * must be a vector ending in \n, not a C-string ending
4615 * in \n\0.
4616 */
4617 pthread_mutex_lock (&am->vlib_rp->mutex);
4618 oldheap = svm_push_data_heap (am->vlib_rp);
4619
4620 vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4621 clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4622
4623 svm_pop_heap (oldheap);
4624 pthread_mutex_unlock (&am->vlib_rp->mutex);
4625
4626 mp->cmd_in_shmem = (u64) cmd;
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004627 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004628 timeout = vat_time_now (vam) + 10.0;
4629
4630 while (vat_time_now (vam) < timeout)
4631 {
4632 if (vam->result_ready == 1)
4633 {
4634 u8 *free_me;
4635 if (vam->shmem_result != NULL)
4636 print (vam->ofp, "%s", vam->shmem_result);
4637 pthread_mutex_lock (&am->vlib_rp->mutex);
4638 oldheap = svm_push_data_heap (am->vlib_rp);
4639
4640 free_me = (u8 *) vam->shmem_result;
4641 vec_free (free_me);
4642
4643 svm_pop_heap (oldheap);
4644 pthread_mutex_unlock (&am->vlib_rp->mutex);
4645 return 0;
4646 }
4647 }
4648 return -99;
4649}
4650
4651/*
4652 * Future replacement of exec() that passes CLI buffers directly in
4653 * the API messages instead of an additional shared memory area.
4654 */
4655static int
4656exec_inband (vat_main_t * vam)
4657{
4658 vl_api_cli_inband_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004659 unformat_input_t *i = vam->input;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004660 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004661
4662 if (vec_len (i->buffer) == 0)
4663 return -1;
4664
4665 if (vam->exec_mode == 0 && unformat (i, "mode"))
4666 {
4667 vam->exec_mode = 1;
4668 return 0;
4669 }
4670 if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4671 {
4672 vam->exec_mode = 0;
4673 return 0;
4674 }
4675
4676 /*
4677 * In order for the CLI command to work, it
4678 * must be a vector ending in \n, not a C-string ending
4679 * in \n\0.
4680 */
4681 u32 len = vec_len (vam->input->buffer);
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004682 M2 (CLI_INBAND, mp, len);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004683 clib_memcpy (mp->cmd, vam->input->buffer, len);
4684 mp->length = htonl (len);
4685
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004686 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06004687 W2 (ret, print (vam->ofp, "%s", vam->cmd_reply));
4688 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004689}
4690
4691static int
4692api_create_loopback (vat_main_t * vam)
4693{
4694 unformat_input_t *i = vam->input;
4695 vl_api_create_loopback_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004696 u8 mac_address[6];
4697 u8 mac_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004698 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004699
4700 memset (mac_address, 0, sizeof (mac_address));
4701
4702 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4703 {
4704 if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4705 mac_set = 1;
4706 else
4707 break;
4708 }
4709
4710 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004711 M (CREATE_LOOPBACK, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004712 if (mac_set)
4713 clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4714
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004715 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06004716 W (ret);
4717 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004718}
4719
4720static int
4721api_delete_loopback (vat_main_t * vam)
4722{
4723 unformat_input_t *i = vam->input;
4724 vl_api_delete_loopback_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004725 u32 sw_if_index = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004726 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004727
4728 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4729 {
4730 if (unformat (i, "sw_if_index %d", &sw_if_index))
4731 ;
4732 else
4733 break;
4734 }
4735
4736 if (sw_if_index == ~0)
4737 {
4738 errmsg ("missing sw_if_index");
4739 return -99;
4740 }
4741
4742 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004743 M (DELETE_LOOPBACK, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004744 mp->sw_if_index = ntohl (sw_if_index);
4745
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004746 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06004747 W (ret);
4748 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004749}
4750
4751static int
4752api_want_stats (vat_main_t * vam)
4753{
4754 unformat_input_t *i = vam->input;
4755 vl_api_want_stats_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004756 int enable = -1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004757 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004758
4759 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4760 {
4761 if (unformat (i, "enable"))
4762 enable = 1;
4763 else if (unformat (i, "disable"))
4764 enable = 0;
4765 else
4766 break;
4767 }
4768
4769 if (enable == -1)
4770 {
4771 errmsg ("missing enable|disable");
4772 return -99;
4773 }
4774
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004775 M (WANT_STATS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004776 mp->enable_disable = enable;
4777
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004778 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06004779 W (ret);
4780 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004781}
4782
4783static int
4784api_want_interface_events (vat_main_t * vam)
4785{
4786 unformat_input_t *i = vam->input;
4787 vl_api_want_interface_events_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004788 int enable = -1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004789 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004790
4791 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4792 {
4793 if (unformat (i, "enable"))
4794 enable = 1;
4795 else if (unformat (i, "disable"))
4796 enable = 0;
4797 else
4798 break;
4799 }
4800
4801 if (enable == -1)
4802 {
4803 errmsg ("missing enable|disable");
4804 return -99;
4805 }
4806
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004807 M (WANT_INTERFACE_EVENTS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004808 mp->enable_disable = enable;
4809
4810 vam->interface_event_display = enable;
4811
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004812 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06004813 W (ret);
4814 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004815}
4816
4817
4818/* Note: non-static, called once to set up the initial intfc table */
4819int
4820api_sw_interface_dump (vat_main_t * vam)
4821{
4822 vl_api_sw_interface_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -06004823 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004824 hash_pair_t *p;
4825 name_sort_t *nses = 0, *ns;
4826 sw_interface_subif_t *sub = NULL;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004827 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004828
4829 /* Toss the old name table */
4830 /* *INDENT-OFF* */
4831 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4832 ({
4833 vec_add2 (nses, ns, 1);
4834 ns->name = (u8 *)(p->key);
4835 ns->value = (u32) p->value[0];
4836 }));
4837 /* *INDENT-ON* */
4838
4839 hash_free (vam->sw_if_index_by_interface_name);
4840
4841 vec_foreach (ns, nses) vec_free (ns->name);
4842
4843 vec_free (nses);
4844
4845 vec_foreach (sub, vam->sw_if_subif_table)
4846 {
4847 vec_free (sub->interface_name);
4848 }
4849 vec_free (vam->sw_if_subif_table);
4850
4851 /* recreate the interface name hash table */
4852 vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4853
4854 /* Get list of ethernets */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004855 M (SW_INTERFACE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004856 mp->name_filter_valid = 1;
4857 strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004858 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004859
4860 /* and local / loopback interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004861 M (SW_INTERFACE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004862 mp->name_filter_valid = 1;
4863 strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004864 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004865
4866 /* and packet-generator interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004867 M (SW_INTERFACE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004868 mp->name_filter_valid = 1;
4869 strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004870 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004871
4872 /* and vxlan-gpe tunnel interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004873 M (SW_INTERFACE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004874 mp->name_filter_valid = 1;
4875 strncpy ((char *) mp->name_filter, "vxlan_gpe",
4876 sizeof (mp->name_filter) - 1);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004877 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004878
4879 /* and vxlan tunnel interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004880 M (SW_INTERFACE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004881 mp->name_filter_valid = 1;
4882 strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004883 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004884
4885 /* and host (af_packet) interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004886 M (SW_INTERFACE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004887 mp->name_filter_valid = 1;
4888 strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004889 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004890
4891 /* and l2tpv3 tunnel interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004892 M (SW_INTERFACE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004893 mp->name_filter_valid = 1;
4894 strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4895 sizeof (mp->name_filter) - 1);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004896 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004897
4898 /* and GRE tunnel interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004899 M (SW_INTERFACE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004900 mp->name_filter_valid = 1;
4901 strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004902 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004903
4904 /* and LISP-GPE interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004905 M (SW_INTERFACE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004906 mp->name_filter_valid = 1;
4907 strncpy ((char *) mp->name_filter, "lisp_gpe",
4908 sizeof (mp->name_filter) - 1);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004909 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004910
4911 /* and IPSEC tunnel interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004912 M (SW_INTERFACE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004913 mp->name_filter_valid = 1;
4914 strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004915 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004916
4917 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -06004918 M (CONTROL_PING, mp_ping);
4919 S (mp_ping);
4920
Jon Loeliger56c7b012017-02-01 12:31:41 -06004921 W (ret);
4922 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004923}
4924
4925static int
4926api_sw_interface_set_flags (vat_main_t * vam)
4927{
4928 unformat_input_t *i = vam->input;
4929 vl_api_sw_interface_set_flags_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004930 u32 sw_if_index;
4931 u8 sw_if_index_set = 0;
4932 u8 admin_up = 0, link_up = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004933 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004934
4935 /* Parse args required to build the message */
4936 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4937 {
4938 if (unformat (i, "admin-up"))
4939 admin_up = 1;
4940 else if (unformat (i, "admin-down"))
4941 admin_up = 0;
4942 else if (unformat (i, "link-up"))
4943 link_up = 1;
4944 else if (unformat (i, "link-down"))
4945 link_up = 0;
4946 else
4947 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4948 sw_if_index_set = 1;
4949 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4950 sw_if_index_set = 1;
4951 else
4952 break;
4953 }
4954
4955 if (sw_if_index_set == 0)
4956 {
4957 errmsg ("missing interface name or sw_if_index");
4958 return -99;
4959 }
4960
4961 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004962 M (SW_INTERFACE_SET_FLAGS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004963 mp->sw_if_index = ntohl (sw_if_index);
4964 mp->admin_up_down = admin_up;
4965 mp->link_up_down = link_up;
4966
4967 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06004968 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004969
4970 /* Wait for a reply, return the good/bad news... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06004971 W (ret);
4972 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004973}
4974
4975static int
4976api_sw_interface_clear_stats (vat_main_t * vam)
4977{
4978 unformat_input_t *i = vam->input;
4979 vl_api_sw_interface_clear_stats_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004980 u32 sw_if_index;
4981 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06004982 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01004983
4984 /* Parse args required to build the message */
4985 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4986 {
4987 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4988 sw_if_index_set = 1;
4989 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4990 sw_if_index_set = 1;
4991 else
4992 break;
4993 }
4994
4995 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06004996 M (SW_INTERFACE_CLEAR_STATS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01004997
4998 if (sw_if_index_set == 1)
4999 mp->sw_if_index = ntohl (sw_if_index);
5000 else
5001 mp->sw_if_index = ~0;
5002
5003 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005004 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005005
5006 /* Wait for a reply, return the good/bad news... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06005007 W (ret);
5008 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005009}
5010
Pavel Kotucek738f3f22017-01-09 15:11:03 +01005011#if DPDK >0
Damjan Marion7cd468a2016-12-19 23:05:39 +01005012static int
5013api_sw_interface_set_dpdk_hqos_pipe (vat_main_t * vam)
5014{
5015 unformat_input_t *i = vam->input;
5016 vl_api_sw_interface_set_dpdk_hqos_pipe_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005017 u32 sw_if_index;
5018 u8 sw_if_index_set = 0;
5019 u32 subport;
5020 u8 subport_set = 0;
5021 u32 pipe;
5022 u8 pipe_set = 0;
5023 u32 profile;
5024 u8 profile_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005025 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005026
5027 /* Parse args required to build the message */
5028 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5029 {
5030 if (unformat (i, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
5031 sw_if_index_set = 1;
5032 else if (unformat (i, "sw_if_index %u", &sw_if_index))
5033 sw_if_index_set = 1;
5034 else if (unformat (i, "subport %u", &subport))
5035 subport_set = 1;
5036 else
5037 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5038 sw_if_index_set = 1;
5039 else if (unformat (i, "pipe %u", &pipe))
5040 pipe_set = 1;
5041 else if (unformat (i, "profile %u", &profile))
5042 profile_set = 1;
5043 else
5044 break;
5045 }
5046
5047 if (sw_if_index_set == 0)
5048 {
5049 errmsg ("missing interface name or sw_if_index");
5050 return -99;
5051 }
5052
5053 if (subport_set == 0)
5054 {
5055 errmsg ("missing subport ");
5056 return -99;
5057 }
5058
5059 if (pipe_set == 0)
5060 {
5061 errmsg ("missing pipe");
5062 return -99;
5063 }
5064
5065 if (profile_set == 0)
5066 {
5067 errmsg ("missing profile");
5068 return -99;
5069 }
5070
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005071 M (SW_INTERFACE_SET_DPDK_HQOS_PIPE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005072
5073 mp->sw_if_index = ntohl (sw_if_index);
5074 mp->subport = ntohl (subport);
5075 mp->pipe = ntohl (pipe);
5076 mp->profile = ntohl (profile);
5077
5078
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005079 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06005080 W (ret);
5081 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005082}
5083
5084static int
5085api_sw_interface_set_dpdk_hqos_subport (vat_main_t * vam)
5086{
5087 unformat_input_t *i = vam->input;
5088 vl_api_sw_interface_set_dpdk_hqos_subport_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005089 u32 sw_if_index;
5090 u8 sw_if_index_set = 0;
5091 u32 subport;
5092 u8 subport_set = 0;
5093 u32 tb_rate = 1250000000; /* 10GbE */
5094 u32 tb_size = 1000000;
5095 u32 tc_rate[] = { 1250000000, 1250000000, 1250000000, 1250000000 };
5096 u32 tc_period = 10;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005097 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005098
5099 /* Parse args required to build the message */
5100 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5101 {
5102 if (unformat (i, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
5103 sw_if_index_set = 1;
5104 else if (unformat (i, "sw_if_index %u", &sw_if_index))
5105 sw_if_index_set = 1;
5106 else if (unformat (i, "subport %u", &subport))
5107 subport_set = 1;
5108 else
5109 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5110 sw_if_index_set = 1;
5111 else if (unformat (i, "rate %u", &tb_rate))
5112 {
5113 u32 tc_id;
5114
5115 for (tc_id = 0; tc_id < (sizeof (tc_rate) / sizeof (tc_rate[0]));
5116 tc_id++)
5117 tc_rate[tc_id] = tb_rate;
5118 }
5119 else if (unformat (i, "bktsize %u", &tb_size))
5120 ;
5121 else if (unformat (i, "tc0 %u", &tc_rate[0]))
5122 ;
5123 else if (unformat (i, "tc1 %u", &tc_rate[1]))
5124 ;
5125 else if (unformat (i, "tc2 %u", &tc_rate[2]))
5126 ;
5127 else if (unformat (i, "tc3 %u", &tc_rate[3]))
5128 ;
5129 else if (unformat (i, "period %u", &tc_period))
5130 ;
5131 else
5132 break;
5133 }
5134
5135 if (sw_if_index_set == 0)
5136 {
5137 errmsg ("missing interface name or sw_if_index");
5138 return -99;
5139 }
5140
5141 if (subport_set == 0)
5142 {
5143 errmsg ("missing subport ");
5144 return -99;
5145 }
5146
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005147 M (SW_INTERFACE_SET_DPDK_HQOS_SUBPORT, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005148
5149 mp->sw_if_index = ntohl (sw_if_index);
5150 mp->subport = ntohl (subport);
5151 mp->tb_rate = ntohl (tb_rate);
5152 mp->tb_size = ntohl (tb_size);
5153 mp->tc_rate[0] = ntohl (tc_rate[0]);
5154 mp->tc_rate[1] = ntohl (tc_rate[1]);
5155 mp->tc_rate[2] = ntohl (tc_rate[2]);
5156 mp->tc_rate[3] = ntohl (tc_rate[3]);
5157 mp->tc_period = ntohl (tc_period);
5158
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005159 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06005160 W (ret);
5161 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005162}
5163
5164static int
5165api_sw_interface_set_dpdk_hqos_tctbl (vat_main_t * vam)
5166{
5167 unformat_input_t *i = vam->input;
5168 vl_api_sw_interface_set_dpdk_hqos_tctbl_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005169 u32 sw_if_index;
5170 u8 sw_if_index_set = 0;
5171 u8 entry_set = 0;
5172 u8 tc_set = 0;
5173 u8 queue_set = 0;
5174 u32 entry, tc, queue;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005175 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005176
5177 /* Parse args required to build the message */
5178 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5179 {
5180 if (unformat (i, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
5181 sw_if_index_set = 1;
5182 else if (unformat (i, "sw_if_index %u", &sw_if_index))
5183 sw_if_index_set = 1;
5184 else if (unformat (i, "entry %d", &entry))
5185 entry_set = 1;
5186 else if (unformat (i, "tc %d", &tc))
5187 tc_set = 1;
5188 else if (unformat (i, "queue %d", &queue))
5189 queue_set = 1;
5190 else
5191 break;
5192 }
5193
5194 if (sw_if_index_set == 0)
5195 {
5196 errmsg ("missing interface name or sw_if_index");
5197 return -99;
5198 }
5199
5200 if (entry_set == 0)
5201 {
5202 errmsg ("missing entry ");
5203 return -99;
5204 }
5205
5206 if (tc_set == 0)
5207 {
5208 errmsg ("missing traffic class ");
5209 return -99;
5210 }
5211
5212 if (queue_set == 0)
5213 {
5214 errmsg ("missing queue ");
5215 return -99;
5216 }
5217
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005218 M (SW_INTERFACE_SET_DPDK_HQOS_TCTBL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005219
5220 mp->sw_if_index = ntohl (sw_if_index);
5221 mp->entry = ntohl (entry);
5222 mp->tc = ntohl (tc);
5223 mp->queue = ntohl (queue);
5224
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005225 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06005226 W (ret);
5227 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005228}
Pavel Kotucek738f3f22017-01-09 15:11:03 +01005229#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +01005230
5231static int
5232api_sw_interface_add_del_address (vat_main_t * vam)
5233{
5234 unformat_input_t *i = vam->input;
5235 vl_api_sw_interface_add_del_address_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005236 u32 sw_if_index;
5237 u8 sw_if_index_set = 0;
5238 u8 is_add = 1, del_all = 0;
5239 u32 address_length = 0;
5240 u8 v4_address_set = 0;
5241 u8 v6_address_set = 0;
5242 ip4_address_t v4address;
5243 ip6_address_t v6address;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005244 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005245
5246 /* Parse args required to build the message */
5247 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5248 {
5249 if (unformat (i, "del-all"))
5250 del_all = 1;
5251 else if (unformat (i, "del"))
5252 is_add = 0;
5253 else
5254 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5255 sw_if_index_set = 1;
5256 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5257 sw_if_index_set = 1;
5258 else if (unformat (i, "%U/%d",
5259 unformat_ip4_address, &v4address, &address_length))
5260 v4_address_set = 1;
5261 else if (unformat (i, "%U/%d",
5262 unformat_ip6_address, &v6address, &address_length))
5263 v6_address_set = 1;
5264 else
5265 break;
5266 }
5267
5268 if (sw_if_index_set == 0)
5269 {
5270 errmsg ("missing interface name or sw_if_index");
5271 return -99;
5272 }
5273 if (v4_address_set && v6_address_set)
5274 {
5275 errmsg ("both v4 and v6 addresses set");
5276 return -99;
5277 }
5278 if (!v4_address_set && !v6_address_set && !del_all)
5279 {
5280 errmsg ("no addresses set");
5281 return -99;
5282 }
5283
5284 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005285 M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005286
5287 mp->sw_if_index = ntohl (sw_if_index);
5288 mp->is_add = is_add;
5289 mp->del_all = del_all;
5290 if (v6_address_set)
5291 {
5292 mp->is_ipv6 = 1;
5293 clib_memcpy (mp->address, &v6address, sizeof (v6address));
5294 }
5295 else
5296 {
5297 clib_memcpy (mp->address, &v4address, sizeof (v4address));
5298 }
5299 mp->address_length = address_length;
5300
5301 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005302 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005303
5304 /* Wait for a reply, return good/bad news */
Jon Loeliger56c7b012017-02-01 12:31:41 -06005305 W (ret);
5306 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005307}
5308
5309static int
5310api_sw_interface_set_mpls_enable (vat_main_t * vam)
5311{
5312 unformat_input_t *i = vam->input;
5313 vl_api_sw_interface_set_mpls_enable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005314 u32 sw_if_index;
5315 u8 sw_if_index_set = 0;
5316 u8 enable = 1;
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, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5323 sw_if_index_set = 1;
5324 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5325 sw_if_index_set = 1;
5326 else if (unformat (i, "disable"))
5327 enable = 0;
5328 else if (unformat (i, "dis"))
5329 enable = 0;
5330 else
5331 break;
5332 }
5333
5334 if (sw_if_index_set == 0)
5335 {
5336 errmsg ("missing interface name or sw_if_index");
5337 return -99;
5338 }
5339
5340 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005341 M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005342
5343 mp->sw_if_index = ntohl (sw_if_index);
5344 mp->enable = enable;
5345
5346 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005347 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005348
5349 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06005350 W (ret);
5351 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005352}
5353
5354static int
5355api_sw_interface_set_table (vat_main_t * vam)
5356{
5357 unformat_input_t *i = vam->input;
5358 vl_api_sw_interface_set_table_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005359 u32 sw_if_index, vrf_id = 0;
5360 u8 sw_if_index_set = 0;
5361 u8 is_ipv6 = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005362 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005363
5364 /* Parse args required to build the message */
5365 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5366 {
5367 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5368 sw_if_index_set = 1;
5369 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5370 sw_if_index_set = 1;
5371 else if (unformat (i, "vrf %d", &vrf_id))
5372 ;
5373 else if (unformat (i, "ipv6"))
5374 is_ipv6 = 1;
5375 else
5376 break;
5377 }
5378
5379 if (sw_if_index_set == 0)
5380 {
5381 errmsg ("missing interface name or sw_if_index");
5382 return -99;
5383 }
5384
5385 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005386 M (SW_INTERFACE_SET_TABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005387
5388 mp->sw_if_index = ntohl (sw_if_index);
5389 mp->is_ipv6 = is_ipv6;
5390 mp->vrf_id = ntohl (vrf_id);
5391
5392 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005393 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005394
5395 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06005396 W (ret);
5397 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005398}
5399
5400static void vl_api_sw_interface_get_table_reply_t_handler
5401 (vl_api_sw_interface_get_table_reply_t * mp)
5402{
5403 vat_main_t *vam = &vat_main;
5404
5405 print (vam->ofp, "%d", ntohl (mp->vrf_id));
5406
5407 vam->retval = ntohl (mp->retval);
5408 vam->result_ready = 1;
5409
5410}
5411
5412static void vl_api_sw_interface_get_table_reply_t_handler_json
5413 (vl_api_sw_interface_get_table_reply_t * mp)
5414{
5415 vat_main_t *vam = &vat_main;
5416 vat_json_node_t node;
5417
5418 vat_json_init_object (&node);
5419 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5420 vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
5421
5422 vat_json_print (vam->ofp, &node);
5423 vat_json_free (&node);
5424
5425 vam->retval = ntohl (mp->retval);
5426 vam->result_ready = 1;
5427}
5428
5429static int
5430api_sw_interface_get_table (vat_main_t * vam)
5431{
5432 unformat_input_t *i = vam->input;
5433 vl_api_sw_interface_get_table_t *mp;
5434 u32 sw_if_index;
5435 u8 sw_if_index_set = 0;
5436 u8 is_ipv6 = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005437 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005438
5439 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5440 {
5441 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5442 sw_if_index_set = 1;
5443 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5444 sw_if_index_set = 1;
5445 else if (unformat (i, "ipv6"))
5446 is_ipv6 = 1;
5447 else
5448 break;
5449 }
5450
5451 if (sw_if_index_set == 0)
5452 {
5453 errmsg ("missing interface name or sw_if_index");
5454 return -99;
5455 }
5456
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005457 M (SW_INTERFACE_GET_TABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005458 mp->sw_if_index = htonl (sw_if_index);
5459 mp->is_ipv6 = is_ipv6;
5460
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005461 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06005462 W (ret);
5463 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005464}
5465
5466static int
5467api_sw_interface_set_vpath (vat_main_t * vam)
5468{
5469 unformat_input_t *i = vam->input;
5470 vl_api_sw_interface_set_vpath_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005471 u32 sw_if_index = 0;
5472 u8 sw_if_index_set = 0;
5473 u8 is_enable = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005474 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005475
5476 /* Parse args required to build the message */
5477 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5478 {
5479 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5480 sw_if_index_set = 1;
5481 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5482 sw_if_index_set = 1;
5483 else if (unformat (i, "enable"))
5484 is_enable = 1;
5485 else if (unformat (i, "disable"))
5486 is_enable = 0;
5487 else
5488 break;
5489 }
5490
5491 if (sw_if_index_set == 0)
5492 {
5493 errmsg ("missing interface name or sw_if_index");
5494 return -99;
5495 }
5496
5497 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005498 M (SW_INTERFACE_SET_VPATH, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005499
5500 mp->sw_if_index = ntohl (sw_if_index);
5501 mp->enable = is_enable;
5502
5503 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005504 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005505
5506 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06005507 W (ret);
5508 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005509}
5510
5511static int
5512api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
5513{
5514 unformat_input_t *i = vam->input;
5515 vl_api_sw_interface_set_vxlan_bypass_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005516 u32 sw_if_index = 0;
5517 u8 sw_if_index_set = 0;
John Lo2b81eb82017-01-30 13:12:10 -05005518 u8 is_enable = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005519 u8 is_ipv6 = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005520 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005521
5522 /* Parse args required to build the message */
5523 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5524 {
5525 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5526 sw_if_index_set = 1;
5527 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5528 sw_if_index_set = 1;
5529 else if (unformat (i, "enable"))
5530 is_enable = 1;
5531 else if (unformat (i, "disable"))
5532 is_enable = 0;
5533 else if (unformat (i, "ip4"))
5534 is_ipv6 = 0;
5535 else if (unformat (i, "ip6"))
5536 is_ipv6 = 1;
5537 else
5538 break;
5539 }
5540
5541 if (sw_if_index_set == 0)
5542 {
5543 errmsg ("missing interface name or sw_if_index");
5544 return -99;
5545 }
5546
5547 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005548 M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005549
5550 mp->sw_if_index = ntohl (sw_if_index);
5551 mp->enable = is_enable;
5552 mp->is_ipv6 = is_ipv6;
5553
5554 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005555 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005556
5557 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06005558 W (ret);
5559 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005560}
5561
5562static int
5563api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5564{
5565 unformat_input_t *i = vam->input;
5566 vl_api_sw_interface_set_l2_xconnect_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005567 u32 rx_sw_if_index;
5568 u8 rx_sw_if_index_set = 0;
5569 u32 tx_sw_if_index;
5570 u8 tx_sw_if_index_set = 0;
5571 u8 enable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005572 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005573
5574 /* Parse args required to build the message */
5575 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5576 {
5577 if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5578 rx_sw_if_index_set = 1;
5579 else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5580 tx_sw_if_index_set = 1;
5581 else if (unformat (i, "rx"))
5582 {
5583 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5584 {
5585 if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5586 &rx_sw_if_index))
5587 rx_sw_if_index_set = 1;
5588 }
5589 else
5590 break;
5591 }
5592 else if (unformat (i, "tx"))
5593 {
5594 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5595 {
5596 if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5597 &tx_sw_if_index))
5598 tx_sw_if_index_set = 1;
5599 }
5600 else
5601 break;
5602 }
5603 else if (unformat (i, "enable"))
5604 enable = 1;
5605 else if (unformat (i, "disable"))
5606 enable = 0;
5607 else
5608 break;
5609 }
5610
5611 if (rx_sw_if_index_set == 0)
5612 {
5613 errmsg ("missing rx interface name or rx_sw_if_index");
5614 return -99;
5615 }
5616
5617 if (enable && (tx_sw_if_index_set == 0))
5618 {
5619 errmsg ("missing tx interface name or tx_sw_if_index");
5620 return -99;
5621 }
5622
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005623 M (SW_INTERFACE_SET_L2_XCONNECT, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005624
5625 mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5626 mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5627 mp->enable = enable;
5628
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005629 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06005630 W (ret);
5631 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005632}
5633
5634static int
5635api_sw_interface_set_l2_bridge (vat_main_t * vam)
5636{
5637 unformat_input_t *i = vam->input;
5638 vl_api_sw_interface_set_l2_bridge_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005639 u32 rx_sw_if_index;
5640 u8 rx_sw_if_index_set = 0;
5641 u32 bd_id;
5642 u8 bd_id_set = 0;
5643 u8 bvi = 0;
5644 u32 shg = 0;
5645 u8 enable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005646 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005647
5648 /* Parse args required to build the message */
5649 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5650 {
5651 if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5652 rx_sw_if_index_set = 1;
5653 else if (unformat (i, "bd_id %d", &bd_id))
5654 bd_id_set = 1;
5655 else
5656 if (unformat
5657 (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
5658 rx_sw_if_index_set = 1;
5659 else if (unformat (i, "shg %d", &shg))
5660 ;
5661 else if (unformat (i, "bvi"))
5662 bvi = 1;
5663 else if (unformat (i, "enable"))
5664 enable = 1;
5665 else if (unformat (i, "disable"))
5666 enable = 0;
5667 else
5668 break;
5669 }
5670
5671 if (rx_sw_if_index_set == 0)
5672 {
5673 errmsg ("missing rx interface name or sw_if_index");
5674 return -99;
5675 }
5676
5677 if (enable && (bd_id_set == 0))
5678 {
5679 errmsg ("missing bridge domain");
5680 return -99;
5681 }
5682
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005683 M (SW_INTERFACE_SET_L2_BRIDGE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005684
5685 mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5686 mp->bd_id = ntohl (bd_id);
5687 mp->shg = (u8) shg;
5688 mp->bvi = bvi;
5689 mp->enable = enable;
5690
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005691 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06005692 W (ret);
5693 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005694}
5695
5696static int
5697api_bridge_domain_dump (vat_main_t * vam)
5698{
5699 unformat_input_t *i = vam->input;
5700 vl_api_bridge_domain_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -06005701 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005702 u32 bd_id = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005703 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005704
5705 /* Parse args required to build the message */
5706 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5707 {
5708 if (unformat (i, "bd_id %d", &bd_id))
5709 ;
5710 else
5711 break;
5712 }
5713
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005714 M (BRIDGE_DOMAIN_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005715 mp->bd_id = ntohl (bd_id);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005716 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005717
5718 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -06005719 M (CONTROL_PING, mp_ping);
5720 S (mp_ping);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005721
Jon Loeliger56c7b012017-02-01 12:31:41 -06005722 W (ret);
5723 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005724}
5725
5726static int
5727api_bridge_domain_add_del (vat_main_t * vam)
5728{
5729 unformat_input_t *i = vam->input;
5730 vl_api_bridge_domain_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005731 u32 bd_id = ~0;
5732 u8 is_add = 1;
5733 u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5734 u32 mac_age = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005735 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005736
5737 /* Parse args required to build the message */
5738 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5739 {
5740 if (unformat (i, "bd_id %d", &bd_id))
5741 ;
5742 else if (unformat (i, "flood %d", &flood))
5743 ;
5744 else if (unformat (i, "uu-flood %d", &uu_flood))
5745 ;
5746 else if (unformat (i, "forward %d", &forward))
5747 ;
5748 else if (unformat (i, "learn %d", &learn))
5749 ;
5750 else if (unformat (i, "arp-term %d", &arp_term))
5751 ;
5752 else if (unformat (i, "mac-age %d", &mac_age))
5753 ;
5754 else if (unformat (i, "del"))
5755 {
5756 is_add = 0;
5757 flood = uu_flood = forward = learn = 0;
5758 }
5759 else
5760 break;
5761 }
5762
5763 if (bd_id == ~0)
5764 {
5765 errmsg ("missing bridge domain");
5766 return -99;
5767 }
5768
5769 if (mac_age > 255)
5770 {
5771 errmsg ("mac age must be less than 256 ");
5772 return -99;
5773 }
5774
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005775 M (BRIDGE_DOMAIN_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005776
5777 mp->bd_id = ntohl (bd_id);
5778 mp->flood = flood;
5779 mp->uu_flood = uu_flood;
5780 mp->forward = forward;
5781 mp->learn = learn;
5782 mp->arp_term = arp_term;
5783 mp->is_add = is_add;
5784 mp->mac_age = (u8) mac_age;
5785
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005786 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06005787 W (ret);
5788 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005789}
5790
5791static int
5792api_l2fib_add_del (vat_main_t * vam)
5793{
5794 unformat_input_t *i = vam->input;
5795 vl_api_l2fib_add_del_t *mp;
5796 f64 timeout;
5797 u64 mac = 0;
5798 u8 mac_set = 0;
5799 u32 bd_id;
5800 u8 bd_id_set = 0;
5801 u32 sw_if_index = ~0;
5802 u8 sw_if_index_set = 0;
5803 u8 is_add = 1;
5804 u8 static_mac = 0;
5805 u8 filter_mac = 0;
5806 u8 bvi_mac = 0;
5807 int count = 1;
5808 f64 before = 0;
5809 int j;
5810
5811 /* Parse args required to build the message */
5812 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5813 {
5814 if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
5815 mac_set = 1;
5816 else if (unformat (i, "bd_id %d", &bd_id))
5817 bd_id_set = 1;
5818 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5819 sw_if_index_set = 1;
5820 else if (unformat (i, "sw_if"))
5821 {
5822 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5823 {
5824 if (unformat
5825 (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5826 sw_if_index_set = 1;
5827 }
5828 else
5829 break;
5830 }
5831 else if (unformat (i, "static"))
5832 static_mac = 1;
5833 else if (unformat (i, "filter"))
5834 {
5835 filter_mac = 1;
5836 static_mac = 1;
5837 }
5838 else if (unformat (i, "bvi"))
5839 {
5840 bvi_mac = 1;
5841 static_mac = 1;
5842 }
5843 else if (unformat (i, "del"))
5844 is_add = 0;
5845 else if (unformat (i, "count %d", &count))
5846 ;
5847 else
5848 break;
5849 }
5850
5851 if (mac_set == 0)
5852 {
5853 errmsg ("missing mac address");
5854 return -99;
5855 }
5856
5857 if (bd_id_set == 0)
5858 {
5859 errmsg ("missing bridge domain");
5860 return -99;
5861 }
5862
5863 if (is_add && sw_if_index_set == 0 && filter_mac == 0)
5864 {
5865 errmsg ("missing interface name or sw_if_index");
5866 return -99;
5867 }
5868
5869 if (count > 1)
5870 {
5871 /* Turn on async mode */
5872 vam->async_mode = 1;
5873 vam->async_errors = 0;
5874 before = vat_time_now (vam);
5875 }
5876
5877 for (j = 0; j < count; j++)
5878 {
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005879 M (L2FIB_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005880
5881 mp->mac = mac;
5882 mp->bd_id = ntohl (bd_id);
5883 mp->is_add = is_add;
5884
5885 if (is_add)
5886 {
5887 mp->sw_if_index = ntohl (sw_if_index);
5888 mp->static_mac = static_mac;
5889 mp->filter_mac = filter_mac;
5890 mp->bvi_mac = bvi_mac;
5891 }
5892 increment_mac_address (&mac);
5893 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005894 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005895 }
5896
5897 if (count > 1)
5898 {
Jon Loeliger2d23eca2017-02-01 13:09:58 -06005899 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005900 f64 after;
5901
5902 /* Shut off async mode */
5903 vam->async_mode = 0;
5904
Jon Loeliger2d23eca2017-02-01 13:09:58 -06005905 M (CONTROL_PING, mp_ping);
5906 S (mp_ping);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005907
5908 timeout = vat_time_now (vam) + 1.0;
5909 while (vat_time_now (vam) < timeout)
5910 if (vam->result_ready == 1)
5911 goto out;
5912 vam->retval = -99;
5913
5914 out:
5915 if (vam->retval == -99)
5916 errmsg ("timeout");
5917
5918 if (vam->async_errors > 0)
5919 {
5920 errmsg ("%d asynchronous errors", vam->async_errors);
5921 vam->retval = -98;
5922 }
5923 vam->async_errors = 0;
5924 after = vat_time_now (vam);
5925
5926 print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
5927 count, after - before, count / (after - before));
5928 }
5929 else
5930 {
Jon Loeliger56c7b012017-02-01 12:31:41 -06005931 int ret;
5932
Damjan Marion7cd468a2016-12-19 23:05:39 +01005933 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06005934 W (ret);
5935 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005936 }
5937 /* Return the good/bad news */
5938 return (vam->retval);
5939}
5940
5941static int
5942api_l2_flags (vat_main_t * vam)
5943{
5944 unformat_input_t *i = vam->input;
5945 vl_api_l2_flags_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005946 u32 sw_if_index;
5947 u32 feature_bitmap = 0;
5948 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06005949 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005950
5951 /* Parse args required to build the message */
5952 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5953 {
5954 if (unformat (i, "sw_if_index %d", &sw_if_index))
5955 sw_if_index_set = 1;
5956 else if (unformat (i, "sw_if"))
5957 {
5958 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5959 {
5960 if (unformat
5961 (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5962 sw_if_index_set = 1;
5963 }
5964 else
5965 break;
5966 }
5967 else if (unformat (i, "learn"))
5968 feature_bitmap |= L2INPUT_FEAT_LEARN;
5969 else if (unformat (i, "forward"))
5970 feature_bitmap |= L2INPUT_FEAT_FWD;
5971 else if (unformat (i, "flood"))
5972 feature_bitmap |= L2INPUT_FEAT_FLOOD;
5973 else if (unformat (i, "uu-flood"))
5974 feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5975 else
5976 break;
5977 }
5978
5979 if (sw_if_index_set == 0)
5980 {
5981 errmsg ("missing interface name or sw_if_index");
5982 return -99;
5983 }
5984
Jon Loeliger8a2aea32017-01-31 13:19:40 -06005985 M (L2_FLAGS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01005986
5987 mp->sw_if_index = ntohl (sw_if_index);
5988 mp->feature_bitmap = ntohl (feature_bitmap);
5989
Jon Loeliger7bc770c2017-01-31 14:03:33 -06005990 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06005991 W (ret);
5992 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01005993}
5994
5995static int
5996api_bridge_flags (vat_main_t * vam)
5997{
5998 unformat_input_t *i = vam->input;
5999 vl_api_bridge_flags_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006000 u32 bd_id;
6001 u8 bd_id_set = 0;
6002 u8 is_set = 1;
6003 u32 flags = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006004 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006005
6006 /* Parse args required to build the message */
6007 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6008 {
6009 if (unformat (i, "bd_id %d", &bd_id))
6010 bd_id_set = 1;
6011 else if (unformat (i, "learn"))
6012 flags |= L2_LEARN;
6013 else if (unformat (i, "forward"))
6014 flags |= L2_FWD;
6015 else if (unformat (i, "flood"))
6016 flags |= L2_FLOOD;
6017 else if (unformat (i, "uu-flood"))
6018 flags |= L2_UU_FLOOD;
6019 else if (unformat (i, "arp-term"))
6020 flags |= L2_ARP_TERM;
6021 else if (unformat (i, "off"))
6022 is_set = 0;
6023 else if (unformat (i, "disable"))
6024 is_set = 0;
6025 else
6026 break;
6027 }
6028
6029 if (bd_id_set == 0)
6030 {
6031 errmsg ("missing bridge domain");
6032 return -99;
6033 }
6034
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006035 M (BRIDGE_FLAGS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006036
6037 mp->bd_id = ntohl (bd_id);
6038 mp->feature_bitmap = ntohl (flags);
6039 mp->is_set = is_set;
6040
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006041 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06006042 W (ret);
6043 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006044}
6045
6046static int
6047api_bd_ip_mac_add_del (vat_main_t * vam)
6048{
6049 unformat_input_t *i = vam->input;
6050 vl_api_bd_ip_mac_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006051 u32 bd_id;
6052 u8 is_ipv6 = 0;
6053 u8 is_add = 1;
6054 u8 bd_id_set = 0;
6055 u8 ip_set = 0;
6056 u8 mac_set = 0;
6057 ip4_address_t v4addr;
6058 ip6_address_t v6addr;
6059 u8 macaddr[6];
Jon Loeliger56c7b012017-02-01 12:31:41 -06006060 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006061
6062
6063 /* Parse args required to build the message */
6064 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6065 {
6066 if (unformat (i, "bd_id %d", &bd_id))
6067 {
6068 bd_id_set++;
6069 }
6070 else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
6071 {
6072 ip_set++;
6073 }
6074 else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
6075 {
6076 ip_set++;
6077 is_ipv6++;
6078 }
6079 else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
6080 {
6081 mac_set++;
6082 }
6083 else if (unformat (i, "del"))
6084 is_add = 0;
6085 else
6086 break;
6087 }
6088
6089 if (bd_id_set == 0)
6090 {
6091 errmsg ("missing bridge domain");
6092 return -99;
6093 }
6094 else if (ip_set == 0)
6095 {
6096 errmsg ("missing IP address");
6097 return -99;
6098 }
6099 else if (mac_set == 0)
6100 {
6101 errmsg ("missing MAC address");
6102 return -99;
6103 }
6104
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006105 M (BD_IP_MAC_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006106
6107 mp->bd_id = ntohl (bd_id);
6108 mp->is_ipv6 = is_ipv6;
6109 mp->is_add = is_add;
6110 if (is_ipv6)
6111 clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
6112 else
6113 clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
6114 clib_memcpy (mp->mac_address, macaddr, 6);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006115 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06006116 W (ret);
6117 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006118}
6119
6120static int
6121api_tap_connect (vat_main_t * vam)
6122{
6123 unformat_input_t *i = vam->input;
6124 vl_api_tap_connect_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006125 u8 mac_address[6];
6126 u8 random_mac = 1;
6127 u8 name_set = 0;
6128 u8 *tap_name;
6129 u8 *tag = 0;
Dave Barach2feaffc2017-01-14 10:30:50 -05006130 ip4_address_t ip4_address;
6131 u32 ip4_mask_width;
6132 int ip4_address_set = 0;
6133 ip6_address_t ip6_address;
6134 u32 ip6_mask_width;
6135 int ip6_address_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006136 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006137
6138 memset (mac_address, 0, sizeof (mac_address));
6139
6140 /* Parse args required to build the message */
6141 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6142 {
6143 if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6144 {
6145 random_mac = 0;
6146 }
6147 else if (unformat (i, "random-mac"))
6148 random_mac = 1;
6149 else if (unformat (i, "tapname %s", &tap_name))
6150 name_set = 1;
6151 else if (unformat (i, "tag %s", &tag))
6152 ;
Dave Barach2feaffc2017-01-14 10:30:50 -05006153 else if (unformat (i, "address %U/%d",
6154 unformat_ip4_address, &ip4_address, &ip4_mask_width))
6155 ip4_address_set = 1;
6156 else if (unformat (i, "address %U/%d",
6157 unformat_ip6_address, &ip6_address, &ip6_mask_width))
6158 ip6_address_set = 1;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006159 else
6160 break;
6161 }
6162
6163 if (name_set == 0)
6164 {
6165 errmsg ("missing tap name");
6166 return -99;
6167 }
6168 if (vec_len (tap_name) > 63)
6169 {
6170 errmsg ("tap name too long");
6171 return -99;
6172 }
6173 vec_add1 (tap_name, 0);
6174
6175 if (vec_len (tag) > 63)
6176 {
6177 errmsg ("tag too long");
6178 return -99;
6179 }
6180
6181 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006182 M (TAP_CONNECT, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006183
6184 mp->use_random_mac = random_mac;
6185 clib_memcpy (mp->mac_address, mac_address, 6);
6186 clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6187 if (tag)
6188 clib_memcpy (mp->tag, tag, vec_len (tag));
6189
Dave Barach2feaffc2017-01-14 10:30:50 -05006190 if (ip4_address_set)
6191 {
6192 mp->ip4_address_set = 1;
6193 clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
6194 mp->ip4_mask_width = ip4_mask_width;
6195 }
6196 if (ip6_address_set)
6197 {
6198 mp->ip6_address_set = 1;
6199 clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
6200 mp->ip6_mask_width = ip6_mask_width;
6201 }
6202
Damjan Marion7cd468a2016-12-19 23:05:39 +01006203 vec_free (tap_name);
6204 vec_free (tag);
6205
6206 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006207 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006208
6209 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06006210 W (ret);
6211 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006212}
6213
6214static int
6215api_tap_modify (vat_main_t * vam)
6216{
6217 unformat_input_t *i = vam->input;
6218 vl_api_tap_modify_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006219 u8 mac_address[6];
6220 u8 random_mac = 1;
6221 u8 name_set = 0;
6222 u8 *tap_name;
6223 u32 sw_if_index = ~0;
6224 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006225 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006226
6227 memset (mac_address, 0, sizeof (mac_address));
6228
6229 /* Parse args required to build the message */
6230 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6231 {
6232 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6233 sw_if_index_set = 1;
6234 else if (unformat (i, "sw_if_index %d", &sw_if_index))
6235 sw_if_index_set = 1;
6236 else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6237 {
6238 random_mac = 0;
6239 }
6240 else if (unformat (i, "random-mac"))
6241 random_mac = 1;
6242 else if (unformat (i, "tapname %s", &tap_name))
6243 name_set = 1;
6244 else
6245 break;
6246 }
6247
6248 if (sw_if_index_set == 0)
6249 {
6250 errmsg ("missing vpp interface name");
6251 return -99;
6252 }
6253 if (name_set == 0)
6254 {
6255 errmsg ("missing tap name");
6256 return -99;
6257 }
6258 if (vec_len (tap_name) > 63)
6259 {
6260 errmsg ("tap name too long");
6261 }
6262 vec_add1 (tap_name, 0);
6263
6264 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006265 M (TAP_MODIFY, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006266
6267 mp->use_random_mac = random_mac;
6268 mp->sw_if_index = ntohl (sw_if_index);
6269 clib_memcpy (mp->mac_address, mac_address, 6);
6270 clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6271 vec_free (tap_name);
6272
6273 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006274 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006275
6276 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06006277 W (ret);
6278 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006279}
6280
6281static int
6282api_tap_delete (vat_main_t * vam)
6283{
6284 unformat_input_t *i = vam->input;
6285 vl_api_tap_delete_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006286 u32 sw_if_index = ~0;
6287 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006288 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006289
6290 /* Parse args required to build the message */
6291 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6292 {
6293 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6294 sw_if_index_set = 1;
6295 else if (unformat (i, "sw_if_index %d", &sw_if_index))
6296 sw_if_index_set = 1;
6297 else
6298 break;
6299 }
6300
6301 if (sw_if_index_set == 0)
6302 {
6303 errmsg ("missing vpp interface name");
6304 return -99;
6305 }
6306
6307 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006308 M (TAP_DELETE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006309
6310 mp->sw_if_index = ntohl (sw_if_index);
6311
6312 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006313 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006314
6315 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06006316 W (ret);
6317 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006318}
6319
6320static int
6321api_ip_add_del_route (vat_main_t * vam)
6322{
6323 unformat_input_t *i = vam->input;
6324 vl_api_ip_add_del_route_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006325 u32 sw_if_index = ~0, vrf_id = 0;
6326 u8 is_ipv6 = 0;
6327 u8 is_local = 0, is_drop = 0;
6328 u8 is_unreach = 0, is_prohibit = 0;
6329 u8 create_vrf_if_needed = 0;
6330 u8 is_add = 1;
6331 u32 next_hop_weight = 1;
6332 u8 not_last = 0;
6333 u8 is_multipath = 0;
6334 u8 address_set = 0;
6335 u8 address_length_set = 0;
6336 u32 next_hop_table_id = 0;
6337 u32 resolve_attempts = 0;
6338 u32 dst_address_length = 0;
6339 u8 next_hop_set = 0;
6340 ip4_address_t v4_dst_address, v4_next_hop_address;
6341 ip6_address_t v6_dst_address, v6_next_hop_address;
6342 int count = 1;
6343 int j;
6344 f64 before = 0;
6345 u32 random_add_del = 0;
6346 u32 *random_vector = 0;
6347 uword *random_hash;
6348 u32 random_seed = 0xdeaddabe;
6349 u32 classify_table_index = ~0;
6350 u8 is_classify = 0;
6351 u8 resolve_host = 0, resolve_attached = 0;
6352 mpls_label_t *next_hop_out_label_stack = NULL;
6353 mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6354 mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6355
6356 /* Parse args required to build the message */
6357 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6358 {
6359 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6360 ;
6361 else if (unformat (i, "sw_if_index %d", &sw_if_index))
6362 ;
6363 else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
6364 {
6365 address_set = 1;
6366 is_ipv6 = 0;
6367 }
6368 else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
6369 {
6370 address_set = 1;
6371 is_ipv6 = 1;
6372 }
6373 else if (unformat (i, "/%d", &dst_address_length))
6374 {
6375 address_length_set = 1;
6376 }
6377
6378 else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
6379 &v4_next_hop_address))
6380 {
6381 next_hop_set = 1;
6382 }
6383 else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
6384 &v6_next_hop_address))
6385 {
6386 next_hop_set = 1;
6387 }
6388 else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6389 ;
6390 else if (unformat (i, "weight %d", &next_hop_weight))
6391 ;
6392 else if (unformat (i, "drop"))
6393 {
6394 is_drop = 1;
6395 }
6396 else if (unformat (i, "null-send-unreach"))
6397 {
6398 is_unreach = 1;
6399 }
6400 else if (unformat (i, "null-send-prohibit"))
6401 {
6402 is_prohibit = 1;
6403 }
6404 else if (unformat (i, "local"))
6405 {
6406 is_local = 1;
6407 }
6408 else if (unformat (i, "classify %d", &classify_table_index))
6409 {
6410 is_classify = 1;
6411 }
6412 else if (unformat (i, "del"))
6413 is_add = 0;
6414 else if (unformat (i, "add"))
6415 is_add = 1;
6416 else if (unformat (i, "not-last"))
6417 not_last = 1;
6418 else if (unformat (i, "resolve-via-host"))
6419 resolve_host = 1;
6420 else if (unformat (i, "resolve-via-attached"))
6421 resolve_attached = 1;
6422 else if (unformat (i, "multipath"))
6423 is_multipath = 1;
6424 else if (unformat (i, "vrf %d", &vrf_id))
6425 ;
6426 else if (unformat (i, "create-vrf"))
6427 create_vrf_if_needed = 1;
6428 else if (unformat (i, "count %d", &count))
6429 ;
6430 else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
6431 ;
6432 else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6433 ;
6434 else if (unformat (i, "out-label %d", &next_hop_out_label))
6435 vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6436 else if (unformat (i, "via-label %d", &next_hop_via_label))
6437 ;
6438 else if (unformat (i, "random"))
6439 random_add_del = 1;
6440 else if (unformat (i, "seed %d", &random_seed))
6441 ;
6442 else
6443 {
6444 clib_warning ("parse error '%U'", format_unformat_error, i);
6445 return -99;
6446 }
6447 }
6448
6449 if (!next_hop_set && !is_drop && !is_local &&
6450 !is_classify && !is_unreach && !is_prohibit &&
6451 MPLS_LABEL_INVALID == next_hop_via_label)
6452 {
6453 errmsg
6454 ("next hop / local / drop / unreach / prohibit / classify not set");
6455 return -99;
6456 }
6457
6458 if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
6459 {
6460 errmsg ("next hop and next-hop via label set");
6461 return -99;
6462 }
6463 if (address_set == 0)
6464 {
6465 errmsg ("missing addresses");
6466 return -99;
6467 }
6468
6469 if (address_length_set == 0)
6470 {
6471 errmsg ("missing address length");
6472 return -99;
6473 }
6474
6475 /* Generate a pile of unique, random routes */
6476 if (random_add_del)
6477 {
6478 u32 this_random_address;
6479 random_hash = hash_create (count, sizeof (uword));
6480
6481 hash_set (random_hash, v4_next_hop_address.as_u32, 1);
6482 for (j = 0; j <= count; j++)
6483 {
6484 do
6485 {
6486 this_random_address = random_u32 (&random_seed);
6487 this_random_address =
6488 clib_host_to_net_u32 (this_random_address);
6489 }
6490 while (hash_get (random_hash, this_random_address));
6491 vec_add1 (random_vector, this_random_address);
6492 hash_set (random_hash, this_random_address, 1);
6493 }
6494 hash_free (random_hash);
6495 v4_dst_address.as_u32 = random_vector[0];
6496 }
6497
6498 if (count > 1)
6499 {
6500 /* Turn on async mode */
6501 vam->async_mode = 1;
6502 vam->async_errors = 0;
6503 before = vat_time_now (vam);
6504 }
6505
6506 for (j = 0; j < count; j++)
6507 {
6508 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006509 M2 (IP_ADD_DEL_ROUTE, mp,
Damjan Marion7cd468a2016-12-19 23:05:39 +01006510 sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6511
6512 mp->next_hop_sw_if_index = ntohl (sw_if_index);
6513 mp->table_id = ntohl (vrf_id);
6514 mp->create_vrf_if_needed = create_vrf_if_needed;
6515
6516 mp->is_add = is_add;
6517 mp->is_drop = is_drop;
6518 mp->is_unreach = is_unreach;
6519 mp->is_prohibit = is_prohibit;
6520 mp->is_ipv6 = is_ipv6;
6521 mp->is_local = is_local;
6522 mp->is_classify = is_classify;
6523 mp->is_multipath = is_multipath;
6524 mp->is_resolve_host = resolve_host;
6525 mp->is_resolve_attached = resolve_attached;
6526 mp->not_last = not_last;
6527 mp->next_hop_weight = next_hop_weight;
6528 mp->dst_address_length = dst_address_length;
6529 mp->next_hop_table_id = ntohl (next_hop_table_id);
6530 mp->classify_table_index = ntohl (classify_table_index);
6531 mp->next_hop_via_label = ntohl (next_hop_via_label);
6532 mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6533 if (0 != mp->next_hop_n_out_labels)
6534 {
6535 memcpy (mp->next_hop_out_label_stack,
6536 next_hop_out_label_stack,
6537 vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6538 vec_free (next_hop_out_label_stack);
6539 }
6540
6541 if (is_ipv6)
6542 {
6543 clib_memcpy (mp->dst_address, &v6_dst_address,
6544 sizeof (v6_dst_address));
6545 if (next_hop_set)
6546 clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
6547 sizeof (v6_next_hop_address));
6548 increment_v6_address (&v6_dst_address);
6549 }
6550 else
6551 {
6552 clib_memcpy (mp->dst_address, &v4_dst_address,
6553 sizeof (v4_dst_address));
6554 if (next_hop_set)
6555 clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
6556 sizeof (v4_next_hop_address));
6557 if (random_add_del)
6558 v4_dst_address.as_u32 = random_vector[j + 1];
6559 else
6560 increment_v4_address (&v4_dst_address);
6561 }
6562 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006563 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006564 /* If we receive SIGTERM, stop now... */
6565 if (vam->do_exit)
6566 break;
6567 }
6568
6569 /* When testing multiple add/del ops, use a control-ping to sync */
6570 if (count > 1)
6571 {
Jon Loeliger2d23eca2017-02-01 13:09:58 -06006572 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006573 f64 after;
Jon Loeliger1f9191f2017-01-31 15:27:19 -06006574 f64 timeout;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006575
6576 /* Shut off async mode */
6577 vam->async_mode = 0;
6578
Jon Loeliger2d23eca2017-02-01 13:09:58 -06006579 M (CONTROL_PING, mp_ping);
6580 S (mp_ping);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006581
6582 timeout = vat_time_now (vam) + 1.0;
6583 while (vat_time_now (vam) < timeout)
6584 if (vam->result_ready == 1)
6585 goto out;
6586 vam->retval = -99;
6587
6588 out:
6589 if (vam->retval == -99)
6590 errmsg ("timeout");
6591
6592 if (vam->async_errors > 0)
6593 {
6594 errmsg ("%d asynchronous errors", vam->async_errors);
6595 vam->retval = -98;
6596 }
6597 vam->async_errors = 0;
6598 after = vat_time_now (vam);
6599
6600 /* slim chance, but we might have eaten SIGTERM on the first iteration */
6601 if (j > 0)
6602 count = j;
6603
6604 print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6605 count, after - before, count / (after - before));
6606 }
6607 else
6608 {
Jon Loeliger56c7b012017-02-01 12:31:41 -06006609 int ret;
6610
Damjan Marion7cd468a2016-12-19 23:05:39 +01006611 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06006612 W (ret);
6613 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006614 }
6615
6616 /* Return the good/bad news */
6617 return (vam->retval);
6618}
6619
6620static int
Neale Ranns32e1c012016-11-22 17:07:28 +00006621api_ip_mroute_add_del (vat_main_t * vam)
6622{
6623 unformat_input_t *i = vam->input;
6624 vl_api_ip_mroute_add_del_t *mp;
Neale Ranns32e1c012016-11-22 17:07:28 +00006625 u32 sw_if_index = ~0, vrf_id = 0;
6626 u8 is_ipv6 = 0;
6627 u8 is_local = 0;
6628 u8 create_vrf_if_needed = 0;
6629 u8 is_add = 1;
6630 u8 address_set = 0;
6631 u32 grp_address_length = 0;
6632 ip4_address_t v4_grp_address, v4_src_address;
6633 ip6_address_t v6_grp_address, v6_src_address;
6634 mfib_itf_flags_t iflags = 0;
6635 mfib_entry_flags_t eflags = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006636 int ret;
Neale Ranns32e1c012016-11-22 17:07:28 +00006637
6638 /* Parse args required to build the message */
6639 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6640 {
6641 if (unformat (i, "sw_if_index %d", &sw_if_index))
6642 ;
6643 else if (unformat (i, "%U %U",
6644 unformat_ip4_address, &v4_src_address,
6645 unformat_ip4_address, &v4_grp_address))
6646 {
6647 grp_address_length = 64;
6648 address_set = 1;
6649 is_ipv6 = 0;
6650 }
6651 else if (unformat (i, "%U %U",
6652 unformat_ip6_address, &v6_src_address,
6653 unformat_ip6_address, &v6_grp_address))
6654 {
6655 grp_address_length = 256;
6656 address_set = 1;
6657 is_ipv6 = 1;
6658 }
6659 else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
6660 {
6661 memset (&v4_src_address, 0, sizeof (v4_src_address));
6662 grp_address_length = 32;
6663 address_set = 1;
6664 is_ipv6 = 0;
6665 }
6666 else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
6667 {
6668 memset (&v6_src_address, 0, sizeof (v6_src_address));
6669 grp_address_length = 128;
6670 address_set = 1;
6671 is_ipv6 = 1;
6672 }
6673 else if (unformat (i, "/%d", &grp_address_length))
6674 ;
6675 else if (unformat (i, "local"))
6676 {
6677 is_local = 1;
6678 }
6679 else if (unformat (i, "del"))
6680 is_add = 0;
6681 else if (unformat (i, "add"))
6682 is_add = 1;
6683 else if (unformat (i, "vrf %d", &vrf_id))
6684 ;
6685 else if (unformat (i, "create-vrf"))
6686 create_vrf_if_needed = 1;
6687 else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
6688 ;
6689 else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
6690 ;
6691 else
6692 {
6693 clib_warning ("parse error '%U'", format_unformat_error, i);
6694 return -99;
6695 }
6696 }
6697
6698 if (address_set == 0)
6699 {
6700 errmsg ("missing addresses\n");
6701 return -99;
6702 }
6703
6704 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006705 M (IP_MROUTE_ADD_DEL, mp);
Neale Ranns32e1c012016-11-22 17:07:28 +00006706
6707 mp->next_hop_sw_if_index = ntohl (sw_if_index);
6708 mp->table_id = ntohl (vrf_id);
6709 mp->create_vrf_if_needed = create_vrf_if_needed;
6710
6711 mp->is_add = is_add;
6712 mp->is_ipv6 = is_ipv6;
6713 mp->is_local = is_local;
6714 mp->itf_flags = ntohl (iflags);
6715 mp->entry_flags = ntohl (eflags);
6716 mp->grp_address_length = grp_address_length;
6717 mp->grp_address_length = ntohs (mp->grp_address_length);
6718
6719 if (is_ipv6)
6720 {
6721 clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
6722 clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
6723 }
6724 else
6725 {
6726 clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
6727 clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
6728
6729 }
6730
6731 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006732 S (mp);
Neale Ranns32e1c012016-11-22 17:07:28 +00006733 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06006734 W (ret);
6735 return ret;
Neale Ranns32e1c012016-11-22 17:07:28 +00006736}
6737
6738static int
Damjan Marion7cd468a2016-12-19 23:05:39 +01006739api_mpls_route_add_del (vat_main_t * vam)
6740{
6741 unformat_input_t *i = vam->input;
6742 vl_api_mpls_route_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006743 u32 sw_if_index = ~0, table_id = 0;
6744 u8 create_table_if_needed = 0;
6745 u8 is_add = 1;
6746 u32 next_hop_weight = 1;
6747 u8 is_multipath = 0;
6748 u32 next_hop_table_id = 0;
6749 u8 next_hop_set = 0;
6750 ip4_address_t v4_next_hop_address = {
6751 .as_u32 = 0,
6752 };
6753 ip6_address_t v6_next_hop_address = { {0} };
6754 int count = 1;
6755 int j;
6756 f64 before = 0;
6757 u32 classify_table_index = ~0;
6758 u8 is_classify = 0;
6759 u8 resolve_host = 0, resolve_attached = 0;
6760 mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6761 mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6762 mpls_label_t *next_hop_out_label_stack = NULL;
6763 mpls_label_t local_label = MPLS_LABEL_INVALID;
6764 u8 is_eos = 0;
6765 u8 next_hop_proto_is_ip4 = 1;
6766
6767 /* Parse args required to build the message */
6768 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6769 {
6770 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6771 ;
6772 else if (unformat (i, "sw_if_index %d", &sw_if_index))
6773 ;
6774 else if (unformat (i, "%d", &local_label))
6775 ;
6776 else if (unformat (i, "eos"))
6777 is_eos = 1;
6778 else if (unformat (i, "non-eos"))
6779 is_eos = 0;
6780 else if (unformat (i, "via %U", unformat_ip4_address,
6781 &v4_next_hop_address))
6782 {
6783 next_hop_set = 1;
6784 next_hop_proto_is_ip4 = 1;
6785 }
6786 else if (unformat (i, "via %U", unformat_ip6_address,
6787 &v6_next_hop_address))
6788 {
6789 next_hop_set = 1;
6790 next_hop_proto_is_ip4 = 0;
6791 }
6792 else if (unformat (i, "weight %d", &next_hop_weight))
6793 ;
6794 else if (unformat (i, "create-table"))
6795 create_table_if_needed = 1;
6796 else if (unformat (i, "classify %d", &classify_table_index))
6797 {
6798 is_classify = 1;
6799 }
6800 else if (unformat (i, "del"))
6801 is_add = 0;
6802 else if (unformat (i, "add"))
6803 is_add = 1;
6804 else if (unformat (i, "resolve-via-host"))
6805 resolve_host = 1;
6806 else if (unformat (i, "resolve-via-attached"))
6807 resolve_attached = 1;
6808 else if (unformat (i, "multipath"))
6809 is_multipath = 1;
6810 else if (unformat (i, "count %d", &count))
6811 ;
6812 else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
6813 {
6814 next_hop_set = 1;
6815 next_hop_proto_is_ip4 = 1;
6816 }
6817 else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
6818 {
6819 next_hop_set = 1;
6820 next_hop_proto_is_ip4 = 0;
6821 }
6822 else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6823 ;
6824 else if (unformat (i, "via-label %d", &next_hop_via_label))
6825 ;
6826 else if (unformat (i, "out-label %d", &next_hop_out_label))
6827 vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6828 else
6829 {
6830 clib_warning ("parse error '%U'", format_unformat_error, i);
6831 return -99;
6832 }
6833 }
6834
6835 if (!next_hop_set && !is_classify)
6836 {
6837 errmsg ("next hop / classify not set");
6838 return -99;
6839 }
6840
6841 if (MPLS_LABEL_INVALID == local_label)
6842 {
6843 errmsg ("missing label");
6844 return -99;
6845 }
6846
6847 if (count > 1)
6848 {
6849 /* Turn on async mode */
6850 vam->async_mode = 1;
6851 vam->async_errors = 0;
6852 before = vat_time_now (vam);
6853 }
6854
6855 for (j = 0; j < count; j++)
6856 {
6857 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06006858 M2 (MPLS_ROUTE_ADD_DEL, mp,
Damjan Marion7cd468a2016-12-19 23:05:39 +01006859 sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6860
6861 mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
6862 mp->mr_table_id = ntohl (table_id);
6863 mp->mr_create_table_if_needed = create_table_if_needed;
6864
6865 mp->mr_is_add = is_add;
6866 mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6867 mp->mr_is_classify = is_classify;
6868 mp->mr_is_multipath = is_multipath;
6869 mp->mr_is_resolve_host = resolve_host;
6870 mp->mr_is_resolve_attached = resolve_attached;
6871 mp->mr_next_hop_weight = next_hop_weight;
6872 mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
6873 mp->mr_classify_table_index = ntohl (classify_table_index);
6874 mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
6875 mp->mr_label = ntohl (local_label);
6876 mp->mr_eos = is_eos;
6877
6878 mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6879 if (0 != mp->mr_next_hop_n_out_labels)
6880 {
6881 memcpy (mp->mr_next_hop_out_label_stack,
6882 next_hop_out_label_stack,
6883 vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6884 vec_free (next_hop_out_label_stack);
6885 }
6886
6887 if (next_hop_set)
6888 {
6889 if (next_hop_proto_is_ip4)
6890 {
6891 clib_memcpy (mp->mr_next_hop,
6892 &v4_next_hop_address,
6893 sizeof (v4_next_hop_address));
6894 }
6895 else
6896 {
6897 clib_memcpy (mp->mr_next_hop,
6898 &v6_next_hop_address,
6899 sizeof (v6_next_hop_address));
6900 }
6901 }
6902 local_label++;
6903
6904 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06006905 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006906 /* If we receive SIGTERM, stop now... */
6907 if (vam->do_exit)
6908 break;
6909 }
6910
6911 /* When testing multiple add/del ops, use a control-ping to sync */
6912 if (count > 1)
6913 {
Jon Loeliger2d23eca2017-02-01 13:09:58 -06006914 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006915 f64 after;
Jon Loeliger1f9191f2017-01-31 15:27:19 -06006916 f64 timeout;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006917
6918 /* Shut off async mode */
6919 vam->async_mode = 0;
6920
Jon Loeliger2d23eca2017-02-01 13:09:58 -06006921 M (CONTROL_PING, mp_ping);
6922 S (mp_ping);
Damjan Marion7cd468a2016-12-19 23:05:39 +01006923
6924 timeout = vat_time_now (vam) + 1.0;
6925 while (vat_time_now (vam) < timeout)
6926 if (vam->result_ready == 1)
6927 goto out;
6928 vam->retval = -99;
6929
6930 out:
6931 if (vam->retval == -99)
6932 errmsg ("timeout");
6933
6934 if (vam->async_errors > 0)
6935 {
6936 errmsg ("%d asynchronous errors", vam->async_errors);
6937 vam->retval = -98;
6938 }
6939 vam->async_errors = 0;
6940 after = vat_time_now (vam);
6941
6942 /* slim chance, but we might have eaten SIGTERM on the first iteration */
6943 if (j > 0)
6944 count = j;
6945
6946 print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6947 count, after - before, count / (after - before));
6948 }
6949 else
6950 {
Jon Loeliger56c7b012017-02-01 12:31:41 -06006951 int ret;
6952
Damjan Marion7cd468a2016-12-19 23:05:39 +01006953 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06006954 W (ret);
6955 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006956 }
6957
6958 /* Return the good/bad news */
6959 return (vam->retval);
6960}
6961
6962static int
6963api_mpls_ip_bind_unbind (vat_main_t * vam)
6964{
6965 unformat_input_t *i = vam->input;
6966 vl_api_mpls_ip_bind_unbind_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006967 u32 ip_table_id = 0;
6968 u8 create_table_if_needed = 0;
6969 u8 is_bind = 1;
6970 u8 is_ip4 = 1;
6971 ip4_address_t v4_address;
6972 ip6_address_t v6_address;
6973 u32 address_length;
6974 u8 address_set = 0;
6975 mpls_label_t local_label = MPLS_LABEL_INVALID;
Jon Loeliger56c7b012017-02-01 12:31:41 -06006976 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01006977
6978 /* Parse args required to build the message */
6979 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6980 {
6981 if (unformat (i, "%U/%d", unformat_ip4_address,
6982 &v4_address, &address_length))
6983 {
6984 is_ip4 = 1;
6985 address_set = 1;
6986 }
6987 else if (unformat (i, "%U/%d", unformat_ip6_address,
6988 &v6_address, &address_length))
6989 {
6990 is_ip4 = 0;
6991 address_set = 1;
6992 }
6993 else if (unformat (i, "%d", &local_label))
6994 ;
6995 else if (unformat (i, "create-table"))
6996 create_table_if_needed = 1;
6997 else if (unformat (i, "table-id %d", &ip_table_id))
6998 ;
6999 else if (unformat (i, "unbind"))
7000 is_bind = 0;
7001 else if (unformat (i, "bind"))
7002 is_bind = 1;
7003 else
7004 {
7005 clib_warning ("parse error '%U'", format_unformat_error, i);
7006 return -99;
7007 }
7008 }
7009
7010 if (!address_set)
7011 {
7012 errmsg ("IP addres not set");
7013 return -99;
7014 }
7015
7016 if (MPLS_LABEL_INVALID == local_label)
7017 {
7018 errmsg ("missing label");
7019 return -99;
7020 }
7021
7022 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007023 M (MPLS_IP_BIND_UNBIND, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007024
7025 mp->mb_create_table_if_needed = create_table_if_needed;
7026 mp->mb_is_bind = is_bind;
7027 mp->mb_is_ip4 = is_ip4;
7028 mp->mb_ip_table_id = ntohl (ip_table_id);
7029 mp->mb_mpls_table_id = 0;
7030 mp->mb_label = ntohl (local_label);
7031 mp->mb_address_length = address_length;
7032
7033 if (is_ip4)
7034 clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
7035 else
7036 clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
7037
7038 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007039 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007040
7041 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -06007042 W (ret);
7043 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007044}
7045
7046static int
7047api_proxy_arp_add_del (vat_main_t * vam)
7048{
7049 unformat_input_t *i = vam->input;
7050 vl_api_proxy_arp_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007051 u32 vrf_id = 0;
7052 u8 is_add = 1;
7053 ip4_address_t lo, hi;
7054 u8 range_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007055 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007056
7057 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7058 {
7059 if (unformat (i, "vrf %d", &vrf_id))
7060 ;
7061 else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
7062 unformat_ip4_address, &hi))
7063 range_set = 1;
7064 else if (unformat (i, "del"))
7065 is_add = 0;
7066 else
7067 {
7068 clib_warning ("parse error '%U'", format_unformat_error, i);
7069 return -99;
7070 }
7071 }
7072
7073 if (range_set == 0)
7074 {
7075 errmsg ("address range not set");
7076 return -99;
7077 }
7078
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007079 M (PROXY_ARP_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007080
7081 mp->vrf_id = ntohl (vrf_id);
7082 mp->is_add = is_add;
7083 clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
7084 clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
7085
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007086 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007087 W (ret);
7088 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007089}
7090
7091static int
7092api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
7093{
7094 unformat_input_t *i = vam->input;
7095 vl_api_proxy_arp_intfc_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007096 u32 sw_if_index;
7097 u8 enable = 1;
7098 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007099 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007100
7101 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7102 {
7103 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7104 sw_if_index_set = 1;
7105 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7106 sw_if_index_set = 1;
7107 else if (unformat (i, "enable"))
7108 enable = 1;
7109 else if (unformat (i, "disable"))
7110 enable = 0;
7111 else
7112 {
7113 clib_warning ("parse error '%U'", format_unformat_error, i);
7114 return -99;
7115 }
7116 }
7117
7118 if (sw_if_index_set == 0)
7119 {
7120 errmsg ("missing interface name or sw_if_index");
7121 return -99;
7122 }
7123
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007124 M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007125
7126 mp->sw_if_index = ntohl (sw_if_index);
7127 mp->enable_disable = enable;
7128
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007129 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007130 W (ret);
7131 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007132}
7133
7134static int
7135api_mpls_tunnel_add_del (vat_main_t * vam)
7136{
7137 unformat_input_t *i = vam->input;
7138 vl_api_mpls_tunnel_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007139
7140 u8 is_add = 1;
7141 u8 l2_only = 0;
7142 u32 sw_if_index = ~0;
7143 u32 next_hop_sw_if_index = ~0;
7144 u32 next_hop_proto_is_ip4 = 1;
7145
7146 u32 next_hop_table_id = 0;
7147 ip4_address_t v4_next_hop_address = {
7148 .as_u32 = 0,
7149 };
7150 ip6_address_t v6_next_hop_address = { {0} };
7151 mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007152 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007153
7154 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7155 {
7156 if (unformat (i, "add"))
7157 is_add = 1;
7158 else if (unformat (i, "del sw_if_index %d", &sw_if_index))
7159 is_add = 0;
7160 else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
7161 ;
7162 else if (unformat (i, "via %U",
7163 unformat_ip4_address, &v4_next_hop_address))
7164 {
7165 next_hop_proto_is_ip4 = 1;
7166 }
7167 else if (unformat (i, "via %U",
7168 unformat_ip6_address, &v6_next_hop_address))
7169 {
7170 next_hop_proto_is_ip4 = 0;
7171 }
7172 else if (unformat (i, "l2-only"))
7173 l2_only = 1;
7174 else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7175 ;
7176 else if (unformat (i, "out-label %d", &next_hop_out_label))
7177 vec_add1 (labels, ntohl (next_hop_out_label));
7178 else
7179 {
7180 clib_warning ("parse error '%U'", format_unformat_error, i);
7181 return -99;
7182 }
7183 }
7184
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007185 M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
Damjan Marion7cd468a2016-12-19 23:05:39 +01007186
7187 mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
7188 mp->mt_sw_if_index = ntohl (sw_if_index);
7189 mp->mt_is_add = is_add;
7190 mp->mt_l2_only = l2_only;
7191 mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
7192 mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7193
7194 mp->mt_next_hop_n_out_labels = vec_len (labels);
7195
7196 if (0 != mp->mt_next_hop_n_out_labels)
7197 {
7198 clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
7199 sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
7200 vec_free (labels);
7201 }
7202
7203 if (next_hop_proto_is_ip4)
7204 {
7205 clib_memcpy (mp->mt_next_hop,
7206 &v4_next_hop_address, sizeof (v4_next_hop_address));
7207 }
7208 else
7209 {
7210 clib_memcpy (mp->mt_next_hop,
7211 &v6_next_hop_address, sizeof (v6_next_hop_address));
7212 }
7213
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007214 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007215 W (ret);
7216 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007217}
7218
7219static int
7220api_sw_interface_set_unnumbered (vat_main_t * vam)
7221{
7222 unformat_input_t *i = vam->input;
7223 vl_api_sw_interface_set_unnumbered_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007224 u32 sw_if_index;
7225 u32 unnum_sw_index = ~0;
7226 u8 is_add = 1;
7227 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007228 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007229
7230 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7231 {
7232 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7233 sw_if_index_set = 1;
7234 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7235 sw_if_index_set = 1;
7236 else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
7237 ;
7238 else if (unformat (i, "del"))
7239 is_add = 0;
7240 else
7241 {
7242 clib_warning ("parse error '%U'", format_unformat_error, i);
7243 return -99;
7244 }
7245 }
7246
7247 if (sw_if_index_set == 0)
7248 {
7249 errmsg ("missing interface name or sw_if_index");
7250 return -99;
7251 }
7252
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007253 M (SW_INTERFACE_SET_UNNUMBERED, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007254
7255 mp->sw_if_index = ntohl (sw_if_index);
7256 mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
7257 mp->is_add = is_add;
7258
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007259 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007260 W (ret);
7261 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007262}
7263
7264static int
7265api_ip_neighbor_add_del (vat_main_t * vam)
7266{
7267 unformat_input_t *i = vam->input;
7268 vl_api_ip_neighbor_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007269 u32 sw_if_index;
7270 u8 sw_if_index_set = 0;
7271 u32 vrf_id = 0;
7272 u8 is_add = 1;
7273 u8 is_static = 0;
7274 u8 mac_address[6];
7275 u8 mac_set = 0;
7276 u8 v4_address_set = 0;
7277 u8 v6_address_set = 0;
7278 ip4_address_t v4address;
7279 ip6_address_t v6address;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007280 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007281
7282 memset (mac_address, 0, sizeof (mac_address));
7283
7284 /* Parse args required to build the message */
7285 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7286 {
7287 if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7288 {
7289 mac_set = 1;
7290 }
7291 else if (unformat (i, "del"))
7292 is_add = 0;
7293 else
7294 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7295 sw_if_index_set = 1;
7296 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7297 sw_if_index_set = 1;
7298 else if (unformat (i, "is_static"))
7299 is_static = 1;
7300 else if (unformat (i, "vrf %d", &vrf_id))
7301 ;
7302 else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
7303 v4_address_set = 1;
7304 else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
7305 v6_address_set = 1;
7306 else
7307 {
7308 clib_warning ("parse error '%U'", format_unformat_error, i);
7309 return -99;
7310 }
7311 }
7312
7313 if (sw_if_index_set == 0)
7314 {
7315 errmsg ("missing interface name or sw_if_index");
7316 return -99;
7317 }
7318 if (v4_address_set && v6_address_set)
7319 {
7320 errmsg ("both v4 and v6 addresses set");
7321 return -99;
7322 }
7323 if (!v4_address_set && !v6_address_set)
7324 {
7325 errmsg ("no address set");
7326 return -99;
7327 }
7328
7329 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007330 M (IP_NEIGHBOR_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007331
7332 mp->sw_if_index = ntohl (sw_if_index);
7333 mp->is_add = is_add;
7334 mp->vrf_id = ntohl (vrf_id);
7335 mp->is_static = is_static;
7336 if (mac_set)
7337 clib_memcpy (mp->mac_address, mac_address, 6);
7338 if (v6_address_set)
7339 {
7340 mp->is_ipv6 = 1;
7341 clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
7342 }
7343 else
7344 {
7345 /* mp->is_ipv6 = 0; via memset in M macro above */
7346 clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
7347 }
7348
7349 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007350 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007351
7352 /* Wait for a reply, return good/bad news */
Jon Loeliger56c7b012017-02-01 12:31:41 -06007353 W (ret);
7354 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007355}
7356
7357static int
7358api_reset_vrf (vat_main_t * vam)
7359{
7360 unformat_input_t *i = vam->input;
7361 vl_api_reset_vrf_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007362 u32 vrf_id = 0;
7363 u8 is_ipv6 = 0;
7364 u8 vrf_id_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007365 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007366
7367 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7368 {
7369 if (unformat (i, "vrf %d", &vrf_id))
7370 vrf_id_set = 1;
7371 else if (unformat (i, "ipv6"))
7372 is_ipv6 = 1;
7373 else
7374 {
7375 clib_warning ("parse error '%U'", format_unformat_error, i);
7376 return -99;
7377 }
7378 }
7379
7380 if (vrf_id_set == 0)
7381 {
7382 errmsg ("missing vrf id");
7383 return -99;
7384 }
7385
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007386 M (RESET_VRF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007387
7388 mp->vrf_id = ntohl (vrf_id);
7389 mp->is_ipv6 = is_ipv6;
7390
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007391 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007392 W (ret);
7393 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007394}
7395
7396static int
7397api_create_vlan_subif (vat_main_t * vam)
7398{
7399 unformat_input_t *i = vam->input;
7400 vl_api_create_vlan_subif_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007401 u32 sw_if_index;
7402 u8 sw_if_index_set = 0;
7403 u32 vlan_id;
7404 u8 vlan_id_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007405 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007406
7407 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7408 {
7409 if (unformat (i, "sw_if_index %d", &sw_if_index))
7410 sw_if_index_set = 1;
7411 else
7412 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7413 sw_if_index_set = 1;
7414 else if (unformat (i, "vlan %d", &vlan_id))
7415 vlan_id_set = 1;
7416 else
7417 {
7418 clib_warning ("parse error '%U'", format_unformat_error, i);
7419 return -99;
7420 }
7421 }
7422
7423 if (sw_if_index_set == 0)
7424 {
7425 errmsg ("missing interface name or sw_if_index");
7426 return -99;
7427 }
7428
7429 if (vlan_id_set == 0)
7430 {
7431 errmsg ("missing vlan_id");
7432 return -99;
7433 }
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007434 M (CREATE_VLAN_SUBIF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007435
7436 mp->sw_if_index = ntohl (sw_if_index);
7437 mp->vlan_id = ntohl (vlan_id);
7438
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007439 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007440 W (ret);
7441 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007442}
7443
7444#define foreach_create_subif_bit \
7445_(no_tags) \
7446_(one_tag) \
7447_(two_tags) \
7448_(dot1ad) \
7449_(exact_match) \
7450_(default_sub) \
7451_(outer_vlan_id_any) \
7452_(inner_vlan_id_any)
7453
7454static int
7455api_create_subif (vat_main_t * vam)
7456{
7457 unformat_input_t *i = vam->input;
7458 vl_api_create_subif_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007459 u32 sw_if_index;
7460 u8 sw_if_index_set = 0;
7461 u32 sub_id;
7462 u8 sub_id_set = 0;
7463 u32 no_tags = 0;
7464 u32 one_tag = 0;
7465 u32 two_tags = 0;
7466 u32 dot1ad = 0;
7467 u32 exact_match = 0;
7468 u32 default_sub = 0;
7469 u32 outer_vlan_id_any = 0;
7470 u32 inner_vlan_id_any = 0;
7471 u32 tmp;
7472 u16 outer_vlan_id = 0;
7473 u16 inner_vlan_id = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007474 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007475
7476 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7477 {
7478 if (unformat (i, "sw_if_index %d", &sw_if_index))
7479 sw_if_index_set = 1;
7480 else
7481 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7482 sw_if_index_set = 1;
7483 else if (unformat (i, "sub_id %d", &sub_id))
7484 sub_id_set = 1;
7485 else if (unformat (i, "outer_vlan_id %d", &tmp))
7486 outer_vlan_id = tmp;
7487 else if (unformat (i, "inner_vlan_id %d", &tmp))
7488 inner_vlan_id = tmp;
7489
7490#define _(a) else if (unformat (i, #a)) a = 1 ;
7491 foreach_create_subif_bit
7492#undef _
7493 else
7494 {
7495 clib_warning ("parse error '%U'", format_unformat_error, i);
7496 return -99;
7497 }
7498 }
7499
7500 if (sw_if_index_set == 0)
7501 {
7502 errmsg ("missing interface name or sw_if_index");
7503 return -99;
7504 }
7505
7506 if (sub_id_set == 0)
7507 {
7508 errmsg ("missing sub_id");
7509 return -99;
7510 }
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007511 M (CREATE_SUBIF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007512
7513 mp->sw_if_index = ntohl (sw_if_index);
7514 mp->sub_id = ntohl (sub_id);
7515
7516#define _(a) mp->a = a;
7517 foreach_create_subif_bit;
7518#undef _
7519
7520 mp->outer_vlan_id = ntohs (outer_vlan_id);
7521 mp->inner_vlan_id = ntohs (inner_vlan_id);
7522
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007523 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007524 W (ret);
7525 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007526}
7527
7528static int
7529api_oam_add_del (vat_main_t * vam)
7530{
7531 unformat_input_t *i = vam->input;
7532 vl_api_oam_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007533 u32 vrf_id = 0;
7534 u8 is_add = 1;
7535 ip4_address_t src, dst;
7536 u8 src_set = 0;
7537 u8 dst_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007538 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007539
7540 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7541 {
7542 if (unformat (i, "vrf %d", &vrf_id))
7543 ;
7544 else if (unformat (i, "src %U", unformat_ip4_address, &src))
7545 src_set = 1;
7546 else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
7547 dst_set = 1;
7548 else if (unformat (i, "del"))
7549 is_add = 0;
7550 else
7551 {
7552 clib_warning ("parse error '%U'", format_unformat_error, i);
7553 return -99;
7554 }
7555 }
7556
7557 if (src_set == 0)
7558 {
7559 errmsg ("missing src addr");
7560 return -99;
7561 }
7562
7563 if (dst_set == 0)
7564 {
7565 errmsg ("missing dst addr");
7566 return -99;
7567 }
7568
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007569 M (OAM_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007570
7571 mp->vrf_id = ntohl (vrf_id);
7572 mp->is_add = is_add;
7573 clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
7574 clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
7575
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007576 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007577 W (ret);
7578 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007579}
7580
7581static int
7582api_reset_fib (vat_main_t * vam)
7583{
7584 unformat_input_t *i = vam->input;
7585 vl_api_reset_fib_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007586 u32 vrf_id = 0;
7587 u8 is_ipv6 = 0;
7588 u8 vrf_id_set = 0;
7589
Jon Loeliger56c7b012017-02-01 12:31:41 -06007590 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007591 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7592 {
7593 if (unformat (i, "vrf %d", &vrf_id))
7594 vrf_id_set = 1;
7595 else if (unformat (i, "ipv6"))
7596 is_ipv6 = 1;
7597 else
7598 {
7599 clib_warning ("parse error '%U'", format_unformat_error, i);
7600 return -99;
7601 }
7602 }
7603
7604 if (vrf_id_set == 0)
7605 {
7606 errmsg ("missing vrf id");
7607 return -99;
7608 }
7609
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007610 M (RESET_FIB, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007611
7612 mp->vrf_id = ntohl (vrf_id);
7613 mp->is_ipv6 = is_ipv6;
7614
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007615 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007616 W (ret);
7617 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007618}
7619
7620static int
7621api_dhcp_proxy_config (vat_main_t * vam)
7622{
7623 unformat_input_t *i = vam->input;
7624 vl_api_dhcp_proxy_config_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007625 u32 vrf_id = 0;
7626 u8 is_add = 1;
7627 u8 insert_cid = 1;
7628 u8 v4_address_set = 0;
7629 u8 v6_address_set = 0;
7630 ip4_address_t v4address;
7631 ip6_address_t v6address;
7632 u8 v4_src_address_set = 0;
7633 u8 v6_src_address_set = 0;
7634 ip4_address_t v4srcaddress;
7635 ip6_address_t v6srcaddress;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007636 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007637
7638 /* Parse args required to build the message */
7639 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7640 {
7641 if (unformat (i, "del"))
7642 is_add = 0;
7643 else if (unformat (i, "vrf %d", &vrf_id))
7644 ;
7645 else if (unformat (i, "insert-cid %d", &insert_cid))
7646 ;
7647 else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7648 v4_address_set = 1;
7649 else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7650 v6_address_set = 1;
7651 else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7652 v4_src_address_set = 1;
7653 else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7654 v6_src_address_set = 1;
7655 else
7656 break;
7657 }
7658
7659 if (v4_address_set && v6_address_set)
7660 {
7661 errmsg ("both v4 and v6 server addresses set");
7662 return -99;
7663 }
7664 if (!v4_address_set && !v6_address_set)
7665 {
7666 errmsg ("no server addresses set");
7667 return -99;
7668 }
7669
7670 if (v4_src_address_set && v6_src_address_set)
7671 {
7672 errmsg ("both v4 and v6 src addresses set");
7673 return -99;
7674 }
7675 if (!v4_src_address_set && !v6_src_address_set)
7676 {
7677 errmsg ("no src addresses set");
7678 return -99;
7679 }
7680
7681 if (!(v4_src_address_set && v4_address_set) &&
7682 !(v6_src_address_set && v6_address_set))
7683 {
7684 errmsg ("no matching server and src addresses set");
7685 return -99;
7686 }
7687
7688 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007689 M (DHCP_PROXY_CONFIG, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007690
7691 mp->insert_circuit_id = insert_cid;
7692 mp->is_add = is_add;
7693 mp->vrf_id = ntohl (vrf_id);
7694 if (v6_address_set)
7695 {
7696 mp->is_ipv6 = 1;
7697 clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7698 clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7699 }
7700 else
7701 {
7702 clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7703 clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7704 }
7705
7706 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007707 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007708
7709 /* Wait for a reply, return good/bad news */
Jon Loeliger56c7b012017-02-01 12:31:41 -06007710 W (ret);
7711 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007712}
7713
7714static int
7715api_dhcp_proxy_config_2 (vat_main_t * vam)
7716{
7717 unformat_input_t *i = vam->input;
7718 vl_api_dhcp_proxy_config_2_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007719 u32 rx_vrf_id = 0;
7720 u32 server_vrf_id = 0;
7721 u8 is_add = 1;
7722 u8 insert_cid = 1;
7723 u8 v4_address_set = 0;
7724 u8 v6_address_set = 0;
7725 ip4_address_t v4address;
7726 ip6_address_t v6address;
7727 u8 v4_src_address_set = 0;
7728 u8 v6_src_address_set = 0;
7729 ip4_address_t v4srcaddress;
7730 ip6_address_t v6srcaddress;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007731 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007732
7733 /* Parse args required to build the message */
7734 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7735 {
7736 if (unformat (i, "del"))
7737 is_add = 0;
7738 else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
7739 ;
7740 else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
7741 ;
7742 else if (unformat (i, "insert-cid %d", &insert_cid))
7743 ;
7744 else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7745 v4_address_set = 1;
7746 else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7747 v6_address_set = 1;
7748 else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7749 v4_src_address_set = 1;
7750 else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7751 v6_src_address_set = 1;
7752 else
7753 break;
7754 }
7755
7756 if (v4_address_set && v6_address_set)
7757 {
7758 errmsg ("both v4 and v6 server addresses set");
7759 return -99;
7760 }
7761 if (!v4_address_set && !v6_address_set)
7762 {
7763 errmsg ("no server addresses set");
7764 return -99;
7765 }
7766
7767 if (v4_src_address_set && v6_src_address_set)
7768 {
7769 errmsg ("both v4 and v6 src addresses set");
7770 return -99;
7771 }
7772 if (!v4_src_address_set && !v6_src_address_set)
7773 {
7774 errmsg ("no src addresses set");
7775 return -99;
7776 }
7777
7778 if (!(v4_src_address_set && v4_address_set) &&
7779 !(v6_src_address_set && v6_address_set))
7780 {
7781 errmsg ("no matching server and src addresses set");
7782 return -99;
7783 }
7784
7785 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007786 M (DHCP_PROXY_CONFIG_2, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007787
7788 mp->insert_circuit_id = insert_cid;
7789 mp->is_add = is_add;
7790 mp->rx_vrf_id = ntohl (rx_vrf_id);
7791 mp->server_vrf_id = ntohl (server_vrf_id);
7792 if (v6_address_set)
7793 {
7794 mp->is_ipv6 = 1;
7795 clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7796 clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7797 }
7798 else
7799 {
7800 clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7801 clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7802 }
7803
7804 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007805 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007806
7807 /* Wait for a reply, return good/bad news */
Jon Loeliger56c7b012017-02-01 12:31:41 -06007808 W (ret);
7809 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007810}
7811
7812static int
7813api_dhcp_proxy_set_vss (vat_main_t * vam)
7814{
7815 unformat_input_t *i = vam->input;
7816 vl_api_dhcp_proxy_set_vss_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007817 u8 is_ipv6 = 0;
7818 u8 is_add = 1;
7819 u32 tbl_id;
7820 u8 tbl_id_set = 0;
7821 u32 oui;
7822 u8 oui_set = 0;
7823 u32 fib_id;
7824 u8 fib_id_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007825 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007826
7827 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7828 {
7829 if (unformat (i, "tbl_id %d", &tbl_id))
7830 tbl_id_set = 1;
7831 if (unformat (i, "fib_id %d", &fib_id))
7832 fib_id_set = 1;
7833 if (unformat (i, "oui %d", &oui))
7834 oui_set = 1;
7835 else if (unformat (i, "ipv6"))
7836 is_ipv6 = 1;
7837 else if (unformat (i, "del"))
7838 is_add = 0;
7839 else
7840 {
7841 clib_warning ("parse error '%U'", format_unformat_error, i);
7842 return -99;
7843 }
7844 }
7845
7846 if (tbl_id_set == 0)
7847 {
7848 errmsg ("missing tbl id");
7849 return -99;
7850 }
7851
7852 if (fib_id_set == 0)
7853 {
7854 errmsg ("missing fib id");
7855 return -99;
7856 }
7857 if (oui_set == 0)
7858 {
7859 errmsg ("missing oui");
7860 return -99;
7861 }
7862
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007863 M (DHCP_PROXY_SET_VSS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007864 mp->tbl_id = ntohl (tbl_id);
7865 mp->fib_id = ntohl (fib_id);
7866 mp->oui = ntohl (oui);
7867 mp->is_ipv6 = is_ipv6;
7868 mp->is_add = is_add;
7869
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007870 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007871 W (ret);
7872 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007873}
7874
7875static int
7876api_dhcp_client_config (vat_main_t * vam)
7877{
7878 unformat_input_t *i = vam->input;
7879 vl_api_dhcp_client_config_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007880 u32 sw_if_index;
7881 u8 sw_if_index_set = 0;
7882 u8 is_add = 1;
7883 u8 *hostname = 0;
7884 u8 disable_event = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007885 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007886
7887 /* Parse args required to build the message */
7888 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7889 {
7890 if (unformat (i, "del"))
7891 is_add = 0;
7892 else
7893 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7894 sw_if_index_set = 1;
7895 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7896 sw_if_index_set = 1;
7897 else if (unformat (i, "hostname %s", &hostname))
7898 ;
7899 else if (unformat (i, "disable_event"))
7900 disable_event = 1;
7901 else
7902 break;
7903 }
7904
7905 if (sw_if_index_set == 0)
7906 {
7907 errmsg ("missing interface name or sw_if_index");
7908 return -99;
7909 }
7910
7911 if (vec_len (hostname) > 63)
7912 {
7913 errmsg ("hostname too long");
7914 }
7915 vec_add1 (hostname, 0);
7916
7917 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007918 M (DHCP_CLIENT_CONFIG, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007919
7920 mp->sw_if_index = ntohl (sw_if_index);
7921 clib_memcpy (mp->hostname, hostname, vec_len (hostname));
7922 vec_free (hostname);
7923 mp->is_add = is_add;
7924 mp->want_dhcp_event = disable_event ? 0 : 1;
7925 mp->pid = getpid ();
7926
7927 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007928 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007929
7930 /* Wait for a reply, return good/bad news */
Jon Loeliger56c7b012017-02-01 12:31:41 -06007931 W (ret);
7932 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007933}
7934
7935static int
7936api_set_ip_flow_hash (vat_main_t * vam)
7937{
7938 unformat_input_t *i = vam->input;
7939 vl_api_set_ip_flow_hash_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007940 u32 vrf_id = 0;
7941 u8 is_ipv6 = 0;
7942 u8 vrf_id_set = 0;
7943 u8 src = 0;
7944 u8 dst = 0;
7945 u8 sport = 0;
7946 u8 dport = 0;
7947 u8 proto = 0;
7948 u8 reverse = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06007949 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007950
7951 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7952 {
7953 if (unformat (i, "vrf %d", &vrf_id))
7954 vrf_id_set = 1;
7955 else if (unformat (i, "ipv6"))
7956 is_ipv6 = 1;
7957 else if (unformat (i, "src"))
7958 src = 1;
7959 else if (unformat (i, "dst"))
7960 dst = 1;
7961 else if (unformat (i, "sport"))
7962 sport = 1;
7963 else if (unformat (i, "dport"))
7964 dport = 1;
7965 else if (unformat (i, "proto"))
7966 proto = 1;
7967 else if (unformat (i, "reverse"))
7968 reverse = 1;
7969
7970 else
7971 {
7972 clib_warning ("parse error '%U'", format_unformat_error, i);
7973 return -99;
7974 }
7975 }
7976
7977 if (vrf_id_set == 0)
7978 {
7979 errmsg ("missing vrf id");
7980 return -99;
7981 }
7982
Jon Loeliger8a2aea32017-01-31 13:19:40 -06007983 M (SET_IP_FLOW_HASH, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01007984 mp->src = src;
7985 mp->dst = dst;
7986 mp->sport = sport;
7987 mp->dport = dport;
7988 mp->proto = proto;
7989 mp->reverse = reverse;
7990 mp->vrf_id = ntohl (vrf_id);
7991 mp->is_ipv6 = is_ipv6;
7992
Jon Loeliger7bc770c2017-01-31 14:03:33 -06007993 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06007994 W (ret);
7995 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01007996}
7997
7998static int
7999api_sw_interface_ip6_enable_disable (vat_main_t * vam)
8000{
8001 unformat_input_t *i = vam->input;
8002 vl_api_sw_interface_ip6_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008003 u32 sw_if_index;
8004 u8 sw_if_index_set = 0;
8005 u8 enable = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008006 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008007
8008 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8009 {
8010 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8011 sw_if_index_set = 1;
8012 else if (unformat (i, "sw_if_index %d", &sw_if_index))
8013 sw_if_index_set = 1;
8014 else if (unformat (i, "enable"))
8015 enable = 1;
8016 else if (unformat (i, "disable"))
8017 enable = 0;
8018 else
8019 {
8020 clib_warning ("parse error '%U'", format_unformat_error, i);
8021 return -99;
8022 }
8023 }
8024
8025 if (sw_if_index_set == 0)
8026 {
8027 errmsg ("missing interface name or sw_if_index");
8028 return -99;
8029 }
8030
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008031 M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008032
8033 mp->sw_if_index = ntohl (sw_if_index);
8034 mp->enable = enable;
8035
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008036 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008037 W (ret);
8038 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008039}
8040
8041static int
8042api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
8043{
8044 unformat_input_t *i = vam->input;
8045 vl_api_sw_interface_ip6_set_link_local_address_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008046 u32 sw_if_index;
8047 u8 sw_if_index_set = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008048 u8 v6_address_set = 0;
8049 ip6_address_t v6address;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008050 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008051
8052 /* Parse args required to build the message */
8053 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8054 {
8055 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8056 sw_if_index_set = 1;
8057 else if (unformat (i, "sw_if_index %d", &sw_if_index))
8058 sw_if_index_set = 1;
Neale Ranns75152282017-01-09 01:00:45 -08008059 else if (unformat (i, "%U", unformat_ip6_address, &v6address))
Damjan Marion7cd468a2016-12-19 23:05:39 +01008060 v6_address_set = 1;
8061 else
8062 break;
8063 }
8064
8065 if (sw_if_index_set == 0)
8066 {
8067 errmsg ("missing interface name or sw_if_index");
8068 return -99;
8069 }
8070 if (!v6_address_set)
8071 {
8072 errmsg ("no address set");
8073 return -99;
8074 }
8075
8076 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008077 M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008078
8079 mp->sw_if_index = ntohl (sw_if_index);
8080 clib_memcpy (mp->address, &v6address, sizeof (v6address));
Damjan Marion7cd468a2016-12-19 23:05:39 +01008081
8082 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008083 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008084
8085 /* Wait for a reply, return good/bad news */
Jon Loeliger56c7b012017-02-01 12:31:41 -06008086 W (ret);
8087 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008088}
8089
8090
8091static int
8092api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
8093{
8094 unformat_input_t *i = vam->input;
8095 vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008096 u32 sw_if_index;
8097 u8 sw_if_index_set = 0;
8098 u32 address_length = 0;
8099 u8 v6_address_set = 0;
8100 ip6_address_t v6address;
8101 u8 use_default = 0;
8102 u8 no_advertise = 0;
8103 u8 off_link = 0;
8104 u8 no_autoconfig = 0;
8105 u8 no_onlink = 0;
8106 u8 is_no = 0;
8107 u32 val_lifetime = 0;
8108 u32 pref_lifetime = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008109 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008110
8111 /* Parse args required to build the message */
8112 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8113 {
8114 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8115 sw_if_index_set = 1;
8116 else if (unformat (i, "sw_if_index %d", &sw_if_index))
8117 sw_if_index_set = 1;
8118 else if (unformat (i, "%U/%d",
8119 unformat_ip6_address, &v6address, &address_length))
8120 v6_address_set = 1;
8121 else if (unformat (i, "val_life %d", &val_lifetime))
8122 ;
8123 else if (unformat (i, "pref_life %d", &pref_lifetime))
8124 ;
8125 else if (unformat (i, "def"))
8126 use_default = 1;
8127 else if (unformat (i, "noadv"))
8128 no_advertise = 1;
8129 else if (unformat (i, "offl"))
8130 off_link = 1;
8131 else if (unformat (i, "noauto"))
8132 no_autoconfig = 1;
8133 else if (unformat (i, "nolink"))
8134 no_onlink = 1;
8135 else if (unformat (i, "isno"))
8136 is_no = 1;
8137 else
8138 {
8139 clib_warning ("parse error '%U'", format_unformat_error, i);
8140 return -99;
8141 }
8142 }
8143
8144 if (sw_if_index_set == 0)
8145 {
8146 errmsg ("missing interface name or sw_if_index");
8147 return -99;
8148 }
8149 if (!v6_address_set)
8150 {
8151 errmsg ("no address set");
8152 return -99;
8153 }
8154
8155 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008156 M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008157
8158 mp->sw_if_index = ntohl (sw_if_index);
8159 clib_memcpy (mp->address, &v6address, sizeof (v6address));
8160 mp->address_length = address_length;
8161 mp->use_default = use_default;
8162 mp->no_advertise = no_advertise;
8163 mp->off_link = off_link;
8164 mp->no_autoconfig = no_autoconfig;
8165 mp->no_onlink = no_onlink;
8166 mp->is_no = is_no;
8167 mp->val_lifetime = ntohl (val_lifetime);
8168 mp->pref_lifetime = ntohl (pref_lifetime);
8169
8170 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008171 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008172
8173 /* Wait for a reply, return good/bad news */
Jon Loeliger56c7b012017-02-01 12:31:41 -06008174 W (ret);
8175 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008176}
8177
8178static int
8179api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
8180{
8181 unformat_input_t *i = vam->input;
8182 vl_api_sw_interface_ip6nd_ra_config_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008183 u32 sw_if_index;
8184 u8 sw_if_index_set = 0;
8185 u8 suppress = 0;
8186 u8 managed = 0;
8187 u8 other = 0;
8188 u8 ll_option = 0;
8189 u8 send_unicast = 0;
8190 u8 cease = 0;
8191 u8 is_no = 0;
8192 u8 default_router = 0;
8193 u32 max_interval = 0;
8194 u32 min_interval = 0;
8195 u32 lifetime = 0;
8196 u32 initial_count = 0;
8197 u32 initial_interval = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008198 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008199
8200
8201 /* Parse args required to build the message */
8202 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8203 {
8204 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8205 sw_if_index_set = 1;
8206 else if (unformat (i, "sw_if_index %d", &sw_if_index))
8207 sw_if_index_set = 1;
8208 else if (unformat (i, "maxint %d", &max_interval))
8209 ;
8210 else if (unformat (i, "minint %d", &min_interval))
8211 ;
8212 else if (unformat (i, "life %d", &lifetime))
8213 ;
8214 else if (unformat (i, "count %d", &initial_count))
8215 ;
8216 else if (unformat (i, "interval %d", &initial_interval))
8217 ;
8218 else if (unformat (i, "suppress") || unformat (i, "surpress"))
8219 suppress = 1;
8220 else if (unformat (i, "managed"))
8221 managed = 1;
8222 else if (unformat (i, "other"))
8223 other = 1;
8224 else if (unformat (i, "ll"))
8225 ll_option = 1;
8226 else if (unformat (i, "send"))
8227 send_unicast = 1;
8228 else if (unformat (i, "cease"))
8229 cease = 1;
8230 else if (unformat (i, "isno"))
8231 is_no = 1;
8232 else if (unformat (i, "def"))
8233 default_router = 1;
8234 else
8235 {
8236 clib_warning ("parse error '%U'", format_unformat_error, i);
8237 return -99;
8238 }
8239 }
8240
8241 if (sw_if_index_set == 0)
8242 {
8243 errmsg ("missing interface name or sw_if_index");
8244 return -99;
8245 }
8246
8247 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008248 M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008249
8250 mp->sw_if_index = ntohl (sw_if_index);
8251 mp->max_interval = ntohl (max_interval);
8252 mp->min_interval = ntohl (min_interval);
8253 mp->lifetime = ntohl (lifetime);
8254 mp->initial_count = ntohl (initial_count);
8255 mp->initial_interval = ntohl (initial_interval);
8256 mp->suppress = suppress;
8257 mp->managed = managed;
8258 mp->other = other;
8259 mp->ll_option = ll_option;
8260 mp->send_unicast = send_unicast;
8261 mp->cease = cease;
8262 mp->is_no = is_no;
8263 mp->default_router = default_router;
8264
8265 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008266 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008267
8268 /* Wait for a reply, return good/bad news */
Jon Loeliger56c7b012017-02-01 12:31:41 -06008269 W (ret);
8270 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008271}
8272
8273static int
8274api_set_arp_neighbor_limit (vat_main_t * vam)
8275{
8276 unformat_input_t *i = vam->input;
8277 vl_api_set_arp_neighbor_limit_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008278 u32 arp_nbr_limit;
8279 u8 limit_set = 0;
8280 u8 is_ipv6 = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008281 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008282
8283 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8284 {
8285 if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
8286 limit_set = 1;
8287 else if (unformat (i, "ipv6"))
8288 is_ipv6 = 1;
8289 else
8290 {
8291 clib_warning ("parse error '%U'", format_unformat_error, i);
8292 return -99;
8293 }
8294 }
8295
8296 if (limit_set == 0)
8297 {
8298 errmsg ("missing limit value");
8299 return -99;
8300 }
8301
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008302 M (SET_ARP_NEIGHBOR_LIMIT, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008303
8304 mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
8305 mp->is_ipv6 = is_ipv6;
8306
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008307 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008308 W (ret);
8309 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008310}
8311
8312static int
8313api_l2_patch_add_del (vat_main_t * vam)
8314{
8315 unformat_input_t *i = vam->input;
8316 vl_api_l2_patch_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008317 u32 rx_sw_if_index;
8318 u8 rx_sw_if_index_set = 0;
8319 u32 tx_sw_if_index;
8320 u8 tx_sw_if_index_set = 0;
8321 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008322 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008323
8324 /* Parse args required to build the message */
8325 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8326 {
8327 if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
8328 rx_sw_if_index_set = 1;
8329 else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
8330 tx_sw_if_index_set = 1;
8331 else if (unformat (i, "rx"))
8332 {
8333 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8334 {
8335 if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8336 &rx_sw_if_index))
8337 rx_sw_if_index_set = 1;
8338 }
8339 else
8340 break;
8341 }
8342 else if (unformat (i, "tx"))
8343 {
8344 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8345 {
8346 if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8347 &tx_sw_if_index))
8348 tx_sw_if_index_set = 1;
8349 }
8350 else
8351 break;
8352 }
8353 else if (unformat (i, "del"))
8354 is_add = 0;
8355 else
8356 break;
8357 }
8358
8359 if (rx_sw_if_index_set == 0)
8360 {
8361 errmsg ("missing rx interface name or rx_sw_if_index");
8362 return -99;
8363 }
8364
8365 if (tx_sw_if_index_set == 0)
8366 {
8367 errmsg ("missing tx interface name or tx_sw_if_index");
8368 return -99;
8369 }
8370
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008371 M (L2_PATCH_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008372
8373 mp->rx_sw_if_index = ntohl (rx_sw_if_index);
8374 mp->tx_sw_if_index = ntohl (tx_sw_if_index);
8375 mp->is_add = is_add;
8376
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008377 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008378 W (ret);
8379 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008380}
8381
8382static int
8383api_ioam_enable (vat_main_t * vam)
8384{
8385 unformat_input_t *input = vam->input;
8386 vl_api_ioam_enable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008387 u32 id = 0;
8388 int has_trace_option = 0;
8389 int has_pot_option = 0;
8390 int has_seqno_option = 0;
8391 int has_analyse_option = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008392 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008393
8394 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8395 {
8396 if (unformat (input, "trace"))
8397 has_trace_option = 1;
8398 else if (unformat (input, "pot"))
8399 has_pot_option = 1;
8400 else if (unformat (input, "seqno"))
8401 has_seqno_option = 1;
8402 else if (unformat (input, "analyse"))
8403 has_analyse_option = 1;
8404 else
8405 break;
8406 }
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008407 M (IOAM_ENABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008408 mp->id = htons (id);
8409 mp->seqno = has_seqno_option;
8410 mp->analyse = has_analyse_option;
8411 mp->pot_enable = has_pot_option;
8412 mp->trace_enable = has_trace_option;
8413
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008414 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008415 W (ret);
8416 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008417}
8418
8419
8420static int
8421api_ioam_disable (vat_main_t * vam)
8422{
8423 vl_api_ioam_disable_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008424 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008425
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008426 M (IOAM_DISABLE, mp);
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008427 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008428 W (ret);
8429 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008430}
8431
8432static int
8433api_sr_tunnel_add_del (vat_main_t * vam)
8434{
8435 unformat_input_t *i = vam->input;
8436 vl_api_sr_tunnel_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008437 int is_del = 0;
8438 int pl_index;
8439 ip6_address_t src_address;
8440 int src_address_set = 0;
8441 ip6_address_t dst_address;
8442 u32 dst_mask_width;
8443 int dst_address_set = 0;
8444 u16 flags = 0;
8445 u32 rx_table_id = 0;
8446 u32 tx_table_id = 0;
8447 ip6_address_t *segments = 0;
8448 ip6_address_t *this_seg;
8449 ip6_address_t *tags = 0;
8450 ip6_address_t *this_tag;
8451 ip6_address_t next_address, tag;
8452 u8 *name = 0;
8453 u8 *policy_name = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008454 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008455
8456 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8457 {
8458 if (unformat (i, "del"))
8459 is_del = 1;
8460 else if (unformat (i, "name %s", &name))
8461 ;
8462 else if (unformat (i, "policy %s", &policy_name))
8463 ;
8464 else if (unformat (i, "rx_fib_id %d", &rx_table_id))
8465 ;
8466 else if (unformat (i, "tx_fib_id %d", &tx_table_id))
8467 ;
8468 else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
8469 src_address_set = 1;
8470 else if (unformat (i, "dst %U/%d",
8471 unformat_ip6_address, &dst_address, &dst_mask_width))
8472 dst_address_set = 1;
8473 else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
8474 {
8475 vec_add2 (segments, this_seg, 1);
8476 clib_memcpy (this_seg->as_u8, next_address.as_u8,
8477 sizeof (*this_seg));
8478 }
8479 else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
8480 {
8481 vec_add2 (tags, this_tag, 1);
8482 clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
8483 }
8484 else if (unformat (i, "clean"))
8485 flags |= IP6_SR_HEADER_FLAG_CLEANUP;
8486 else if (unformat (i, "protected"))
8487 flags |= IP6_SR_HEADER_FLAG_PROTECTED;
8488 else if (unformat (i, "InPE %d", &pl_index))
8489 {
8490 if (pl_index <= 0 || pl_index > 4)
8491 {
8492 pl_index_range_error:
8493 errmsg ("pl index %d out of range", pl_index);
8494 return -99;
8495 }
8496 flags |=
8497 IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
8498 }
8499 else if (unformat (i, "EgPE %d", &pl_index))
8500 {
8501 if (pl_index <= 0 || pl_index > 4)
8502 goto pl_index_range_error;
8503 flags |=
8504 IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
8505 }
8506 else if (unformat (i, "OrgSrc %d", &pl_index))
8507 {
8508 if (pl_index <= 0 || pl_index > 4)
8509 goto pl_index_range_error;
8510 flags |=
8511 IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
8512 }
8513 else
8514 break;
8515 }
8516
8517 if (!src_address_set)
8518 {
8519 errmsg ("src address required");
8520 return -99;
8521 }
8522
8523 if (!dst_address_set)
8524 {
8525 errmsg ("dst address required");
8526 return -99;
8527 }
8528
8529 if (!segments)
8530 {
8531 errmsg ("at least one sr segment required");
8532 return -99;
8533 }
8534
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008535 M2 (SR_TUNNEL_ADD_DEL, mp,
Damjan Marion7cd468a2016-12-19 23:05:39 +01008536 vec_len (segments) * sizeof (ip6_address_t)
8537 + vec_len (tags) * sizeof (ip6_address_t));
8538
8539 clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
8540 clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
8541 mp->dst_mask_width = dst_mask_width;
8542 mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
8543 mp->n_segments = vec_len (segments);
8544 mp->n_tags = vec_len (tags);
8545 mp->is_add = is_del == 0;
8546 clib_memcpy (mp->segs_and_tags, segments,
8547 vec_len (segments) * sizeof (ip6_address_t));
8548 clib_memcpy (mp->segs_and_tags +
8549 vec_len (segments) * sizeof (ip6_address_t), tags,
8550 vec_len (tags) * sizeof (ip6_address_t));
8551
8552 mp->outer_vrf_id = ntohl (rx_table_id);
8553 mp->inner_vrf_id = ntohl (tx_table_id);
8554 memcpy (mp->name, name, vec_len (name));
8555 memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8556
8557 vec_free (segments);
8558 vec_free (tags);
8559
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008560 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008561 W (ret);
8562 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008563}
8564
8565static int
8566api_sr_policy_add_del (vat_main_t * vam)
8567{
8568 unformat_input_t *input = vam->input;
8569 vl_api_sr_policy_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008570 int is_del = 0;
8571 u8 *name = 0;
8572 u8 *tunnel_name = 0;
8573 u8 **tunnel_names = 0;
8574
8575 int name_set = 0;
8576 int tunnel_set = 0;
8577 int j = 0;
8578 int tunnel_names_length = 1; // Init to 1 to offset the #tunnel_names counter byte
8579 int tun_name_len = 0; // Different naming convention used as confusing these would be "bad" (TM)
Jon Loeliger56c7b012017-02-01 12:31:41 -06008580 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008581
8582 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8583 {
8584 if (unformat (input, "del"))
8585 is_del = 1;
8586 else if (unformat (input, "name %s", &name))
8587 name_set = 1;
8588 else if (unformat (input, "tunnel %s", &tunnel_name))
8589 {
8590 if (tunnel_name)
8591 {
8592 vec_add1 (tunnel_names, tunnel_name);
8593 /* For serializer:
8594 - length = #bytes to store in serial vector
8595 - +1 = byte to store that length
8596 */
8597 tunnel_names_length += (vec_len (tunnel_name) + 1);
8598 tunnel_set = 1;
8599 tunnel_name = 0;
8600 }
8601 }
8602 else
8603 break;
8604 }
8605
8606 if (!name_set)
8607 {
8608 errmsg ("policy name required");
8609 return -99;
8610 }
8611
8612 if ((!tunnel_set) && (!is_del))
8613 {
8614 errmsg ("tunnel name required");
8615 return -99;
8616 }
8617
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008618 M2 (SR_POLICY_ADD_DEL, mp, tunnel_names_length);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008619
8620
8621
8622 mp->is_add = !is_del;
8623
8624 memcpy (mp->name, name, vec_len (name));
8625 // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
8626 u8 *serial_orig = 0;
8627 vec_validate (serial_orig, tunnel_names_length);
8628 *serial_orig = vec_len (tunnel_names); // Store the number of tunnels as length in first byte of serialized vector
8629 serial_orig += 1; // Move along one byte to store the length of first tunnel_name
8630
8631 for (j = 0; j < vec_len (tunnel_names); j++)
8632 {
8633 tun_name_len = vec_len (tunnel_names[j]);
8634 *serial_orig = tun_name_len; // Store length of tunnel name in first byte of Length/Value pair
8635 serial_orig += 1; // Move along one byte to store the actual tunnel name
8636 memcpy (serial_orig, tunnel_names[j], tun_name_len);
8637 serial_orig += tun_name_len; // Advance past the copy
8638 }
8639 memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length); // Regress serial_orig to head then copy fwd
8640
8641 vec_free (tunnel_names);
8642 vec_free (tunnel_name);
8643
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008644 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008645 W (ret);
8646 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008647}
8648
8649static int
8650api_sr_multicast_map_add_del (vat_main_t * vam)
8651{
8652 unformat_input_t *input = vam->input;
8653 vl_api_sr_multicast_map_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008654 int is_del = 0;
8655 ip6_address_t multicast_address;
8656 u8 *policy_name = 0;
8657 int multicast_address_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06008658 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008659
8660 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8661 {
8662 if (unformat (input, "del"))
8663 is_del = 1;
8664 else
8665 if (unformat
8666 (input, "address %U", unformat_ip6_address, &multicast_address))
8667 multicast_address_set = 1;
8668 else if (unformat (input, "sr-policy %s", &policy_name))
8669 ;
8670 else
8671 break;
8672 }
8673
8674 if (!is_del && !policy_name)
8675 {
8676 errmsg ("sr-policy name required");
8677 return -99;
8678 }
8679
8680
8681 if (!multicast_address_set)
8682 {
8683 errmsg ("address required");
8684 return -99;
8685 }
8686
Jon Loeliger8a2aea32017-01-31 13:19:40 -06008687 M (SR_MULTICAST_MAP_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01008688
8689 mp->is_add = !is_del;
8690 memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8691 clib_memcpy (mp->multicast_address, &multicast_address,
8692 sizeof (mp->multicast_address));
8693
8694
8695 vec_free (policy_name);
8696
Jon Loeliger7bc770c2017-01-31 14:03:33 -06008697 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06008698 W (ret);
8699 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01008700}
8701
8702
8703#define foreach_tcp_proto_field \
8704_(src_port) \
8705_(dst_port)
8706
8707#define foreach_udp_proto_field \
8708_(src_port) \
8709_(dst_port)
8710
8711#define foreach_ip4_proto_field \
8712_(src_address) \
8713_(dst_address) \
8714_(tos) \
8715_(length) \
8716_(fragment_id) \
8717_(ttl) \
8718_(protocol) \
8719_(checksum)
8720
8721uword
8722unformat_tcp_mask (unformat_input_t * input, va_list * args)
8723{
8724 u8 **maskp = va_arg (*args, u8 **);
8725 u8 *mask = 0;
8726 u8 found_something = 0;
8727 tcp_header_t *tcp;
8728
8729#define _(a) u8 a=0;
8730 foreach_tcp_proto_field;
8731#undef _
8732
8733 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8734 {
8735 if (0);
8736#define _(a) else if (unformat (input, #a)) a=1;
8737 foreach_tcp_proto_field
8738#undef _
8739 else
8740 break;
8741 }
8742
8743#define _(a) found_something += a;
8744 foreach_tcp_proto_field;
8745#undef _
8746
8747 if (found_something == 0)
8748 return 0;
8749
8750 vec_validate (mask, sizeof (*tcp) - 1);
8751
8752 tcp = (tcp_header_t *) mask;
8753
8754#define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8755 foreach_tcp_proto_field;
8756#undef _
8757
8758 *maskp = mask;
8759 return 1;
8760}
8761
8762uword
8763unformat_udp_mask (unformat_input_t * input, va_list * args)
8764{
8765 u8 **maskp = va_arg (*args, u8 **);
8766 u8 *mask = 0;
8767 u8 found_something = 0;
8768 udp_header_t *udp;
8769
8770#define _(a) u8 a=0;
8771 foreach_udp_proto_field;
8772#undef _
8773
8774 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8775 {
8776 if (0);
8777#define _(a) else if (unformat (input, #a)) a=1;
8778 foreach_udp_proto_field
8779#undef _
8780 else
8781 break;
8782 }
8783
8784#define _(a) found_something += a;
8785 foreach_udp_proto_field;
8786#undef _
8787
8788 if (found_something == 0)
8789 return 0;
8790
8791 vec_validate (mask, sizeof (*udp) - 1);
8792
8793 udp = (udp_header_t *) mask;
8794
8795#define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8796 foreach_udp_proto_field;
8797#undef _
8798
8799 *maskp = mask;
8800 return 1;
8801}
8802
8803typedef struct
8804{
8805 u16 src_port, dst_port;
8806} tcpudp_header_t;
8807
8808uword
8809unformat_l4_mask (unformat_input_t * input, va_list * args)
8810{
8811 u8 **maskp = va_arg (*args, u8 **);
8812 u16 src_port = 0, dst_port = 0;
8813 tcpudp_header_t *tcpudp;
8814
8815 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8816 {
8817 if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
8818 return 1;
8819 else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
8820 return 1;
8821 else if (unformat (input, "src_port"))
8822 src_port = 0xFFFF;
8823 else if (unformat (input, "dst_port"))
8824 dst_port = 0xFFFF;
8825 else
8826 return 0;
8827 }
8828
8829 if (!src_port && !dst_port)
8830 return 0;
8831
8832 u8 *mask = 0;
8833 vec_validate (mask, sizeof (tcpudp_header_t) - 1);
8834
8835 tcpudp = (tcpudp_header_t *) mask;
8836 tcpudp->src_port = src_port;
8837 tcpudp->dst_port = dst_port;
8838
8839 *maskp = mask;
8840
8841 return 1;
8842}
8843
8844uword
8845unformat_ip4_mask (unformat_input_t * input, va_list * args)
8846{
8847 u8 **maskp = va_arg (*args, u8 **);
8848 u8 *mask = 0;
8849 u8 found_something = 0;
8850 ip4_header_t *ip;
8851
8852#define _(a) u8 a=0;
8853 foreach_ip4_proto_field;
8854#undef _
8855 u8 version = 0;
8856 u8 hdr_length = 0;
8857
8858
8859 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8860 {
8861 if (unformat (input, "version"))
8862 version = 1;
8863 else if (unformat (input, "hdr_length"))
8864 hdr_length = 1;
8865 else if (unformat (input, "src"))
8866 src_address = 1;
8867 else if (unformat (input, "dst"))
8868 dst_address = 1;
8869 else if (unformat (input, "proto"))
8870 protocol = 1;
8871
8872#define _(a) else if (unformat (input, #a)) a=1;
8873 foreach_ip4_proto_field
8874#undef _
8875 else
8876 break;
8877 }
8878
8879#define _(a) found_something += a;
8880 foreach_ip4_proto_field;
8881#undef _
8882
8883 if (found_something == 0)
8884 return 0;
8885
8886 vec_validate (mask, sizeof (*ip) - 1);
8887
8888 ip = (ip4_header_t *) mask;
8889
8890#define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8891 foreach_ip4_proto_field;
8892#undef _
8893
8894 ip->ip_version_and_header_length = 0;
8895
8896 if (version)
8897 ip->ip_version_and_header_length |= 0xF0;
8898
8899 if (hdr_length)
8900 ip->ip_version_and_header_length |= 0x0F;
8901
8902 *maskp = mask;
8903 return 1;
8904}
8905
8906#define foreach_ip6_proto_field \
8907_(src_address) \
8908_(dst_address) \
8909_(payload_length) \
8910_(hop_limit) \
8911_(protocol)
8912
8913uword
8914unformat_ip6_mask (unformat_input_t * input, va_list * args)
8915{
8916 u8 **maskp = va_arg (*args, u8 **);
8917 u8 *mask = 0;
8918 u8 found_something = 0;
8919 ip6_header_t *ip;
8920 u32 ip_version_traffic_class_and_flow_label;
8921
8922#define _(a) u8 a=0;
8923 foreach_ip6_proto_field;
8924#undef _
8925 u8 version = 0;
8926 u8 traffic_class = 0;
8927 u8 flow_label = 0;
8928
8929 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8930 {
8931 if (unformat (input, "version"))
8932 version = 1;
8933 else if (unformat (input, "traffic-class"))
8934 traffic_class = 1;
8935 else if (unformat (input, "flow-label"))
8936 flow_label = 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_ip6_proto_field
8946#undef _
8947 else
8948 break;
8949 }
8950
8951#define _(a) found_something += a;
8952 foreach_ip6_proto_field;
8953#undef _
8954
8955 if (found_something == 0)
8956 return 0;
8957
8958 vec_validate (mask, sizeof (*ip) - 1);
8959
8960 ip = (ip6_header_t *) mask;
8961
8962#define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8963 foreach_ip6_proto_field;
8964#undef _
8965
8966 ip_version_traffic_class_and_flow_label = 0;
8967
8968 if (version)
8969 ip_version_traffic_class_and_flow_label |= 0xF0000000;
8970
8971 if (traffic_class)
8972 ip_version_traffic_class_and_flow_label |= 0x0FF00000;
8973
8974 if (flow_label)
8975 ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
8976
8977 ip->ip_version_traffic_class_and_flow_label =
8978 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8979
8980 *maskp = mask;
8981 return 1;
8982}
8983
8984uword
8985unformat_l3_mask (unformat_input_t * input, va_list * args)
8986{
8987 u8 **maskp = va_arg (*args, u8 **);
8988
8989 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8990 {
8991 if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
8992 return 1;
8993 else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
8994 return 1;
8995 else
8996 break;
8997 }
8998 return 0;
8999}
9000
9001uword
9002unformat_l2_mask (unformat_input_t * input, va_list * args)
9003{
9004 u8 **maskp = va_arg (*args, u8 **);
9005 u8 *mask = 0;
9006 u8 src = 0;
9007 u8 dst = 0;
9008 u8 proto = 0;
9009 u8 tag1 = 0;
9010 u8 tag2 = 0;
9011 u8 ignore_tag1 = 0;
9012 u8 ignore_tag2 = 0;
9013 u8 cos1 = 0;
9014 u8 cos2 = 0;
9015 u8 dot1q = 0;
9016 u8 dot1ad = 0;
9017 int len = 14;
9018
9019 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9020 {
9021 if (unformat (input, "src"))
9022 src = 1;
9023 else if (unformat (input, "dst"))
9024 dst = 1;
9025 else if (unformat (input, "proto"))
9026 proto = 1;
9027 else if (unformat (input, "tag1"))
9028 tag1 = 1;
9029 else if (unformat (input, "tag2"))
9030 tag2 = 1;
9031 else if (unformat (input, "ignore-tag1"))
9032 ignore_tag1 = 1;
9033 else if (unformat (input, "ignore-tag2"))
9034 ignore_tag2 = 1;
9035 else if (unformat (input, "cos1"))
9036 cos1 = 1;
9037 else if (unformat (input, "cos2"))
9038 cos2 = 1;
9039 else if (unformat (input, "dot1q"))
9040 dot1q = 1;
9041 else if (unformat (input, "dot1ad"))
9042 dot1ad = 1;
9043 else
9044 break;
9045 }
9046 if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9047 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9048 return 0;
9049
9050 if (tag1 || ignore_tag1 || cos1 || dot1q)
9051 len = 18;
9052 if (tag2 || ignore_tag2 || cos2 || dot1ad)
9053 len = 22;
9054
9055 vec_validate (mask, len - 1);
9056
9057 if (dst)
9058 memset (mask, 0xff, 6);
9059
9060 if (src)
9061 memset (mask + 6, 0xff, 6);
9062
9063 if (tag2 || dot1ad)
9064 {
9065 /* inner vlan tag */
9066 if (tag2)
9067 {
9068 mask[19] = 0xff;
9069 mask[18] = 0x0f;
9070 }
9071 if (cos2)
9072 mask[18] |= 0xe0;
9073 if (proto)
9074 mask[21] = mask[20] = 0xff;
9075 if (tag1)
9076 {
9077 mask[15] = 0xff;
9078 mask[14] = 0x0f;
9079 }
9080 if (cos1)
9081 mask[14] |= 0xe0;
9082 *maskp = mask;
9083 return 1;
9084 }
9085 if (tag1 | dot1q)
9086 {
9087 if (tag1)
9088 {
9089 mask[15] = 0xff;
9090 mask[14] = 0x0f;
9091 }
9092 if (cos1)
9093 mask[14] |= 0xe0;
9094 if (proto)
9095 mask[16] = mask[17] = 0xff;
9096
9097 *maskp = mask;
9098 return 1;
9099 }
9100 if (cos2)
9101 mask[18] |= 0xe0;
9102 if (cos1)
9103 mask[14] |= 0xe0;
9104 if (proto)
9105 mask[12] = mask[13] = 0xff;
9106
9107 *maskp = mask;
9108 return 1;
9109}
9110
9111uword
9112unformat_classify_mask (unformat_input_t * input, va_list * args)
9113{
9114 u8 **maskp = va_arg (*args, u8 **);
9115 u32 *skipp = va_arg (*args, u32 *);
9116 u32 *matchp = va_arg (*args, u32 *);
9117 u32 match;
9118 u8 *mask = 0;
9119 u8 *l2 = 0;
9120 u8 *l3 = 0;
9121 u8 *l4 = 0;
9122 int i;
9123
9124 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9125 {
9126 if (unformat (input, "hex %U", unformat_hex_string, &mask))
9127 ;
9128 else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
9129 ;
9130 else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
9131 ;
9132 else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
9133 ;
9134 else
9135 break;
9136 }
9137
9138 if (l4 && !l3)
9139 {
9140 vec_free (mask);
9141 vec_free (l2);
9142 vec_free (l4);
9143 return 0;
9144 }
9145
9146 if (mask || l2 || l3 || l4)
9147 {
9148 if (l2 || l3 || l4)
9149 {
9150 /* "With a free Ethernet header in every package" */
9151 if (l2 == 0)
9152 vec_validate (l2, 13);
9153 mask = l2;
9154 if (vec_len (l3))
9155 {
9156 vec_append (mask, l3);
9157 vec_free (l3);
9158 }
9159 if (vec_len (l4))
9160 {
9161 vec_append (mask, l4);
9162 vec_free (l4);
9163 }
9164 }
9165
9166 /* Scan forward looking for the first significant mask octet */
9167 for (i = 0; i < vec_len (mask); i++)
9168 if (mask[i])
9169 break;
9170
9171 /* compute (skip, match) params */
9172 *skipp = i / sizeof (u32x4);
9173 vec_delete (mask, *skipp * sizeof (u32x4), 0);
9174
9175 /* Pad mask to an even multiple of the vector size */
9176 while (vec_len (mask) % sizeof (u32x4))
9177 vec_add1 (mask, 0);
9178
9179 match = vec_len (mask) / sizeof (u32x4);
9180
9181 for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9182 {
9183 u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9184 if (*tmp || *(tmp + 1))
9185 break;
9186 match--;
9187 }
9188 if (match == 0)
9189 clib_warning ("BUG: match 0");
9190
9191 _vec_len (mask) = match * sizeof (u32x4);
9192
9193 *matchp = match;
9194 *maskp = mask;
9195
9196 return 1;
9197 }
9198
9199 return 0;
9200}
9201
9202#define foreach_l2_next \
9203_(drop, DROP) \
9204_(ethernet, ETHERNET_INPUT) \
9205_(ip4, IP4_INPUT) \
9206_(ip6, IP6_INPUT)
9207
9208uword
9209unformat_l2_next_index (unformat_input_t * input, va_list * args)
9210{
9211 u32 *miss_next_indexp = va_arg (*args, u32 *);
9212 u32 next_index = 0;
9213 u32 tmp;
9214
9215#define _(n,N) \
9216 if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9217 foreach_l2_next;
9218#undef _
9219
9220 if (unformat (input, "%d", &tmp))
9221 {
9222 next_index = tmp;
9223 goto out;
9224 }
9225
9226 return 0;
9227
9228out:
9229 *miss_next_indexp = next_index;
9230 return 1;
9231}
9232
9233#define foreach_ip_next \
9234_(drop, DROP) \
9235_(local, LOCAL) \
9236_(rewrite, REWRITE)
9237
9238uword
9239unformat_ip_next_index (unformat_input_t * input, va_list * args)
9240{
9241 u32 *miss_next_indexp = va_arg (*args, u32 *);
9242 u32 next_index = 0;
9243 u32 tmp;
9244
9245#define _(n,N) \
9246 if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9247 foreach_ip_next;
9248#undef _
9249
9250 if (unformat (input, "%d", &tmp))
9251 {
9252 next_index = tmp;
9253 goto out;
9254 }
9255
9256 return 0;
9257
9258out:
9259 *miss_next_indexp = next_index;
9260 return 1;
9261}
9262
9263#define foreach_acl_next \
9264_(deny, DENY)
9265
9266uword
9267unformat_acl_next_index (unformat_input_t * input, va_list * args)
9268{
9269 u32 *miss_next_indexp = va_arg (*args, u32 *);
9270 u32 next_index = 0;
9271 u32 tmp;
9272
9273#define _(n,N) \
9274 if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
9275 foreach_acl_next;
9276#undef _
9277
9278 if (unformat (input, "permit"))
9279 {
9280 next_index = ~0;
9281 goto out;
9282 }
9283 else if (unformat (input, "%d", &tmp))
9284 {
9285 next_index = tmp;
9286 goto out;
9287 }
9288
9289 return 0;
9290
9291out:
9292 *miss_next_indexp = next_index;
9293 return 1;
9294}
9295
9296uword
9297unformat_policer_precolor (unformat_input_t * input, va_list * args)
9298{
9299 u32 *r = va_arg (*args, u32 *);
9300
9301 if (unformat (input, "conform-color"))
9302 *r = POLICE_CONFORM;
9303 else if (unformat (input, "exceed-color"))
9304 *r = POLICE_EXCEED;
9305 else
9306 return 0;
9307
9308 return 1;
9309}
9310
9311static int
9312api_classify_add_del_table (vat_main_t * vam)
9313{
9314 unformat_input_t *i = vam->input;
9315 vl_api_classify_add_del_table_t *mp;
9316
9317 u32 nbuckets = 2;
9318 u32 skip = ~0;
9319 u32 match = ~0;
9320 int is_add = 1;
9321 int del_chain = 0;
9322 u32 table_index = ~0;
9323 u32 next_table_index = ~0;
9324 u32 miss_next_index = ~0;
9325 u32 memory_size = 32 << 20;
9326 u8 *mask = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009327 u32 current_data_flag = 0;
9328 int current_data_offset = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009329 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009330
9331 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9332 {
9333 if (unformat (i, "del"))
9334 is_add = 0;
9335 else if (unformat (i, "del-chain"))
9336 {
9337 is_add = 0;
9338 del_chain = 1;
9339 }
9340 else if (unformat (i, "buckets %d", &nbuckets))
9341 ;
9342 else if (unformat (i, "memory_size %d", &memory_size))
9343 ;
9344 else if (unformat (i, "skip %d", &skip))
9345 ;
9346 else if (unformat (i, "match %d", &match))
9347 ;
9348 else if (unformat (i, "table %d", &table_index))
9349 ;
9350 else if (unformat (i, "mask %U", unformat_classify_mask,
9351 &mask, &skip, &match))
9352 ;
9353 else if (unformat (i, "next-table %d", &next_table_index))
9354 ;
9355 else if (unformat (i, "miss-next %U", unformat_ip_next_index,
9356 &miss_next_index))
9357 ;
9358 else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
9359 &miss_next_index))
9360 ;
9361 else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
9362 &miss_next_index))
9363 ;
9364 else if (unformat (i, "current-data-flag %d", &current_data_flag))
9365 ;
9366 else if (unformat (i, "current-data-offset %d", &current_data_offset))
9367 ;
9368 else
9369 break;
9370 }
9371
9372 if (is_add && mask == 0)
9373 {
9374 errmsg ("Mask required");
9375 return -99;
9376 }
9377
9378 if (is_add && skip == ~0)
9379 {
9380 errmsg ("skip count required");
9381 return -99;
9382 }
9383
9384 if (is_add && match == ~0)
9385 {
9386 errmsg ("match count required");
9387 return -99;
9388 }
9389
9390 if (!is_add && table_index == ~0)
9391 {
9392 errmsg ("table index required for delete");
9393 return -99;
9394 }
9395
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009396 M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
Damjan Marion7cd468a2016-12-19 23:05:39 +01009397
9398 mp->is_add = is_add;
9399 mp->del_chain = del_chain;
9400 mp->table_index = ntohl (table_index);
9401 mp->nbuckets = ntohl (nbuckets);
9402 mp->memory_size = ntohl (memory_size);
9403 mp->skip_n_vectors = ntohl (skip);
9404 mp->match_n_vectors = ntohl (match);
9405 mp->next_table_index = ntohl (next_table_index);
9406 mp->miss_next_index = ntohl (miss_next_index);
9407 mp->current_data_flag = ntohl (current_data_flag);
9408 mp->current_data_offset = ntohl (current_data_offset);
9409 clib_memcpy (mp->mask, mask, vec_len (mask));
9410
9411 vec_free (mask);
9412
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009413 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06009414 W (ret);
9415 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009416}
9417
9418uword
9419unformat_l4_match (unformat_input_t * input, va_list * args)
9420{
9421 u8 **matchp = va_arg (*args, u8 **);
9422
9423 u8 *proto_header = 0;
9424 int src_port = 0;
9425 int dst_port = 0;
9426
9427 tcpudp_header_t h;
9428
9429 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9430 {
9431 if (unformat (input, "src_port %d", &src_port))
9432 ;
9433 else if (unformat (input, "dst_port %d", &dst_port))
9434 ;
9435 else
9436 return 0;
9437 }
9438
9439 h.src_port = clib_host_to_net_u16 (src_port);
9440 h.dst_port = clib_host_to_net_u16 (dst_port);
9441 vec_validate (proto_header, sizeof (h) - 1);
9442 memcpy (proto_header, &h, sizeof (h));
9443
9444 *matchp = proto_header;
9445
9446 return 1;
9447}
9448
9449uword
9450unformat_ip4_match (unformat_input_t * input, va_list * args)
9451{
9452 u8 **matchp = va_arg (*args, u8 **);
9453 u8 *match = 0;
9454 ip4_header_t *ip;
9455 int version = 0;
9456 u32 version_val;
9457 int hdr_length = 0;
9458 u32 hdr_length_val;
9459 int src = 0, dst = 0;
9460 ip4_address_t src_val, dst_val;
9461 int proto = 0;
9462 u32 proto_val;
9463 int tos = 0;
9464 u32 tos_val;
9465 int length = 0;
9466 u32 length_val;
9467 int fragment_id = 0;
9468 u32 fragment_id_val;
9469 int ttl = 0;
9470 int ttl_val;
9471 int checksum = 0;
9472 u32 checksum_val;
9473
9474 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9475 {
9476 if (unformat (input, "version %d", &version_val))
9477 version = 1;
9478 else if (unformat (input, "hdr_length %d", &hdr_length_val))
9479 hdr_length = 1;
9480 else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
9481 src = 1;
9482 else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
9483 dst = 1;
9484 else if (unformat (input, "proto %d", &proto_val))
9485 proto = 1;
9486 else if (unformat (input, "tos %d", &tos_val))
9487 tos = 1;
9488 else if (unformat (input, "length %d", &length_val))
9489 length = 1;
9490 else if (unformat (input, "fragment_id %d", &fragment_id_val))
9491 fragment_id = 1;
9492 else if (unformat (input, "ttl %d", &ttl_val))
9493 ttl = 1;
9494 else if (unformat (input, "checksum %d", &checksum_val))
9495 checksum = 1;
9496 else
9497 break;
9498 }
9499
9500 if (version + hdr_length + src + dst + proto + tos + length + fragment_id
9501 + ttl + checksum == 0)
9502 return 0;
9503
9504 /*
9505 * Aligned because we use the real comparison functions
9506 */
9507 vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9508
9509 ip = (ip4_header_t *) match;
9510
9511 /* These are realistically matched in practice */
9512 if (src)
9513 ip->src_address.as_u32 = src_val.as_u32;
9514
9515 if (dst)
9516 ip->dst_address.as_u32 = dst_val.as_u32;
9517
9518 if (proto)
9519 ip->protocol = proto_val;
9520
9521
9522 /* These are not, but they're included for completeness */
9523 if (version)
9524 ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
9525
9526 if (hdr_length)
9527 ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
9528
9529 if (tos)
9530 ip->tos = tos_val;
9531
9532 if (length)
9533 ip->length = clib_host_to_net_u16 (length_val);
9534
9535 if (ttl)
9536 ip->ttl = ttl_val;
9537
9538 if (checksum)
9539 ip->checksum = clib_host_to_net_u16 (checksum_val);
9540
9541 *matchp = match;
9542 return 1;
9543}
9544
9545uword
9546unformat_ip6_match (unformat_input_t * input, va_list * args)
9547{
9548 u8 **matchp = va_arg (*args, u8 **);
9549 u8 *match = 0;
9550 ip6_header_t *ip;
9551 int version = 0;
9552 u32 version_val;
9553 u8 traffic_class = 0;
9554 u32 traffic_class_val = 0;
9555 u8 flow_label = 0;
9556 u8 flow_label_val;
9557 int src = 0, dst = 0;
9558 ip6_address_t src_val, dst_val;
9559 int proto = 0;
9560 u32 proto_val;
9561 int payload_length = 0;
9562 u32 payload_length_val;
9563 int hop_limit = 0;
9564 int hop_limit_val;
9565 u32 ip_version_traffic_class_and_flow_label;
9566
9567 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9568 {
9569 if (unformat (input, "version %d", &version_val))
9570 version = 1;
9571 else if (unformat (input, "traffic_class %d", &traffic_class_val))
9572 traffic_class = 1;
9573 else if (unformat (input, "flow_label %d", &flow_label_val))
9574 flow_label = 1;
9575 else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
9576 src = 1;
9577 else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
9578 dst = 1;
9579 else if (unformat (input, "proto %d", &proto_val))
9580 proto = 1;
9581 else if (unformat (input, "payload_length %d", &payload_length_val))
9582 payload_length = 1;
9583 else if (unformat (input, "hop_limit %d", &hop_limit_val))
9584 hop_limit = 1;
9585 else
9586 break;
9587 }
9588
9589 if (version + traffic_class + flow_label + src + dst + proto +
9590 payload_length + hop_limit == 0)
9591 return 0;
9592
9593 /*
9594 * Aligned because we use the real comparison functions
9595 */
9596 vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9597
9598 ip = (ip6_header_t *) match;
9599
9600 if (src)
9601 clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9602
9603 if (dst)
9604 clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9605
9606 if (proto)
9607 ip->protocol = proto_val;
9608
9609 ip_version_traffic_class_and_flow_label = 0;
9610
9611 if (version)
9612 ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9613
9614 if (traffic_class)
9615 ip_version_traffic_class_and_flow_label |=
9616 (traffic_class_val & 0xFF) << 20;
9617
9618 if (flow_label)
9619 ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9620
9621 ip->ip_version_traffic_class_and_flow_label =
9622 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9623
9624 if (payload_length)
9625 ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9626
9627 if (hop_limit)
9628 ip->hop_limit = hop_limit_val;
9629
9630 *matchp = match;
9631 return 1;
9632}
9633
9634uword
9635unformat_l3_match (unformat_input_t * input, va_list * args)
9636{
9637 u8 **matchp = va_arg (*args, u8 **);
9638
9639 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9640 {
9641 if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9642 return 1;
9643 else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9644 return 1;
9645 else
9646 break;
9647 }
9648 return 0;
9649}
9650
9651uword
9652unformat_vlan_tag (unformat_input_t * input, va_list * args)
9653{
9654 u8 *tagp = va_arg (*args, u8 *);
9655 u32 tag;
9656
9657 if (unformat (input, "%d", &tag))
9658 {
9659 tagp[0] = (tag >> 8) & 0x0F;
9660 tagp[1] = tag & 0xFF;
9661 return 1;
9662 }
9663
9664 return 0;
9665}
9666
9667uword
9668unformat_l2_match (unformat_input_t * input, va_list * args)
9669{
9670 u8 **matchp = va_arg (*args, u8 **);
9671 u8 *match = 0;
9672 u8 src = 0;
9673 u8 src_val[6];
9674 u8 dst = 0;
9675 u8 dst_val[6];
9676 u8 proto = 0;
9677 u16 proto_val;
9678 u8 tag1 = 0;
9679 u8 tag1_val[2];
9680 u8 tag2 = 0;
9681 u8 tag2_val[2];
9682 int len = 14;
9683 u8 ignore_tag1 = 0;
9684 u8 ignore_tag2 = 0;
9685 u8 cos1 = 0;
9686 u8 cos2 = 0;
9687 u32 cos1_val = 0;
9688 u32 cos2_val = 0;
9689
9690 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9691 {
9692 if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9693 src = 1;
9694 else
9695 if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9696 dst = 1;
9697 else if (unformat (input, "proto %U",
9698 unformat_ethernet_type_host_byte_order, &proto_val))
9699 proto = 1;
9700 else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9701 tag1 = 1;
9702 else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9703 tag2 = 1;
9704 else if (unformat (input, "ignore-tag1"))
9705 ignore_tag1 = 1;
9706 else if (unformat (input, "ignore-tag2"))
9707 ignore_tag2 = 1;
9708 else if (unformat (input, "cos1 %d", &cos1_val))
9709 cos1 = 1;
9710 else if (unformat (input, "cos2 %d", &cos2_val))
9711 cos2 = 1;
9712 else
9713 break;
9714 }
9715 if ((src + dst + proto + tag1 + tag2 +
9716 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9717 return 0;
9718
9719 if (tag1 || ignore_tag1 || cos1)
9720 len = 18;
9721 if (tag2 || ignore_tag2 || cos2)
9722 len = 22;
9723
9724 vec_validate_aligned (match, len - 1, sizeof (u32x4));
9725
9726 if (dst)
9727 clib_memcpy (match, dst_val, 6);
9728
9729 if (src)
9730 clib_memcpy (match + 6, src_val, 6);
9731
9732 if (tag2)
9733 {
9734 /* inner vlan tag */
9735 match[19] = tag2_val[1];
9736 match[18] = tag2_val[0];
9737 if (cos2)
9738 match[18] |= (cos2_val & 0x7) << 5;
9739 if (proto)
9740 {
9741 match[21] = proto_val & 0xff;
9742 match[20] = proto_val >> 8;
9743 }
9744 if (tag1)
9745 {
9746 match[15] = tag1_val[1];
9747 match[14] = tag1_val[0];
9748 }
9749 if (cos1)
9750 match[14] |= (cos1_val & 0x7) << 5;
9751 *matchp = match;
9752 return 1;
9753 }
9754 if (tag1)
9755 {
9756 match[15] = tag1_val[1];
9757 match[14] = tag1_val[0];
9758 if (proto)
9759 {
9760 match[17] = proto_val & 0xff;
9761 match[16] = proto_val >> 8;
9762 }
9763 if (cos1)
9764 match[14] |= (cos1_val & 0x7) << 5;
9765
9766 *matchp = match;
9767 return 1;
9768 }
9769 if (cos2)
9770 match[18] |= (cos2_val & 0x7) << 5;
9771 if (cos1)
9772 match[14] |= (cos1_val & 0x7) << 5;
9773 if (proto)
9774 {
9775 match[13] = proto_val & 0xff;
9776 match[12] = proto_val >> 8;
9777 }
9778
9779 *matchp = match;
9780 return 1;
9781}
9782
9783
9784uword
9785unformat_classify_match (unformat_input_t * input, va_list * args)
9786{
9787 u8 **matchp = va_arg (*args, u8 **);
9788 u32 skip_n_vectors = va_arg (*args, u32);
9789 u32 match_n_vectors = va_arg (*args, u32);
9790
9791 u8 *match = 0;
9792 u8 *l2 = 0;
9793 u8 *l3 = 0;
9794 u8 *l4 = 0;
9795
9796 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9797 {
9798 if (unformat (input, "hex %U", unformat_hex_string, &match))
9799 ;
9800 else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9801 ;
9802 else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9803 ;
9804 else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9805 ;
9806 else
9807 break;
9808 }
9809
9810 if (l4 && !l3)
9811 {
9812 vec_free (match);
9813 vec_free (l2);
9814 vec_free (l4);
9815 return 0;
9816 }
9817
9818 if (match || l2 || l3 || l4)
9819 {
9820 if (l2 || l3 || l4)
9821 {
9822 /* "Win a free Ethernet header in every packet" */
9823 if (l2 == 0)
9824 vec_validate_aligned (l2, 13, sizeof (u32x4));
9825 match = l2;
9826 if (vec_len (l3))
9827 {
9828 vec_append_aligned (match, l3, sizeof (u32x4));
9829 vec_free (l3);
9830 }
9831 if (vec_len (l4))
9832 {
9833 vec_append_aligned (match, l4, sizeof (u32x4));
9834 vec_free (l4);
9835 }
9836 }
9837
9838 /* Make sure the vector is big enough even if key is all 0's */
9839 vec_validate_aligned
9840 (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
9841 sizeof (u32x4));
9842
9843 /* Set size, include skipped vectors */
9844 _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
9845
9846 *matchp = match;
9847
9848 return 1;
9849 }
9850
9851 return 0;
9852}
9853
9854static int
9855api_classify_add_del_session (vat_main_t * vam)
9856{
9857 unformat_input_t *i = vam->input;
9858 vl_api_classify_add_del_session_t *mp;
9859 int is_add = 1;
9860 u32 table_index = ~0;
9861 u32 hit_next_index = ~0;
9862 u32 opaque_index = ~0;
9863 u8 *match = 0;
9864 i32 advance = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009865 u32 skip_n_vectors = 0;
9866 u32 match_n_vectors = 0;
9867 u32 action = 0;
9868 u32 metadata = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009869 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009870
9871 /*
9872 * Warning: you have to supply skip_n and match_n
9873 * because the API client cant simply look at the classify
9874 * table object.
9875 */
9876
9877 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9878 {
9879 if (unformat (i, "del"))
9880 is_add = 0;
9881 else if (unformat (i, "hit-next %U", unformat_ip_next_index,
9882 &hit_next_index))
9883 ;
9884 else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
9885 &hit_next_index))
9886 ;
9887 else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
9888 &hit_next_index))
9889 ;
9890 else if (unformat (i, "policer-hit-next %d", &hit_next_index))
9891 ;
9892 else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
9893 ;
9894 else if (unformat (i, "opaque-index %d", &opaque_index))
9895 ;
9896 else if (unformat (i, "skip_n %d", &skip_n_vectors))
9897 ;
9898 else if (unformat (i, "match_n %d", &match_n_vectors))
9899 ;
9900 else if (unformat (i, "match %U", unformat_classify_match,
9901 &match, skip_n_vectors, match_n_vectors))
9902 ;
9903 else if (unformat (i, "advance %d", &advance))
9904 ;
9905 else if (unformat (i, "table-index %d", &table_index))
9906 ;
9907 else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
9908 action = 1;
9909 else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
9910 action = 2;
9911 else if (unformat (i, "action %d", &action))
9912 ;
9913 else if (unformat (i, "metadata %d", &metadata))
9914 ;
9915 else
9916 break;
9917 }
9918
9919 if (table_index == ~0)
9920 {
9921 errmsg ("Table index required");
9922 return -99;
9923 }
9924
9925 if (is_add && match == 0)
9926 {
9927 errmsg ("Match value required");
9928 return -99;
9929 }
9930
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009931 M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
Damjan Marion7cd468a2016-12-19 23:05:39 +01009932
9933 mp->is_add = is_add;
9934 mp->table_index = ntohl (table_index);
9935 mp->hit_next_index = ntohl (hit_next_index);
9936 mp->opaque_index = ntohl (opaque_index);
9937 mp->advance = ntohl (advance);
9938 mp->action = action;
9939 mp->metadata = ntohl (metadata);
9940 clib_memcpy (mp->match, match, vec_len (match));
9941 vec_free (match);
9942
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009943 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06009944 W (ret);
9945 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009946}
9947
9948static int
9949api_classify_set_interface_ip_table (vat_main_t * vam)
9950{
9951 unformat_input_t *i = vam->input;
9952 vl_api_classify_set_interface_ip_table_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009953 u32 sw_if_index;
9954 int sw_if_index_set;
9955 u32 table_index = ~0;
9956 u8 is_ipv6 = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -06009957 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009958
9959 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9960 {
9961 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9962 sw_if_index_set = 1;
9963 else if (unformat (i, "sw_if_index %d", &sw_if_index))
9964 sw_if_index_set = 1;
9965 else if (unformat (i, "table %d", &table_index))
9966 ;
9967 else
9968 {
9969 clib_warning ("parse error '%U'", format_unformat_error, i);
9970 return -99;
9971 }
9972 }
9973
9974 if (sw_if_index_set == 0)
9975 {
9976 errmsg ("missing interface name or sw_if_index");
9977 return -99;
9978 }
9979
9980
Jon Loeliger8a2aea32017-01-31 13:19:40 -06009981 M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +01009982
9983 mp->sw_if_index = ntohl (sw_if_index);
9984 mp->table_index = ntohl (table_index);
9985 mp->is_ipv6 = is_ipv6;
9986
Jon Loeliger7bc770c2017-01-31 14:03:33 -06009987 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -06009988 W (ret);
9989 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009990}
9991
9992static int
9993api_classify_set_interface_l2_tables (vat_main_t * vam)
9994{
9995 unformat_input_t *i = vam->input;
9996 vl_api_classify_set_interface_l2_tables_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +01009997 u32 sw_if_index;
9998 int sw_if_index_set;
9999 u32 ip4_table_index = ~0;
10000 u32 ip6_table_index = ~0;
10001 u32 other_table_index = ~0;
10002 u32 is_input = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010003 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010004
10005 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10006 {
10007 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10008 sw_if_index_set = 1;
10009 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10010 sw_if_index_set = 1;
10011 else if (unformat (i, "ip4-table %d", &ip4_table_index))
10012 ;
10013 else if (unformat (i, "ip6-table %d", &ip6_table_index))
10014 ;
10015 else if (unformat (i, "other-table %d", &other_table_index))
10016 ;
10017 else if (unformat (i, "is-input %d", &is_input))
10018 ;
10019 else
10020 {
10021 clib_warning ("parse error '%U'", format_unformat_error, i);
10022 return -99;
10023 }
10024 }
10025
10026 if (sw_if_index_set == 0)
10027 {
10028 errmsg ("missing interface name or sw_if_index");
10029 return -99;
10030 }
10031
10032
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010033 M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010034
10035 mp->sw_if_index = ntohl (sw_if_index);
10036 mp->ip4_table_index = ntohl (ip4_table_index);
10037 mp->ip6_table_index = ntohl (ip6_table_index);
10038 mp->other_table_index = ntohl (other_table_index);
10039 mp->is_input = (u8) is_input;
10040
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010041 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010042 W (ret);
10043 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010044}
10045
10046static int
10047api_set_ipfix_exporter (vat_main_t * vam)
10048{
10049 unformat_input_t *i = vam->input;
10050 vl_api_set_ipfix_exporter_t *mp;
10051 ip4_address_t collector_address;
10052 u8 collector_address_set = 0;
10053 u32 collector_port = ~0;
10054 ip4_address_t src_address;
10055 u8 src_address_set = 0;
10056 u32 vrf_id = ~0;
10057 u32 path_mtu = ~0;
10058 u32 template_interval = ~0;
10059 u8 udp_checksum = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010060 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010061
10062 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10063 {
10064 if (unformat (i, "collector_address %U", unformat_ip4_address,
10065 &collector_address))
10066 collector_address_set = 1;
10067 else if (unformat (i, "collector_port %d", &collector_port))
10068 ;
10069 else if (unformat (i, "src_address %U", unformat_ip4_address,
10070 &src_address))
10071 src_address_set = 1;
10072 else if (unformat (i, "vrf_id %d", &vrf_id))
10073 ;
10074 else if (unformat (i, "path_mtu %d", &path_mtu))
10075 ;
10076 else if (unformat (i, "template_interval %d", &template_interval))
10077 ;
10078 else if (unformat (i, "udp_checksum"))
10079 udp_checksum = 1;
10080 else
10081 break;
10082 }
10083
10084 if (collector_address_set == 0)
10085 {
10086 errmsg ("collector_address required");
10087 return -99;
10088 }
10089
10090 if (src_address_set == 0)
10091 {
10092 errmsg ("src_address required");
10093 return -99;
10094 }
10095
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010096 M (SET_IPFIX_EXPORTER, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010097
10098 memcpy (mp->collector_address, collector_address.data,
10099 sizeof (collector_address.data));
10100 mp->collector_port = htons ((u16) collector_port);
10101 memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
10102 mp->vrf_id = htonl (vrf_id);
10103 mp->path_mtu = htonl (path_mtu);
10104 mp->template_interval = htonl (template_interval);
10105 mp->udp_checksum = udp_checksum;
10106
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010107 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010108 W (ret);
10109 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010110}
10111
10112static int
10113api_set_ipfix_classify_stream (vat_main_t * vam)
10114{
10115 unformat_input_t *i = vam->input;
10116 vl_api_set_ipfix_classify_stream_t *mp;
10117 u32 domain_id = 0;
10118 u32 src_port = UDP_DST_PORT_ipfix;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010119 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010120
10121 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10122 {
10123 if (unformat (i, "domain %d", &domain_id))
10124 ;
10125 else if (unformat (i, "src_port %d", &src_port))
10126 ;
10127 else
10128 {
10129 errmsg ("unknown input `%U'", format_unformat_error, i);
10130 return -99;
10131 }
10132 }
10133
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010134 M (SET_IPFIX_CLASSIFY_STREAM, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010135
10136 mp->domain_id = htonl (domain_id);
10137 mp->src_port = htons ((u16) src_port);
10138
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010139 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010140 W (ret);
10141 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010142}
10143
10144static int
10145api_ipfix_classify_table_add_del (vat_main_t * vam)
10146{
10147 unformat_input_t *i = vam->input;
10148 vl_api_ipfix_classify_table_add_del_t *mp;
10149 int is_add = -1;
10150 u32 classify_table_index = ~0;
10151 u8 ip_version = 0;
10152 u8 transport_protocol = 255;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010153 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010154
10155 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10156 {
10157 if (unformat (i, "add"))
10158 is_add = 1;
10159 else if (unformat (i, "del"))
10160 is_add = 0;
10161 else if (unformat (i, "table %d", &classify_table_index))
10162 ;
10163 else if (unformat (i, "ip4"))
10164 ip_version = 4;
10165 else if (unformat (i, "ip6"))
10166 ip_version = 6;
10167 else if (unformat (i, "tcp"))
10168 transport_protocol = 6;
10169 else if (unformat (i, "udp"))
10170 transport_protocol = 17;
10171 else
10172 {
10173 errmsg ("unknown input `%U'", format_unformat_error, i);
10174 return -99;
10175 }
10176 }
10177
10178 if (is_add == -1)
10179 {
10180 errmsg ("expecting: add|del");
10181 return -99;
10182 }
10183 if (classify_table_index == ~0)
10184 {
10185 errmsg ("classifier table not specified");
10186 return -99;
10187 }
10188 if (ip_version == 0)
10189 {
10190 errmsg ("IP version not specified");
10191 return -99;
10192 }
10193
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010194 M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010195
10196 mp->is_add = is_add;
10197 mp->table_id = htonl (classify_table_index);
10198 mp->ip_version = ip_version;
10199 mp->transport_protocol = transport_protocol;
10200
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010201 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010202 W (ret);
10203 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010204}
10205
10206static int
10207api_get_node_index (vat_main_t * vam)
10208{
10209 unformat_input_t *i = vam->input;
10210 vl_api_get_node_index_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010211 u8 *name = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010212 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010213
10214 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10215 {
10216 if (unformat (i, "node %s", &name))
10217 ;
10218 else
10219 break;
10220 }
10221 if (name == 0)
10222 {
10223 errmsg ("node name required");
10224 return -99;
10225 }
10226 if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10227 {
10228 errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10229 return -99;
10230 }
10231
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010232 M (GET_NODE_INDEX, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010233 clib_memcpy (mp->node_name, name, vec_len (name));
10234 vec_free (name);
10235
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010236 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010237 W (ret);
10238 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010239}
10240
10241static int
10242api_get_next_index (vat_main_t * vam)
10243{
10244 unformat_input_t *i = vam->input;
10245 vl_api_get_next_index_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010246 u8 *node_name = 0, *next_node_name = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010247 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010248
10249 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10250 {
10251 if (unformat (i, "node-name %s", &node_name))
10252 ;
10253 else if (unformat (i, "next-node-name %s", &next_node_name))
10254 break;
10255 }
10256
10257 if (node_name == 0)
10258 {
10259 errmsg ("node name required");
10260 return -99;
10261 }
10262 if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
10263 {
10264 errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10265 return -99;
10266 }
10267
10268 if (next_node_name == 0)
10269 {
10270 errmsg ("next node name required");
10271 return -99;
10272 }
10273 if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
10274 {
10275 errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
10276 return -99;
10277 }
10278
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010279 M (GET_NEXT_INDEX, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010280 clib_memcpy (mp->node_name, node_name, vec_len (node_name));
10281 clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
10282 vec_free (node_name);
10283 vec_free (next_node_name);
10284
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010285 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010286 W (ret);
10287 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010288}
10289
10290static int
10291api_add_node_next (vat_main_t * vam)
10292{
10293 unformat_input_t *i = vam->input;
10294 vl_api_add_node_next_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010295 u8 *name = 0;
10296 u8 *next = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010297 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010298
10299 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10300 {
10301 if (unformat (i, "node %s", &name))
10302 ;
10303 else if (unformat (i, "next %s", &next))
10304 ;
10305 else
10306 break;
10307 }
10308 if (name == 0)
10309 {
10310 errmsg ("node name required");
10311 return -99;
10312 }
10313 if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10314 {
10315 errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10316 return -99;
10317 }
10318 if (next == 0)
10319 {
10320 errmsg ("next node required");
10321 return -99;
10322 }
10323 if (vec_len (next) >= ARRAY_LEN (mp->next_name))
10324 {
10325 errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
10326 return -99;
10327 }
10328
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010329 M (ADD_NODE_NEXT, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010330 clib_memcpy (mp->node_name, name, vec_len (name));
10331 clib_memcpy (mp->next_name, next, vec_len (next));
10332 vec_free (name);
10333 vec_free (next);
10334
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010335 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010336 W (ret);
10337 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010338}
10339
10340static int
10341api_l2tpv3_create_tunnel (vat_main_t * vam)
10342{
10343 unformat_input_t *i = vam->input;
10344 ip6_address_t client_address, our_address;
10345 int client_address_set = 0;
10346 int our_address_set = 0;
10347 u32 local_session_id = 0;
10348 u32 remote_session_id = 0;
10349 u64 local_cookie = 0;
10350 u64 remote_cookie = 0;
10351 u8 l2_sublayer_present = 0;
10352 vl_api_l2tpv3_create_tunnel_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010353 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010354
10355 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10356 {
10357 if (unformat (i, "client_address %U", unformat_ip6_address,
10358 &client_address))
10359 client_address_set = 1;
10360 else if (unformat (i, "our_address %U", unformat_ip6_address,
10361 &our_address))
10362 our_address_set = 1;
10363 else if (unformat (i, "local_session_id %d", &local_session_id))
10364 ;
10365 else if (unformat (i, "remote_session_id %d", &remote_session_id))
10366 ;
10367 else if (unformat (i, "local_cookie %lld", &local_cookie))
10368 ;
10369 else if (unformat (i, "remote_cookie %lld", &remote_cookie))
10370 ;
10371 else if (unformat (i, "l2-sublayer-present"))
10372 l2_sublayer_present = 1;
10373 else
10374 break;
10375 }
10376
10377 if (client_address_set == 0)
10378 {
10379 errmsg ("client_address required");
10380 return -99;
10381 }
10382
10383 if (our_address_set == 0)
10384 {
10385 errmsg ("our_address required");
10386 return -99;
10387 }
10388
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010389 M (L2TPV3_CREATE_TUNNEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010390
10391 clib_memcpy (mp->client_address, client_address.as_u8,
10392 sizeof (mp->client_address));
10393
10394 clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
10395
10396 mp->local_session_id = ntohl (local_session_id);
10397 mp->remote_session_id = ntohl (remote_session_id);
10398 mp->local_cookie = clib_host_to_net_u64 (local_cookie);
10399 mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
10400 mp->l2_sublayer_present = l2_sublayer_present;
10401 mp->is_ipv6 = 1;
10402
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010403 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010404 W (ret);
10405 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010406}
10407
10408static int
10409api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
10410{
10411 unformat_input_t *i = vam->input;
10412 u32 sw_if_index;
10413 u8 sw_if_index_set = 0;
10414 u64 new_local_cookie = 0;
10415 u64 new_remote_cookie = 0;
10416 vl_api_l2tpv3_set_tunnel_cookies_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010417 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010418
10419 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10420 {
10421 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10422 sw_if_index_set = 1;
10423 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10424 sw_if_index_set = 1;
10425 else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
10426 ;
10427 else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
10428 ;
10429 else
10430 break;
10431 }
10432
10433 if (sw_if_index_set == 0)
10434 {
10435 errmsg ("missing interface name or sw_if_index");
10436 return -99;
10437 }
10438
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010439 M (L2TPV3_SET_TUNNEL_COOKIES, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010440
10441 mp->sw_if_index = ntohl (sw_if_index);
10442 mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
10443 mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
10444
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010445 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010446 W (ret);
10447 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010448}
10449
10450static int
10451api_l2tpv3_interface_enable_disable (vat_main_t * vam)
10452{
10453 unformat_input_t *i = vam->input;
10454 vl_api_l2tpv3_interface_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010455 u32 sw_if_index;
10456 u8 sw_if_index_set = 0;
10457 u8 enable_disable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010458 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010459
10460 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10461 {
10462 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10463 sw_if_index_set = 1;
10464 else if (unformat (i, "sw_if_index %d", &sw_if_index))
10465 sw_if_index_set = 1;
10466 else if (unformat (i, "enable"))
10467 enable_disable = 1;
10468 else if (unformat (i, "disable"))
10469 enable_disable = 0;
10470 else
10471 break;
10472 }
10473
10474 if (sw_if_index_set == 0)
10475 {
10476 errmsg ("missing interface name or sw_if_index");
10477 return -99;
10478 }
10479
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010480 M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010481
10482 mp->sw_if_index = ntohl (sw_if_index);
10483 mp->enable_disable = enable_disable;
10484
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010485 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010486 W (ret);
10487 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010488}
10489
10490static int
10491api_l2tpv3_set_lookup_key (vat_main_t * vam)
10492{
10493 unformat_input_t *i = vam->input;
10494 vl_api_l2tpv3_set_lookup_key_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010495 u8 key = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010496 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010497
10498 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10499 {
10500 if (unformat (i, "lookup_v6_src"))
10501 key = L2T_LOOKUP_SRC_ADDRESS;
10502 else if (unformat (i, "lookup_v6_dst"))
10503 key = L2T_LOOKUP_DST_ADDRESS;
10504 else if (unformat (i, "lookup_session_id"))
10505 key = L2T_LOOKUP_SESSION_ID;
10506 else
10507 break;
10508 }
10509
10510 if (key == (u8) ~ 0)
10511 {
10512 errmsg ("l2tp session lookup key unset");
10513 return -99;
10514 }
10515
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010516 M (L2TPV3_SET_LOOKUP_KEY, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010517
10518 mp->key = key;
10519
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010520 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010521 W (ret);
10522 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010523}
10524
10525static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
10526 (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10527{
10528 vat_main_t *vam = &vat_main;
10529
10530 print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
10531 format_ip6_address, mp->our_address,
10532 format_ip6_address, mp->client_address,
10533 clib_net_to_host_u32 (mp->sw_if_index));
10534
10535 print (vam->ofp,
10536 " local cookies %016llx %016llx remote cookie %016llx",
10537 clib_net_to_host_u64 (mp->local_cookie[0]),
10538 clib_net_to_host_u64 (mp->local_cookie[1]),
10539 clib_net_to_host_u64 (mp->remote_cookie));
10540
10541 print (vam->ofp, " local session-id %d remote session-id %d",
10542 clib_net_to_host_u32 (mp->local_session_id),
10543 clib_net_to_host_u32 (mp->remote_session_id));
10544
10545 print (vam->ofp, " l2 specific sublayer %s\n",
10546 mp->l2_sublayer_present ? "preset" : "absent");
10547
10548}
10549
10550static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
10551 (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10552{
10553 vat_main_t *vam = &vat_main;
10554 vat_json_node_t *node = NULL;
10555 struct in6_addr addr;
10556
10557 if (VAT_JSON_ARRAY != vam->json_tree.type)
10558 {
10559 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10560 vat_json_init_array (&vam->json_tree);
10561 }
10562 node = vat_json_array_add (&vam->json_tree);
10563
10564 vat_json_init_object (node);
10565
10566 clib_memcpy (&addr, mp->our_address, sizeof (addr));
10567 vat_json_object_add_ip6 (node, "our_address", addr);
10568 clib_memcpy (&addr, mp->client_address, sizeof (addr));
10569 vat_json_object_add_ip6 (node, "client_address", addr);
10570
10571 vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
10572 vat_json_init_array (lc);
10573 vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
10574 vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
10575 vat_json_object_add_uint (node, "remote_cookie",
10576 clib_net_to_host_u64 (mp->remote_cookie));
10577
10578 printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
10579 vat_json_object_add_uint (node, "local_session_id",
10580 clib_net_to_host_u32 (mp->local_session_id));
10581 vat_json_object_add_uint (node, "remote_session_id",
10582 clib_net_to_host_u32 (mp->remote_session_id));
10583 vat_json_object_add_string_copy (node, "l2_sublayer",
10584 mp->l2_sublayer_present ? (u8 *) "present"
10585 : (u8 *) "absent");
10586}
10587
10588static int
10589api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
10590{
10591 vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010592 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010593 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010594
10595 /* Get list of l2tpv3-tunnel interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010596 M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010597 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010598
10599 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010600 M (CONTROL_PING, mp_ping);
10601 S (mp_ping);
10602
Jon Loeliger56c7b012017-02-01 12:31:41 -060010603 W (ret);
10604 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010605}
10606
10607
10608static void vl_api_sw_interface_tap_details_t_handler
10609 (vl_api_sw_interface_tap_details_t * mp)
10610{
10611 vat_main_t *vam = &vat_main;
10612
10613 print (vam->ofp, "%-16s %d",
10614 mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10615}
10616
10617static void vl_api_sw_interface_tap_details_t_handler_json
10618 (vl_api_sw_interface_tap_details_t * mp)
10619{
10620 vat_main_t *vam = &vat_main;
10621 vat_json_node_t *node = NULL;
10622
10623 if (VAT_JSON_ARRAY != vam->json_tree.type)
10624 {
10625 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10626 vat_json_init_array (&vam->json_tree);
10627 }
10628 node = vat_json_array_add (&vam->json_tree);
10629
10630 vat_json_init_object (node);
10631 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10632 vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10633}
10634
10635static int
10636api_sw_interface_tap_dump (vat_main_t * vam)
10637{
10638 vl_api_sw_interface_tap_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010639 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010640 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010641
10642 print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
10643 /* Get list of tap interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010644 M (SW_INTERFACE_TAP_DUMP, mp);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010645 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010646
10647 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010648 M (CONTROL_PING, mp_ping);
10649 S (mp_ping);
10650
Jon Loeliger56c7b012017-02-01 12:31:41 -060010651 W (ret);
10652 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010653}
10654
10655static uword unformat_vxlan_decap_next
10656 (unformat_input_t * input, va_list * args)
10657{
10658 u32 *result = va_arg (*args, u32 *);
10659 u32 tmp;
10660
10661 if (unformat (input, "l2"))
10662 *result = VXLAN_INPUT_NEXT_L2_INPUT;
10663 else if (unformat (input, "%d", &tmp))
10664 *result = tmp;
10665 else
10666 return 0;
10667 return 1;
10668}
10669
10670static int
10671api_vxlan_add_del_tunnel (vat_main_t * vam)
10672{
10673 unformat_input_t *line_input = vam->input;
10674 vl_api_vxlan_add_del_tunnel_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010675 ip46_address_t src, dst;
10676 u8 is_add = 1;
10677 u8 ipv4_set = 0, ipv6_set = 0;
10678 u8 src_set = 0;
10679 u8 dst_set = 0;
10680 u8 grp_set = 0;
10681 u32 mcast_sw_if_index = ~0;
10682 u32 encap_vrf_id = 0;
10683 u32 decap_next_index = ~0;
10684 u32 vni = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010685 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010686
10687 /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
10688 memset (&src, 0, sizeof src);
10689 memset (&dst, 0, sizeof dst);
10690
10691 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10692 {
10693 if (unformat (line_input, "del"))
10694 is_add = 0;
10695 else
10696 if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
10697 {
10698 ipv4_set = 1;
10699 src_set = 1;
10700 }
10701 else
10702 if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
10703 {
10704 ipv4_set = 1;
10705 dst_set = 1;
10706 }
10707 else
10708 if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
10709 {
10710 ipv6_set = 1;
10711 src_set = 1;
10712 }
10713 else
10714 if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
10715 {
10716 ipv6_set = 1;
10717 dst_set = 1;
10718 }
10719 else if (unformat (line_input, "group %U %U",
10720 unformat_ip4_address, &dst.ip4,
10721 api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10722 {
10723 grp_set = dst_set = 1;
10724 ipv4_set = 1;
10725 }
10726 else if (unformat (line_input, "group %U",
10727 unformat_ip4_address, &dst.ip4))
10728 {
10729 grp_set = dst_set = 1;
10730 ipv4_set = 1;
10731 }
10732 else if (unformat (line_input, "group %U %U",
10733 unformat_ip6_address, &dst.ip6,
10734 api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10735 {
10736 grp_set = dst_set = 1;
10737 ipv6_set = 1;
10738 }
10739 else if (unformat (line_input, "group %U",
10740 unformat_ip6_address, &dst.ip6))
10741 {
10742 grp_set = dst_set = 1;
10743 ipv6_set = 1;
10744 }
10745 else
10746 if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10747 ;
10748 else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10749 ;
10750 else if (unformat (line_input, "decap-next %U",
10751 unformat_vxlan_decap_next, &decap_next_index))
10752 ;
10753 else if (unformat (line_input, "vni %d", &vni))
10754 ;
10755 else
10756 {
10757 errmsg ("parse error '%U'", format_unformat_error, line_input);
10758 return -99;
10759 }
10760 }
10761
10762 if (src_set == 0)
10763 {
10764 errmsg ("tunnel src address not specified");
10765 return -99;
10766 }
10767 if (dst_set == 0)
10768 {
10769 errmsg ("tunnel dst address not specified");
10770 return -99;
10771 }
10772
10773 if (grp_set && !ip46_address_is_multicast (&dst))
10774 {
10775 errmsg ("tunnel group address not multicast");
10776 return -99;
10777 }
10778 if (grp_set && mcast_sw_if_index == ~0)
10779 {
10780 errmsg ("tunnel nonexistent multicast device");
10781 return -99;
10782 }
10783 if (grp_set == 0 && ip46_address_is_multicast (&dst))
10784 {
10785 errmsg ("tunnel dst address must be unicast");
10786 return -99;
10787 }
10788
10789
10790 if (ipv4_set && ipv6_set)
10791 {
10792 errmsg ("both IPv4 and IPv6 addresses specified");
10793 return -99;
10794 }
10795
10796 if ((vni == 0) || (vni >> 24))
10797 {
10798 errmsg ("vni not specified or out of range");
10799 return -99;
10800 }
10801
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010802 M (VXLAN_ADD_DEL_TUNNEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010803
10804 if (ipv6_set)
10805 {
10806 clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
10807 clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
10808 }
10809 else
10810 {
10811 clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
10812 clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
10813 }
10814 mp->encap_vrf_id = ntohl (encap_vrf_id);
10815 mp->decap_next_index = ntohl (decap_next_index);
10816 mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
10817 mp->vni = ntohl (vni);
10818 mp->is_add = is_add;
10819 mp->is_ipv6 = ipv6_set;
10820
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010821 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010822 W (ret);
10823 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010824}
10825
10826static void vl_api_vxlan_tunnel_details_t_handler
10827 (vl_api_vxlan_tunnel_details_t * mp)
10828{
10829 vat_main_t *vam = &vat_main;
10830 ip46_address_t src, dst;
10831
10832 ip46_from_addr_buf (mp->is_ipv6, mp->src_address, &src);
10833 ip46_from_addr_buf (mp->is_ipv6, mp->dst_address, &dst);
10834
10835 print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
10836 ntohl (mp->sw_if_index),
10837 format_ip46_address, &src, IP46_TYPE_ANY,
10838 format_ip46_address, &dst, IP46_TYPE_ANY,
10839 ntohl (mp->encap_vrf_id),
10840 ntohl (mp->decap_next_index), ntohl (mp->vni),
10841 ntohl (mp->mcast_sw_if_index));
10842}
10843
10844static void vl_api_vxlan_tunnel_details_t_handler_json
10845 (vl_api_vxlan_tunnel_details_t * mp)
10846{
10847 vat_main_t *vam = &vat_main;
10848 vat_json_node_t *node = NULL;
10849
10850 if (VAT_JSON_ARRAY != vam->json_tree.type)
10851 {
10852 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10853 vat_json_init_array (&vam->json_tree);
10854 }
10855 node = vat_json_array_add (&vam->json_tree);
10856
10857 vat_json_init_object (node);
10858 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10859 if (mp->is_ipv6)
10860 {
10861 struct in6_addr ip6;
10862
10863 clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
10864 vat_json_object_add_ip6 (node, "src_address", ip6);
10865 clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
10866 vat_json_object_add_ip6 (node, "dst_address", ip6);
10867 }
10868 else
10869 {
10870 struct in_addr ip4;
10871
10872 clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
10873 vat_json_object_add_ip4 (node, "src_address", ip4);
10874 clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
10875 vat_json_object_add_ip4 (node, "dst_address", ip4);
10876 }
10877 vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10878 vat_json_object_add_uint (node, "decap_next_index",
10879 ntohl (mp->decap_next_index));
10880 vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10881 vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10882 vat_json_object_add_uint (node, "mcast_sw_if_index",
10883 ntohl (mp->mcast_sw_if_index));
10884}
10885
10886static int
10887api_vxlan_tunnel_dump (vat_main_t * vam)
10888{
10889 unformat_input_t *i = vam->input;
10890 vl_api_vxlan_tunnel_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010891 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010892 u32 sw_if_index;
10893 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010894 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010895
10896 /* Parse args required to build the message */
10897 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10898 {
10899 if (unformat (i, "sw_if_index %d", &sw_if_index))
10900 sw_if_index_set = 1;
10901 else
10902 break;
10903 }
10904
10905 if (sw_if_index_set == 0)
10906 {
10907 sw_if_index = ~0;
10908 }
10909
10910 if (!vam->json_output)
10911 {
10912 print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
10913 "sw_if_index", "src_address", "dst_address",
10914 "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
10915 }
10916
10917 /* Get list of vxlan-tunnel interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010918 M (VXLAN_TUNNEL_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010919
10920 mp->sw_if_index = htonl (sw_if_index);
10921
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010922 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010923
10924 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060010925 M (CONTROL_PING, mp_ping);
10926 S (mp_ping);
10927
Jon Loeliger56c7b012017-02-01 12:31:41 -060010928 W (ret);
10929 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010930}
10931
10932static int
10933api_gre_add_del_tunnel (vat_main_t * vam)
10934{
10935 unformat_input_t *line_input = vam->input;
10936 vl_api_gre_add_del_tunnel_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010937 ip4_address_t src4, dst4;
10938 u8 is_add = 1;
10939 u8 teb = 0;
10940 u8 src_set = 0;
10941 u8 dst_set = 0;
10942 u32 outer_fib_id = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060010943 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010944
10945 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10946 {
10947 if (unformat (line_input, "del"))
10948 is_add = 0;
10949 else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10950 src_set = 1;
10951 else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10952 dst_set = 1;
10953 else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
10954 ;
10955 else if (unformat (line_input, "teb"))
10956 teb = 1;
10957 else
10958 {
10959 errmsg ("parse error '%U'", format_unformat_error, line_input);
10960 return -99;
10961 }
10962 }
10963
10964 if (src_set == 0)
10965 {
10966 errmsg ("tunnel src address not specified");
10967 return -99;
10968 }
10969 if (dst_set == 0)
10970 {
10971 errmsg ("tunnel dst address not specified");
10972 return -99;
10973 }
10974
10975
Jon Loeliger8a2aea32017-01-31 13:19:40 -060010976 M (GRE_ADD_DEL_TUNNEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010010977
10978 clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10979 clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10980 mp->outer_fib_id = ntohl (outer_fib_id);
10981 mp->is_add = is_add;
10982 mp->teb = teb;
10983
Jon Loeliger7bc770c2017-01-31 14:03:33 -060010984 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060010985 W (ret);
10986 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010010987}
10988
10989static void vl_api_gre_tunnel_details_t_handler
10990 (vl_api_gre_tunnel_details_t * mp)
10991{
10992 vat_main_t *vam = &vat_main;
10993
10994 print (vam->ofp, "%11d%15U%15U%6d%14d",
10995 ntohl (mp->sw_if_index),
10996 format_ip4_address, &mp->src_address,
10997 format_ip4_address, &mp->dst_address,
10998 mp->teb, ntohl (mp->outer_fib_id));
10999}
11000
11001static void vl_api_gre_tunnel_details_t_handler_json
11002 (vl_api_gre_tunnel_details_t * mp)
11003{
11004 vat_main_t *vam = &vat_main;
11005 vat_json_node_t *node = NULL;
11006 struct in_addr ip4;
11007
11008 if (VAT_JSON_ARRAY != vam->json_tree.type)
11009 {
11010 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11011 vat_json_init_array (&vam->json_tree);
11012 }
11013 node = vat_json_array_add (&vam->json_tree);
11014
11015 vat_json_init_object (node);
11016 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11017 clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
11018 vat_json_object_add_ip4 (node, "src_address", ip4);
11019 clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
11020 vat_json_object_add_ip4 (node, "dst_address", ip4);
11021 vat_json_object_add_uint (node, "teb", mp->teb);
11022 vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
11023}
11024
11025static int
11026api_gre_tunnel_dump (vat_main_t * vam)
11027{
11028 unformat_input_t *i = vam->input;
11029 vl_api_gre_tunnel_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011030 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011031 u32 sw_if_index;
11032 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011033 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011034
11035 /* Parse args required to build the message */
11036 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11037 {
11038 if (unformat (i, "sw_if_index %d", &sw_if_index))
11039 sw_if_index_set = 1;
11040 else
11041 break;
11042 }
11043
11044 if (sw_if_index_set == 0)
11045 {
11046 sw_if_index = ~0;
11047 }
11048
11049 if (!vam->json_output)
11050 {
11051 print (vam->ofp, "%11s%15s%15s%6s%14s",
11052 "sw_if_index", "src_address", "dst_address", "teb",
11053 "outer_fib_id");
11054 }
11055
11056 /* Get list of gre-tunnel interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011057 M (GRE_TUNNEL_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011058
11059 mp->sw_if_index = htonl (sw_if_index);
11060
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011061 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011062
11063 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011064 M (CONTROL_PING, mp_ping);
11065 S (mp_ping);
11066
Jon Loeliger56c7b012017-02-01 12:31:41 -060011067 W (ret);
11068 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011069}
11070
11071static int
11072api_l2_fib_clear_table (vat_main_t * vam)
11073{
11074// unformat_input_t * i = vam->input;
11075 vl_api_l2_fib_clear_table_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011076 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011077
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011078 M (L2_FIB_CLEAR_TABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011079
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011080 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011081 W (ret);
11082 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011083}
11084
11085static int
11086api_l2_interface_efp_filter (vat_main_t * vam)
11087{
11088 unformat_input_t *i = vam->input;
11089 vl_api_l2_interface_efp_filter_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011090 u32 sw_if_index;
11091 u8 enable = 1;
11092 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011093 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011094
11095 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11096 {
11097 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11098 sw_if_index_set = 1;
11099 else if (unformat (i, "sw_if_index %d", &sw_if_index))
11100 sw_if_index_set = 1;
11101 else if (unformat (i, "enable"))
11102 enable = 1;
11103 else if (unformat (i, "disable"))
11104 enable = 0;
11105 else
11106 {
11107 clib_warning ("parse error '%U'", format_unformat_error, i);
11108 return -99;
11109 }
11110 }
11111
11112 if (sw_if_index_set == 0)
11113 {
11114 errmsg ("missing sw_if_index");
11115 return -99;
11116 }
11117
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011118 M (L2_INTERFACE_EFP_FILTER, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011119
11120 mp->sw_if_index = ntohl (sw_if_index);
11121 mp->enable_disable = enable;
11122
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011123 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011124 W (ret);
11125 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011126}
11127
11128#define foreach_vtr_op \
11129_("disable", L2_VTR_DISABLED) \
11130_("push-1", L2_VTR_PUSH_1) \
11131_("push-2", L2_VTR_PUSH_2) \
11132_("pop-1", L2_VTR_POP_1) \
11133_("pop-2", L2_VTR_POP_2) \
11134_("translate-1-1", L2_VTR_TRANSLATE_1_1) \
11135_("translate-1-2", L2_VTR_TRANSLATE_1_2) \
11136_("translate-2-1", L2_VTR_TRANSLATE_2_1) \
11137_("translate-2-2", L2_VTR_TRANSLATE_2_2)
11138
11139static int
11140api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
11141{
11142 unformat_input_t *i = vam->input;
11143 vl_api_l2_interface_vlan_tag_rewrite_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011144 u32 sw_if_index;
11145 u8 sw_if_index_set = 0;
11146 u8 vtr_op_set = 0;
11147 u32 vtr_op = 0;
11148 u32 push_dot1q = 1;
11149 u32 tag1 = ~0;
11150 u32 tag2 = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011151 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011152
11153 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11154 {
11155 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11156 sw_if_index_set = 1;
11157 else if (unformat (i, "sw_if_index %d", &sw_if_index))
11158 sw_if_index_set = 1;
11159 else if (unformat (i, "vtr_op %d", &vtr_op))
11160 vtr_op_set = 1;
11161#define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
11162 foreach_vtr_op
11163#undef _
11164 else if (unformat (i, "push_dot1q %d", &push_dot1q))
11165 ;
11166 else if (unformat (i, "tag1 %d", &tag1))
11167 ;
11168 else if (unformat (i, "tag2 %d", &tag2))
11169 ;
11170 else
11171 {
11172 clib_warning ("parse error '%U'", format_unformat_error, i);
11173 return -99;
11174 }
11175 }
11176
11177 if ((sw_if_index_set == 0) || (vtr_op_set == 0))
11178 {
11179 errmsg ("missing vtr operation or sw_if_index");
11180 return -99;
11181 }
11182
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011183 M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
11184 mp->sw_if_index = ntohl (sw_if_index);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011185 mp->vtr_op = ntohl (vtr_op);
11186 mp->push_dot1q = ntohl (push_dot1q);
11187 mp->tag1 = ntohl (tag1);
11188 mp->tag2 = ntohl (tag2);
11189
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011190 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011191 W (ret);
11192 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011193}
11194
11195static int
11196api_create_vhost_user_if (vat_main_t * vam)
11197{
11198 unformat_input_t *i = vam->input;
11199 vl_api_create_vhost_user_if_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011200 u8 *file_name;
11201 u8 is_server = 0;
11202 u8 file_name_set = 0;
11203 u32 custom_dev_instance = ~0;
11204 u8 hwaddr[6];
11205 u8 use_custom_mac = 0;
11206 u8 *tag = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011207 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011208
11209 /* Shut up coverity */
11210 memset (hwaddr, 0, sizeof (hwaddr));
11211
11212 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11213 {
11214 if (unformat (i, "socket %s", &file_name))
11215 {
11216 file_name_set = 1;
11217 }
11218 else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11219 ;
11220 else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
11221 use_custom_mac = 1;
11222 else if (unformat (i, "server"))
11223 is_server = 1;
11224 else if (unformat (i, "tag %s", &tag))
11225 ;
11226 else
11227 break;
11228 }
11229
11230 if (file_name_set == 0)
11231 {
11232 errmsg ("missing socket file name");
11233 return -99;
11234 }
11235
11236 if (vec_len (file_name) > 255)
11237 {
11238 errmsg ("socket file name too long");
11239 return -99;
11240 }
11241 vec_add1 (file_name, 0);
11242
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011243 M (CREATE_VHOST_USER_IF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011244
11245 mp->is_server = is_server;
11246 clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11247 vec_free (file_name);
11248 if (custom_dev_instance != ~0)
11249 {
11250 mp->renumber = 1;
11251 mp->custom_dev_instance = ntohl (custom_dev_instance);
11252 }
11253 mp->use_custom_mac = use_custom_mac;
11254 clib_memcpy (mp->mac_address, hwaddr, 6);
11255 if (tag)
11256 strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
11257 vec_free (tag);
11258
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011259 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011260 W (ret);
11261 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011262}
11263
11264static int
11265api_modify_vhost_user_if (vat_main_t * vam)
11266{
11267 unformat_input_t *i = vam->input;
11268 vl_api_modify_vhost_user_if_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011269 u8 *file_name;
11270 u8 is_server = 0;
11271 u8 file_name_set = 0;
11272 u32 custom_dev_instance = ~0;
11273 u8 sw_if_index_set = 0;
11274 u32 sw_if_index = (u32) ~ 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011275 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011276
11277 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11278 {
11279 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11280 sw_if_index_set = 1;
11281 else if (unformat (i, "sw_if_index %d", &sw_if_index))
11282 sw_if_index_set = 1;
11283 else if (unformat (i, "socket %s", &file_name))
11284 {
11285 file_name_set = 1;
11286 }
11287 else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11288 ;
11289 else if (unformat (i, "server"))
11290 is_server = 1;
11291 else
11292 break;
11293 }
11294
11295 if (sw_if_index_set == 0)
11296 {
11297 errmsg ("missing sw_if_index or interface name");
11298 return -99;
11299 }
11300
11301 if (file_name_set == 0)
11302 {
11303 errmsg ("missing socket file name");
11304 return -99;
11305 }
11306
11307 if (vec_len (file_name) > 255)
11308 {
11309 errmsg ("socket file name too long");
11310 return -99;
11311 }
11312 vec_add1 (file_name, 0);
11313
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011314 M (MODIFY_VHOST_USER_IF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011315
11316 mp->sw_if_index = ntohl (sw_if_index);
11317 mp->is_server = is_server;
11318 clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11319 vec_free (file_name);
11320 if (custom_dev_instance != ~0)
11321 {
11322 mp->renumber = 1;
11323 mp->custom_dev_instance = ntohl (custom_dev_instance);
11324 }
11325
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011326 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011327 W (ret);
11328 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011329}
11330
11331static int
11332api_delete_vhost_user_if (vat_main_t * vam)
11333{
11334 unformat_input_t *i = vam->input;
11335 vl_api_delete_vhost_user_if_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011336 u32 sw_if_index = ~0;
11337 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011338 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011339
11340 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11341 {
11342 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11343 sw_if_index_set = 1;
11344 else if (unformat (i, "sw_if_index %d", &sw_if_index))
11345 sw_if_index_set = 1;
11346 else
11347 break;
11348 }
11349
11350 if (sw_if_index_set == 0)
11351 {
11352 errmsg ("missing sw_if_index or interface name");
11353 return -99;
11354 }
11355
11356
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011357 M (DELETE_VHOST_USER_IF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011358
11359 mp->sw_if_index = ntohl (sw_if_index);
11360
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011361 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011362 W (ret);
11363 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011364}
11365
11366static void vl_api_sw_interface_vhost_user_details_t_handler
11367 (vl_api_sw_interface_vhost_user_details_t * mp)
11368{
11369 vat_main_t *vam = &vat_main;
11370
11371 print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
11372 (char *) mp->interface_name,
11373 ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
11374 clib_net_to_host_u64 (mp->features), mp->is_server,
11375 ntohl (mp->num_regions), (char *) mp->sock_filename);
11376 print (vam->ofp, " Status: '%s'", strerror (ntohl (mp->sock_errno)));
11377}
11378
11379static void vl_api_sw_interface_vhost_user_details_t_handler_json
11380 (vl_api_sw_interface_vhost_user_details_t * mp)
11381{
11382 vat_main_t *vam = &vat_main;
11383 vat_json_node_t *node = NULL;
11384
11385 if (VAT_JSON_ARRAY != vam->json_tree.type)
11386 {
11387 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11388 vat_json_init_array (&vam->json_tree);
11389 }
11390 node = vat_json_array_add (&vam->json_tree);
11391
11392 vat_json_init_object (node);
11393 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11394 vat_json_object_add_string_copy (node, "interface_name",
11395 mp->interface_name);
11396 vat_json_object_add_uint (node, "virtio_net_hdr_sz",
11397 ntohl (mp->virtio_net_hdr_sz));
11398 vat_json_object_add_uint (node, "features",
11399 clib_net_to_host_u64 (mp->features));
11400 vat_json_object_add_uint (node, "is_server", mp->is_server);
11401 vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
11402 vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
11403 vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
11404}
11405
11406static int
11407api_sw_interface_vhost_user_dump (vat_main_t * vam)
11408{
11409 vl_api_sw_interface_vhost_user_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011410 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011411 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011412 print (vam->ofp,
11413 "Interface name idx hdr_sz features server regions filename");
11414
11415 /* Get list of vhost-user interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011416 M (SW_INTERFACE_VHOST_USER_DUMP, mp);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011417 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011418
11419 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011420 M (CONTROL_PING, mp_ping);
11421 S (mp_ping);
11422
Jon Loeliger56c7b012017-02-01 12:31:41 -060011423 W (ret);
11424 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011425}
11426
11427static int
11428api_show_version (vat_main_t * vam)
11429{
11430 vl_api_show_version_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011431 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011432
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011433 M (SHOW_VERSION, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011434
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
11440
11441static int
11442api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
11443{
11444 unformat_input_t *line_input = vam->input;
11445 vl_api_vxlan_gpe_add_del_tunnel_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011446 ip4_address_t local4, remote4;
11447 ip6_address_t local6, remote6;
11448 u8 is_add = 1;
11449 u8 ipv4_set = 0, ipv6_set = 0;
11450 u8 local_set = 0;
11451 u8 remote_set = 0;
11452 u32 encap_vrf_id = 0;
11453 u32 decap_vrf_id = 0;
11454 u8 protocol = ~0;
11455 u32 vni;
11456 u8 vni_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011457 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011458
11459 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11460 {
11461 if (unformat (line_input, "del"))
11462 is_add = 0;
11463 else if (unformat (line_input, "local %U",
11464 unformat_ip4_address, &local4))
11465 {
11466 local_set = 1;
11467 ipv4_set = 1;
11468 }
11469 else if (unformat (line_input, "remote %U",
11470 unformat_ip4_address, &remote4))
11471 {
11472 remote_set = 1;
11473 ipv4_set = 1;
11474 }
11475 else if (unformat (line_input, "local %U",
11476 unformat_ip6_address, &local6))
11477 {
11478 local_set = 1;
11479 ipv6_set = 1;
11480 }
11481 else if (unformat (line_input, "remote %U",
11482 unformat_ip6_address, &remote6))
11483 {
11484 remote_set = 1;
11485 ipv6_set = 1;
11486 }
11487 else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11488 ;
11489 else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
11490 ;
11491 else if (unformat (line_input, "vni %d", &vni))
11492 vni_set = 1;
11493 else if (unformat (line_input, "next-ip4"))
11494 protocol = 1;
11495 else if (unformat (line_input, "next-ip6"))
11496 protocol = 2;
11497 else if (unformat (line_input, "next-ethernet"))
11498 protocol = 3;
11499 else if (unformat (line_input, "next-nsh"))
11500 protocol = 4;
11501 else
11502 {
11503 errmsg ("parse error '%U'", format_unformat_error, line_input);
11504 return -99;
11505 }
11506 }
11507
11508 if (local_set == 0)
11509 {
11510 errmsg ("tunnel local address not specified");
11511 return -99;
11512 }
11513 if (remote_set == 0)
11514 {
11515 errmsg ("tunnel remote address not specified");
11516 return -99;
11517 }
11518 if (ipv4_set && ipv6_set)
11519 {
11520 errmsg ("both IPv4 and IPv6 addresses specified");
11521 return -99;
11522 }
11523
11524 if (vni_set == 0)
11525 {
11526 errmsg ("vni not specified");
11527 return -99;
11528 }
11529
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011530 M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011531
11532
11533 if (ipv6_set)
11534 {
11535 clib_memcpy (&mp->local, &local6, sizeof (local6));
11536 clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
11537 }
11538 else
11539 {
11540 clib_memcpy (&mp->local, &local4, sizeof (local4));
11541 clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
11542 }
11543
11544 mp->encap_vrf_id = ntohl (encap_vrf_id);
11545 mp->decap_vrf_id = ntohl (decap_vrf_id);
11546 mp->protocol = protocol;
11547 mp->vni = ntohl (vni);
11548 mp->is_add = is_add;
11549 mp->is_ipv6 = ipv6_set;
11550
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011551 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011552 W (ret);
11553 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011554}
11555
11556static void vl_api_vxlan_gpe_tunnel_details_t_handler
11557 (vl_api_vxlan_gpe_tunnel_details_t * mp)
11558{
11559 vat_main_t *vam = &vat_main;
11560
11561 print (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d",
11562 ntohl (mp->sw_if_index),
11563 format_ip46_address, &(mp->local[0]),
11564 format_ip46_address, &(mp->remote[0]),
11565 ntohl (mp->vni),
11566 ntohl (mp->protocol),
11567 ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
11568}
11569
11570static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
11571 (vl_api_vxlan_gpe_tunnel_details_t * mp)
11572{
11573 vat_main_t *vam = &vat_main;
11574 vat_json_node_t *node = NULL;
11575 struct in_addr ip4;
11576 struct in6_addr ip6;
11577
11578 if (VAT_JSON_ARRAY != vam->json_tree.type)
11579 {
11580 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11581 vat_json_init_array (&vam->json_tree);
11582 }
11583 node = vat_json_array_add (&vam->json_tree);
11584
11585 vat_json_init_object (node);
11586 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11587 if (mp->is_ipv6)
11588 {
11589 clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
11590 vat_json_object_add_ip6 (node, "local", ip6);
11591 clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
11592 vat_json_object_add_ip6 (node, "remote", ip6);
11593 }
11594 else
11595 {
11596 clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
11597 vat_json_object_add_ip4 (node, "local", ip4);
11598 clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
11599 vat_json_object_add_ip4 (node, "remote", ip4);
11600 }
11601 vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11602 vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
11603 vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11604 vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
11605 vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11606}
11607
11608static int
11609api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
11610{
11611 unformat_input_t *i = vam->input;
11612 vl_api_vxlan_gpe_tunnel_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011613 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011614 u32 sw_if_index;
11615 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011616 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011617
11618 /* Parse args required to build the message */
11619 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11620 {
11621 if (unformat (i, "sw_if_index %d", &sw_if_index))
11622 sw_if_index_set = 1;
11623 else
11624 break;
11625 }
11626
11627 if (sw_if_index_set == 0)
11628 {
11629 sw_if_index = ~0;
11630 }
11631
11632 if (!vam->json_output)
11633 {
11634 print (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s",
11635 "sw_if_index", "local", "remote", "vni",
11636 "protocol", "encap_vrf_id", "decap_vrf_id");
11637 }
11638
11639 /* Get list of vxlan-tunnel interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011640 M (VXLAN_GPE_TUNNEL_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011641
11642 mp->sw_if_index = htonl (sw_if_index);
11643
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011644 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011645
11646 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011647 M (CONTROL_PING, mp_ping);
11648 S (mp_ping);
11649
Jon Loeliger56c7b012017-02-01 12:31:41 -060011650 W (ret);
11651 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011652}
11653
11654u8 *
11655format_l2_fib_mac_address (u8 * s, va_list * args)
11656{
11657 u8 *a = va_arg (*args, u8 *);
11658
11659 return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11660 a[2], a[3], a[4], a[5], a[6], a[7]);
11661}
11662
11663static void vl_api_l2_fib_table_entry_t_handler
11664 (vl_api_l2_fib_table_entry_t * mp)
11665{
11666 vat_main_t *vam = &vat_main;
11667
11668 print (vam->ofp, "%3" PRIu32 " %U %3" PRIu32
11669 " %d %d %d",
11670 ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11671 ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11672 mp->bvi_mac);
11673}
11674
11675static void vl_api_l2_fib_table_entry_t_handler_json
11676 (vl_api_l2_fib_table_entry_t * mp)
11677{
11678 vat_main_t *vam = &vat_main;
11679 vat_json_node_t *node = NULL;
11680
11681 if (VAT_JSON_ARRAY != vam->json_tree.type)
11682 {
11683 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11684 vat_json_init_array (&vam->json_tree);
11685 }
11686 node = vat_json_array_add (&vam->json_tree);
11687
11688 vat_json_init_object (node);
11689 vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11690 vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11691 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11692 vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11693 vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11694 vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11695}
11696
11697static int
11698api_l2_fib_table_dump (vat_main_t * vam)
11699{
11700 unformat_input_t *i = vam->input;
11701 vl_api_l2_fib_table_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011702 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011703 u32 bd_id;
11704 u8 bd_id_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011705 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011706
11707 /* Parse args required to build the message */
11708 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11709 {
11710 if (unformat (i, "bd_id %d", &bd_id))
11711 bd_id_set = 1;
11712 else
11713 break;
11714 }
11715
11716 if (bd_id_set == 0)
11717 {
11718 errmsg ("missing bridge domain");
11719 return -99;
11720 }
11721
11722 print (vam->ofp, "BD-ID Mac Address sw-ndx Static Filter BVI");
11723
11724 /* Get list of l2 fib entries */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011725 M (L2_FIB_TABLE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011726
11727 mp->bd_id = ntohl (bd_id);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011728 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011729
11730 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011731 M (CONTROL_PING, mp_ping);
11732 S (mp_ping);
11733
Jon Loeliger56c7b012017-02-01 12:31:41 -060011734 W (ret);
11735 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011736}
11737
11738
11739static int
11740api_interface_name_renumber (vat_main_t * vam)
11741{
11742 unformat_input_t *line_input = vam->input;
11743 vl_api_interface_name_renumber_t *mp;
11744 u32 sw_if_index = ~0;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011745 u32 new_show_dev_instance = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011746 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011747
11748 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11749 {
11750 if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
11751 &sw_if_index))
11752 ;
11753 else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11754 ;
11755 else if (unformat (line_input, "new_show_dev_instance %d",
11756 &new_show_dev_instance))
11757 ;
11758 else
11759 break;
11760 }
11761
11762 if (sw_if_index == ~0)
11763 {
11764 errmsg ("missing interface name or sw_if_index");
11765 return -99;
11766 }
11767
11768 if (new_show_dev_instance == ~0)
11769 {
11770 errmsg ("missing new_show_dev_instance");
11771 return -99;
11772 }
11773
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011774 M (INTERFACE_NAME_RENUMBER, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011775
11776 mp->sw_if_index = ntohl (sw_if_index);
11777 mp->new_show_dev_instance = ntohl (new_show_dev_instance);
11778
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011779 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011780 W (ret);
11781 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011782}
11783
11784static int
11785api_want_ip4_arp_events (vat_main_t * vam)
11786{
11787 unformat_input_t *line_input = vam->input;
11788 vl_api_want_ip4_arp_events_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011789 ip4_address_t address;
11790 int address_set = 0;
11791 u32 enable_disable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011792 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011793
11794 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11795 {
11796 if (unformat (line_input, "address %U", unformat_ip4_address, &address))
11797 address_set = 1;
11798 else if (unformat (line_input, "del"))
11799 enable_disable = 0;
11800 else
11801 break;
11802 }
11803
11804 if (address_set == 0)
11805 {
11806 errmsg ("missing addresses");
11807 return -99;
11808 }
11809
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011810 M (WANT_IP4_ARP_EVENTS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011811 mp->enable_disable = enable_disable;
11812 mp->pid = getpid ();
11813 mp->address = address.as_u32;
11814
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011815 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011816 W (ret);
11817 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011818}
11819
11820static int
11821api_want_ip6_nd_events (vat_main_t * vam)
11822{
11823 unformat_input_t *line_input = vam->input;
11824 vl_api_want_ip6_nd_events_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011825 ip6_address_t address;
11826 int address_set = 0;
11827 u32 enable_disable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011828 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011829
11830 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11831 {
11832 if (unformat (line_input, "address %U", unformat_ip6_address, &address))
11833 address_set = 1;
11834 else if (unformat (line_input, "del"))
11835 enable_disable = 0;
11836 else
11837 break;
11838 }
11839
11840 if (address_set == 0)
11841 {
11842 errmsg ("missing addresses");
11843 return -99;
11844 }
11845
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011846 M (WANT_IP6_ND_EVENTS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011847 mp->enable_disable = enable_disable;
11848 mp->pid = getpid ();
11849 clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
11850
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011851 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011852 W (ret);
11853 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011854}
11855
11856static int
11857api_input_acl_set_interface (vat_main_t * vam)
11858{
11859 unformat_input_t *i = vam->input;
11860 vl_api_input_acl_set_interface_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011861 u32 sw_if_index;
11862 int sw_if_index_set;
11863 u32 ip4_table_index = ~0;
11864 u32 ip6_table_index = ~0;
11865 u32 l2_table_index = ~0;
11866 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011867 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011868
11869 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11870 {
11871 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11872 sw_if_index_set = 1;
11873 else if (unformat (i, "sw_if_index %d", &sw_if_index))
11874 sw_if_index_set = 1;
11875 else if (unformat (i, "del"))
11876 is_add = 0;
11877 else if (unformat (i, "ip4-table %d", &ip4_table_index))
11878 ;
11879 else if (unformat (i, "ip6-table %d", &ip6_table_index))
11880 ;
11881 else if (unformat (i, "l2-table %d", &l2_table_index))
11882 ;
11883 else
11884 {
11885 clib_warning ("parse error '%U'", format_unformat_error, i);
11886 return -99;
11887 }
11888 }
11889
11890 if (sw_if_index_set == 0)
11891 {
11892 errmsg ("missing interface name or sw_if_index");
11893 return -99;
11894 }
11895
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011896 M (INPUT_ACL_SET_INTERFACE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011897
11898 mp->sw_if_index = ntohl (sw_if_index);
11899 mp->ip4_table_index = ntohl (ip4_table_index);
11900 mp->ip6_table_index = ntohl (ip6_table_index);
11901 mp->l2_table_index = ntohl (l2_table_index);
11902 mp->is_add = is_add;
11903
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011904 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060011905 W (ret);
11906 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011907}
11908
11909static int
11910api_ip_address_dump (vat_main_t * vam)
11911{
11912 unformat_input_t *i = vam->input;
11913 vl_api_ip_address_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011914 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011915 u32 sw_if_index = ~0;
11916 u8 sw_if_index_set = 0;
11917 u8 ipv4_set = 0;
11918 u8 ipv6_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011919 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011920
11921 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11922 {
11923 if (unformat (i, "sw_if_index %d", &sw_if_index))
11924 sw_if_index_set = 1;
11925 else
11926 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11927 sw_if_index_set = 1;
11928 else if (unformat (i, "ipv4"))
11929 ipv4_set = 1;
11930 else if (unformat (i, "ipv6"))
11931 ipv6_set = 1;
11932 else
11933 break;
11934 }
11935
11936 if (ipv4_set && ipv6_set)
11937 {
11938 errmsg ("ipv4 and ipv6 flags cannot be both set");
11939 return -99;
11940 }
11941
11942 if ((!ipv4_set) && (!ipv6_set))
11943 {
11944 errmsg ("no ipv4 nor ipv6 flag set");
11945 return -99;
11946 }
11947
11948 if (sw_if_index_set == 0)
11949 {
11950 errmsg ("missing interface name or sw_if_index");
11951 return -99;
11952 }
11953
11954 vam->current_sw_if_index = sw_if_index;
11955 vam->is_ipv6 = ipv6_set;
11956
Jon Loeliger8a2aea32017-01-31 13:19:40 -060011957 M (IP_ADDRESS_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011958 mp->sw_if_index = ntohl (sw_if_index);
11959 mp->is_ipv6 = ipv6_set;
Jon Loeliger7bc770c2017-01-31 14:03:33 -060011960 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010011961
11962 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011963 M (CONTROL_PING, mp_ping);
11964 S (mp_ping);
11965
Jon Loeliger56c7b012017-02-01 12:31:41 -060011966 W (ret);
11967 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011968}
11969
11970static int
11971api_ip_dump (vat_main_t * vam)
11972{
11973 vl_api_ip_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060011974 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011975 unformat_input_t *in = vam->input;
11976 int ipv4_set = 0;
11977 int ipv6_set = 0;
11978 int is_ipv6;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011979 int i;
Jon Loeliger56c7b012017-02-01 12:31:41 -060011980 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010011981
11982 while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
11983 {
11984 if (unformat (in, "ipv4"))
11985 ipv4_set = 1;
11986 else if (unformat (in, "ipv6"))
11987 ipv6_set = 1;
11988 else
11989 break;
11990 }
11991
11992 if (ipv4_set && ipv6_set)
11993 {
11994 errmsg ("ipv4 and ipv6 flags cannot be both set");
11995 return -99;
11996 }
11997
11998 if ((!ipv4_set) && (!ipv6_set))
11999 {
12000 errmsg ("no ipv4 nor ipv6 flag set");
12001 return -99;
12002 }
12003
12004 is_ipv6 = ipv6_set;
12005 vam->is_ipv6 = is_ipv6;
12006
12007 /* free old data */
12008 for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
12009 {
12010 vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
12011 }
12012 vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
12013
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012014 M (IP_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012015 mp->is_ipv6 = ipv6_set;
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012016 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012017
12018 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060012019 M (CONTROL_PING, mp_ping);
12020 S (mp_ping);
12021
Jon Loeliger56c7b012017-02-01 12:31:41 -060012022 W (ret);
12023 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012024}
12025
12026static int
12027api_ipsec_spd_add_del (vat_main_t * vam)
12028{
12029 unformat_input_t *i = vam->input;
12030 vl_api_ipsec_spd_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012031 u32 spd_id = ~0;
12032 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012033 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012034
12035 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12036 {
12037 if (unformat (i, "spd_id %d", &spd_id))
12038 ;
12039 else if (unformat (i, "del"))
12040 is_add = 0;
12041 else
12042 {
12043 clib_warning ("parse error '%U'", format_unformat_error, i);
12044 return -99;
12045 }
12046 }
12047 if (spd_id == ~0)
12048 {
12049 errmsg ("spd_id must be set");
12050 return -99;
12051 }
12052
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012053 M (IPSEC_SPD_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012054
12055 mp->spd_id = ntohl (spd_id);
12056 mp->is_add = is_add;
12057
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012058 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012059 W (ret);
12060 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012061}
12062
12063static int
12064api_ipsec_interface_add_del_spd (vat_main_t * vam)
12065{
12066 unformat_input_t *i = vam->input;
12067 vl_api_ipsec_interface_add_del_spd_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012068 u32 sw_if_index;
12069 u8 sw_if_index_set = 0;
12070 u32 spd_id = (u32) ~ 0;
12071 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012072 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012073
12074 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12075 {
12076 if (unformat (i, "del"))
12077 is_add = 0;
12078 else if (unformat (i, "spd_id %d", &spd_id))
12079 ;
12080 else
12081 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12082 sw_if_index_set = 1;
12083 else if (unformat (i, "sw_if_index %d", &sw_if_index))
12084 sw_if_index_set = 1;
12085 else
12086 {
12087 clib_warning ("parse error '%U'", format_unformat_error, i);
12088 return -99;
12089 }
12090
12091 }
12092
12093 if (spd_id == (u32) ~ 0)
12094 {
12095 errmsg ("spd_id must be set");
12096 return -99;
12097 }
12098
12099 if (sw_if_index_set == 0)
12100 {
12101 errmsg ("missing interface name or sw_if_index");
12102 return -99;
12103 }
12104
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012105 M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012106
12107 mp->spd_id = ntohl (spd_id);
12108 mp->sw_if_index = ntohl (sw_if_index);
12109 mp->is_add = is_add;
12110
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012111 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012112 W (ret);
12113 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012114}
12115
12116static int
12117api_ipsec_spd_add_del_entry (vat_main_t * vam)
12118{
12119 unformat_input_t *i = vam->input;
12120 vl_api_ipsec_spd_add_del_entry_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012121 u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
12122 u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
12123 i32 priority = 0;
12124 u32 rport_start = 0, rport_stop = (u32) ~ 0;
12125 u32 lport_start = 0, lport_stop = (u32) ~ 0;
12126 ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
12127 ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012128 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012129
12130 laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
12131 laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
12132 laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
12133 laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
12134 laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
12135 laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
12136
12137 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12138 {
12139 if (unformat (i, "del"))
12140 is_add = 0;
12141 if (unformat (i, "outbound"))
12142 is_outbound = 1;
12143 if (unformat (i, "inbound"))
12144 is_outbound = 0;
12145 else if (unformat (i, "spd_id %d", &spd_id))
12146 ;
12147 else if (unformat (i, "sa_id %d", &sa_id))
12148 ;
12149 else if (unformat (i, "priority %d", &priority))
12150 ;
12151 else if (unformat (i, "protocol %d", &protocol))
12152 ;
12153 else if (unformat (i, "lport_start %d", &lport_start))
12154 ;
12155 else if (unformat (i, "lport_stop %d", &lport_stop))
12156 ;
12157 else if (unformat (i, "rport_start %d", &rport_start))
12158 ;
12159 else if (unformat (i, "rport_stop %d", &rport_stop))
12160 ;
12161 else
12162 if (unformat
12163 (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
12164 {
12165 is_ipv6 = 0;
12166 is_ip_any = 0;
12167 }
12168 else
12169 if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
12170 {
12171 is_ipv6 = 0;
12172 is_ip_any = 0;
12173 }
12174 else
12175 if (unformat
12176 (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
12177 {
12178 is_ipv6 = 0;
12179 is_ip_any = 0;
12180 }
12181 else
12182 if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
12183 {
12184 is_ipv6 = 0;
12185 is_ip_any = 0;
12186 }
12187 else
12188 if (unformat
12189 (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
12190 {
12191 is_ipv6 = 1;
12192 is_ip_any = 0;
12193 }
12194 else
12195 if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
12196 {
12197 is_ipv6 = 1;
12198 is_ip_any = 0;
12199 }
12200 else
12201 if (unformat
12202 (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
12203 {
12204 is_ipv6 = 1;
12205 is_ip_any = 0;
12206 }
12207 else
12208 if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
12209 {
12210 is_ipv6 = 1;
12211 is_ip_any = 0;
12212 }
12213 else
12214 if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
12215 {
12216 if (policy == IPSEC_POLICY_ACTION_RESOLVE)
12217 {
12218 clib_warning ("unsupported action: 'resolve'");
12219 return -99;
12220 }
12221 }
12222 else
12223 {
12224 clib_warning ("parse error '%U'", format_unformat_error, i);
12225 return -99;
12226 }
12227
12228 }
12229
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012230 M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012231
12232 mp->spd_id = ntohl (spd_id);
12233 mp->priority = ntohl (priority);
12234 mp->is_outbound = is_outbound;
12235
12236 mp->is_ipv6 = is_ipv6;
12237 if (is_ipv6 || is_ip_any)
12238 {
12239 clib_memcpy (mp->remote_address_start, &raddr6_start,
12240 sizeof (ip6_address_t));
12241 clib_memcpy (mp->remote_address_stop, &raddr6_stop,
12242 sizeof (ip6_address_t));
12243 clib_memcpy (mp->local_address_start, &laddr6_start,
12244 sizeof (ip6_address_t));
12245 clib_memcpy (mp->local_address_stop, &laddr6_stop,
12246 sizeof (ip6_address_t));
12247 }
12248 else
12249 {
12250 clib_memcpy (mp->remote_address_start, &raddr4_start,
12251 sizeof (ip4_address_t));
12252 clib_memcpy (mp->remote_address_stop, &raddr4_stop,
12253 sizeof (ip4_address_t));
12254 clib_memcpy (mp->local_address_start, &laddr4_start,
12255 sizeof (ip4_address_t));
12256 clib_memcpy (mp->local_address_stop, &laddr4_stop,
12257 sizeof (ip4_address_t));
12258 }
12259 mp->protocol = (u8) protocol;
12260 mp->local_port_start = ntohs ((u16) lport_start);
12261 mp->local_port_stop = ntohs ((u16) lport_stop);
12262 mp->remote_port_start = ntohs ((u16) rport_start);
12263 mp->remote_port_stop = ntohs ((u16) rport_stop);
12264 mp->policy = (u8) policy;
12265 mp->sa_id = ntohl (sa_id);
12266 mp->is_add = is_add;
12267 mp->is_ip_any = is_ip_any;
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012268 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012269 W (ret);
12270 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012271}
12272
12273static int
12274api_ipsec_sad_add_del_entry (vat_main_t * vam)
12275{
12276 unformat_input_t *i = vam->input;
12277 vl_api_ipsec_sad_add_del_entry_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012278 u32 sad_id = 0, spi = 0;
12279 u8 *ck = 0, *ik = 0;
12280 u8 is_add = 1;
12281
12282 u8 protocol = IPSEC_PROTOCOL_AH;
12283 u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
12284 u32 crypto_alg = 0, integ_alg = 0;
12285 ip4_address_t tun_src4;
12286 ip4_address_t tun_dst4;
12287 ip6_address_t tun_src6;
12288 ip6_address_t tun_dst6;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012289 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012290
12291 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12292 {
12293 if (unformat (i, "del"))
12294 is_add = 0;
12295 else if (unformat (i, "sad_id %d", &sad_id))
12296 ;
12297 else if (unformat (i, "spi %d", &spi))
12298 ;
12299 else if (unformat (i, "esp"))
12300 protocol = IPSEC_PROTOCOL_ESP;
12301 else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
12302 {
12303 is_tunnel = 1;
12304 is_tunnel_ipv6 = 0;
12305 }
12306 else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
12307 {
12308 is_tunnel = 1;
12309 is_tunnel_ipv6 = 0;
12310 }
12311 else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
12312 {
12313 is_tunnel = 1;
12314 is_tunnel_ipv6 = 1;
12315 }
12316 else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
12317 {
12318 is_tunnel = 1;
12319 is_tunnel_ipv6 = 1;
12320 }
12321 else
12322 if (unformat
12323 (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
12324 {
12325 if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
12326 crypto_alg >= IPSEC_CRYPTO_N_ALG)
12327 {
12328 clib_warning ("unsupported crypto-alg: '%U'",
12329 format_ipsec_crypto_alg, crypto_alg);
12330 return -99;
12331 }
12332 }
12333 else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12334 ;
12335 else
12336 if (unformat
12337 (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
12338 {
Damjan Marion7cd468a2016-12-19 23:05:39 +010012339 if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
Damjan Marion7cd468a2016-12-19 23:05:39 +010012340 integ_alg >= IPSEC_INTEG_N_ALG)
12341 {
12342 clib_warning ("unsupported integ-alg: '%U'",
12343 format_ipsec_integ_alg, integ_alg);
12344 return -99;
12345 }
12346 }
12347 else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12348 ;
12349 else
12350 {
12351 clib_warning ("parse error '%U'", format_unformat_error, i);
12352 return -99;
12353 }
12354
12355 }
12356
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012357 M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012358
12359 mp->sad_id = ntohl (sad_id);
12360 mp->is_add = is_add;
12361 mp->protocol = protocol;
12362 mp->spi = ntohl (spi);
12363 mp->is_tunnel = is_tunnel;
12364 mp->is_tunnel_ipv6 = is_tunnel_ipv6;
12365 mp->crypto_algorithm = crypto_alg;
12366 mp->integrity_algorithm = integ_alg;
12367 mp->crypto_key_length = vec_len (ck);
12368 mp->integrity_key_length = vec_len (ik);
12369
12370 if (mp->crypto_key_length > sizeof (mp->crypto_key))
12371 mp->crypto_key_length = sizeof (mp->crypto_key);
12372
12373 if (mp->integrity_key_length > sizeof (mp->integrity_key))
12374 mp->integrity_key_length = sizeof (mp->integrity_key);
12375
12376 if (ck)
12377 clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12378 if (ik)
12379 clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12380
12381 if (is_tunnel)
12382 {
12383 if (is_tunnel_ipv6)
12384 {
12385 clib_memcpy (mp->tunnel_src_address, &tun_src6,
12386 sizeof (ip6_address_t));
12387 clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
12388 sizeof (ip6_address_t));
12389 }
12390 else
12391 {
12392 clib_memcpy (mp->tunnel_src_address, &tun_src4,
12393 sizeof (ip4_address_t));
12394 clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
12395 sizeof (ip4_address_t));
12396 }
12397 }
12398
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012399 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012400 W (ret);
12401 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012402}
12403
12404static int
12405api_ipsec_sa_set_key (vat_main_t * vam)
12406{
12407 unformat_input_t *i = vam->input;
12408 vl_api_ipsec_sa_set_key_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012409 u32 sa_id;
12410 u8 *ck = 0, *ik = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012411 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012412
12413 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12414 {
12415 if (unformat (i, "sa_id %d", &sa_id))
12416 ;
12417 else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12418 ;
12419 else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12420 ;
12421 else
12422 {
12423 clib_warning ("parse error '%U'", format_unformat_error, i);
12424 return -99;
12425 }
12426 }
12427
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012428 M (IPSEC_SA_SET_KEY, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012429
12430 mp->sa_id = ntohl (sa_id);
12431 mp->crypto_key_length = vec_len (ck);
12432 mp->integrity_key_length = vec_len (ik);
12433
12434 if (mp->crypto_key_length > sizeof (mp->crypto_key))
12435 mp->crypto_key_length = sizeof (mp->crypto_key);
12436
12437 if (mp->integrity_key_length > sizeof (mp->integrity_key))
12438 mp->integrity_key_length = sizeof (mp->integrity_key);
12439
12440 if (ck)
12441 clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12442 if (ik)
12443 clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12444
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012445 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012446 W (ret);
12447 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012448}
12449
12450static int
12451api_ikev2_profile_add_del (vat_main_t * vam)
12452{
12453 unformat_input_t *i = vam->input;
12454 vl_api_ikev2_profile_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012455 u8 is_add = 1;
12456 u8 *name = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012457 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012458
12459 const char *valid_chars = "a-zA-Z0-9_";
12460
12461 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12462 {
12463 if (unformat (i, "del"))
12464 is_add = 0;
12465 else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12466 vec_add1 (name, 0);
12467 else
12468 {
12469 errmsg ("parse error '%U'", format_unformat_error, i);
12470 return -99;
12471 }
12472 }
12473
12474 if (!vec_len (name))
12475 {
12476 errmsg ("profile name must be specified");
12477 return -99;
12478 }
12479
12480 if (vec_len (name) > 64)
12481 {
12482 errmsg ("profile name too long");
12483 return -99;
12484 }
12485
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012486 M (IKEV2_PROFILE_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012487
12488 clib_memcpy (mp->name, name, vec_len (name));
12489 mp->is_add = is_add;
12490 vec_free (name);
12491
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012492 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012493 W (ret);
12494 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012495}
12496
12497static int
12498api_ikev2_profile_set_auth (vat_main_t * vam)
12499{
12500 unformat_input_t *i = vam->input;
12501 vl_api_ikev2_profile_set_auth_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012502 u8 *name = 0;
12503 u8 *data = 0;
12504 u32 auth_method = 0;
12505 u8 is_hex = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012506 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012507
12508 const char *valid_chars = "a-zA-Z0-9_";
12509
12510 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12511 {
12512 if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12513 vec_add1 (name, 0);
12514 else if (unformat (i, "auth_method %U",
12515 unformat_ikev2_auth_method, &auth_method))
12516 ;
12517 else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
12518 is_hex = 1;
12519 else if (unformat (i, "auth_data %v", &data))
12520 ;
12521 else
12522 {
12523 errmsg ("parse error '%U'", format_unformat_error, i);
12524 return -99;
12525 }
12526 }
12527
12528 if (!vec_len (name))
12529 {
12530 errmsg ("profile name must be specified");
12531 return -99;
12532 }
12533
12534 if (vec_len (name) > 64)
12535 {
12536 errmsg ("profile name too long");
12537 return -99;
12538 }
12539
12540 if (!vec_len (data))
12541 {
12542 errmsg ("auth_data must be specified");
12543 return -99;
12544 }
12545
12546 if (!auth_method)
12547 {
12548 errmsg ("auth_method must be specified");
12549 return -99;
12550 }
12551
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012552 M (IKEV2_PROFILE_SET_AUTH, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012553
12554 mp->is_hex = is_hex;
12555 mp->auth_method = (u8) auth_method;
12556 mp->data_len = vec_len (data);
12557 clib_memcpy (mp->name, name, vec_len (name));
12558 clib_memcpy (mp->data, data, vec_len (data));
12559 vec_free (name);
12560 vec_free (data);
12561
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012562 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012563 W (ret);
12564 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012565}
12566
12567static int
12568api_ikev2_profile_set_id (vat_main_t * vam)
12569{
12570 unformat_input_t *i = vam->input;
12571 vl_api_ikev2_profile_set_id_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012572 u8 *name = 0;
12573 u8 *data = 0;
12574 u8 is_local = 0;
12575 u32 id_type = 0;
12576 ip4_address_t ip4;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012577 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012578
12579 const char *valid_chars = "a-zA-Z0-9_";
12580
12581 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12582 {
12583 if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12584 vec_add1 (name, 0);
12585 else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
12586 ;
12587 else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
12588 {
12589 data = vec_new (u8, 4);
12590 clib_memcpy (data, ip4.as_u8, 4);
12591 }
12592 else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
12593 ;
12594 else if (unformat (i, "id_data %v", &data))
12595 ;
12596 else if (unformat (i, "local"))
12597 is_local = 1;
12598 else if (unformat (i, "remote"))
12599 is_local = 0;
12600 else
12601 {
12602 errmsg ("parse error '%U'", format_unformat_error, i);
12603 return -99;
12604 }
12605 }
12606
12607 if (!vec_len (name))
12608 {
12609 errmsg ("profile name must be specified");
12610 return -99;
12611 }
12612
12613 if (vec_len (name) > 64)
12614 {
12615 errmsg ("profile name too long");
12616 return -99;
12617 }
12618
12619 if (!vec_len (data))
12620 {
12621 errmsg ("id_data must be specified");
12622 return -99;
12623 }
12624
12625 if (!id_type)
12626 {
12627 errmsg ("id_type must be specified");
12628 return -99;
12629 }
12630
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012631 M (IKEV2_PROFILE_SET_ID, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012632
12633 mp->is_local = is_local;
12634 mp->id_type = (u8) id_type;
12635 mp->data_len = vec_len (data);
12636 clib_memcpy (mp->name, name, vec_len (name));
12637 clib_memcpy (mp->data, data, vec_len (data));
12638 vec_free (name);
12639 vec_free (data);
12640
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012641 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012642 W (ret);
12643 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012644}
12645
12646static int
12647api_ikev2_profile_set_ts (vat_main_t * vam)
12648{
12649 unformat_input_t *i = vam->input;
12650 vl_api_ikev2_profile_set_ts_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012651 u8 *name = 0;
12652 u8 is_local = 0;
12653 u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
12654 ip4_address_t start_addr, end_addr;
12655
12656 const char *valid_chars = "a-zA-Z0-9_";
Jon Loeliger56c7b012017-02-01 12:31:41 -060012657 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012658
12659 start_addr.as_u32 = 0;
12660 end_addr.as_u32 = (u32) ~ 0;
12661
12662 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12663 {
12664 if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12665 vec_add1 (name, 0);
12666 else if (unformat (i, "protocol %d", &proto))
12667 ;
12668 else if (unformat (i, "start_port %d", &start_port))
12669 ;
12670 else if (unformat (i, "end_port %d", &end_port))
12671 ;
12672 else
12673 if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
12674 ;
12675 else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
12676 ;
12677 else if (unformat (i, "local"))
12678 is_local = 1;
12679 else if (unformat (i, "remote"))
12680 is_local = 0;
12681 else
12682 {
12683 errmsg ("parse error '%U'", format_unformat_error, i);
12684 return -99;
12685 }
12686 }
12687
12688 if (!vec_len (name))
12689 {
12690 errmsg ("profile name must be specified");
12691 return -99;
12692 }
12693
12694 if (vec_len (name) > 64)
12695 {
12696 errmsg ("profile name too long");
12697 return -99;
12698 }
12699
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012700 M (IKEV2_PROFILE_SET_TS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012701
12702 mp->is_local = is_local;
12703 mp->proto = (u8) proto;
12704 mp->start_port = (u16) start_port;
12705 mp->end_port = (u16) end_port;
12706 mp->start_addr = start_addr.as_u32;
12707 mp->end_addr = end_addr.as_u32;
12708 clib_memcpy (mp->name, name, vec_len (name));
12709 vec_free (name);
12710
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012711 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012712 W (ret);
12713 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012714}
12715
12716static int
12717api_ikev2_set_local_key (vat_main_t * vam)
12718{
12719 unformat_input_t *i = vam->input;
12720 vl_api_ikev2_set_local_key_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012721 u8 *file = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060012722 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012723
12724 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12725 {
12726 if (unformat (i, "file %v", &file))
12727 vec_add1 (file, 0);
12728 else
12729 {
12730 errmsg ("parse error '%U'", format_unformat_error, i);
12731 return -99;
12732 }
12733 }
12734
12735 if (!vec_len (file))
12736 {
12737 errmsg ("RSA key file must be specified");
12738 return -99;
12739 }
12740
12741 if (vec_len (file) > 256)
12742 {
12743 errmsg ("file name too long");
12744 return -99;
12745 }
12746
Jon Loeliger8a2aea32017-01-31 13:19:40 -060012747 M (IKEV2_SET_LOCAL_KEY, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010012748
12749 clib_memcpy (mp->key_file, file, vec_len (file));
12750 vec_free (file);
12751
Jon Loeliger7bc770c2017-01-31 14:03:33 -060012752 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060012753 W (ret);
12754 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010012755}
12756
Radu Nicolaucb33dc22017-02-16 16:49:46 +000012757static int
12758api_ikev2_set_responder (vat_main_t * vam)
12759{
12760 unformat_input_t *i = vam->input;
12761 vl_api_ikev2_set_responder_t *mp;
12762 int ret;
12763 u8 *name = 0;
12764 u32 sw_if_index = ~0;
12765 ip4_address_t address;
12766
12767 const char *valid_chars = "a-zA-Z0-9_";
12768
12769 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12770 {
12771 if (unformat
12772 (i, "%U interface %d address %U", unformat_token, valid_chars,
12773 &name, &sw_if_index, unformat_ip4_address, &address))
12774 vec_add1 (name, 0);
12775 else
12776 {
12777 errmsg ("parse error '%U'", format_unformat_error, i);
12778 return -99;
12779 }
12780 }
12781
12782 if (!vec_len (name))
12783 {
12784 errmsg ("profile name must be specified");
12785 return -99;
12786 }
12787
12788 if (vec_len (name) > 64)
12789 {
12790 errmsg ("profile name too long");
12791 return -99;
12792 }
12793
12794 M (IKEV2_SET_RESPONDER, mp);
12795
12796 clib_memcpy (mp->name, name, vec_len (name));
12797 vec_free (name);
12798
12799 mp->sw_if_index = sw_if_index;
12800 clib_memcpy (mp->address, &address, sizeof (address));
12801
12802 S (mp);
12803 W (ret);
12804 return ret;
12805}
12806
12807static int
12808api_ikev2_set_ike_transforms (vat_main_t * vam)
12809{
12810 unformat_input_t *i = vam->input;
12811 vl_api_ikev2_set_ike_transforms_t *mp;
12812 int ret;
12813 u8 *name = 0;
12814 u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
12815
12816 const char *valid_chars = "a-zA-Z0-9_";
12817
12818 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12819 {
12820 if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
12821 &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
12822 vec_add1 (name, 0);
12823 else
12824 {
12825 errmsg ("parse error '%U'", format_unformat_error, i);
12826 return -99;
12827 }
12828 }
12829
12830 if (!vec_len (name))
12831 {
12832 errmsg ("profile name must be specified");
12833 return -99;
12834 }
12835
12836 if (vec_len (name) > 64)
12837 {
12838 errmsg ("profile name too long");
12839 return -99;
12840 }
12841
12842 M (IKEV2_SET_IKE_TRANSFORMS, mp);
12843
12844 clib_memcpy (mp->name, name, vec_len (name));
12845 vec_free (name);
12846 mp->crypto_alg = crypto_alg;
12847 mp->crypto_key_size = crypto_key_size;
12848 mp->integ_alg = integ_alg;
12849 mp->dh_group = dh_group;
12850
12851 S (mp);
12852 W (ret);
12853 return ret;
12854}
12855
12856
12857static int
12858api_ikev2_set_esp_transforms (vat_main_t * vam)
12859{
12860 unformat_input_t *i = vam->input;
12861 vl_api_ikev2_set_esp_transforms_t *mp;
12862 int ret;
12863 u8 *name = 0;
12864 u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
12865
12866 const char *valid_chars = "a-zA-Z0-9_";
12867
12868 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12869 {
12870 if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
12871 &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
12872 vec_add1 (name, 0);
12873 else
12874 {
12875 errmsg ("parse error '%U'", format_unformat_error, i);
12876 return -99;
12877 }
12878 }
12879
12880 if (!vec_len (name))
12881 {
12882 errmsg ("profile name must be specified");
12883 return -99;
12884 }
12885
12886 if (vec_len (name) > 64)
12887 {
12888 errmsg ("profile name too long");
12889 return -99;
12890 }
12891
12892 M (IKEV2_SET_ESP_TRANSFORMS, mp);
12893
12894 clib_memcpy (mp->name, name, vec_len (name));
12895 vec_free (name);
12896 mp->crypto_alg = crypto_alg;
12897 mp->crypto_key_size = crypto_key_size;
12898 mp->integ_alg = integ_alg;
12899 mp->dh_group = dh_group;
12900
12901 S (mp);
12902 W (ret);
12903 return ret;
12904}
12905
12906static int
12907api_ikev2_set_sa_lifetime (vat_main_t * vam)
12908{
12909 unformat_input_t *i = vam->input;
12910 vl_api_ikev2_set_sa_lifetime_t *mp;
12911 int ret;
12912 u8 *name = 0;
12913 u64 lifetime, lifetime_maxdata;
12914 u32 lifetime_jitter, handover;
12915
12916 const char *valid_chars = "a-zA-Z0-9_";
12917
12918 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12919 {
12920 if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
12921 &lifetime, &lifetime_jitter, &handover,
12922 &lifetime_maxdata))
12923 vec_add1 (name, 0);
12924 else
12925 {
12926 errmsg ("parse error '%U'", format_unformat_error, i);
12927 return -99;
12928 }
12929 }
12930
12931 if (!vec_len (name))
12932 {
12933 errmsg ("profile name must be specified");
12934 return -99;
12935 }
12936
12937 if (vec_len (name) > 64)
12938 {
12939 errmsg ("profile name too long");
12940 return -99;
12941 }
12942
12943 M (IKEV2_SET_SA_LIFETIME, mp);
12944
12945 clib_memcpy (mp->name, name, vec_len (name));
12946 vec_free (name);
12947 mp->lifetime = lifetime;
12948 mp->lifetime_jitter = lifetime_jitter;
12949 mp->handover = handover;
12950 mp->lifetime_maxdata = lifetime_maxdata;
12951
12952 S (mp);
12953 W (ret);
12954 return ret;
12955}
12956
12957static int
12958api_ikev2_initiate_sa_init (vat_main_t * vam)
12959{
12960 unformat_input_t *i = vam->input;
12961 vl_api_ikev2_initiate_sa_init_t *mp;
12962 int ret;
12963 u8 *name = 0;
12964
12965 const char *valid_chars = "a-zA-Z0-9_";
12966
12967 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12968 {
12969 if (unformat (i, "%U", unformat_token, valid_chars, &name))
12970 vec_add1 (name, 0);
12971 else
12972 {
12973 errmsg ("parse error '%U'", format_unformat_error, i);
12974 return -99;
12975 }
12976 }
12977
12978 if (!vec_len (name))
12979 {
12980 errmsg ("profile name must be specified");
12981 return -99;
12982 }
12983
12984 if (vec_len (name) > 64)
12985 {
12986 errmsg ("profile name too long");
12987 return -99;
12988 }
12989
12990 M (IKEV2_INITIATE_SA_INIT, mp);
12991
12992 clib_memcpy (mp->name, name, vec_len (name));
12993 vec_free (name);
12994
12995 S (mp);
12996 W (ret);
12997 return ret;
12998}
12999
13000static int
13001api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
13002{
13003 unformat_input_t *i = vam->input;
13004 vl_api_ikev2_initiate_del_ike_sa_t *mp;
13005 int ret;
13006 u64 ispi;
13007
13008
13009 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13010 {
13011 if (unformat (i, "%lx", &ispi))
13012 ;
13013 else
13014 {
13015 errmsg ("parse error '%U'", format_unformat_error, i);
13016 return -99;
13017 }
13018 }
13019
13020 M (IKEV2_INITIATE_DEL_IKE_SA, mp);
13021
13022 mp->ispi = ispi;
13023
13024 S (mp);
13025 W (ret);
13026 return ret;
13027}
13028
13029static int
13030api_ikev2_initiate_del_child_sa (vat_main_t * vam)
13031{
13032 unformat_input_t *i = vam->input;
13033 vl_api_ikev2_initiate_del_child_sa_t *mp;
13034 int ret;
13035 u32 ispi;
13036
13037
13038 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13039 {
13040 if (unformat (i, "%x", &ispi))
13041 ;
13042 else
13043 {
13044 errmsg ("parse error '%U'", format_unformat_error, i);
13045 return -99;
13046 }
13047 }
13048
13049 M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
13050
13051 mp->ispi = ispi;
13052
13053 S (mp);
13054 W (ret);
13055 return ret;
13056}
13057
13058static int
13059api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
13060{
13061 unformat_input_t *i = vam->input;
13062 vl_api_ikev2_initiate_rekey_child_sa_t *mp;
13063 int ret;
13064 u32 ispi;
13065
13066
13067 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13068 {
13069 if (unformat (i, "%x", &ispi))
13070 ;
13071 else
13072 {
13073 errmsg ("parse error '%U'", format_unformat_error, i);
13074 return -99;
13075 }
13076 }
13077
13078 M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
13079
13080 mp->ispi = ispi;
13081
13082 S (mp);
13083 W (ret);
13084 return ret;
13085}
13086
Damjan Marion7cd468a2016-12-19 23:05:39 +010013087/*
13088 * MAP
13089 */
13090static int
13091api_map_add_domain (vat_main_t * vam)
13092{
13093 unformat_input_t *i = vam->input;
13094 vl_api_map_add_domain_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013095
13096 ip4_address_t ip4_prefix;
13097 ip6_address_t ip6_prefix;
13098 ip6_address_t ip6_src;
13099 u32 num_m_args = 0;
13100 u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
13101 0, psid_length = 0;
13102 u8 is_translation = 0;
13103 u32 mtu = 0;
13104 u32 ip6_src_len = 128;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013105 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013106
13107 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13108 {
13109 if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
13110 &ip4_prefix, &ip4_prefix_len))
13111 num_m_args++;
13112 else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
13113 &ip6_prefix, &ip6_prefix_len))
13114 num_m_args++;
13115 else
13116 if (unformat
13117 (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
13118 &ip6_src_len))
13119 num_m_args++;
13120 else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
13121 num_m_args++;
13122 else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
13123 num_m_args++;
13124 else if (unformat (i, "psid-offset %d", &psid_offset))
13125 num_m_args++;
13126 else if (unformat (i, "psid-len %d", &psid_length))
13127 num_m_args++;
13128 else if (unformat (i, "mtu %d", &mtu))
13129 num_m_args++;
13130 else if (unformat (i, "map-t"))
13131 is_translation = 1;
13132 else
13133 {
13134 clib_warning ("parse error '%U'", format_unformat_error, i);
13135 return -99;
13136 }
13137 }
13138
13139 if (num_m_args < 3)
13140 {
13141 errmsg ("mandatory argument(s) missing");
13142 return -99;
13143 }
13144
13145 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013146 M (MAP_ADD_DOMAIN, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013147
13148 clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
13149 mp->ip4_prefix_len = ip4_prefix_len;
13150
13151 clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
13152 mp->ip6_prefix_len = ip6_prefix_len;
13153
13154 clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
13155 mp->ip6_src_prefix_len = ip6_src_len;
13156
13157 mp->ea_bits_len = ea_bits_len;
13158 mp->psid_offset = psid_offset;
13159 mp->psid_length = psid_length;
13160 mp->is_translation = is_translation;
13161 mp->mtu = htons (mtu);
13162
13163 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013164 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013165
13166 /* Wait for a reply, return good/bad news */
Jon Loeliger56c7b012017-02-01 12:31:41 -060013167 W (ret);
13168 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013169}
13170
13171static int
13172api_map_del_domain (vat_main_t * vam)
13173{
13174 unformat_input_t *i = vam->input;
13175 vl_api_map_del_domain_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013176
13177 u32 num_m_args = 0;
13178 u32 index;
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, "index %d", &index))
13184 num_m_args++;
13185 else
13186 {
13187 clib_warning ("parse error '%U'", format_unformat_error, i);
13188 return -99;
13189 }
13190 }
13191
13192 if (num_m_args != 1)
13193 {
13194 errmsg ("mandatory argument(s) missing");
13195 return -99;
13196 }
13197
13198 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013199 M (MAP_DEL_DOMAIN, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013200
13201 mp->index = ntohl (index);
13202
13203 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013204 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013205
13206 /* Wait for a reply, return good/bad news */
Jon Loeliger56c7b012017-02-01 12:31:41 -060013207 W (ret);
13208 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013209}
13210
13211static int
13212api_map_add_del_rule (vat_main_t * vam)
13213{
13214 unformat_input_t *i = vam->input;
13215 vl_api_map_add_del_rule_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013216 u8 is_add = 1;
13217 ip6_address_t ip6_dst;
13218 u32 num_m_args = 0, index, psid = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013219 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013220
13221 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13222 {
13223 if (unformat (i, "index %d", &index))
13224 num_m_args++;
13225 else if (unformat (i, "psid %d", &psid))
13226 num_m_args++;
13227 else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
13228 num_m_args++;
13229 else if (unformat (i, "del"))
13230 {
13231 is_add = 0;
13232 }
13233 else
13234 {
13235 clib_warning ("parse error '%U'", format_unformat_error, i);
13236 return -99;
13237 }
13238 }
13239
13240 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013241 M (MAP_ADD_DEL_RULE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013242
13243 mp->index = ntohl (index);
13244 mp->is_add = is_add;
13245 clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
13246 mp->psid = ntohs (psid);
13247
13248 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013249 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013250
13251 /* Wait for a reply, return good/bad news */
Jon Loeliger56c7b012017-02-01 12:31:41 -060013252 W (ret);
13253 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013254}
13255
13256static int
13257api_map_domain_dump (vat_main_t * vam)
13258{
13259 vl_api_map_domain_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060013260 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013261 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013262
13263 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013264 M (MAP_DOMAIN_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013265
13266 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013267 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013268
13269 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060013270 M (CONTROL_PING, mp_ping);
13271 S (mp_ping);
13272
Jon Loeliger56c7b012017-02-01 12:31:41 -060013273 W (ret);
13274 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013275}
13276
13277static int
13278api_map_rule_dump (vat_main_t * vam)
13279{
13280 unformat_input_t *i = vam->input;
13281 vl_api_map_rule_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060013282 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013283 u32 domain_index = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013284 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013285
13286 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13287 {
13288 if (unformat (i, "index %u", &domain_index))
13289 ;
13290 else
13291 break;
13292 }
13293
13294 if (domain_index == ~0)
13295 {
13296 clib_warning ("parse error: domain index expected");
13297 return -99;
13298 }
13299
13300 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013301 M (MAP_RULE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013302
13303 mp->domain_index = htonl (domain_index);
13304
13305 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013306 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013307
13308 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060013309 M (CONTROL_PING, mp_ping);
13310 S (mp_ping);
13311
Jon Loeliger56c7b012017-02-01 12:31:41 -060013312 W (ret);
13313 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013314}
13315
13316static void vl_api_map_add_domain_reply_t_handler
13317 (vl_api_map_add_domain_reply_t * mp)
13318{
13319 vat_main_t *vam = &vat_main;
13320 i32 retval = ntohl (mp->retval);
13321
13322 if (vam->async_mode)
13323 {
13324 vam->async_errors += (retval < 0);
13325 }
13326 else
13327 {
13328 vam->retval = retval;
13329 vam->result_ready = 1;
13330 }
13331}
13332
13333static void vl_api_map_add_domain_reply_t_handler_json
13334 (vl_api_map_add_domain_reply_t * mp)
13335{
13336 vat_main_t *vam = &vat_main;
13337 vat_json_node_t node;
13338
13339 vat_json_init_object (&node);
13340 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
13341 vat_json_object_add_uint (&node, "index", ntohl (mp->index));
13342
13343 vat_json_print (vam->ofp, &node);
13344 vat_json_free (&node);
13345
13346 vam->retval = ntohl (mp->retval);
13347 vam->result_ready = 1;
13348}
13349
13350static int
13351api_get_first_msg_id (vat_main_t * vam)
13352{
13353 vl_api_get_first_msg_id_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013354 unformat_input_t *i = vam->input;
13355 u8 *name;
13356 u8 name_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013357 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013358
13359 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13360 {
13361 if (unformat (i, "client %s", &name))
13362 name_set = 1;
13363 else
13364 break;
13365 }
13366
13367 if (name_set == 0)
13368 {
13369 errmsg ("missing client name");
13370 return -99;
13371 }
13372 vec_add1 (name, 0);
13373
13374 if (vec_len (name) > 63)
13375 {
13376 errmsg ("client name too long");
13377 return -99;
13378 }
13379
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013380 M (GET_FIRST_MSG_ID, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013381 clib_memcpy (mp->name, name, vec_len (name));
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013382 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060013383 W (ret);
13384 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013385}
13386
13387static int
13388api_cop_interface_enable_disable (vat_main_t * vam)
13389{
13390 unformat_input_t *line_input = vam->input;
13391 vl_api_cop_interface_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013392 u32 sw_if_index = ~0;
13393 u8 enable_disable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013394 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013395
13396 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13397 {
13398 if (unformat (line_input, "disable"))
13399 enable_disable = 0;
13400 if (unformat (line_input, "enable"))
13401 enable_disable = 1;
13402 else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13403 vam, &sw_if_index))
13404 ;
13405 else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13406 ;
13407 else
13408 break;
13409 }
13410
13411 if (sw_if_index == ~0)
13412 {
13413 errmsg ("missing interface name or sw_if_index");
13414 return -99;
13415 }
13416
13417 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013418 M (COP_INTERFACE_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013419 mp->sw_if_index = ntohl (sw_if_index);
13420 mp->enable_disable = enable_disable;
13421
13422 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013423 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013424 /* Wait for the reply */
Jon Loeliger56c7b012017-02-01 12:31:41 -060013425 W (ret);
13426 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013427}
13428
13429static int
13430api_cop_whitelist_enable_disable (vat_main_t * vam)
13431{
13432 unformat_input_t *line_input = vam->input;
13433 vl_api_cop_whitelist_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013434 u32 sw_if_index = ~0;
13435 u8 ip4 = 0, ip6 = 0, default_cop = 0;
13436 u32 fib_id = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013437 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013438
13439 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13440 {
13441 if (unformat (line_input, "ip4"))
13442 ip4 = 1;
13443 else if (unformat (line_input, "ip6"))
13444 ip6 = 1;
13445 else if (unformat (line_input, "default"))
13446 default_cop = 1;
13447 else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13448 vam, &sw_if_index))
13449 ;
13450 else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13451 ;
13452 else if (unformat (line_input, "fib-id %d", &fib_id))
13453 ;
13454 else
13455 break;
13456 }
13457
13458 if (sw_if_index == ~0)
13459 {
13460 errmsg ("missing interface name or sw_if_index");
13461 return -99;
13462 }
13463
13464 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013465 M (COP_WHITELIST_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013466 mp->sw_if_index = ntohl (sw_if_index);
13467 mp->fib_id = ntohl (fib_id);
13468 mp->ip4 = ip4;
13469 mp->ip6 = ip6;
13470 mp->default_cop = default_cop;
13471
13472 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013473 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013474 /* Wait for the reply */
Jon Loeliger56c7b012017-02-01 12:31:41 -060013475 W (ret);
13476 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013477}
13478
13479static int
13480api_get_node_graph (vat_main_t * vam)
13481{
13482 vl_api_get_node_graph_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013483 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013484
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013485 M (GET_NODE_GRAPH, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013486
13487 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013488 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013489 /* Wait for the reply */
Jon Loeliger56c7b012017-02-01 12:31:41 -060013490 W (ret);
13491 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013492}
13493
13494/* *INDENT-OFF* */
13495/** Used for parsing LISP eids */
13496typedef CLIB_PACKED(struct{
13497 u8 addr[16]; /**< eid address */
13498 u32 len; /**< prefix length if IP */
13499 u8 type; /**< type of eid */
13500}) lisp_eid_vat_t;
13501/* *INDENT-ON* */
13502
13503static uword
13504unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
13505{
13506 lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
13507
13508 memset (a, 0, sizeof (a[0]));
13509
13510 if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
13511 {
13512 a->type = 0; /* ipv4 type */
13513 }
13514 else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
13515 {
13516 a->type = 1; /* ipv6 type */
13517 }
13518 else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
13519 {
13520 a->type = 2; /* mac type */
13521 }
13522 else
13523 {
13524 return 0;
13525 }
13526
13527 if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
13528 {
13529 return 0;
13530 }
13531
13532 return 1;
13533}
13534
13535static int
13536lisp_eid_size_vat (u8 type)
13537{
13538 switch (type)
13539 {
13540 case 0:
13541 return 4;
13542 case 1:
13543 return 16;
13544 case 2:
13545 return 6;
13546 }
13547 return 0;
13548}
13549
13550static void
13551lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
13552{
13553 clib_memcpy (dst, eid, lisp_eid_size_vat (type));
13554}
13555
Damjan Marion7cd468a2016-12-19 23:05:39 +010013556static int
13557api_lisp_add_del_locator_set (vat_main_t * vam)
13558{
13559 unformat_input_t *input = vam->input;
13560 vl_api_lisp_add_del_locator_set_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013561 u8 is_add = 1;
13562 u8 *locator_set_name = NULL;
13563 u8 locator_set_name_set = 0;
Filip Tehlar05a057b2017-02-01 08:50:31 +010013564 vl_api_local_locator_t locator, *locators = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013565 u32 sw_if_index, priority, weight;
13566 u32 data_len = 0;
13567
Jon Loeliger56c7b012017-02-01 12:31:41 -060013568 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013569 /* Parse args required to build the message */
13570 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13571 {
13572 if (unformat (input, "del"))
13573 {
13574 is_add = 0;
13575 }
13576 else if (unformat (input, "locator-set %s", &locator_set_name))
13577 {
13578 locator_set_name_set = 1;
13579 }
13580 else if (unformat (input, "sw_if_index %u p %u w %u",
13581 &sw_if_index, &priority, &weight))
13582 {
13583 locator.sw_if_index = htonl (sw_if_index);
13584 locator.priority = priority;
13585 locator.weight = weight;
13586 vec_add1 (locators, locator);
13587 }
13588 else
13589 if (unformat
13590 (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
13591 &sw_if_index, &priority, &weight))
13592 {
13593 locator.sw_if_index = htonl (sw_if_index);
13594 locator.priority = priority;
13595 locator.weight = weight;
13596 vec_add1 (locators, locator);
13597 }
13598 else
13599 break;
13600 }
13601
13602 if (locator_set_name_set == 0)
13603 {
13604 errmsg ("missing locator-set name");
13605 vec_free (locators);
13606 return -99;
13607 }
13608
13609 if (vec_len (locator_set_name) > 64)
13610 {
13611 errmsg ("locator-set name too long");
13612 vec_free (locator_set_name);
13613 vec_free (locators);
13614 return -99;
13615 }
13616 vec_add1 (locator_set_name, 0);
13617
Filip Tehlar05a057b2017-02-01 08:50:31 +010013618 data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013619
13620 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013621 M2 (LISP_ADD_DEL_LOCATOR_SET, mp, data_len);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013622
13623 mp->is_add = is_add;
13624 clib_memcpy (mp->locator_set_name, locator_set_name,
13625 vec_len (locator_set_name));
13626 vec_free (locator_set_name);
13627
13628 mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
13629 if (locators)
13630 clib_memcpy (mp->locators, locators, data_len);
13631 vec_free (locators);
13632
13633 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013634 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013635
13636 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060013637 W (ret);
13638 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013639}
13640
13641static int
13642api_lisp_add_del_locator (vat_main_t * vam)
13643{
13644 unformat_input_t *input = vam->input;
13645 vl_api_lisp_add_del_locator_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013646 u32 tmp_if_index = ~0;
13647 u32 sw_if_index = ~0;
13648 u8 sw_if_index_set = 0;
13649 u8 sw_if_index_if_name_set = 0;
13650 u32 priority = ~0;
13651 u8 priority_set = 0;
13652 u32 weight = ~0;
13653 u8 weight_set = 0;
13654 u8 is_add = 1;
13655 u8 *locator_set_name = NULL;
13656 u8 locator_set_name_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013657 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013658
13659 /* Parse args required to build the message */
13660 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13661 {
13662 if (unformat (input, "del"))
13663 {
13664 is_add = 0;
13665 }
13666 else if (unformat (input, "locator-set %s", &locator_set_name))
13667 {
13668 locator_set_name_set = 1;
13669 }
13670 else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
13671 &tmp_if_index))
13672 {
13673 sw_if_index_if_name_set = 1;
13674 sw_if_index = tmp_if_index;
13675 }
13676 else if (unformat (input, "sw_if_index %d", &tmp_if_index))
13677 {
13678 sw_if_index_set = 1;
13679 sw_if_index = tmp_if_index;
13680 }
13681 else if (unformat (input, "p %d", &priority))
13682 {
13683 priority_set = 1;
13684 }
13685 else if (unformat (input, "w %d", &weight))
13686 {
13687 weight_set = 1;
13688 }
13689 else
13690 break;
13691 }
13692
13693 if (locator_set_name_set == 0)
13694 {
13695 errmsg ("missing locator-set name");
13696 return -99;
13697 }
13698
13699 if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
13700 {
13701 errmsg ("missing sw_if_index");
13702 vec_free (locator_set_name);
13703 return -99;
13704 }
13705
13706 if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
13707 {
13708 errmsg ("cannot use both params interface name and sw_if_index");
13709 vec_free (locator_set_name);
13710 return -99;
13711 }
13712
13713 if (priority_set == 0)
13714 {
13715 errmsg ("missing locator-set priority");
13716 vec_free (locator_set_name);
13717 return -99;
13718 }
13719
13720 if (weight_set == 0)
13721 {
13722 errmsg ("missing locator-set weight");
13723 vec_free (locator_set_name);
13724 return -99;
13725 }
13726
13727 if (vec_len (locator_set_name) > 64)
13728 {
13729 errmsg ("locator-set name too long");
13730 vec_free (locator_set_name);
13731 return -99;
13732 }
13733 vec_add1 (locator_set_name, 0);
13734
13735 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013736 M (LISP_ADD_DEL_LOCATOR, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013737
13738 mp->is_add = is_add;
13739 mp->sw_if_index = ntohl (sw_if_index);
13740 mp->priority = priority;
13741 mp->weight = weight;
13742 clib_memcpy (mp->locator_set_name, locator_set_name,
13743 vec_len (locator_set_name));
13744 vec_free (locator_set_name);
13745
13746 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013747 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013748
13749 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060013750 W (ret);
13751 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013752}
13753
13754uword
13755unformat_hmac_key_id (unformat_input_t * input, va_list * args)
13756{
13757 u32 *key_id = va_arg (*args, u32 *);
13758 u8 *s = 0;
13759
13760 if (unformat (input, "%s", &s))
13761 {
13762 if (!strcmp ((char *) s, "sha1"))
13763 key_id[0] = HMAC_SHA_1_96;
13764 else if (!strcmp ((char *) s, "sha256"))
13765 key_id[0] = HMAC_SHA_256_128;
13766 else
13767 {
13768 clib_warning ("invalid key_id: '%s'", s);
13769 key_id[0] = HMAC_NO_KEY;
13770 }
13771 }
13772 else
13773 return 0;
13774
13775 vec_free (s);
13776 return 1;
13777}
13778
13779static int
13780api_lisp_add_del_local_eid (vat_main_t * vam)
13781{
13782 unformat_input_t *input = vam->input;
13783 vl_api_lisp_add_del_local_eid_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013784 u8 is_add = 1;
13785 u8 eid_set = 0;
13786 lisp_eid_vat_t _eid, *eid = &_eid;
13787 u8 *locator_set_name = 0;
13788 u8 locator_set_name_set = 0;
13789 u32 vni = 0;
13790 u16 key_id = 0;
13791 u8 *key = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013792 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013793
13794 /* Parse args required to build the message */
13795 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13796 {
13797 if (unformat (input, "del"))
13798 {
13799 is_add = 0;
13800 }
13801 else if (unformat (input, "vni %d", &vni))
13802 {
13803 ;
13804 }
13805 else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13806 {
13807 eid_set = 1;
13808 }
13809 else if (unformat (input, "locator-set %s", &locator_set_name))
13810 {
13811 locator_set_name_set = 1;
13812 }
13813 else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
13814 ;
13815 else if (unformat (input, "secret-key %_%v%_", &key))
13816 ;
13817 else
13818 break;
13819 }
13820
13821 if (locator_set_name_set == 0)
13822 {
13823 errmsg ("missing locator-set name");
13824 return -99;
13825 }
13826
13827 if (0 == eid_set)
13828 {
13829 errmsg ("EID address not set!");
13830 vec_free (locator_set_name);
13831 return -99;
13832 }
13833
13834 if (key && (0 == key_id))
13835 {
13836 errmsg ("invalid key_id!");
13837 return -99;
13838 }
13839
13840 if (vec_len (key) > 64)
13841 {
13842 errmsg ("key too long");
13843 vec_free (key);
13844 return -99;
13845 }
13846
13847 if (vec_len (locator_set_name) > 64)
13848 {
13849 errmsg ("locator-set name too long");
13850 vec_free (locator_set_name);
13851 return -99;
13852 }
13853 vec_add1 (locator_set_name, 0);
13854
13855 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013856 M (LISP_ADD_DEL_LOCAL_EID, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013857
13858 mp->is_add = is_add;
13859 lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13860 mp->eid_type = eid->type;
13861 mp->prefix_len = eid->len;
13862 mp->vni = clib_host_to_net_u32 (vni);
13863 mp->key_id = clib_host_to_net_u16 (key_id);
13864 clib_memcpy (mp->locator_set_name, locator_set_name,
13865 vec_len (locator_set_name));
13866 clib_memcpy (mp->key, key, vec_len (key));
13867
13868 vec_free (locator_set_name);
13869 vec_free (key);
13870
13871 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060013872 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013873
13874 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060013875 W (ret);
13876 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013877}
13878
13879/* *INDENT-OFF* */
13880/** Used for transferring locators via VPP API */
13881typedef CLIB_PACKED(struct
13882{
13883 u8 is_ip4; /**< is locator an IPv4 address? */
13884 u8 priority; /**< locator priority */
13885 u8 weight; /**< locator weight */
13886 u8 addr[16]; /**< IPv4/IPv6 address */
13887}) rloc_t;
13888/* *INDENT-ON* */
13889
13890static int
13891api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
13892{
Filip Tehlarc3af7bf2017-01-13 14:13:09 +010013893 u32 dp_table = 0, vni = 0;;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013894 unformat_input_t *input = vam->input;
13895 vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013896 u8 is_add = 1;
13897 lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
13898 lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
13899 u8 rmt_eid_set = 0, lcl_eid_set = 0;
Filip Tehlarc3af7bf2017-01-13 14:13:09 +010013900 u32 action = ~0, w;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013901 ip4_address_t rmt_rloc4, lcl_rloc4;
13902 ip6_address_t rmt_rloc6, lcl_rloc6;
Filip Tehlarc3af7bf2017-01-13 14:13:09 +010013903 vl_api_lisp_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc =
13904 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060013905 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013906
13907 memset (&rloc, 0, sizeof (rloc));
13908
13909 /* Parse args required to build the message */
13910 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13911 {
13912 if (unformat (input, "del"))
Filip Tehlarc3af7bf2017-01-13 14:13:09 +010013913 is_add = 0;
13914 else if (unformat (input, "add"))
13915 is_add = 1;
13916 else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
Damjan Marion7cd468a2016-12-19 23:05:39 +010013917 {
13918 rmt_eid_set = 1;
13919 }
Filip Tehlarc3af7bf2017-01-13 14:13:09 +010013920 else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
Damjan Marion7cd468a2016-12-19 23:05:39 +010013921 {
13922 lcl_eid_set = 1;
13923 }
Filip Tehlarc3af7bf2017-01-13 14:13:09 +010013924 else if (unformat (input, "vrf %d", &dp_table))
13925 ;
13926 else if (unformat (input, "bd %d", &dp_table))
13927 ;
13928 else if (unformat (input, "vni %d", &vni))
13929 ;
13930 else if (unformat (input, "w %d", &w))
Damjan Marion7cd468a2016-12-19 23:05:39 +010013931 {
13932 if (!curr_rloc)
13933 {
13934 errmsg ("No RLOC configured for setting priority/weight!");
13935 return -99;
13936 }
Damjan Marion7cd468a2016-12-19 23:05:39 +010013937 curr_rloc->weight = w;
13938 }
13939 else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
13940 &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
13941 {
13942 rloc.is_ip4 = 1;
13943
13944 clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
Filip Tehlarc3af7bf2017-01-13 14:13:09 +010013945 rloc.weight = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013946 vec_add1 (lcl_locs, rloc);
13947
13948 clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
13949 vec_add1 (rmt_locs, rloc);
Filip Tehlarc3af7bf2017-01-13 14:13:09 +010013950 /* weight saved in rmt loc */
Damjan Marion7cd468a2016-12-19 23:05:39 +010013951 curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13952 }
13953 else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
13954 &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
13955 {
13956 rloc.is_ip4 = 0;
13957 clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
Filip Tehlarc3af7bf2017-01-13 14:13:09 +010013958 rloc.weight = 0;
Damjan Marion7cd468a2016-12-19 23:05:39 +010013959 vec_add1 (lcl_locs, rloc);
13960
13961 clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
13962 vec_add1 (rmt_locs, rloc);
Filip Tehlarc3af7bf2017-01-13 14:13:09 +010013963 /* weight saved in rmt loc */
Damjan Marion7cd468a2016-12-19 23:05:39 +010013964 curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13965 }
13966 else if (unformat (input, "action %d", &action))
13967 {
13968 ;
13969 }
13970 else
13971 {
13972 clib_warning ("parse error '%U'", format_unformat_error, input);
13973 return -99;
13974 }
13975 }
13976
13977 if (!rmt_eid_set)
13978 {
13979 errmsg ("remote eid addresses not set");
13980 return -99;
13981 }
13982
13983 if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
13984 {
13985 errmsg ("eid types don't match");
13986 return -99;
13987 }
13988
13989 if (0 == rmt_locs && (u32) ~ 0 == action)
13990 {
13991 errmsg ("action not set for negative mapping");
13992 return -99;
13993 }
13994
13995 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060013996 M2 (LISP_GPE_ADD_DEL_FWD_ENTRY, mp,
Filip Tehlarc3af7bf2017-01-13 14:13:09 +010013997 sizeof (vl_api_lisp_gpe_locator_t) * vec_len (rmt_locs) * 2);
Damjan Marion7cd468a2016-12-19 23:05:39 +010013998
13999 mp->is_add = is_add;
14000 lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
14001 lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
14002 mp->eid_type = rmt_eid->type;
Filip Tehlarc3af7bf2017-01-13 14:13:09 +010014003 mp->dp_table = clib_host_to_net_u32 (dp_table);
14004 mp->vni = clib_host_to_net_u32 (vni);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014005 mp->rmt_len = rmt_eid->len;
14006 mp->lcl_len = lcl_eid->len;
14007 mp->action = action;
14008
14009 if (0 != rmt_locs && 0 != lcl_locs)
14010 {
Filip Tehlarc3af7bf2017-01-13 14:13:09 +010014011 mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
14012 clib_memcpy (mp->locs, lcl_locs,
14013 (sizeof (vl_api_lisp_gpe_locator_t) * vec_len (lcl_locs)));
14014
14015 u32 offset = sizeof (vl_api_lisp_gpe_locator_t) * vec_len (lcl_locs);
14016 clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
14017 (sizeof (vl_api_lisp_gpe_locator_t) * vec_len (rmt_locs)));
Damjan Marion7cd468a2016-12-19 23:05:39 +010014018 }
14019 vec_free (lcl_locs);
14020 vec_free (rmt_locs);
14021
14022 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014023 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014024
14025 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014026 W (ret);
14027 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014028}
14029
14030static int
14031api_lisp_add_del_map_server (vat_main_t * vam)
14032{
14033 unformat_input_t *input = vam->input;
14034 vl_api_lisp_add_del_map_server_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014035 u8 is_add = 1;
14036 u8 ipv4_set = 0;
14037 u8 ipv6_set = 0;
14038 ip4_address_t ipv4;
14039 ip6_address_t ipv6;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014040 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014041
14042 /* Parse args required to build the message */
14043 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14044 {
14045 if (unformat (input, "del"))
14046 {
14047 is_add = 0;
14048 }
14049 else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14050 {
14051 ipv4_set = 1;
14052 }
14053 else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14054 {
14055 ipv6_set = 1;
14056 }
14057 else
14058 break;
14059 }
14060
14061 if (ipv4_set && ipv6_set)
14062 {
14063 errmsg ("both eid v4 and v6 addresses set");
14064 return -99;
14065 }
14066
14067 if (!ipv4_set && !ipv6_set)
14068 {
14069 errmsg ("eid addresses not set");
14070 return -99;
14071 }
14072
14073 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060014074 M (LISP_ADD_DEL_MAP_SERVER, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014075
14076 mp->is_add = is_add;
14077 if (ipv6_set)
14078 {
14079 mp->is_ipv6 = 1;
14080 clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14081 }
14082 else
14083 {
14084 mp->is_ipv6 = 0;
14085 clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14086 }
14087
14088 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014089 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014090
14091 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014092 W (ret);
14093 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014094}
14095
14096static int
14097api_lisp_add_del_map_resolver (vat_main_t * vam)
14098{
14099 unformat_input_t *input = vam->input;
14100 vl_api_lisp_add_del_map_resolver_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014101 u8 is_add = 1;
14102 u8 ipv4_set = 0;
14103 u8 ipv6_set = 0;
14104 ip4_address_t ipv4;
14105 ip6_address_t ipv6;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014106 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014107
14108 /* Parse args required to build the message */
14109 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14110 {
14111 if (unformat (input, "del"))
14112 {
14113 is_add = 0;
14114 }
14115 else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14116 {
14117 ipv4_set = 1;
14118 }
14119 else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14120 {
14121 ipv6_set = 1;
14122 }
14123 else
14124 break;
14125 }
14126
14127 if (ipv4_set && ipv6_set)
14128 {
14129 errmsg ("both eid v4 and v6 addresses set");
14130 return -99;
14131 }
14132
14133 if (!ipv4_set && !ipv6_set)
14134 {
14135 errmsg ("eid addresses not set");
14136 return -99;
14137 }
14138
14139 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060014140 M (LISP_ADD_DEL_MAP_RESOLVER, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014141
14142 mp->is_add = is_add;
14143 if (ipv6_set)
14144 {
14145 mp->is_ipv6 = 1;
14146 clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14147 }
14148 else
14149 {
14150 mp->is_ipv6 = 0;
14151 clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14152 }
14153
14154 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014155 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014156
14157 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014158 W (ret);
14159 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014160}
14161
14162static int
14163api_lisp_gpe_enable_disable (vat_main_t * vam)
14164{
14165 unformat_input_t *input = vam->input;
14166 vl_api_lisp_gpe_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014167 u8 is_set = 0;
14168 u8 is_en = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014169 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014170
14171 /* Parse args required to build the message */
14172 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14173 {
14174 if (unformat (input, "enable"))
14175 {
14176 is_set = 1;
14177 is_en = 1;
14178 }
14179 else if (unformat (input, "disable"))
14180 {
14181 is_set = 1;
14182 is_en = 0;
14183 }
14184 else
14185 break;
14186 }
14187
14188 if (is_set == 0)
14189 {
14190 errmsg ("Value not set");
14191 return -99;
14192 }
14193
14194 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060014195 M (LISP_GPE_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014196
14197 mp->is_en = is_en;
14198
14199 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014200 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014201
14202 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014203 W (ret);
14204 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014205}
14206
14207static int
14208api_lisp_rloc_probe_enable_disable (vat_main_t * vam)
14209{
14210 unformat_input_t *input = vam->input;
14211 vl_api_lisp_rloc_probe_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014212 u8 is_set = 0;
14213 u8 is_en = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014214 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014215
14216 /* Parse args required to build the message */
14217 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14218 {
14219 if (unformat (input, "enable"))
14220 {
14221 is_set = 1;
14222 is_en = 1;
14223 }
14224 else if (unformat (input, "disable"))
14225 is_set = 1;
14226 else
14227 break;
14228 }
14229
14230 if (!is_set)
14231 {
14232 errmsg ("Value not set");
14233 return -99;
14234 }
14235
14236 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060014237 M (LISP_RLOC_PROBE_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014238
14239 mp->is_enabled = is_en;
14240
14241 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014242 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014243
14244 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014245 W (ret);
14246 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014247}
14248
14249static int
14250api_lisp_map_register_enable_disable (vat_main_t * vam)
14251{
14252 unformat_input_t *input = vam->input;
14253 vl_api_lisp_map_register_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014254 u8 is_set = 0;
14255 u8 is_en = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014256 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014257
14258 /* Parse args required to build the message */
14259 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14260 {
14261 if (unformat (input, "enable"))
14262 {
14263 is_set = 1;
14264 is_en = 1;
14265 }
14266 else if (unformat (input, "disable"))
14267 is_set = 1;
14268 else
14269 break;
14270 }
14271
14272 if (!is_set)
14273 {
14274 errmsg ("Value not set");
14275 return -99;
14276 }
14277
14278 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060014279 M (LISP_MAP_REGISTER_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014280
14281 mp->is_enabled = is_en;
14282
14283 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014284 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014285
14286 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014287 W (ret);
14288 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014289}
14290
14291static int
14292api_lisp_enable_disable (vat_main_t * vam)
14293{
14294 unformat_input_t *input = vam->input;
14295 vl_api_lisp_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014296 u8 is_set = 0;
14297 u8 is_en = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014298 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014299
14300 /* Parse args required to build the message */
14301 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14302 {
14303 if (unformat (input, "enable"))
14304 {
14305 is_set = 1;
14306 is_en = 1;
14307 }
14308 else if (unformat (input, "disable"))
14309 {
14310 is_set = 1;
14311 }
14312 else
14313 break;
14314 }
14315
14316 if (!is_set)
14317 {
14318 errmsg ("Value not set");
14319 return -99;
14320 }
14321
14322 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060014323 M (LISP_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014324
14325 mp->is_en = is_en;
14326
14327 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014328 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014329
14330 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014331 W (ret);
14332 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014333}
14334
14335static int
14336api_show_lisp_map_register_state (vat_main_t * vam)
14337{
Damjan Marion7cd468a2016-12-19 23:05:39 +010014338 vl_api_show_lisp_map_register_state_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014339 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014340
Jon Loeliger8a2aea32017-01-31 13:19:40 -060014341 M (SHOW_LISP_MAP_REGISTER_STATE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014342
14343 /* send */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014344 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014345
14346 /* wait for reply */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014347 W (ret);
14348 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014349}
14350
14351static int
14352api_show_lisp_rloc_probe_state (vat_main_t * vam)
14353{
Damjan Marion7cd468a2016-12-19 23:05:39 +010014354 vl_api_show_lisp_rloc_probe_state_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014355 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014356
Jon Loeliger8a2aea32017-01-31 13:19:40 -060014357 M (SHOW_LISP_RLOC_PROBE_STATE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014358
14359 /* send */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014360 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014361
14362 /* wait for reply */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014363 W (ret);
14364 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014365}
14366
14367static int
14368api_show_lisp_map_request_mode (vat_main_t * vam)
14369{
Damjan Marion7cd468a2016-12-19 23:05:39 +010014370 vl_api_show_lisp_map_request_mode_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014371 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014372
Jon Loeliger8a2aea32017-01-31 13:19:40 -060014373 M (SHOW_LISP_MAP_REQUEST_MODE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014374
14375 /* send */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014376 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014377
14378 /* wait for reply */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014379 W (ret);
14380 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014381}
14382
14383static int
14384api_lisp_map_request_mode (vat_main_t * vam)
14385{
Damjan Marion7cd468a2016-12-19 23:05:39 +010014386 unformat_input_t *input = vam->input;
14387 vl_api_lisp_map_request_mode_t *mp;
14388 u8 mode = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014389 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014390
14391 /* Parse args required to build the message */
14392 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14393 {
14394 if (unformat (input, "dst-only"))
14395 mode = 0;
14396 else if (unformat (input, "src-dst"))
14397 mode = 1;
14398 else
14399 {
14400 errmsg ("parse error '%U'", format_unformat_error, input);
14401 return -99;
14402 }
14403 }
14404
Jon Loeliger8a2aea32017-01-31 13:19:40 -060014405 M (LISP_MAP_REQUEST_MODE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014406
14407 mp->mode = mode;
14408
14409 /* send */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014410 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014411
14412 /* wait for reply */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014413 W (ret);
14414 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014415}
14416
14417/**
14418 * Enable/disable LISP proxy ITR.
14419 *
14420 * @param vam vpp API test context
14421 * @return return code
14422 */
14423static int
14424api_lisp_pitr_set_locator_set (vat_main_t * vam)
14425{
Damjan Marion7cd468a2016-12-19 23:05:39 +010014426 u8 ls_name_set = 0;
14427 unformat_input_t *input = vam->input;
14428 vl_api_lisp_pitr_set_locator_set_t *mp;
14429 u8 is_add = 1;
14430 u8 *ls_name = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014431 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014432
14433 /* Parse args required to build the message */
14434 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14435 {
14436 if (unformat (input, "del"))
14437 is_add = 0;
14438 else if (unformat (input, "locator-set %s", &ls_name))
14439 ls_name_set = 1;
14440 else
14441 {
14442 errmsg ("parse error '%U'", format_unformat_error, input);
14443 return -99;
14444 }
14445 }
14446
14447 if (!ls_name_set)
14448 {
14449 errmsg ("locator-set name not set!");
14450 return -99;
14451 }
14452
Jon Loeliger8a2aea32017-01-31 13:19:40 -060014453 M (LISP_PITR_SET_LOCATOR_SET, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014454
14455 mp->is_add = is_add;
14456 clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
14457 vec_free (ls_name);
14458
14459 /* send */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014460 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014461
14462 /* wait for reply */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014463 W (ret);
14464 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014465}
14466
14467static int
14468api_show_lisp_pitr (vat_main_t * vam)
14469{
14470 vl_api_show_lisp_pitr_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014471 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014472
14473 if (!vam->json_output)
14474 {
14475 print (vam->ofp, "%=20s", "lisp status:");
14476 }
14477
Jon Loeliger8a2aea32017-01-31 13:19:40 -060014478 M (SHOW_LISP_PITR, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014479 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014480 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014481
14482 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014483 W (ret);
14484 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014485}
14486
14487/**
14488 * Add/delete mapping between vni and vrf
14489 */
14490static int
14491api_lisp_eid_table_add_del_map (vat_main_t * vam)
14492{
Damjan Marion7cd468a2016-12-19 23:05:39 +010014493 unformat_input_t *input = vam->input;
14494 vl_api_lisp_eid_table_add_del_map_t *mp;
14495 u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
14496 u32 vni, vrf, bd_index;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014497 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014498
14499 /* Parse args required to build the message */
14500 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14501 {
14502 if (unformat (input, "del"))
14503 is_add = 0;
14504 else if (unformat (input, "vrf %d", &vrf))
14505 vrf_set = 1;
14506 else if (unformat (input, "bd_index %d", &bd_index))
14507 bd_index_set = 1;
14508 else if (unformat (input, "vni %d", &vni))
14509 vni_set = 1;
14510 else
14511 break;
14512 }
14513
14514 if (!vni_set || (!vrf_set && !bd_index_set))
14515 {
14516 errmsg ("missing arguments!");
14517 return -99;
14518 }
14519
14520 if (vrf_set && bd_index_set)
14521 {
14522 errmsg ("error: both vrf and bd entered!");
14523 return -99;
14524 }
14525
Jon Loeliger8a2aea32017-01-31 13:19:40 -060014526 M (LISP_EID_TABLE_ADD_DEL_MAP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014527
14528 mp->is_add = is_add;
14529 mp->vni = htonl (vni);
14530 mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
14531 mp->is_l2 = bd_index_set;
14532
14533 /* send */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014534 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014535
14536 /* wait for reply */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014537 W (ret);
14538 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014539}
14540
14541uword
14542unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
14543{
14544 u32 *action = va_arg (*args, u32 *);
14545 u8 *s = 0;
14546
14547 if (unformat (input, "%s", &s))
14548 {
14549 if (!strcmp ((char *) s, "no-action"))
14550 action[0] = 0;
14551 else if (!strcmp ((char *) s, "natively-forward"))
14552 action[0] = 1;
14553 else if (!strcmp ((char *) s, "send-map-request"))
14554 action[0] = 2;
14555 else if (!strcmp ((char *) s, "drop"))
14556 action[0] = 3;
14557 else
14558 {
14559 clib_warning ("invalid action: '%s'", s);
14560 action[0] = 3;
14561 }
14562 }
14563 else
14564 return 0;
14565
14566 vec_free (s);
14567 return 1;
14568}
14569
14570/**
14571 * Add/del remote mapping to/from LISP control plane
14572 *
14573 * @param vam vpp API test context
14574 * @return return code
14575 */
14576static int
14577api_lisp_add_del_remote_mapping (vat_main_t * vam)
14578{
14579 unformat_input_t *input = vam->input;
14580 vl_api_lisp_add_del_remote_mapping_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014581 u32 vni = 0;
14582 lisp_eid_vat_t _eid, *eid = &_eid;
14583 lisp_eid_vat_t _seid, *seid = &_seid;
14584 u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
14585 u32 action = ~0, p, w, data_len;
14586 ip4_address_t rloc4;
14587 ip6_address_t rloc6;
Filip Tehlar05a057b2017-02-01 08:50:31 +010014588 vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014589 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014590
14591 memset (&rloc, 0, sizeof (rloc));
14592
14593 /* Parse args required to build the message */
14594 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14595 {
14596 if (unformat (input, "del-all"))
14597 {
14598 del_all = 1;
14599 }
14600 else if (unformat (input, "del"))
14601 {
14602 is_add = 0;
14603 }
14604 else if (unformat (input, "add"))
14605 {
14606 is_add = 1;
14607 }
14608 else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14609 {
14610 eid_set = 1;
14611 }
14612 else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
14613 {
14614 seid_set = 1;
14615 }
14616 else if (unformat (input, "vni %d", &vni))
14617 {
14618 ;
14619 }
14620 else if (unformat (input, "p %d w %d", &p, &w))
14621 {
14622 if (!curr_rloc)
14623 {
14624 errmsg ("No RLOC configured for setting priority/weight!");
14625 return -99;
14626 }
14627 curr_rloc->priority = p;
14628 curr_rloc->weight = w;
14629 }
14630 else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
14631 {
14632 rloc.is_ip4 = 1;
14633 clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
14634 vec_add1 (rlocs, rloc);
14635 curr_rloc = &rlocs[vec_len (rlocs) - 1];
14636 }
14637 else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
14638 {
14639 rloc.is_ip4 = 0;
14640 clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
14641 vec_add1 (rlocs, rloc);
14642 curr_rloc = &rlocs[vec_len (rlocs) - 1];
14643 }
14644 else if (unformat (input, "action %U",
14645 unformat_negative_mapping_action, &action))
14646 {
14647 ;
14648 }
14649 else
14650 {
14651 clib_warning ("parse error '%U'", format_unformat_error, input);
14652 return -99;
14653 }
14654 }
14655
14656 if (0 == eid_set)
14657 {
14658 errmsg ("missing params!");
14659 return -99;
14660 }
14661
14662 if (is_add && (~0 == action) && 0 == vec_len (rlocs))
14663 {
14664 errmsg ("no action set for negative map-reply!");
14665 return -99;
14666 }
14667
Filip Tehlar05a057b2017-02-01 08:50:31 +010014668 data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014669
Jon Loeliger8a2aea32017-01-31 13:19:40 -060014670 M2 (LISP_ADD_DEL_REMOTE_MAPPING, mp, data_len);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014671 mp->is_add = is_add;
14672 mp->vni = htonl (vni);
14673 mp->action = (u8) action;
14674 mp->is_src_dst = seid_set;
14675 mp->eid_len = eid->len;
14676 mp->seid_len = seid->len;
14677 mp->del_all = del_all;
14678 mp->eid_type = eid->type;
14679 lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14680 lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
14681
14682 mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
14683 clib_memcpy (mp->rlocs, rlocs, data_len);
14684 vec_free (rlocs);
14685
14686 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014687 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014688
14689 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014690 W (ret);
14691 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014692}
14693
14694/**
14695 * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
14696 * forwarding entries in data-plane accordingly.
14697 *
14698 * @param vam vpp API test context
14699 * @return return code
14700 */
14701static int
14702api_lisp_add_del_adjacency (vat_main_t * vam)
14703{
14704 unformat_input_t *input = vam->input;
14705 vl_api_lisp_add_del_adjacency_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014706 u32 vni = 0;
14707 ip4_address_t leid4, reid4;
14708 ip6_address_t leid6, reid6;
14709 u8 reid_mac[6] = { 0 };
14710 u8 leid_mac[6] = { 0 };
14711 u8 reid_type, leid_type;
14712 u32 leid_len = 0, reid_len = 0, len;
14713 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014714 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014715
14716 leid_type = reid_type = (u8) ~ 0;
14717
14718 /* Parse args required to build the message */
14719 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14720 {
14721 if (unformat (input, "del"))
14722 {
14723 is_add = 0;
14724 }
14725 else if (unformat (input, "add"))
14726 {
14727 is_add = 1;
14728 }
14729 else if (unformat (input, "reid %U/%d", unformat_ip4_address,
14730 &reid4, &len))
14731 {
14732 reid_type = 0; /* ipv4 */
14733 reid_len = len;
14734 }
14735 else if (unformat (input, "reid %U/%d", unformat_ip6_address,
14736 &reid6, &len))
14737 {
14738 reid_type = 1; /* ipv6 */
14739 reid_len = len;
14740 }
14741 else if (unformat (input, "reid %U", unformat_ethernet_address,
14742 reid_mac))
14743 {
14744 reid_type = 2; /* mac */
14745 }
14746 else if (unformat (input, "leid %U/%d", unformat_ip4_address,
14747 &leid4, &len))
14748 {
14749 leid_type = 0; /* ipv4 */
14750 leid_len = len;
14751 }
14752 else if (unformat (input, "leid %U/%d", unformat_ip6_address,
14753 &leid6, &len))
14754 {
14755 leid_type = 1; /* ipv6 */
14756 leid_len = len;
14757 }
14758 else if (unformat (input, "leid %U", unformat_ethernet_address,
14759 leid_mac))
14760 {
14761 leid_type = 2; /* mac */
14762 }
14763 else if (unformat (input, "vni %d", &vni))
14764 {
14765 ;
14766 }
14767 else
14768 {
14769 errmsg ("parse error '%U'", format_unformat_error, input);
14770 return -99;
14771 }
14772 }
14773
14774 if ((u8) ~ 0 == reid_type)
14775 {
14776 errmsg ("missing params!");
14777 return -99;
14778 }
14779
14780 if (leid_type != reid_type)
14781 {
14782 errmsg ("remote and local EIDs are of different types!");
14783 return -99;
14784 }
14785
Jon Loeliger8a2aea32017-01-31 13:19:40 -060014786 M (LISP_ADD_DEL_ADJACENCY, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014787 mp->is_add = is_add;
14788 mp->vni = htonl (vni);
14789 mp->leid_len = leid_len;
14790 mp->reid_len = reid_len;
14791 mp->eid_type = reid_type;
14792
14793 switch (mp->eid_type)
14794 {
14795 case 0:
14796 clib_memcpy (mp->leid, &leid4, sizeof (leid4));
14797 clib_memcpy (mp->reid, &reid4, sizeof (reid4));
14798 break;
14799 case 1:
14800 clib_memcpy (mp->leid, &leid6, sizeof (leid6));
14801 clib_memcpy (mp->reid, &reid6, sizeof (reid6));
14802 break;
14803 case 2:
14804 clib_memcpy (mp->leid, leid_mac, 6);
14805 clib_memcpy (mp->reid, reid_mac, 6);
14806 break;
14807 default:
14808 errmsg ("unknown EID type %d!", mp->eid_type);
14809 return 0;
14810 }
14811
14812 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014813 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014814
14815 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014816 W (ret);
14817 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014818}
14819
14820static int
14821api_lisp_gpe_add_del_iface (vat_main_t * vam)
14822{
14823 unformat_input_t *input = vam->input;
14824 vl_api_lisp_gpe_add_del_iface_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014825 u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
14826 u32 dp_table = 0, vni = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014827 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014828
14829 /* Parse args required to build the message */
14830 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14831 {
14832 if (unformat (input, "up"))
14833 {
14834 action_set = 1;
14835 is_add = 1;
14836 }
14837 else if (unformat (input, "down"))
14838 {
14839 action_set = 1;
14840 is_add = 0;
14841 }
14842 else if (unformat (input, "table_id %d", &dp_table))
14843 {
14844 dp_table_set = 1;
14845 }
14846 else if (unformat (input, "bd_id %d", &dp_table))
14847 {
14848 dp_table_set = 1;
14849 is_l2 = 1;
14850 }
14851 else if (unformat (input, "vni %d", &vni))
14852 {
14853 vni_set = 1;
14854 }
14855 else
14856 break;
14857 }
14858
14859 if (action_set == 0)
14860 {
14861 errmsg ("Action not set");
14862 return -99;
14863 }
14864 if (dp_table_set == 0 || vni_set == 0)
14865 {
14866 errmsg ("vni and dp_table must be set");
14867 return -99;
14868 }
14869
14870 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060014871 M (LISP_GPE_ADD_DEL_IFACE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014872
14873 mp->is_add = is_add;
14874 mp->dp_table = dp_table;
14875 mp->is_l2 = is_l2;
14876 mp->vni = vni;
14877
14878 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014879 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014880
14881 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014882 W (ret);
14883 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014884}
14885
14886/**
14887 * Add/del map request itr rlocs from LISP control plane and updates
14888 *
14889 * @param vam vpp API test context
14890 * @return return code
14891 */
14892static int
14893api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
14894{
14895 unformat_input_t *input = vam->input;
14896 vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014897 u8 *locator_set_name = 0;
14898 u8 locator_set_name_set = 0;
14899 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014900 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014901
14902 /* Parse args required to build the message */
14903 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14904 {
14905 if (unformat (input, "del"))
14906 {
14907 is_add = 0;
14908 }
14909 else if (unformat (input, "%_%v%_", &locator_set_name))
14910 {
14911 locator_set_name_set = 1;
14912 }
14913 else
14914 {
14915 clib_warning ("parse error '%U'", format_unformat_error, input);
14916 return -99;
14917 }
14918 }
14919
14920 if (is_add && !locator_set_name_set)
14921 {
14922 errmsg ("itr-rloc is not set!");
14923 return -99;
14924 }
14925
14926 if (is_add && vec_len (locator_set_name) > 64)
14927 {
14928 errmsg ("itr-rloc locator-set name too long");
14929 vec_free (locator_set_name);
14930 return -99;
14931 }
14932
Jon Loeliger8a2aea32017-01-31 13:19:40 -060014933 M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014934 mp->is_add = is_add;
14935 if (is_add)
14936 {
14937 clib_memcpy (mp->locator_set_name, locator_set_name,
14938 vec_len (locator_set_name));
14939 }
14940 else
14941 {
14942 memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
14943 }
14944 vec_free (locator_set_name);
14945
14946 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060014947 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010014948
14949 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060014950 W (ret);
14951 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014952}
14953
14954static int
14955api_lisp_locator_dump (vat_main_t * vam)
14956{
14957 unformat_input_t *input = vam->input;
14958 vl_api_lisp_locator_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060014959 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014960 u8 is_index_set = 0, is_name_set = 0;
14961 u8 *ls_name = 0;
14962 u32 ls_index = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060014963 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010014964
14965 /* Parse args required to build the message */
14966 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14967 {
14968 if (unformat (input, "ls_name %_%v%_", &ls_name))
14969 {
14970 is_name_set = 1;
14971 }
14972 else if (unformat (input, "ls_index %d", &ls_index))
14973 {
14974 is_index_set = 1;
14975 }
14976 else
14977 {
14978 errmsg ("parse error '%U'", format_unformat_error, input);
14979 return -99;
14980 }
14981 }
14982
14983 if (!is_index_set && !is_name_set)
14984 {
14985 errmsg ("error: expected one of index or name!");
14986 return -99;
14987 }
14988
14989 if (is_index_set && is_name_set)
14990 {
14991 errmsg ("error: only one param expected!");
14992 return -99;
14993 }
14994
14995 if (vec_len (ls_name) > 62)
14996 {
14997 errmsg ("error: locator set name too long!");
14998 return -99;
14999 }
15000
15001 if (!vam->json_output)
15002 {
15003 print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
15004 }
15005
Jon Loeliger8a2aea32017-01-31 13:19:40 -060015006 M (LISP_LOCATOR_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015007 mp->is_index_set = is_index_set;
15008
15009 if (is_index_set)
15010 mp->ls_index = clib_host_to_net_u32 (ls_index);
15011 else
15012 {
15013 vec_add1 (ls_name, 0);
15014 strncpy ((char *) mp->ls_name, (char *) ls_name,
15015 sizeof (mp->ls_name) - 1);
15016 }
15017
15018 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015019 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015020
15021 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060015022 M (CONTROL_PING, mp_ping);
15023 S (mp_ping);
15024
Damjan Marion7cd468a2016-12-19 23:05:39 +010015025 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060015026 W (ret);
15027 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015028}
15029
15030static int
15031api_lisp_locator_set_dump (vat_main_t * vam)
15032{
15033 vl_api_lisp_locator_set_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060015034 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015035 unformat_input_t *input = vam->input;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015036 u8 filter = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015037 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015038
15039 /* Parse args required to build the message */
15040 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15041 {
15042 if (unformat (input, "local"))
15043 {
15044 filter = 1;
15045 }
15046 else if (unformat (input, "remote"))
15047 {
15048 filter = 2;
15049 }
15050 else
15051 {
15052 errmsg ("parse error '%U'", format_unformat_error, input);
15053 return -99;
15054 }
15055 }
15056
15057 if (!vam->json_output)
15058 {
15059 print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
15060 }
15061
Jon Loeliger8a2aea32017-01-31 13:19:40 -060015062 M (LISP_LOCATOR_SET_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015063
15064 mp->filter = filter;
15065
15066 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015067 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015068
15069 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060015070 M (CONTROL_PING, mp_ping);
15071 S (mp_ping);
15072
Damjan Marion7cd468a2016-12-19 23:05:39 +010015073 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060015074 W (ret);
15075 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015076}
15077
15078static int
15079api_lisp_eid_table_map_dump (vat_main_t * vam)
15080{
15081 u8 is_l2 = 0;
15082 u8 mode_set = 0;
15083 unformat_input_t *input = vam->input;
15084 vl_api_lisp_eid_table_map_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060015085 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015086 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015087
15088 /* Parse args required to build the message */
15089 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15090 {
15091 if (unformat (input, "l2"))
15092 {
15093 is_l2 = 1;
15094 mode_set = 1;
15095 }
15096 else if (unformat (input, "l3"))
15097 {
15098 is_l2 = 0;
15099 mode_set = 1;
15100 }
15101 else
15102 {
15103 errmsg ("parse error '%U'", format_unformat_error, input);
15104 return -99;
15105 }
15106 }
15107
15108 if (!mode_set)
15109 {
15110 errmsg ("expected one of 'l2' or 'l3' parameter!");
15111 return -99;
15112 }
15113
15114 if (!vam->json_output)
15115 {
15116 print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
15117 }
15118
Jon Loeliger8a2aea32017-01-31 13:19:40 -060015119 M (LISP_EID_TABLE_MAP_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015120 mp->is_l2 = is_l2;
15121
15122 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015123 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015124
15125 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060015126 M (CONTROL_PING, mp_ping);
15127 S (mp_ping);
15128
Damjan Marion7cd468a2016-12-19 23:05:39 +010015129 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060015130 W (ret);
15131 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015132}
15133
15134static int
15135api_lisp_eid_table_vni_dump (vat_main_t * vam)
15136{
15137 vl_api_lisp_eid_table_vni_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060015138 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015139 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015140
15141 if (!vam->json_output)
15142 {
15143 print (vam->ofp, "VNI");
15144 }
15145
Jon Loeliger8a2aea32017-01-31 13:19:40 -060015146 M (LISP_EID_TABLE_VNI_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015147
15148 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015149 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015150
15151 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060015152 M (CONTROL_PING, mp_ping);
15153 S (mp_ping);
15154
Damjan Marion7cd468a2016-12-19 23:05:39 +010015155 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060015156 W (ret);
15157 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015158}
15159
15160static int
15161api_lisp_eid_table_dump (vat_main_t * vam)
15162{
15163 unformat_input_t *i = vam->input;
15164 vl_api_lisp_eid_table_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060015165 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015166 struct in_addr ip4;
15167 struct in6_addr ip6;
15168 u8 mac[6];
15169 u8 eid_type = ~0, eid_set = 0;
15170 u32 prefix_length = ~0, t, vni = 0;
15171 u8 filter = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015172 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015173
15174 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15175 {
15176 if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
15177 {
15178 eid_set = 1;
15179 eid_type = 0;
15180 prefix_length = t;
15181 }
15182 else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
15183 {
15184 eid_set = 1;
15185 eid_type = 1;
15186 prefix_length = t;
15187 }
15188 else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
15189 {
15190 eid_set = 1;
15191 eid_type = 2;
15192 }
15193 else if (unformat (i, "vni %d", &t))
15194 {
15195 vni = t;
15196 }
15197 else if (unformat (i, "local"))
15198 {
15199 filter = 1;
15200 }
15201 else if (unformat (i, "remote"))
15202 {
15203 filter = 2;
15204 }
15205 else
15206 {
15207 errmsg ("parse error '%U'", format_unformat_error, i);
15208 return -99;
15209 }
15210 }
15211
15212 if (!vam->json_output)
15213 {
15214 print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
15215 "type", "ls_index", "ttl", "authoritative", "key_id", "key");
15216 }
15217
Jon Loeliger8a2aea32017-01-31 13:19:40 -060015218 M (LISP_EID_TABLE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015219
15220 mp->filter = filter;
15221 if (eid_set)
15222 {
15223 mp->eid_set = 1;
15224 mp->vni = htonl (vni);
15225 mp->eid_type = eid_type;
15226 switch (eid_type)
15227 {
15228 case 0:
15229 mp->prefix_length = prefix_length;
15230 clib_memcpy (mp->eid, &ip4, sizeof (ip4));
15231 break;
15232 case 1:
15233 mp->prefix_length = prefix_length;
15234 clib_memcpy (mp->eid, &ip6, sizeof (ip6));
15235 break;
15236 case 2:
15237 clib_memcpy (mp->eid, mac, sizeof (mac));
15238 break;
15239 default:
15240 errmsg ("unknown EID type %d!", eid_type);
15241 return -99;
15242 }
15243 }
15244
15245 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015246 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015247
15248 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060015249 M (CONTROL_PING, mp_ping);
15250 S (mp_ping);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015251
15252 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060015253 W (ret);
15254 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015255}
15256
15257static int
Filip Tehlar5fae99c2017-01-18 12:57:37 +010015258api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
15259{
15260 unformat_input_t *i = vam->input;
15261 vl_api_lisp_gpe_fwd_entries_get_t *mp;
Filip Tehlar5fae99c2017-01-18 12:57:37 +010015262 u8 vni_set = 0;
15263 u32 vni = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015264 int ret;
Filip Tehlar5fae99c2017-01-18 12:57:37 +010015265
15266 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15267 {
15268 if (unformat (i, "vni %d", &vni))
15269 {
15270 vni_set = 1;
15271 }
15272 else
15273 {
15274 errmsg ("parse error '%U'", format_unformat_error, i);
15275 return -99;
15276 }
15277 }
15278
15279 if (!vni_set)
15280 {
15281 errmsg ("vni not set!");
15282 return -99;
15283 }
15284
15285 if (!vam->json_output)
15286 {
15287 print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
15288 "leid", "reid");
15289 }
15290
Jon Loeliger8a2aea32017-01-31 13:19:40 -060015291 M (LISP_GPE_FWD_ENTRIES_GET, mp);
Filip Tehlar5fae99c2017-01-18 12:57:37 +010015292 mp->vni = clib_host_to_net_u32 (vni);
15293
15294 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015295 S (mp);
Filip Tehlar5fae99c2017-01-18 12:57:37 +010015296
15297 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060015298 W (ret);
15299 return ret;
Filip Tehlar5fae99c2017-01-18 12:57:37 +010015300}
15301
15302#define vl_api_lisp_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
15303#define vl_api_lisp_gpe_fwd_entries_get_reply_t_print vl_noop_handler
15304#define vl_api_lisp_gpe_fwd_entry_path_details_t_endian vl_noop_handler
15305#define vl_api_lisp_gpe_fwd_entry_path_details_t_print vl_noop_handler
15306
15307static int
Damjan Marion7cd468a2016-12-19 23:05:39 +010015308api_lisp_adjacencies_get (vat_main_t * vam)
15309{
15310 unformat_input_t *i = vam->input;
15311 vl_api_lisp_adjacencies_get_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015312 u8 vni_set = 0;
15313 u32 vni = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015314 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015315
15316 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15317 {
15318 if (unformat (i, "vni %d", &vni))
15319 {
15320 vni_set = 1;
15321 }
15322 else
15323 {
15324 errmsg ("parse error '%U'", format_unformat_error, i);
15325 return -99;
15326 }
15327 }
15328
15329 if (!vni_set)
15330 {
15331 errmsg ("vni not set!");
15332 return -99;
15333 }
15334
15335 if (!vam->json_output)
15336 {
15337 print (vam->ofp, "%s %40s", "leid", "reid");
15338 }
15339
Jon Loeliger8a2aea32017-01-31 13:19:40 -060015340 M (LISP_ADJACENCIES_GET, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015341 mp->vni = clib_host_to_net_u32 (vni);
15342
15343 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015344 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015345
15346 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060015347 W (ret);
15348 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015349}
15350
15351static int
15352api_lisp_map_server_dump (vat_main_t * vam)
15353{
15354 vl_api_lisp_map_server_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060015355 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015356 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015357
15358 if (!vam->json_output)
15359 {
15360 print (vam->ofp, "%=20s", "Map server");
15361 }
15362
Jon Loeliger8a2aea32017-01-31 13:19:40 -060015363 M (LISP_MAP_SERVER_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015364 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015365 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015366
15367 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060015368 M (CONTROL_PING, mp_ping);
15369 S (mp_ping);
15370
Damjan Marion7cd468a2016-12-19 23:05:39 +010015371 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060015372 W (ret);
15373 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015374}
15375
15376static int
15377api_lisp_map_resolver_dump (vat_main_t * vam)
15378{
15379 vl_api_lisp_map_resolver_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060015380 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015381 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015382
15383 if (!vam->json_output)
15384 {
15385 print (vam->ofp, "%=20s", "Map resolver");
15386 }
15387
Jon Loeliger8a2aea32017-01-31 13:19:40 -060015388 M (LISP_MAP_RESOLVER_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015389 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015390 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015391
15392 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060015393 M (CONTROL_PING, mp_ping);
15394 S (mp_ping);
15395
Damjan Marion7cd468a2016-12-19 23:05:39 +010015396 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060015397 W (ret);
15398 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015399}
15400
15401static int
15402api_show_lisp_status (vat_main_t * vam)
15403{
15404 vl_api_show_lisp_status_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015405 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015406
15407 if (!vam->json_output)
15408 {
15409 print (vam->ofp, "%-20s%-16s", "lisp status", "locator-set");
15410 }
15411
Jon Loeliger8a2aea32017-01-31 13:19:40 -060015412 M (SHOW_LISP_STATUS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015413 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015414 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015415 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060015416 W (ret);
15417 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015418}
15419
15420static int
Filip Tehlar5fae99c2017-01-18 12:57:37 +010015421api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
15422{
15423 vl_api_lisp_gpe_fwd_entry_path_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060015424 vl_api_control_ping_t *mp_ping;
Filip Tehlar5fae99c2017-01-18 12:57:37 +010015425 unformat_input_t *i = vam->input;
15426 u32 fwd_entry_index = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015427 int ret;
Filip Tehlar5fae99c2017-01-18 12:57:37 +010015428
15429 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15430 {
15431 if (unformat (i, "index %d", &fwd_entry_index))
15432 ;
15433 else
15434 break;
15435 }
15436
15437 if (~0 == fwd_entry_index)
15438 {
15439 errmsg ("no index specified!");
15440 return -99;
15441 }
15442
15443 if (!vam->json_output)
15444 {
15445 print (vam->ofp, "first line");
15446 }
15447
Jon Loeliger8a2aea32017-01-31 13:19:40 -060015448 M (LISP_GPE_FWD_ENTRY_PATH_DUMP, mp);
Filip Tehlar5fae99c2017-01-18 12:57:37 +010015449
15450 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015451 S (mp);
Filip Tehlar5fae99c2017-01-18 12:57:37 +010015452 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060015453 M (CONTROL_PING, mp_ping);
15454 S (mp_ping);
15455
Filip Tehlar5fae99c2017-01-18 12:57:37 +010015456 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060015457 W (ret);
15458 return ret;
Filip Tehlar5fae99c2017-01-18 12:57:37 +010015459}
15460
15461static int
Damjan Marion7cd468a2016-12-19 23:05:39 +010015462api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
15463{
15464 vl_api_lisp_get_map_request_itr_rlocs_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015465 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015466
15467 if (!vam->json_output)
15468 {
15469 print (vam->ofp, "%=20s", "itr-rlocs:");
15470 }
15471
Jon Loeliger8a2aea32017-01-31 13:19:40 -060015472 M (LISP_GET_MAP_REQUEST_ITR_RLOCS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015473 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015474 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015475 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060015476 W (ret);
15477 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015478}
15479
15480static int
15481api_af_packet_create (vat_main_t * vam)
15482{
15483 unformat_input_t *i = vam->input;
15484 vl_api_af_packet_create_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015485 u8 *host_if_name = 0;
15486 u8 hw_addr[6];
15487 u8 random_hw_addr = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015488 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015489
15490 memset (hw_addr, 0, sizeof (hw_addr));
15491
15492 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15493 {
15494 if (unformat (i, "name %s", &host_if_name))
15495 vec_add1 (host_if_name, 0);
15496 else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15497 random_hw_addr = 0;
15498 else
15499 break;
15500 }
15501
15502 if (!vec_len (host_if_name))
15503 {
15504 errmsg ("host-interface name must be specified");
15505 return -99;
15506 }
15507
15508 if (vec_len (host_if_name) > 64)
15509 {
15510 errmsg ("host-interface name too long");
15511 return -99;
15512 }
15513
Jon Loeliger8a2aea32017-01-31 13:19:40 -060015514 M (AF_PACKET_CREATE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015515
15516 clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
15517 clib_memcpy (mp->hw_addr, hw_addr, 6);
15518 mp->use_random_hw_addr = random_hw_addr;
15519 vec_free (host_if_name);
15520
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015521 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060015522 W2 (ret, fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
15523 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015524}
15525
15526static int
15527api_af_packet_delete (vat_main_t * vam)
15528{
15529 unformat_input_t *i = vam->input;
15530 vl_api_af_packet_delete_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015531 u8 *host_if_name = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015532 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015533
15534 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15535 {
15536 if (unformat (i, "name %s", &host_if_name))
15537 vec_add1 (host_if_name, 0);
15538 else
15539 break;
15540 }
15541
15542 if (!vec_len (host_if_name))
15543 {
15544 errmsg ("host-interface name must be specified");
15545 return -99;
15546 }
15547
15548 if (vec_len (host_if_name) > 64)
15549 {
15550 errmsg ("host-interface name too long");
15551 return -99;
15552 }
15553
Jon Loeliger8a2aea32017-01-31 13:19:40 -060015554 M (AF_PACKET_DELETE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015555
15556 clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
15557 vec_free (host_if_name);
15558
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015559 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060015560 W (ret);
15561 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015562}
15563
15564static int
15565api_policer_add_del (vat_main_t * vam)
15566{
15567 unformat_input_t *i = vam->input;
15568 vl_api_policer_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015569 u8 is_add = 1;
15570 u8 *name = 0;
15571 u32 cir = 0;
15572 u32 eir = 0;
15573 u64 cb = 0;
15574 u64 eb = 0;
15575 u8 rate_type = 0;
15576 u8 round_type = 0;
15577 u8 type = 0;
15578 u8 color_aware = 0;
15579 sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015580 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015581
15582 conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
15583 conform_action.dscp = 0;
15584 exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
15585 exceed_action.dscp = 0;
15586 violate_action.action_type = SSE2_QOS_ACTION_DROP;
15587 violate_action.dscp = 0;
15588
15589 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15590 {
15591 if (unformat (i, "del"))
15592 is_add = 0;
15593 else if (unformat (i, "name %s", &name))
15594 vec_add1 (name, 0);
15595 else if (unformat (i, "cir %u", &cir))
15596 ;
15597 else if (unformat (i, "eir %u", &eir))
15598 ;
15599 else if (unformat (i, "cb %u", &cb))
15600 ;
15601 else if (unformat (i, "eb %u", &eb))
15602 ;
15603 else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
15604 &rate_type))
15605 ;
15606 else if (unformat (i, "round_type %U", unformat_policer_round_type,
15607 &round_type))
15608 ;
15609 else if (unformat (i, "type %U", unformat_policer_type, &type))
15610 ;
15611 else if (unformat (i, "conform_action %U", unformat_policer_action_type,
15612 &conform_action))
15613 ;
15614 else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
15615 &exceed_action))
15616 ;
15617 else if (unformat (i, "violate_action %U", unformat_policer_action_type,
15618 &violate_action))
15619 ;
15620 else if (unformat (i, "color-aware"))
15621 color_aware = 1;
15622 else
15623 break;
15624 }
15625
15626 if (!vec_len (name))
15627 {
15628 errmsg ("policer name must be specified");
15629 return -99;
15630 }
15631
15632 if (vec_len (name) > 64)
15633 {
15634 errmsg ("policer name too long");
15635 return -99;
15636 }
15637
Jon Loeliger8a2aea32017-01-31 13:19:40 -060015638 M (POLICER_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015639
15640 clib_memcpy (mp->name, name, vec_len (name));
15641 vec_free (name);
15642 mp->is_add = is_add;
15643 mp->cir = cir;
15644 mp->eir = eir;
15645 mp->cb = cb;
15646 mp->eb = eb;
15647 mp->rate_type = rate_type;
15648 mp->round_type = round_type;
15649 mp->type = type;
15650 mp->conform_action_type = conform_action.action_type;
15651 mp->conform_dscp = conform_action.dscp;
15652 mp->exceed_action_type = exceed_action.action_type;
15653 mp->exceed_dscp = exceed_action.dscp;
15654 mp->violate_action_type = violate_action.action_type;
15655 mp->violate_dscp = violate_action.dscp;
15656 mp->color_aware = color_aware;
15657
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015658 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060015659 W (ret);
15660 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015661}
15662
15663static int
15664api_policer_dump (vat_main_t * vam)
15665{
15666 unformat_input_t *i = vam->input;
15667 vl_api_policer_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060015668 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015669 u8 *match_name = 0;
15670 u8 match_name_valid = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015671 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015672
15673 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15674 {
15675 if (unformat (i, "name %s", &match_name))
15676 {
15677 vec_add1 (match_name, 0);
15678 match_name_valid = 1;
15679 }
15680 else
15681 break;
15682 }
15683
Jon Loeliger8a2aea32017-01-31 13:19:40 -060015684 M (POLICER_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015685 mp->match_name_valid = match_name_valid;
15686 clib_memcpy (mp->match_name, match_name, vec_len (match_name));
15687 vec_free (match_name);
15688 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015689 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015690
15691 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060015692 M (CONTROL_PING, mp_ping);
15693 S (mp_ping);
15694
Damjan Marion7cd468a2016-12-19 23:05:39 +010015695 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060015696 W (ret);
15697 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015698}
15699
15700static int
15701api_policer_classify_set_interface (vat_main_t * vam)
15702{
15703 unformat_input_t *i = vam->input;
15704 vl_api_policer_classify_set_interface_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015705 u32 sw_if_index;
15706 int sw_if_index_set;
15707 u32 ip4_table_index = ~0;
15708 u32 ip6_table_index = ~0;
15709 u32 l2_table_index = ~0;
15710 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015711 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015712
15713 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15714 {
15715 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15716 sw_if_index_set = 1;
15717 else if (unformat (i, "sw_if_index %d", &sw_if_index))
15718 sw_if_index_set = 1;
15719 else if (unformat (i, "del"))
15720 is_add = 0;
15721 else if (unformat (i, "ip4-table %d", &ip4_table_index))
15722 ;
15723 else if (unformat (i, "ip6-table %d", &ip6_table_index))
15724 ;
15725 else if (unformat (i, "l2-table %d", &l2_table_index))
15726 ;
15727 else
15728 {
15729 clib_warning ("parse error '%U'", format_unformat_error, i);
15730 return -99;
15731 }
15732 }
15733
15734 if (sw_if_index_set == 0)
15735 {
15736 errmsg ("missing interface name or sw_if_index");
15737 return -99;
15738 }
15739
Jon Loeliger8a2aea32017-01-31 13:19:40 -060015740 M (POLICER_CLASSIFY_SET_INTERFACE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015741
15742 mp->sw_if_index = ntohl (sw_if_index);
15743 mp->ip4_table_index = ntohl (ip4_table_index);
15744 mp->ip6_table_index = ntohl (ip6_table_index);
15745 mp->l2_table_index = ntohl (l2_table_index);
15746 mp->is_add = is_add;
15747
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015748 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060015749 W (ret);
15750 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015751}
15752
15753static int
15754api_policer_classify_dump (vat_main_t * vam)
15755{
15756 unformat_input_t *i = vam->input;
15757 vl_api_policer_classify_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060015758 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015759 u8 type = POLICER_CLASSIFY_N_TABLES;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015760 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015761
15762 if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
15763 ;
15764 else
15765 {
15766 errmsg ("classify table type must be specified");
15767 return -99;
15768 }
15769
15770 if (!vam->json_output)
15771 {
15772 print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
15773 }
15774
Jon Loeliger8a2aea32017-01-31 13:19:40 -060015775 M (POLICER_CLASSIFY_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015776 mp->type = type;
15777 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015778 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015779
15780 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060015781 M (CONTROL_PING, mp_ping);
15782 S (mp_ping);
15783
Damjan Marion7cd468a2016-12-19 23:05:39 +010015784 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060015785 W (ret);
15786 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015787}
15788
15789static int
15790api_netmap_create (vat_main_t * vam)
15791{
15792 unformat_input_t *i = vam->input;
15793 vl_api_netmap_create_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015794 u8 *if_name = 0;
15795 u8 hw_addr[6];
15796 u8 random_hw_addr = 1;
15797 u8 is_pipe = 0;
15798 u8 is_master = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015799 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015800
15801 memset (hw_addr, 0, sizeof (hw_addr));
15802
15803 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15804 {
15805 if (unformat (i, "name %s", &if_name))
15806 vec_add1 (if_name, 0);
15807 else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15808 random_hw_addr = 0;
15809 else if (unformat (i, "pipe"))
15810 is_pipe = 1;
15811 else if (unformat (i, "master"))
15812 is_master = 1;
15813 else if (unformat (i, "slave"))
15814 is_master = 0;
15815 else
15816 break;
15817 }
15818
15819 if (!vec_len (if_name))
15820 {
15821 errmsg ("interface name must be specified");
15822 return -99;
15823 }
15824
15825 if (vec_len (if_name) > 64)
15826 {
15827 errmsg ("interface name too long");
15828 return -99;
15829 }
15830
Jon Loeliger8a2aea32017-01-31 13:19:40 -060015831 M (NETMAP_CREATE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015832
15833 clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15834 clib_memcpy (mp->hw_addr, hw_addr, 6);
15835 mp->use_random_hw_addr = random_hw_addr;
15836 mp->is_pipe = is_pipe;
15837 mp->is_master = is_master;
15838 vec_free (if_name);
15839
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015840 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060015841 W (ret);
15842 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015843}
15844
15845static int
15846api_netmap_delete (vat_main_t * vam)
15847{
15848 unformat_input_t *i = vam->input;
15849 vl_api_netmap_delete_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015850 u8 *if_name = 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", &if_name))
15856 vec_add1 (if_name, 0);
15857 else
15858 break;
15859 }
15860
15861 if (!vec_len (if_name))
15862 {
15863 errmsg ("interface name must be specified");
15864 return -99;
15865 }
15866
15867 if (vec_len (if_name) > 64)
15868 {
15869 errmsg ("interface name too long");
15870 return -99;
15871 }
15872
Jon Loeliger8a2aea32017-01-31 13:19:40 -060015873 M (NETMAP_DELETE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015874
15875 clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15876 vec_free (if_name);
15877
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015878 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060015879 W (ret);
15880 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015881}
15882
15883static void vl_api_mpls_tunnel_details_t_handler
15884 (vl_api_mpls_tunnel_details_t * mp)
15885{
15886 vat_main_t *vam = &vat_main;
15887 i32 len = mp->mt_next_hop_n_labels;
15888 i32 i;
15889
15890 print (vam->ofp, "[%d]: via %U %d labels ",
15891 mp->tunnel_index,
15892 format_ip4_address, mp->mt_next_hop,
15893 ntohl (mp->mt_next_hop_sw_if_index));
15894 for (i = 0; i < len; i++)
15895 {
15896 print (vam->ofp, "%u ", ntohl (mp->mt_next_hop_out_labels[i]));
15897 }
15898 print (vam->ofp, "");
15899}
15900
15901static void vl_api_mpls_tunnel_details_t_handler_json
15902 (vl_api_mpls_tunnel_details_t * mp)
15903{
15904 vat_main_t *vam = &vat_main;
15905 vat_json_node_t *node = NULL;
15906 struct in_addr ip4;
15907 i32 i;
15908 i32 len = mp->mt_next_hop_n_labels;
15909
15910 if (VAT_JSON_ARRAY != vam->json_tree.type)
15911 {
15912 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15913 vat_json_init_array (&vam->json_tree);
15914 }
15915 node = vat_json_array_add (&vam->json_tree);
15916
15917 vat_json_init_object (node);
15918 vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
15919 clib_memcpy (&ip4, &(mp->mt_next_hop), sizeof (ip4));
15920 vat_json_object_add_ip4 (node, "next_hop", ip4);
15921 vat_json_object_add_uint (node, "next_hop_sw_if_index",
15922 ntohl (mp->mt_next_hop_sw_if_index));
15923 vat_json_object_add_uint (node, "l2_only", ntohl (mp->mt_l2_only));
15924 vat_json_object_add_uint (node, "label_count", len);
15925 for (i = 0; i < len; i++)
15926 {
15927 vat_json_object_add_uint (node, "label",
15928 ntohl (mp->mt_next_hop_out_labels[i]));
15929 }
15930}
15931
15932static int
15933api_mpls_tunnel_dump (vat_main_t * vam)
15934{
15935 vl_api_mpls_tunnel_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060015936 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015937 i32 index = -1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060015938 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015939
15940 /* Parse args required to build the message */
15941 while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
15942 {
15943 if (!unformat (vam->input, "tunnel_index %d", &index))
15944 {
15945 index = -1;
15946 break;
15947 }
15948 }
15949
15950 print (vam->ofp, " tunnel_index %d", index);
15951
Jon Loeliger8a2aea32017-01-31 13:19:40 -060015952 M (MPLS_TUNNEL_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015953 mp->tunnel_index = htonl (index);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060015954 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010015955
15956 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060015957 M (CONTROL_PING, mp_ping);
15958 S (mp_ping);
15959
Jon Loeliger56c7b012017-02-01 12:31:41 -060015960 W (ret);
15961 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010015962}
15963
15964#define vl_api_mpls_fib_details_t_endian vl_noop_handler
15965#define vl_api_mpls_fib_details_t_print vl_noop_handler
15966
15967static void
15968vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
15969{
15970 vat_main_t *vam = &vat_main;
15971 int count = ntohl (mp->count);
15972 vl_api_fib_path2_t *fp;
15973 int i;
15974
15975 print (vam->ofp,
15976 "table-id %d, label %u, ess_bit %u",
15977 ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
15978 fp = mp->path;
15979 for (i = 0; i < count; i++)
15980 {
15981 if (fp->afi == IP46_TYPE_IP6)
15982 print (vam->ofp,
15983 " weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15984 "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15985 ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15986 fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15987 format_ip6_address, fp->next_hop);
15988 else if (fp->afi == IP46_TYPE_IP4)
15989 print (vam->ofp,
15990 " weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15991 "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15992 ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15993 fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15994 format_ip4_address, fp->next_hop);
15995 fp++;
15996 }
15997}
15998
15999static void vl_api_mpls_fib_details_t_handler_json
16000 (vl_api_mpls_fib_details_t * mp)
16001{
16002 vat_main_t *vam = &vat_main;
16003 int count = ntohl (mp->count);
16004 vat_json_node_t *node = NULL;
16005 struct in_addr ip4;
16006 struct in6_addr ip6;
16007 vl_api_fib_path2_t *fp;
16008 int i;
16009
16010 if (VAT_JSON_ARRAY != vam->json_tree.type)
16011 {
16012 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16013 vat_json_init_array (&vam->json_tree);
16014 }
16015 node = vat_json_array_add (&vam->json_tree);
16016
16017 vat_json_init_object (node);
16018 vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16019 vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
16020 vat_json_object_add_uint (node, "label", ntohl (mp->label));
16021 vat_json_object_add_uint (node, "path_count", count);
16022 fp = mp->path;
16023 for (i = 0; i < count; i++)
16024 {
16025 vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16026 vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16027 vat_json_object_add_uint (node, "is_local", fp->is_local);
16028 vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16029 vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16030 vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16031 vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16032 if (fp->afi == IP46_TYPE_IP4)
16033 {
16034 clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16035 vat_json_object_add_ip4 (node, "next_hop", ip4);
16036 }
16037 else if (fp->afi == IP46_TYPE_IP6)
16038 {
16039 clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16040 vat_json_object_add_ip6 (node, "next_hop", ip6);
16041 }
16042 }
16043}
16044
16045static int
16046api_mpls_fib_dump (vat_main_t * vam)
16047{
16048 vl_api_mpls_fib_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016049 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016050 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016051
Jon Loeliger8a2aea32017-01-31 13:19:40 -060016052 M (MPLS_FIB_DUMP, mp);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016053 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016054
16055 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016056 M (CONTROL_PING, mp_ping);
16057 S (mp_ping);
16058
Jon Loeliger56c7b012017-02-01 12:31:41 -060016059 W (ret);
16060 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016061}
16062
16063#define vl_api_ip_fib_details_t_endian vl_noop_handler
16064#define vl_api_ip_fib_details_t_print vl_noop_handler
16065
16066static void
16067vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
16068{
16069 vat_main_t *vam = &vat_main;
16070 int count = ntohl (mp->count);
16071 vl_api_fib_path_t *fp;
16072 int i;
16073
16074 print (vam->ofp,
16075 "table-id %d, prefix %U/%d",
16076 ntohl (mp->table_id), format_ip4_address, mp->address,
16077 mp->address_length);
16078 fp = mp->path;
16079 for (i = 0; i < count; i++)
16080 {
16081 if (fp->afi == IP46_TYPE_IP6)
16082 print (vam->ofp,
16083 " weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16084 "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16085 ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16086 fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16087 format_ip6_address, fp->next_hop);
16088 else if (fp->afi == IP46_TYPE_IP4)
16089 print (vam->ofp,
16090 " weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16091 "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16092 ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16093 fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16094 format_ip4_address, fp->next_hop);
16095 fp++;
16096 }
16097}
16098
16099static void vl_api_ip_fib_details_t_handler_json
16100 (vl_api_ip_fib_details_t * mp)
16101{
16102 vat_main_t *vam = &vat_main;
16103 int count = ntohl (mp->count);
16104 vat_json_node_t *node = NULL;
16105 struct in_addr ip4;
16106 struct in6_addr ip6;
16107 vl_api_fib_path_t *fp;
16108 int i;
16109
16110 if (VAT_JSON_ARRAY != vam->json_tree.type)
16111 {
16112 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16113 vat_json_init_array (&vam->json_tree);
16114 }
16115 node = vat_json_array_add (&vam->json_tree);
16116
16117 vat_json_init_object (node);
16118 vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16119 clib_memcpy (&ip4, &mp->address, sizeof (ip4));
16120 vat_json_object_add_ip4 (node, "prefix", ip4);
16121 vat_json_object_add_uint (node, "mask_length", mp->address_length);
16122 vat_json_object_add_uint (node, "path_count", count);
16123 fp = mp->path;
16124 for (i = 0; i < count; i++)
16125 {
16126 vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16127 vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16128 vat_json_object_add_uint (node, "is_local", fp->is_local);
16129 vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16130 vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16131 vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16132 vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16133 if (fp->afi == IP46_TYPE_IP4)
16134 {
16135 clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16136 vat_json_object_add_ip4 (node, "next_hop", ip4);
16137 }
16138 else if (fp->afi == IP46_TYPE_IP6)
16139 {
16140 clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16141 vat_json_object_add_ip6 (node, "next_hop", ip6);
16142 }
16143 }
16144}
16145
16146static int
16147api_ip_fib_dump (vat_main_t * vam)
16148{
16149 vl_api_ip_fib_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016150 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016151 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016152
Jon Loeliger8a2aea32017-01-31 13:19:40 -060016153 M (IP_FIB_DUMP, mp);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016154 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016155
16156 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016157 M (CONTROL_PING, mp_ping);
16158 S (mp_ping);
16159
Jon Loeliger56c7b012017-02-01 12:31:41 -060016160 W (ret);
16161 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016162}
16163
Neale Ranns5a8123b2017-01-26 01:18:23 -080016164static int
16165api_ip_mfib_dump (vat_main_t * vam)
16166{
16167 vl_api_ip_mfib_dump_t *mp;
16168 vl_api_control_ping_t *mp_ping;
16169 int ret;
16170
16171 M (IP_MFIB_DUMP, mp);
16172 S (mp);
16173
16174 /* Use a control ping for synchronization */
16175 M (CONTROL_PING, mp_ping);
16176 S (mp_ping);
16177
16178 W (ret);
16179 return ret;
16180}
16181
Damjan Marion7cd468a2016-12-19 23:05:39 +010016182static void vl_api_ip_neighbor_details_t_handler
16183 (vl_api_ip_neighbor_details_t * mp)
16184{
16185 vat_main_t *vam = &vat_main;
16186
16187 print (vam->ofp, "%c %U %U",
16188 (mp->is_static) ? 'S' : 'D',
16189 format_ethernet_address, &mp->mac_address,
16190 (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
16191 &mp->ip_address);
16192}
16193
16194static void vl_api_ip_neighbor_details_t_handler_json
16195 (vl_api_ip_neighbor_details_t * mp)
16196{
16197
16198 vat_main_t *vam = &vat_main;
16199 vat_json_node_t *node;
16200 struct in_addr ip4;
16201 struct in6_addr ip6;
16202
16203 if (VAT_JSON_ARRAY != vam->json_tree.type)
16204 {
16205 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16206 vat_json_init_array (&vam->json_tree);
16207 }
16208 node = vat_json_array_add (&vam->json_tree);
16209
16210 vat_json_init_object (node);
16211 vat_json_object_add_string_copy (node, "flag",
16212 (mp->is_static) ? (u8 *) "static" : (u8 *)
16213 "dynamic");
16214
16215 vat_json_object_add_string_copy (node, "link_layer",
16216 format (0, "%U", format_ethernet_address,
16217 &mp->mac_address));
16218
16219 if (mp->is_ipv6)
16220 {
16221 clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
16222 vat_json_object_add_ip6 (node, "ip_address", ip6);
16223 }
16224 else
16225 {
16226 clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
16227 vat_json_object_add_ip4 (node, "ip_address", ip4);
16228 }
16229}
16230
16231static int
16232api_ip_neighbor_dump (vat_main_t * vam)
16233{
16234 unformat_input_t *i = vam->input;
16235 vl_api_ip_neighbor_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016236 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016237 u8 is_ipv6 = 0;
16238 u32 sw_if_index = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016239 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016240
16241 /* Parse args required to build the message */
16242 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16243 {
16244 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16245 ;
16246 else if (unformat (i, "sw_if_index %d", &sw_if_index))
16247 ;
16248 else if (unformat (i, "ip6"))
16249 is_ipv6 = 1;
16250 else
16251 break;
16252 }
16253
16254 if (sw_if_index == ~0)
16255 {
16256 errmsg ("missing interface name or sw_if_index");
16257 return -99;
16258 }
16259
Jon Loeliger8a2aea32017-01-31 13:19:40 -060016260 M (IP_NEIGHBOR_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016261 mp->is_ipv6 = (u8) is_ipv6;
16262 mp->sw_if_index = ntohl (sw_if_index);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016263 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016264
16265 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016266 M (CONTROL_PING, mp_ping);
16267 S (mp_ping);
16268
Jon Loeliger56c7b012017-02-01 12:31:41 -060016269 W (ret);
16270 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016271}
16272
16273#define vl_api_ip6_fib_details_t_endian vl_noop_handler
16274#define vl_api_ip6_fib_details_t_print vl_noop_handler
16275
16276static void
16277vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
16278{
16279 vat_main_t *vam = &vat_main;
16280 int count = ntohl (mp->count);
16281 vl_api_fib_path_t *fp;
16282 int i;
16283
16284 print (vam->ofp,
16285 "table-id %d, prefix %U/%d",
16286 ntohl (mp->table_id), format_ip6_address, mp->address,
16287 mp->address_length);
16288 fp = mp->path;
16289 for (i = 0; i < count; i++)
16290 {
16291 if (fp->afi == IP46_TYPE_IP6)
16292 print (vam->ofp,
16293 " weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16294 "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16295 ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16296 fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16297 format_ip6_address, fp->next_hop);
16298 else if (fp->afi == IP46_TYPE_IP4)
16299 print (vam->ofp,
16300 " weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16301 "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16302 ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16303 fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16304 format_ip4_address, fp->next_hop);
16305 fp++;
16306 }
16307}
16308
16309static void vl_api_ip6_fib_details_t_handler_json
16310 (vl_api_ip6_fib_details_t * mp)
16311{
16312 vat_main_t *vam = &vat_main;
16313 int count = ntohl (mp->count);
16314 vat_json_node_t *node = NULL;
16315 struct in_addr ip4;
16316 struct in6_addr ip6;
16317 vl_api_fib_path_t *fp;
16318 int i;
16319
16320 if (VAT_JSON_ARRAY != vam->json_tree.type)
16321 {
16322 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16323 vat_json_init_array (&vam->json_tree);
16324 }
16325 node = vat_json_array_add (&vam->json_tree);
16326
16327 vat_json_init_object (node);
16328 vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16329 clib_memcpy (&ip6, &mp->address, sizeof (ip6));
16330 vat_json_object_add_ip6 (node, "prefix", ip6);
16331 vat_json_object_add_uint (node, "mask_length", mp->address_length);
16332 vat_json_object_add_uint (node, "path_count", count);
16333 fp = mp->path;
16334 for (i = 0; i < count; i++)
16335 {
16336 vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16337 vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16338 vat_json_object_add_uint (node, "is_local", fp->is_local);
16339 vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16340 vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16341 vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16342 vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16343 if (fp->afi == IP46_TYPE_IP4)
16344 {
16345 clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16346 vat_json_object_add_ip4 (node, "next_hop", ip4);
16347 }
16348 else if (fp->afi == IP46_TYPE_IP6)
16349 {
16350 clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16351 vat_json_object_add_ip6 (node, "next_hop", ip6);
16352 }
16353 }
16354}
16355
16356static int
16357api_ip6_fib_dump (vat_main_t * vam)
16358{
16359 vl_api_ip6_fib_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016360 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016361 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016362
Jon Loeliger8a2aea32017-01-31 13:19:40 -060016363 M (IP6_FIB_DUMP, mp);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016364 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016365
16366 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016367 M (CONTROL_PING, mp_ping);
16368 S (mp_ping);
16369
Jon Loeliger56c7b012017-02-01 12:31:41 -060016370 W (ret);
16371 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016372}
16373
Neale Ranns5a8123b2017-01-26 01:18:23 -080016374static int
16375api_ip6_mfib_dump (vat_main_t * vam)
16376{
16377 vl_api_ip6_mfib_dump_t *mp;
16378 vl_api_control_ping_t *mp_ping;
16379 int ret;
16380
16381 M (IP6_MFIB_DUMP, mp);
16382 S (mp);
16383
16384 /* Use a control ping for synchronization */
16385 M (CONTROL_PING, mp_ping);
16386 S (mp_ping);
16387
16388 W (ret);
16389 return ret;
16390}
16391
Damjan Marion7cd468a2016-12-19 23:05:39 +010016392int
16393api_classify_table_ids (vat_main_t * vam)
16394{
16395 vl_api_classify_table_ids_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016396 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016397
16398 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060016399 M (CLASSIFY_TABLE_IDS, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016400 mp->context = 0;
16401
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016402 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060016403 W (ret);
16404 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016405}
16406
16407int
16408api_classify_table_by_interface (vat_main_t * vam)
16409{
16410 unformat_input_t *input = vam->input;
16411 vl_api_classify_table_by_interface_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016412
16413 u32 sw_if_index = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016414 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016415 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16416 {
16417 if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16418 ;
16419 else if (unformat (input, "sw_if_index %d", &sw_if_index))
16420 ;
16421 else
16422 break;
16423 }
16424 if (sw_if_index == ~0)
16425 {
16426 errmsg ("missing interface name or sw_if_index");
16427 return -99;
16428 }
16429
16430 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060016431 M (CLASSIFY_TABLE_BY_INTERFACE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016432 mp->context = 0;
16433 mp->sw_if_index = ntohl (sw_if_index);
16434
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016435 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060016436 W (ret);
16437 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016438}
16439
16440int
16441api_classify_table_info (vat_main_t * vam)
16442{
16443 unformat_input_t *input = vam->input;
16444 vl_api_classify_table_info_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016445
16446 u32 table_id = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016447 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016448 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16449 {
16450 if (unformat (input, "table_id %d", &table_id))
16451 ;
16452 else
16453 break;
16454 }
16455 if (table_id == ~0)
16456 {
16457 errmsg ("missing table id");
16458 return -99;
16459 }
16460
16461 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060016462 M (CLASSIFY_TABLE_INFO, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016463 mp->context = 0;
16464 mp->table_id = ntohl (table_id);
16465
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016466 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060016467 W (ret);
16468 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016469}
16470
16471int
16472api_classify_session_dump (vat_main_t * vam)
16473{
16474 unformat_input_t *input = vam->input;
16475 vl_api_classify_session_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016476 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016477
16478 u32 table_id = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016479 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016480 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16481 {
16482 if (unformat (input, "table_id %d", &table_id))
16483 ;
16484 else
16485 break;
16486 }
16487 if (table_id == ~0)
16488 {
16489 errmsg ("missing table id");
16490 return -99;
16491 }
16492
16493 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060016494 M (CLASSIFY_SESSION_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016495 mp->context = 0;
16496 mp->table_id = ntohl (table_id);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016497 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016498
16499 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016500 M (CONTROL_PING, mp_ping);
16501 S (mp_ping);
16502
Jon Loeliger56c7b012017-02-01 12:31:41 -060016503 W (ret);
16504 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016505}
16506
16507static void
16508vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
16509{
16510 vat_main_t *vam = &vat_main;
16511
16512 print (vam->ofp, "collector_address %U, collector_port %d, "
16513 "src_address %U, vrf_id %d, path_mtu %u, "
16514 "template_interval %u, udp_checksum %d",
16515 format_ip4_address, mp->collector_address,
16516 ntohs (mp->collector_port),
16517 format_ip4_address, mp->src_address,
16518 ntohl (mp->vrf_id), ntohl (mp->path_mtu),
16519 ntohl (mp->template_interval), mp->udp_checksum);
16520
16521 vam->retval = 0;
16522 vam->result_ready = 1;
16523}
16524
16525static void
16526 vl_api_ipfix_exporter_details_t_handler_json
16527 (vl_api_ipfix_exporter_details_t * mp)
16528{
16529 vat_main_t *vam = &vat_main;
16530 vat_json_node_t node;
16531 struct in_addr collector_address;
16532 struct in_addr src_address;
16533
16534 vat_json_init_object (&node);
16535 clib_memcpy (&collector_address, &mp->collector_address,
16536 sizeof (collector_address));
16537 vat_json_object_add_ip4 (&node, "collector_address", collector_address);
16538 vat_json_object_add_uint (&node, "collector_port",
16539 ntohs (mp->collector_port));
16540 clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
16541 vat_json_object_add_ip4 (&node, "src_address", src_address);
16542 vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
16543 vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
16544 vat_json_object_add_uint (&node, "template_interval",
16545 ntohl (mp->template_interval));
16546 vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
16547
16548 vat_json_print (vam->ofp, &node);
16549 vat_json_free (&node);
16550 vam->retval = 0;
16551 vam->result_ready = 1;
16552}
16553
16554int
16555api_ipfix_exporter_dump (vat_main_t * vam)
16556{
16557 vl_api_ipfix_exporter_dump_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016558 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016559
16560 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060016561 M (IPFIX_EXPORTER_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016562 mp->context = 0;
16563
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016564 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060016565 W (ret);
16566 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016567}
16568
16569static int
16570api_ipfix_classify_stream_dump (vat_main_t * vam)
16571{
16572 vl_api_ipfix_classify_stream_dump_t *mp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016573 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016574
16575 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060016576 M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016577 mp->context = 0;
16578
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016579 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060016580 W (ret);
16581 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016582 /* NOTREACHED */
16583 return 0;
16584}
16585
16586static void
16587 vl_api_ipfix_classify_stream_details_t_handler
16588 (vl_api_ipfix_classify_stream_details_t * mp)
16589{
16590 vat_main_t *vam = &vat_main;
16591 print (vam->ofp, "domain_id %d, src_port %d",
16592 ntohl (mp->domain_id), ntohs (mp->src_port));
16593 vam->retval = 0;
16594 vam->result_ready = 1;
16595}
16596
16597static void
16598 vl_api_ipfix_classify_stream_details_t_handler_json
16599 (vl_api_ipfix_classify_stream_details_t * mp)
16600{
16601 vat_main_t *vam = &vat_main;
16602 vat_json_node_t node;
16603
16604 vat_json_init_object (&node);
16605 vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
16606 vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
16607
16608 vat_json_print (vam->ofp, &node);
16609 vat_json_free (&node);
16610 vam->retval = 0;
16611 vam->result_ready = 1;
16612}
16613
16614static int
16615api_ipfix_classify_table_dump (vat_main_t * vam)
16616{
16617 vl_api_ipfix_classify_table_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016618 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016619 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016620
16621 if (!vam->json_output)
16622 {
16623 print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
16624 "transport_protocol");
16625 }
16626
16627 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060016628 M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016629
16630 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016631 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016632
16633 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016634 M (CONTROL_PING, mp_ping);
16635 S (mp_ping);
16636
Jon Loeliger56c7b012017-02-01 12:31:41 -060016637 W (ret);
16638 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016639}
16640
16641static void
16642 vl_api_ipfix_classify_table_details_t_handler
16643 (vl_api_ipfix_classify_table_details_t * mp)
16644{
16645 vat_main_t *vam = &vat_main;
16646 print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
16647 mp->transport_protocol);
16648}
16649
16650static void
16651 vl_api_ipfix_classify_table_details_t_handler_json
16652 (vl_api_ipfix_classify_table_details_t * mp)
16653{
16654 vat_json_node_t *node = NULL;
16655 vat_main_t *vam = &vat_main;
16656
16657 if (VAT_JSON_ARRAY != vam->json_tree.type)
16658 {
16659 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16660 vat_json_init_array (&vam->json_tree);
16661 }
16662
16663 node = vat_json_array_add (&vam->json_tree);
16664 vat_json_init_object (node);
16665
16666 vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
16667 vat_json_object_add_uint (node, "ip_version", mp->ip_version);
16668 vat_json_object_add_uint (node, "transport_protocol",
16669 mp->transport_protocol);
16670}
16671
16672static int
16673api_sw_interface_span_enable_disable (vat_main_t * vam)
16674{
16675 unformat_input_t *i = vam->input;
16676 vl_api_sw_interface_span_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016677 u32 src_sw_if_index = ~0;
16678 u32 dst_sw_if_index = ~0;
16679 u8 state = 3;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016680 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016681
16682 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16683 {
16684 if (unformat
16685 (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
16686 ;
16687 else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
16688 ;
16689 else
16690 if (unformat
16691 (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
16692 ;
16693 else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
16694 ;
16695 else if (unformat (i, "disable"))
16696 state = 0;
16697 else if (unformat (i, "rx"))
16698 state = 1;
16699 else if (unformat (i, "tx"))
16700 state = 2;
16701 else if (unformat (i, "both"))
16702 state = 3;
16703 else
16704 break;
16705 }
16706
Jon Loeliger8a2aea32017-01-31 13:19:40 -060016707 M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016708
16709 mp->sw_if_index_from = htonl (src_sw_if_index);
16710 mp->sw_if_index_to = htonl (dst_sw_if_index);
16711 mp->state = state;
16712
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016713 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060016714 W (ret);
16715 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016716}
16717
16718static void
16719vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
16720 * mp)
16721{
16722 vat_main_t *vam = &vat_main;
16723 u8 *sw_if_from_name = 0;
16724 u8 *sw_if_to_name = 0;
16725 u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16726 u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16727 char *states[] = { "none", "rx", "tx", "both" };
16728 hash_pair_t *p;
16729
16730 /* *INDENT-OFF* */
16731 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16732 ({
16733 if ((u32) p->value[0] == sw_if_index_from)
16734 {
16735 sw_if_from_name = (u8 *)(p->key);
16736 if (sw_if_to_name)
16737 break;
16738 }
16739 if ((u32) p->value[0] == sw_if_index_to)
16740 {
16741 sw_if_to_name = (u8 *)(p->key);
16742 if (sw_if_from_name)
16743 break;
16744 }
16745 }));
16746 /* *INDENT-ON* */
16747 print (vam->ofp, "%20s => %20s (%s)",
16748 sw_if_from_name, sw_if_to_name, states[mp->state]);
16749}
16750
16751static void
16752 vl_api_sw_interface_span_details_t_handler_json
16753 (vl_api_sw_interface_span_details_t * mp)
16754{
16755 vat_main_t *vam = &vat_main;
16756 vat_json_node_t *node = NULL;
16757 u8 *sw_if_from_name = 0;
16758 u8 *sw_if_to_name = 0;
16759 u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16760 u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16761 hash_pair_t *p;
16762
16763 /* *INDENT-OFF* */
16764 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16765 ({
16766 if ((u32) p->value[0] == sw_if_index_from)
16767 {
16768 sw_if_from_name = (u8 *)(p->key);
16769 if (sw_if_to_name)
16770 break;
16771 }
16772 if ((u32) p->value[0] == sw_if_index_to)
16773 {
16774 sw_if_to_name = (u8 *)(p->key);
16775 if (sw_if_from_name)
16776 break;
16777 }
16778 }));
16779 /* *INDENT-ON* */
16780
16781 if (VAT_JSON_ARRAY != vam->json_tree.type)
16782 {
16783 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16784 vat_json_init_array (&vam->json_tree);
16785 }
16786 node = vat_json_array_add (&vam->json_tree);
16787
16788 vat_json_init_object (node);
16789 vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
16790 vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
16791 vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
Neale Ranns05b2bf22017-01-30 06:44:58 -080016792 if (0 != sw_if_to_name)
16793 {
16794 vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
16795 }
Damjan Marion7cd468a2016-12-19 23:05:39 +010016796 vat_json_object_add_uint (node, "state", mp->state);
16797}
16798
16799static int
16800api_sw_interface_span_dump (vat_main_t * vam)
16801{
16802 vl_api_sw_interface_span_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016803 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016804 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016805
Jon Loeliger8a2aea32017-01-31 13:19:40 -060016806 M (SW_INTERFACE_SPAN_DUMP, mp);
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016807 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016808
16809 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060016810 M (CONTROL_PING, mp_ping);
16811 S (mp_ping);
16812
Jon Loeliger56c7b012017-02-01 12:31:41 -060016813 W (ret);
16814 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016815}
16816
16817int
16818api_pg_create_interface (vat_main_t * vam)
16819{
16820 unformat_input_t *input = vam->input;
16821 vl_api_pg_create_interface_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016822
16823 u32 if_id = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016824 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016825 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16826 {
16827 if (unformat (input, "if_id %d", &if_id))
16828 ;
16829 else
16830 break;
16831 }
16832 if (if_id == ~0)
16833 {
16834 errmsg ("missing pg interface index");
16835 return -99;
16836 }
16837
16838 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060016839 M (PG_CREATE_INTERFACE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016840 mp->context = 0;
16841 mp->interface_id = ntohl (if_id);
16842
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016843 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060016844 W (ret);
16845 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016846}
16847
16848int
16849api_pg_capture (vat_main_t * vam)
16850{
16851 unformat_input_t *input = vam->input;
16852 vl_api_pg_capture_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016853
16854 u32 if_id = ~0;
16855 u8 enable = 1;
16856 u32 count = 1;
16857 u8 pcap_file_set = 0;
16858 u8 *pcap_file = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016859 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016860 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16861 {
16862 if (unformat (input, "if_id %d", &if_id))
16863 ;
16864 else if (unformat (input, "pcap %s", &pcap_file))
16865 pcap_file_set = 1;
16866 else if (unformat (input, "count %d", &count))
16867 ;
16868 else if (unformat (input, "disable"))
16869 enable = 0;
16870 else
16871 break;
16872 }
16873 if (if_id == ~0)
16874 {
16875 errmsg ("missing pg interface index");
16876 return -99;
16877 }
16878 if (pcap_file_set > 0)
16879 {
16880 if (vec_len (pcap_file) > 255)
16881 {
16882 errmsg ("pcap file name is too long");
16883 return -99;
16884 }
16885 }
16886
16887 u32 name_len = vec_len (pcap_file);
16888 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060016889 M (PG_CAPTURE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016890 mp->context = 0;
16891 mp->interface_id = ntohl (if_id);
16892 mp->is_enabled = enable;
16893 mp->count = ntohl (count);
16894 mp->pcap_name_length = ntohl (name_len);
16895 if (pcap_file_set != 0)
16896 {
16897 clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
16898 }
16899 vec_free (pcap_file);
16900
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016901 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060016902 W (ret);
16903 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016904}
16905
16906int
16907api_pg_enable_disable (vat_main_t * vam)
16908{
16909 unformat_input_t *input = vam->input;
16910 vl_api_pg_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016911
16912 u8 enable = 1;
16913 u8 stream_name_set = 0;
16914 u8 *stream_name = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016915 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016916 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16917 {
16918 if (unformat (input, "stream %s", &stream_name))
16919 stream_name_set = 1;
16920 else if (unformat (input, "disable"))
16921 enable = 0;
16922 else
16923 break;
16924 }
16925
16926 if (stream_name_set > 0)
16927 {
16928 if (vec_len (stream_name) > 255)
16929 {
16930 errmsg ("stream name too long");
16931 return -99;
16932 }
16933 }
16934
16935 u32 name_len = vec_len (stream_name);
16936 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060016937 M (PG_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010016938 mp->context = 0;
16939 mp->is_enabled = enable;
16940 if (stream_name_set != 0)
16941 {
16942 mp->stream_name_length = ntohl (name_len);
16943 clib_memcpy (mp->stream_name, stream_name, name_len);
16944 }
16945 vec_free (stream_name);
16946
Jon Loeliger7bc770c2017-01-31 14:03:33 -060016947 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060016948 W (ret);
16949 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016950}
16951
16952int
16953api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
16954{
16955 unformat_input_t *input = vam->input;
16956 vl_api_ip_source_and_port_range_check_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016957
16958 u16 *low_ports = 0;
16959 u16 *high_ports = 0;
16960 u16 this_low;
16961 u16 this_hi;
16962 ip4_address_t ip4_addr;
16963 ip6_address_t ip6_addr;
16964 u32 length;
16965 u32 tmp, tmp2;
16966 u8 prefix_set = 0;
16967 u32 vrf_id = ~0;
16968 u8 is_add = 1;
16969 u8 is_ipv6 = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060016970 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010016971
16972 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16973 {
16974 if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
16975 {
16976 prefix_set = 1;
16977 }
16978 else
16979 if (unformat
16980 (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
16981 {
16982 prefix_set = 1;
16983 is_ipv6 = 1;
16984 }
16985 else if (unformat (input, "vrf %d", &vrf_id))
16986 ;
16987 else if (unformat (input, "del"))
16988 is_add = 0;
16989 else if (unformat (input, "port %d", &tmp))
16990 {
16991 if (tmp == 0 || tmp > 65535)
16992 {
16993 errmsg ("port %d out of range", tmp);
16994 return -99;
16995 }
16996 this_low = tmp;
16997 this_hi = this_low + 1;
16998 vec_add1 (low_ports, this_low);
16999 vec_add1 (high_ports, this_hi);
17000 }
17001 else if (unformat (input, "range %d - %d", &tmp, &tmp2))
17002 {
17003 if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
17004 {
17005 errmsg ("incorrect range parameters");
17006 return -99;
17007 }
17008 this_low = tmp;
17009 /* Note: in debug CLI +1 is added to high before
17010 passing to real fn that does "the work"
17011 (ip_source_and_port_range_check_add_del).
17012 This fn is a wrapper around the binary API fn a
17013 control plane will call, which expects this increment
17014 to have occurred. Hence letting the binary API control
17015 plane fn do the increment for consistency between VAT
17016 and other control planes.
17017 */
17018 this_hi = tmp2;
17019 vec_add1 (low_ports, this_low);
17020 vec_add1 (high_ports, this_hi);
17021 }
17022 else
17023 break;
17024 }
17025
17026 if (prefix_set == 0)
17027 {
17028 errmsg ("<address>/<mask> not specified");
17029 return -99;
17030 }
17031
17032 if (vrf_id == ~0)
17033 {
17034 errmsg ("VRF ID required, not specified");
17035 return -99;
17036 }
17037
17038 if (vrf_id == 0)
17039 {
17040 errmsg
17041 ("VRF ID should not be default. Should be distinct VRF for this purpose.");
17042 return -99;
17043 }
17044
17045 if (vec_len (low_ports) == 0)
17046 {
17047 errmsg ("At least one port or port range required");
17048 return -99;
17049 }
17050
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017051 M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017052
17053 mp->is_add = is_add;
17054
17055 if (is_ipv6)
17056 {
17057 mp->is_ipv6 = 1;
17058 clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
17059 }
17060 else
17061 {
17062 mp->is_ipv6 = 0;
17063 clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
17064 }
17065
17066 mp->mask_length = length;
17067 mp->number_of_ranges = vec_len (low_ports);
17068
17069 clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
17070 vec_free (low_ports);
17071
17072 clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
17073 vec_free (high_ports);
17074
17075 mp->vrf_id = ntohl (vrf_id);
17076
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017077 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060017078 W (ret);
17079 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017080}
17081
17082int
17083api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
17084{
17085 unformat_input_t *input = vam->input;
17086 vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017087 u32 sw_if_index = ~0;
17088 int vrf_set = 0;
17089 u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
17090 u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
17091 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017092 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017093
17094 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17095 {
17096 if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17097 ;
17098 else if (unformat (input, "sw_if_index %d", &sw_if_index))
17099 ;
17100 else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
17101 vrf_set = 1;
17102 else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
17103 vrf_set = 1;
17104 else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
17105 vrf_set = 1;
17106 else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
17107 vrf_set = 1;
17108 else if (unformat (input, "del"))
17109 is_add = 0;
17110 else
17111 break;
17112 }
17113
17114 if (sw_if_index == ~0)
17115 {
17116 errmsg ("Interface required but not specified");
17117 return -99;
17118 }
17119
17120 if (vrf_set == 0)
17121 {
17122 errmsg ("VRF ID required but not specified");
17123 return -99;
17124 }
17125
17126 if (tcp_out_vrf_id == 0
17127 || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
17128 {
17129 errmsg
17130 ("VRF ID should not be default. Should be distinct VRF for this purpose.");
17131 return -99;
17132 }
17133
17134 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017135 M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017136
17137 mp->sw_if_index = ntohl (sw_if_index);
17138 mp->is_add = is_add;
17139 mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
17140 mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
17141 mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
17142 mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
17143
17144 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017145 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017146
17147 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060017148 W (ret);
17149 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017150}
17151
17152static int
17153api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
17154{
17155 unformat_input_t *i = vam->input;
17156 vl_api_ipsec_gre_add_del_tunnel_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017157 u32 local_sa_id = 0;
17158 u32 remote_sa_id = 0;
17159 ip4_address_t src_address;
17160 ip4_address_t dst_address;
17161 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017162 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017163
17164 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17165 {
17166 if (unformat (i, "local_sa %d", &local_sa_id))
17167 ;
17168 else if (unformat (i, "remote_sa %d", &remote_sa_id))
17169 ;
17170 else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
17171 ;
17172 else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
17173 ;
17174 else if (unformat (i, "del"))
17175 is_add = 0;
17176 else
17177 {
17178 clib_warning ("parse error '%U'", format_unformat_error, i);
17179 return -99;
17180 }
17181 }
17182
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017183 M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017184
17185 mp->local_sa_id = ntohl (local_sa_id);
17186 mp->remote_sa_id = ntohl (remote_sa_id);
17187 clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
17188 clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
17189 mp->is_add = is_add;
17190
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017191 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060017192 W (ret);
17193 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017194}
17195
17196static int
17197api_punt (vat_main_t * vam)
17198{
17199 unformat_input_t *i = vam->input;
17200 vl_api_punt_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017201 u32 ipv = ~0;
17202 u32 protocol = ~0;
17203 u32 port = ~0;
17204 int is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017205 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017206
17207 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17208 {
17209 if (unformat (i, "ip %d", &ipv))
17210 ;
17211 else if (unformat (i, "protocol %d", &protocol))
17212 ;
17213 else if (unformat (i, "port %d", &port))
17214 ;
17215 else if (unformat (i, "del"))
17216 is_add = 0;
17217 else
17218 {
17219 clib_warning ("parse error '%U'", format_unformat_error, i);
17220 return -99;
17221 }
17222 }
17223
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017224 M (PUNT, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017225
17226 mp->is_add = (u8) is_add;
17227 mp->ipv = (u8) ipv;
17228 mp->l4_protocol = (u8) protocol;
17229 mp->l4_port = htons ((u16) port);
17230
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017231 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060017232 W (ret);
17233 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017234}
17235
17236static void vl_api_ipsec_gre_tunnel_details_t_handler
17237 (vl_api_ipsec_gre_tunnel_details_t * mp)
17238{
17239 vat_main_t *vam = &vat_main;
17240
17241 print (vam->ofp, "%11d%15U%15U%14d%14d",
17242 ntohl (mp->sw_if_index),
17243 format_ip4_address, &mp->src_address,
17244 format_ip4_address, &mp->dst_address,
17245 ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
17246}
17247
17248static void vl_api_ipsec_gre_tunnel_details_t_handler_json
17249 (vl_api_ipsec_gre_tunnel_details_t * mp)
17250{
17251 vat_main_t *vam = &vat_main;
17252 vat_json_node_t *node = NULL;
17253 struct in_addr ip4;
17254
17255 if (VAT_JSON_ARRAY != vam->json_tree.type)
17256 {
17257 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17258 vat_json_init_array (&vam->json_tree);
17259 }
17260 node = vat_json_array_add (&vam->json_tree);
17261
17262 vat_json_init_object (node);
17263 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17264 clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
17265 vat_json_object_add_ip4 (node, "src_address", ip4);
17266 clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
17267 vat_json_object_add_ip4 (node, "dst_address", ip4);
17268 vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
17269 vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
17270}
17271
17272static int
17273api_ipsec_gre_tunnel_dump (vat_main_t * vam)
17274{
17275 unformat_input_t *i = vam->input;
17276 vl_api_ipsec_gre_tunnel_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060017277 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017278 u32 sw_if_index;
17279 u8 sw_if_index_set = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017280 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017281
17282 /* Parse args required to build the message */
17283 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17284 {
17285 if (unformat (i, "sw_if_index %d", &sw_if_index))
17286 sw_if_index_set = 1;
17287 else
17288 break;
17289 }
17290
17291 if (sw_if_index_set == 0)
17292 {
17293 sw_if_index = ~0;
17294 }
17295
17296 if (!vam->json_output)
17297 {
17298 print (vam->ofp, "%11s%15s%15s%14s%14s",
17299 "sw_if_index", "src_address", "dst_address",
17300 "local_sa_id", "remote_sa_id");
17301 }
17302
17303 /* Get list of gre-tunnel interfaces */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017304 M (IPSEC_GRE_TUNNEL_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017305
17306 mp->sw_if_index = htonl (sw_if_index);
17307
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017308 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017309
17310 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060017311 M (CONTROL_PING, mp_ping);
17312 S (mp_ping);
17313
Jon Loeliger56c7b012017-02-01 12:31:41 -060017314 W (ret);
17315 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017316}
17317
17318static int
17319api_delete_subif (vat_main_t * vam)
17320{
17321 unformat_input_t *i = vam->input;
17322 vl_api_delete_subif_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017323 u32 sw_if_index = ~0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017324 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017325
17326 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17327 {
17328 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17329 ;
17330 if (unformat (i, "sw_if_index %d", &sw_if_index))
17331 ;
17332 else
17333 break;
17334 }
17335
17336 if (sw_if_index == ~0)
17337 {
17338 errmsg ("missing sw_if_index");
17339 return -99;
17340 }
17341
17342 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017343 M (DELETE_SUBIF, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017344 mp->sw_if_index = ntohl (sw_if_index);
17345
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017346 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060017347 W (ret);
17348 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017349}
17350
17351#define foreach_pbb_vtr_op \
17352_("disable", L2_VTR_DISABLED) \
17353_("pop", L2_VTR_POP_2) \
17354_("push", L2_VTR_PUSH_2)
17355
17356static int
17357api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
17358{
17359 unformat_input_t *i = vam->input;
17360 vl_api_l2_interface_pbb_tag_rewrite_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017361 u32 sw_if_index = ~0, vtr_op = ~0;
17362 u16 outer_tag = ~0;
17363 u8 dmac[6], smac[6];
17364 u8 dmac_set = 0, smac_set = 0;
17365 u16 vlanid = 0;
17366 u32 sid = ~0;
17367 u32 tmp;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017368 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017369
17370 /* Shut up coverity */
17371 memset (dmac, 0, sizeof (dmac));
17372 memset (smac, 0, sizeof (smac));
17373
17374 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17375 {
17376 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17377 ;
17378 else if (unformat (i, "sw_if_index %d", &sw_if_index))
17379 ;
17380 else if (unformat (i, "vtr_op %d", &vtr_op))
17381 ;
17382#define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
17383 foreach_pbb_vtr_op
17384#undef _
17385 else if (unformat (i, "translate_pbb_stag"))
17386 {
17387 if (unformat (i, "%d", &tmp))
17388 {
17389 vtr_op = L2_VTR_TRANSLATE_2_1;
17390 outer_tag = tmp;
17391 }
17392 else
17393 {
17394 errmsg
17395 ("translate_pbb_stag operation requires outer tag definition");
17396 return -99;
17397 }
17398 }
17399 else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
17400 dmac_set++;
17401 else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
17402 smac_set++;
17403 else if (unformat (i, "sid %d", &sid))
17404 ;
17405 else if (unformat (i, "vlanid %d", &tmp))
17406 vlanid = tmp;
17407 else
17408 {
17409 clib_warning ("parse error '%U'", format_unformat_error, i);
17410 return -99;
17411 }
17412 }
17413
17414 if ((sw_if_index == ~0) || (vtr_op == ~0))
17415 {
17416 errmsg ("missing sw_if_index or vtr operation");
17417 return -99;
17418 }
17419 if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
17420 && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
17421 {
17422 errmsg
17423 ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
17424 return -99;
17425 }
17426
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017427 M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017428 mp->sw_if_index = ntohl (sw_if_index);
17429 mp->vtr_op = ntohl (vtr_op);
17430 mp->outer_tag = ntohs (outer_tag);
17431 clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
17432 clib_memcpy (mp->b_smac, smac, sizeof (smac));
17433 mp->b_vlanid = ntohs (vlanid);
17434 mp->i_sid = ntohl (sid);
17435
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017436 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060017437 W (ret);
17438 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017439}
17440
17441static int
17442api_flow_classify_set_interface (vat_main_t * vam)
17443{
17444 unformat_input_t *i = vam->input;
17445 vl_api_flow_classify_set_interface_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017446 u32 sw_if_index;
17447 int sw_if_index_set;
17448 u32 ip4_table_index = ~0;
17449 u32 ip6_table_index = ~0;
17450 u8 is_add = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017451 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017452
17453 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17454 {
17455 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17456 sw_if_index_set = 1;
17457 else if (unformat (i, "sw_if_index %d", &sw_if_index))
17458 sw_if_index_set = 1;
17459 else if (unformat (i, "del"))
17460 is_add = 0;
17461 else if (unformat (i, "ip4-table %d", &ip4_table_index))
17462 ;
17463 else if (unformat (i, "ip6-table %d", &ip6_table_index))
17464 ;
17465 else
17466 {
17467 clib_warning ("parse error '%U'", format_unformat_error, i);
17468 return -99;
17469 }
17470 }
17471
17472 if (sw_if_index_set == 0)
17473 {
17474 errmsg ("missing interface name or sw_if_index");
17475 return -99;
17476 }
17477
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017478 M (FLOW_CLASSIFY_SET_INTERFACE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017479
17480 mp->sw_if_index = ntohl (sw_if_index);
17481 mp->ip4_table_index = ntohl (ip4_table_index);
17482 mp->ip6_table_index = ntohl (ip6_table_index);
17483 mp->is_add = is_add;
17484
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017485 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060017486 W (ret);
17487 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017488}
17489
17490static int
17491api_flow_classify_dump (vat_main_t * vam)
17492{
17493 unformat_input_t *i = vam->input;
17494 vl_api_flow_classify_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060017495 vl_api_control_ping_t *mp_ping;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017496 u8 type = FLOW_CLASSIFY_N_TABLES;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017497 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017498
17499 if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
17500 ;
17501 else
17502 {
17503 errmsg ("classify table type must be specified");
17504 return -99;
17505 }
17506
17507 if (!vam->json_output)
17508 {
17509 print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17510 }
17511
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017512 M (FLOW_CLASSIFY_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017513 mp->type = type;
17514 /* send it... */
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017515 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017516
17517 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060017518 M (CONTROL_PING, mp_ping);
17519 S (mp_ping);
17520
Damjan Marion7cd468a2016-12-19 23:05:39 +010017521 /* Wait for a reply... */
Jon Loeliger56c7b012017-02-01 12:31:41 -060017522 W (ret);
17523 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017524}
17525
17526static int
17527api_feature_enable_disable (vat_main_t * vam)
17528{
17529 unformat_input_t *i = vam->input;
17530 vl_api_feature_enable_disable_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017531 u8 *arc_name = 0;
17532 u8 *feature_name = 0;
17533 u32 sw_if_index = ~0;
17534 u8 enable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017535 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017536
17537 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17538 {
17539 if (unformat (i, "arc_name %s", &arc_name))
17540 ;
17541 else if (unformat (i, "feature_name %s", &feature_name))
17542 ;
17543 else
17544 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17545 ;
17546 else if (unformat (i, "sw_if_index %d", &sw_if_index))
17547 ;
17548 else if (unformat (i, "disable"))
17549 enable = 0;
17550 else
17551 break;
17552 }
17553
17554 if (arc_name == 0)
17555 {
17556 errmsg ("missing arc name");
17557 return -99;
17558 }
17559 if (vec_len (arc_name) > 63)
17560 {
17561 errmsg ("arc name too long");
17562 }
17563
17564 if (feature_name == 0)
17565 {
17566 errmsg ("missing feature name");
17567 return -99;
17568 }
17569 if (vec_len (feature_name) > 63)
17570 {
17571 errmsg ("feature name too long");
17572 }
17573
17574 if (sw_if_index == ~0)
17575 {
17576 errmsg ("missing interface name or sw_if_index");
17577 return -99;
17578 }
17579
17580 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017581 M (FEATURE_ENABLE_DISABLE, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017582 mp->sw_if_index = ntohl (sw_if_index);
17583 mp->enable = enable;
17584 clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
17585 clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
17586 vec_free (arc_name);
17587 vec_free (feature_name);
17588
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017589 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060017590 W (ret);
17591 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017592}
17593
17594static int
17595api_sw_interface_tag_add_del (vat_main_t * vam)
17596{
17597 unformat_input_t *i = vam->input;
17598 vl_api_sw_interface_tag_add_del_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017599 u32 sw_if_index = ~0;
17600 u8 *tag = 0;
17601 u8 enable = 1;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017602 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017603
17604 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17605 {
17606 if (unformat (i, "tag %s", &tag))
17607 ;
17608 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17609 ;
17610 else if (unformat (i, "sw_if_index %d", &sw_if_index))
17611 ;
17612 else if (unformat (i, "del"))
17613 enable = 0;
17614 else
17615 break;
17616 }
17617
17618 if (sw_if_index == ~0)
17619 {
17620 errmsg ("missing interface name or sw_if_index");
17621 return -99;
17622 }
17623
17624 if (enable && (tag == 0))
17625 {
17626 errmsg ("no tag specified");
17627 return -99;
17628 }
17629
17630 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017631 M (SW_INTERFACE_TAG_ADD_DEL, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017632 mp->sw_if_index = ntohl (sw_if_index);
17633 mp->is_add = enable;
17634 if (enable)
17635 strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
17636 vec_free (tag);
17637
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017638 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060017639 W (ret);
17640 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017641}
17642
17643static void vl_api_l2_xconnect_details_t_handler
17644 (vl_api_l2_xconnect_details_t * mp)
17645{
17646 vat_main_t *vam = &vat_main;
17647
17648 print (vam->ofp, "%15d%15d",
17649 ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
17650}
17651
17652static void vl_api_l2_xconnect_details_t_handler_json
17653 (vl_api_l2_xconnect_details_t * mp)
17654{
17655 vat_main_t *vam = &vat_main;
17656 vat_json_node_t *node = NULL;
17657
17658 if (VAT_JSON_ARRAY != vam->json_tree.type)
17659 {
17660 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17661 vat_json_init_array (&vam->json_tree);
17662 }
17663 node = vat_json_array_add (&vam->json_tree);
17664
17665 vat_json_init_object (node);
17666 vat_json_object_add_uint (node, "rx_sw_if_index",
17667 ntohl (mp->rx_sw_if_index));
17668 vat_json_object_add_uint (node, "tx_sw_if_index",
17669 ntohl (mp->tx_sw_if_index));
17670}
17671
17672static int
17673api_l2_xconnect_dump (vat_main_t * vam)
17674{
17675 vl_api_l2_xconnect_dump_t *mp;
Jon Loeliger2d23eca2017-02-01 13:09:58 -060017676 vl_api_control_ping_t *mp_ping;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017677 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017678
17679 if (!vam->json_output)
17680 {
17681 print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
17682 }
17683
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017684 M (L2_XCONNECT_DUMP, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017685
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017686 S (mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017687
17688 /* Use a control ping for synchronization */
Jon Loeliger2d23eca2017-02-01 13:09:58 -060017689 M (CONTROL_PING, mp_ping);
17690 S (mp_ping);
17691
Jon Loeliger56c7b012017-02-01 12:31:41 -060017692 W (ret);
17693 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017694}
17695
17696static int
17697api_sw_interface_set_mtu (vat_main_t * vam)
17698{
17699 unformat_input_t *i = vam->input;
17700 vl_api_sw_interface_set_mtu_t *mp;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017701 u32 sw_if_index = ~0;
17702 u32 mtu = 0;
Jon Loeliger56c7b012017-02-01 12:31:41 -060017703 int ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017704
17705 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17706 {
17707 if (unformat (i, "mtu %d", &mtu))
17708 ;
17709 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17710 ;
17711 else if (unformat (i, "sw_if_index %d", &sw_if_index))
17712 ;
17713 else
17714 break;
17715 }
17716
17717 if (sw_if_index == ~0)
17718 {
17719 errmsg ("missing interface name or sw_if_index");
17720 return -99;
17721 }
17722
17723 if (mtu == 0)
17724 {
17725 errmsg ("no mtu specified");
17726 return -99;
17727 }
17728
17729 /* Construct the API message */
Jon Loeliger8a2aea32017-01-31 13:19:40 -060017730 M (SW_INTERFACE_SET_MTU, mp);
Damjan Marion7cd468a2016-12-19 23:05:39 +010017731 mp->sw_if_index = ntohl (sw_if_index);
17732 mp->mtu = ntohs ((u16) mtu);
17733
Jon Loeliger7bc770c2017-01-31 14:03:33 -060017734 S (mp);
Jon Loeliger56c7b012017-02-01 12:31:41 -060017735 W (ret);
17736 return ret;
Damjan Marion7cd468a2016-12-19 23:05:39 +010017737}
17738
17739
17740static int
17741q_or_quit (vat_main_t * vam)
17742{
17743 longjmp (vam->jump_buf, 1);
17744 return 0; /* not so much */
17745}
17746
17747static int
17748q (vat_main_t * vam)
17749{
17750 return q_or_quit (vam);
17751}
17752
17753static int
17754quit (vat_main_t * vam)
17755{
17756 return q_or_quit (vam);
17757}
17758
17759static int
17760comment (vat_main_t * vam)
17761{
17762 return 0;
17763}
17764
17765static int
17766cmd_cmp (void *a1, void *a2)
17767{
17768 u8 **c1 = a1;
17769 u8 **c2 = a2;
17770
17771 return strcmp ((char *) (c1[0]), (char *) (c2[0]));
17772}
17773
17774static int
17775help (vat_main_t * vam)
17776{
17777 u8 **cmds = 0;
17778 u8 *name = 0;
17779 hash_pair_t *p;
17780 unformat_input_t *i = vam->input;
17781 int j;
17782
17783 if (unformat (i, "%s", &name))
17784 {
17785 uword *hs;
17786
17787 vec_add1 (name, 0);
17788
17789 hs = hash_get_mem (vam->help_by_name, name);
17790 if (hs)
17791 print (vam->ofp, "usage: %s %s", name, hs[0]);
17792 else
17793 print (vam->ofp, "No such msg / command '%s'", name);
17794 vec_free (name);
17795 return 0;
17796 }
17797
17798 print (vam->ofp, "Help is available for the following:");
17799
17800 /* *INDENT-OFF* */
17801 hash_foreach_pair (p, vam->function_by_name,
17802 ({
17803 vec_add1 (cmds, (u8 *)(p->key));
17804 }));
17805 /* *INDENT-ON* */
17806
17807 vec_sort_with_function (cmds, cmd_cmp);
17808
17809 for (j = 0; j < vec_len (cmds); j++)
17810 print (vam->ofp, "%s", cmds[j]);
17811
17812 vec_free (cmds);
17813 return 0;
17814}
17815
17816static int
17817set (vat_main_t * vam)
17818{
17819 u8 *name = 0, *value = 0;
17820 unformat_input_t *i = vam->input;
17821
17822 if (unformat (i, "%s", &name))
17823 {
17824 /* The input buffer is a vector, not a string. */
17825 value = vec_dup (i->buffer);
17826 vec_delete (value, i->index, 0);
17827 /* Almost certainly has a trailing newline */
17828 if (value[vec_len (value) - 1] == '\n')
17829 value[vec_len (value) - 1] = 0;
17830 /* Make sure it's a proper string, one way or the other */
17831 vec_add1 (value, 0);
17832 (void) clib_macro_set_value (&vam->macro_main,
17833 (char *) name, (char *) value);
17834 }
17835 else
17836 errmsg ("usage: set <name> <value>");
17837
17838 vec_free (name);
17839 vec_free (value);
17840 return 0;
17841}
17842
17843static int
17844unset (vat_main_t * vam)
17845{
17846 u8 *name = 0;
17847
17848 if (unformat (vam->input, "%s", &name))
17849 if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
17850 errmsg ("unset: %s wasn't set", name);
17851 vec_free (name);
17852 return 0;
17853}
17854
17855typedef struct
17856{
17857 u8 *name;
17858 u8 *value;
17859} macro_sort_t;
17860
17861
17862static int
17863macro_sort_cmp (void *a1, void *a2)
17864{
17865 macro_sort_t *s1 = a1;
17866 macro_sort_t *s2 = a2;
17867
17868 return strcmp ((char *) (s1->name), (char *) (s2->name));
17869}
17870
17871static int
17872dump_macro_table (vat_main_t * vam)
17873{
17874 macro_sort_t *sort_me = 0, *sm;
17875 int i;
17876 hash_pair_t *p;
17877
17878 /* *INDENT-OFF* */
17879 hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
17880 ({
17881 vec_add2 (sort_me, sm, 1);
17882 sm->name = (u8 *)(p->key);
17883 sm->value = (u8 *) (p->value[0]);
17884 }));
17885 /* *INDENT-ON* */
17886
17887 vec_sort_with_function (sort_me, macro_sort_cmp);
17888
17889 if (vec_len (sort_me))
17890 print (vam->ofp, "%-15s%s", "Name", "Value");
17891 else
17892 print (vam->ofp, "The macro table is empty...");
17893
17894 for (i = 0; i < vec_len (sort_me); i++)
17895 print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
17896 return 0;
17897}
17898
17899static int
17900dump_node_table (vat_main_t * vam)
17901{
17902 int i, j;
17903 vlib_node_t *node, *next_node;
17904
17905 if (vec_len (vam->graph_nodes) == 0)
17906 {
17907 print (vam->ofp, "Node table empty, issue get_node_graph...");
17908 return 0;
17909 }
17910
17911 for (i = 0; i < vec_len (vam->graph_nodes); i++)
17912 {
17913 node = vam->graph_nodes[i];
17914 print (vam->ofp, "[%d] %s", i, node->name);
17915 for (j = 0; j < vec_len (node->next_nodes); j++)
17916 {
17917 if (node->next_nodes[j] != ~0)
17918 {
17919 next_node = vam->graph_nodes[node->next_nodes[j]];
17920 print (vam->ofp, " [%d] %s", j, next_node->name);
17921 }
17922 }
17923 }
17924 return 0;
17925}
17926
17927static int
17928value_sort_cmp (void *a1, void *a2)
17929{
17930 name_sort_t *n1 = a1;
17931 name_sort_t *n2 = a2;
17932
17933 if (n1->value < n2->value)
17934 return -1;
17935 if (n1->value > n2->value)
17936 return 1;
17937 return 0;
17938}
17939
17940
17941static int
17942dump_msg_api_table (vat_main_t * vam)
17943{
17944 api_main_t *am = &api_main;
17945 name_sort_t *nses = 0, *ns;
17946 hash_pair_t *hp;
17947 int i;
17948
17949 /* *INDENT-OFF* */
17950 hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
17951 ({
17952 vec_add2 (nses, ns, 1);
17953 ns->name = (u8 *)(hp->key);
17954 ns->value = (u32) hp->value[0];
17955 }));
17956 /* *INDENT-ON* */
17957
17958 vec_sort_with_function (nses, value_sort_cmp);
17959
17960 for (i = 0; i < vec_len (nses); i++)
17961 print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
17962 vec_free (nses);
17963 return 0;
17964}
17965
17966static int
17967get_msg_id (vat_main_t * vam)
17968{
17969 u8 *name_and_crc;
17970 u32 message_index;
17971
17972 if (unformat (vam->input, "%s", &name_and_crc))
17973 {
17974 message_index = vl_api_get_msg_index (name_and_crc);
17975 if (message_index == ~0)
17976 {
17977 print (vam->ofp, " '%s' not found", name_and_crc);
17978 return 0;
17979 }
17980 print (vam->ofp, " '%s' has message index %d",
17981 name_and_crc, message_index);
17982 return 0;
17983 }
17984 errmsg ("name_and_crc required...");
17985 return 0;
17986}
17987
17988static int
17989search_node_table (vat_main_t * vam)
17990{
17991 unformat_input_t *line_input = vam->input;
17992 u8 *node_to_find;
17993 int j;
17994 vlib_node_t *node, *next_node;
17995 uword *p;
17996
17997 if (vam->graph_node_index_by_name == 0)
17998 {
17999 print (vam->ofp, "Node table empty, issue get_node_graph...");
18000 return 0;
18001 }
18002
18003 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
18004 {
18005 if (unformat (line_input, "%s", &node_to_find))
18006 {
18007 vec_add1 (node_to_find, 0);
18008 p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
18009 if (p == 0)
18010 {
18011 print (vam->ofp, "%s not found...", node_to_find);
18012 goto out;
18013 }
18014 node = vam->graph_nodes[p[0]];
18015 print (vam->ofp, "[%d] %s", p[0], node->name);
18016 for (j = 0; j < vec_len (node->next_nodes); j++)
18017 {
18018 if (node->next_nodes[j] != ~0)
18019 {
18020 next_node = vam->graph_nodes[node->next_nodes[j]];
18021 print (vam->ofp, " [%d] %s", j, next_node->name);
18022 }
18023 }
18024 }
18025
18026 else
18027 {
18028 clib_warning ("parse error '%U'", format_unformat_error,
18029 line_input);
18030 return -99;
18031 }
18032
18033 out:
18034 vec_free (node_to_find);
18035
18036 }
18037
18038 return 0;
18039}
18040
18041
18042static int
18043script (vat_main_t * vam)
18044{
18045#if (VPP_API_TEST_BUILTIN==0)
18046 u8 *s = 0;
18047 char *save_current_file;
18048 unformat_input_t save_input;
18049 jmp_buf save_jump_buf;
18050 u32 save_line_number;
18051
18052 FILE *new_fp, *save_ifp;
18053
18054 if (unformat (vam->input, "%s", &s))
18055 {
18056 new_fp = fopen ((char *) s, "r");
18057 if (new_fp == 0)
18058 {
18059 errmsg ("Couldn't open script file %s", s);
18060 vec_free (s);
18061 return -99;
18062 }
18063 }
18064 else
18065 {
18066 errmsg ("Missing script name");
18067 return -99;
18068 }
18069
18070 clib_memcpy (&save_input, &vam->input, sizeof (save_input));
18071 clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
18072 save_ifp = vam->ifp;
18073 save_line_number = vam->input_line_number;
18074 save_current_file = (char *) vam->current_file;
18075
18076 vam->input_line_number = 0;
18077 vam->ifp = new_fp;
18078 vam->current_file = s;
18079 do_one_file (vam);
18080
18081 clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
18082 clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
18083 vam->ifp = save_ifp;
18084 vam->input_line_number = save_line_number;
18085 vam->current_file = (u8 *) save_current_file;
18086 vec_free (s);
18087
18088 return 0;
18089#else
18090 clib_warning ("use the exec command...");
18091 return -99;
18092#endif
18093}
18094
18095static int
18096echo (vat_main_t * vam)
18097{
18098 print (vam->ofp, "%v", vam->input->buffer);
18099 return 0;
18100}
18101
18102/* List of API message constructors, CLI names map to api_xxx */
18103#define foreach_vpe_api_msg \
18104_(create_loopback,"[mac <mac-addr>]") \
18105_(sw_interface_dump,"") \
18106_(sw_interface_set_flags, \
18107 "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
18108_(sw_interface_add_del_address, \
18109 "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
18110_(sw_interface_set_table, \
18111 "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]") \
18112_(sw_interface_set_mpls_enable, \
18113 "<intfc> | sw_if_index [disable | dis]") \
18114_(sw_interface_set_vpath, \
18115 "<intfc> | sw_if_index <id> enable | disable") \
18116_(sw_interface_set_vxlan_bypass, \
John Lo2b81eb82017-01-30 13:12:10 -050018117 "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010018118_(sw_interface_set_l2_xconnect, \
18119 "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
18120 "enable | disable") \
18121_(sw_interface_set_l2_bridge, \
18122 "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n" \
18123 "[shg <split-horizon-group>] [bvi]\n" \
18124 "enable | disable") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010018125_(bridge_domain_add_del, \
18126 "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n") \
18127_(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n") \
18128_(l2fib_add_del, \
18129 "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
18130_(l2_flags, \
18131 "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n") \
18132_(bridge_flags, \
18133 "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
18134_(tap_connect, \
18135 "tapname <name> mac <mac-addr> | random-mac [tag <string>]") \
18136_(tap_modify, \
18137 "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
18138_(tap_delete, \
18139 "<vpp-if-name> | sw_if_index <id>") \
18140_(sw_interface_tap_dump, "") \
18141_(ip_add_del_route, \
18142 "<addr>/<mask> via <addr> [table-id <n>]\n" \
18143 "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n" \
18144 "[weight <n>] [drop] [local] [classify <n>] [del]\n" \
18145 "[multipath] [count <n>]") \
Neale Ranns32e1c012016-11-22 17:07:28 +000018146_(ip_mroute_add_del, \
18147 "<src> <grp>/<mask> [table-id <n>]\n" \
18148 "[<intfc> | sw_if_index <id>] [local] [del]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010018149_(mpls_route_add_del, \
18150 "<label> <eos> via <addr> [table-id <n>]\n" \
18151 "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n" \
18152 "[weight <n>] [drop] [local] [classify <n>] [del]\n" \
18153 "[multipath] [count <n>]") \
18154_(mpls_ip_bind_unbind, \
18155 "<label> <addr/len>") \
18156_(mpls_tunnel_add_del, \
18157 " via <addr> [table-id <n>]\n" \
18158 "sw_if_index <id>] [l2] [del]") \
18159_(proxy_arp_add_del, \
18160 "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]") \
18161_(proxy_arp_intfc_enable_disable, \
18162 "<intfc> | sw_if_index <id> enable | disable") \
18163_(sw_interface_set_unnumbered, \
18164 "<intfc> | sw_if_index <id> unnum_if_index <id> [del]") \
18165_(ip_neighbor_add_del, \
18166 "(<intfc> | sw_if_index <id>) dst <ip46-address> " \
18167 "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]") \
18168_(reset_vrf, "vrf <id> [ipv6]") \
18169_(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>") \
18170_(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n" \
18171 "[outer_vlan_id <n>][inner_vlan_id <n>]\n" \
18172 "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n" \
18173 "[outer_vlan_id_any][inner_vlan_id_any]") \
18174_(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]") \
18175_(reset_fib, "vrf <n> [ipv6]") \
18176_(dhcp_proxy_config, \
18177 "svr <v46-address> src <v46-address>\n" \
18178 "insert-cid <n> [del]") \
18179_(dhcp_proxy_config_2, \
18180 "svr <v46-address> src <v46-address>\n" \
18181 "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]") \
18182_(dhcp_proxy_set_vss, \
18183 "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]") \
18184_(dhcp_client_config, \
18185 "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
18186_(set_ip_flow_hash, \
18187 "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]") \
18188_(sw_interface_ip6_enable_disable, \
18189 "<intfc> | sw_if_index <id> enable | disable") \
18190_(sw_interface_ip6_set_link_local_address, \
18191 "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>") \
18192_(sw_interface_ip6nd_ra_prefix, \
18193 "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n" \
18194 "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n" \
18195 "[nolink] [isno]") \
18196_(sw_interface_ip6nd_ra_config, \
18197 "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n" \
18198 "[life <n>] [count <n>] [interval <n>] [suppress]\n" \
18199 "[managed] [other] [ll] [send] [cease] [isno] [def]") \
18200_(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]") \
18201_(l2_patch_add_del, \
18202 "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
18203 "enable | disable") \
18204_(sr_tunnel_add_del, \
18205 "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n" \
18206 "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n" \
18207 "[policy <policy_name>]") \
18208_(sr_policy_add_del, \
18209 "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]") \
18210_(sr_multicast_map_add_del, \
18211 "address [ip6 multicast address] sr-policy [policy name] [del]") \
18212_(classify_add_del_table, \
18213 "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n" \
18214 " [del] [del-chain] mask <mask-value>\n" \
18215 " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n" \
18216 " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]") \
18217_(classify_add_del_session, \
18218 "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n" \
18219 " table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n" \
18220 " [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n" \
18221 " [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]") \
18222_(classify_set_interface_ip_table, \
18223 "<intfc> | sw_if_index <nn> table <nn>") \
18224_(classify_set_interface_l2_tables, \
18225 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
18226 " [other-table <nn>]") \
18227_(get_node_index, "node <node-name") \
18228_(add_node_next, "node <node-name> next <next-node-name>") \
18229_(l2tpv3_create_tunnel, \
18230 "client_address <ip6-addr> our_address <ip6-addr>\n" \
18231 "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
18232 "[remote_cookie <nn>]\n[l2-sublayer-preset]\n") \
18233_(l2tpv3_set_tunnel_cookies, \
18234 "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n" \
18235 "[new_remote_cookie <nn>]\n") \
18236_(l2tpv3_interface_enable_disable, \
18237 "<intfc> | sw_if_index <nn> enable | disable") \
18238_(l2tpv3_set_lookup_key, \
18239 "lookup_v6_src | lookup_v6_dst | lookup_session_id") \
18240_(sw_if_l2tpv3_tunnel_dump, "") \
18241_(vxlan_add_del_tunnel, \
18242 "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n" \
18243 "{ <intfc> | mcast_sw_if_index <nn> } }\n" \
18244 "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]") \
18245_(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]") \
18246_(gre_add_del_tunnel, \
18247 "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n") \
18248_(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]") \
18249_(l2_fib_clear_table, "") \
18250_(l2_interface_efp_filter, "sw_if_index <nn> enable | disable") \
18251_(l2_interface_vlan_tag_rewrite, \
18252 "<intfc> | sw_if_index <nn> \n" \
18253 "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n" \
18254 "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>") \
18255_(create_vhost_user_if, \
18256 "socket <filename> [server] [renumber <dev_instance>] " \
18257 "[mac <mac_address>]") \
18258_(modify_vhost_user_if, \
18259 "<intfc> | sw_if_index <nn> socket <filename>\n" \
18260 "[server] [renumber <dev_instance>]") \
18261_(delete_vhost_user_if, "<intfc> | sw_if_index <nn>") \
18262_(sw_interface_vhost_user_dump, "") \
18263_(show_version, "") \
18264_(vxlan_gpe_add_del_tunnel, \
18265 "local <addr> remote <addr> vni <nn>\n" \
18266 "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]" \
18267 "[next-ethernet] [next-nsh]\n") \
18268_(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]") \
18269_(l2_fib_table_dump, "bd_id <bridge-domain-id>") \
18270_(interface_name_renumber, \
18271 "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>") \
18272_(input_acl_set_interface, \
18273 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
18274 " [l2-table <nn>] [del]") \
18275_(want_ip4_arp_events, "address <ip4-address> [del]") \
18276_(want_ip6_nd_events, "address <ip6-address> [del]") \
18277_(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)") \
18278_(ip_dump, "ipv4 | ipv6") \
18279_(ipsec_spd_add_del, "spd_id <n> [del]") \
18280_(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n" \
18281 " spid_id <n> ") \
18282_(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n" \
18283 " crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n" \
18284 " integ_alg <alg> integ_key <hex>") \
18285_(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n" \
18286 " (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n" \
18287 " laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
18288 " [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
18289_(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>") \
18290_(ikev2_profile_add_del, "name <profile_name> [del]") \
18291_(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n" \
18292 "(auth_data 0x<data> | auth_data <data>)") \
18293_(ikev2_profile_set_id, "name <profile_name> id_type <type>\n" \
18294 "(id_data 0x<data> | id_data <data>) (local|remote)") \
18295_(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n" \
18296 "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
18297 "(local|remote)") \
18298_(ikev2_set_local_key, "file <absolute_file_path>") \
Radu Nicolaucb33dc22017-02-16 16:49:46 +000018299_(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
18300_(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
18301_(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
18302_(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
18303_(ikev2_initiate_sa_init, "<profile_name>") \
18304_(ikev2_initiate_del_ike_sa, "<ispi>") \
18305_(ikev2_initiate_del_child_sa, "<ispi>") \
18306_(ikev2_initiate_rekey_child_sa, "<ispi>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010018307_(delete_loopback,"sw_if_index <nn>") \
18308_(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
18309_(map_add_domain, \
18310 "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> " \
18311 "ip6-src <ip6addr> " \
18312 "ea-bits-len <n> psid-offset <n> psid-len <n>") \
18313_(map_del_domain, "index <n>") \
18314_(map_add_del_rule, \
18315 "index <n> psid <n> dst <ip6addr> [del]") \
18316_(map_domain_dump, "") \
18317_(map_rule_dump, "index <map-domain>") \
18318_(want_interface_events, "enable|disable") \
18319_(want_stats,"enable|disable") \
18320_(get_first_msg_id, "client <name>") \
18321_(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
18322_(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n" \
18323 "fib-id <nn> [ip4][ip6][default]") \
18324_(get_node_graph, " ") \
18325_(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>") \
18326_(ioam_enable, "[trace] [pow] [ppc <encap|decap>]") \
18327_(ioam_disable, "") \
18328_(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
18329 " sw_if_index <sw_if_index> p <priority> " \
18330 "w <weight>] [del]") \
18331_(lisp_add_del_locator, "locator-set <locator_name> " \
18332 "iface <intf> | sw_if_index <sw_if_index> " \
18333 "p <priority> w <weight> [del]") \
18334_(lisp_add_del_local_eid,"vni <vni> eid " \
18335 "<ipv4|ipv6>/<prefix> | <L2 address> " \
18336 "locator-set <locator_name> [del]" \
18337 "[key-id sha1|sha256 secret-key <secret-key>]") \
Filip Tehlarc3af7bf2017-01-13 14:13:09 +010018338_(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>" \
18339 "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010018340_(lisp_add_del_map_resolver, "<ip4|6-addr> [del]") \
18341_(lisp_add_del_map_server, "<ip4|6-addr> [del]") \
18342_(lisp_gpe_enable_disable, "enable|disable") \
18343_(lisp_enable_disable, "enable|disable") \
18344_(lisp_map_register_enable_disable, "enable|disable") \
18345_(lisp_rloc_probe_enable_disable, "enable|disable") \
18346_(lisp_gpe_add_del_iface, "up|down") \
18347_(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> " \
18348 "[seid <seid>] " \
18349 "rloc <locator> p <prio> " \
18350 "w <weight> [rloc <loc> ... ] " \
18351 "action <action> [del-all]") \
18352_(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid " \
18353 "<local-eid>") \
18354_(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del") \
18355_(lisp_map_request_mode, "src-dst|dst-only") \
18356_(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]") \
18357_(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>") \
18358_(lisp_locator_set_dump, "[local | remote]") \
18359_(lisp_locator_dump, "ls_index <index> | ls_name <name>") \
18360_(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] " \
18361 "[local] | [remote]") \
18362_(lisp_eid_table_vni_dump, "") \
18363_(lisp_eid_table_map_dump, "l2|l3") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010018364_(lisp_map_resolver_dump, "") \
18365_(lisp_map_server_dump, "") \
18366_(lisp_adjacencies_get, "vni <vni>") \
Filip Tehlar5fae99c2017-01-18 12:57:37 +010018367_(lisp_gpe_fwd_entries_get, "vni <vni>") \
18368_(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010018369_(show_lisp_rloc_probe_state, "") \
18370_(show_lisp_map_register_state, "") \
18371_(show_lisp_status, "") \
18372_(lisp_get_map_request_itr_rlocs, "") \
18373_(show_lisp_pitr, "") \
18374_(show_lisp_map_request_mode, "") \
18375_(af_packet_create, "name <host interface name> [hw_addr <mac>]") \
18376_(af_packet_delete, "name <host interface name>") \
18377_(policer_add_del, "name <policer name> <params> [del]") \
18378_(policer_dump, "[name <policer name>]") \
18379_(policer_classify_set_interface, \
18380 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
18381 " [l2-table <nn>] [del]") \
18382_(policer_classify_dump, "type [ip4|ip6|l2]") \
18383_(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] " \
18384 "[master|slave]") \
18385_(netmap_delete, "name <interface name>") \
18386_(mpls_tunnel_dump, "tunnel_index <tunnel-id>") \
18387_(mpls_fib_dump, "") \
18388_(classify_table_ids, "") \
18389_(classify_table_by_interface, "sw_if_index <sw_if_index>") \
18390_(classify_table_info, "table_id <nn>") \
18391_(classify_session_dump, "table_id <nn>") \
18392_(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] " \
18393 "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] " \
18394 "[template_interval <nn>] [udp_checksum]") \
18395_(ipfix_exporter_dump, "") \
18396_(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
18397_(ipfix_classify_stream_dump, "") \
18398_(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
18399_(ipfix_classify_table_dump, "") \
18400_(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
18401_(sw_interface_span_dump, "") \
18402_(get_next_index, "node-name <node-name> next-node-name <node-name>") \
18403_(pg_create_interface, "if_id <nn>") \
18404_(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]") \
18405_(pg_enable_disable, "[stream <id>] disable") \
18406_(ip_source_and_port_range_check_add_del, \
18407 "<ip-addr>/<mask> range <nn>-<nn> vrf <id>") \
18408_(ip_source_and_port_range_check_interface_add_del, \
18409 "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]" \
18410 "[udp-in-vrf <id>] [udp-out-vrf <id>]") \
18411_(ipsec_gre_add_del_tunnel, \
18412 "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]") \
18413_(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]") \
18414_(delete_subif,"<intfc> | sw_if_index <nn>") \
18415_(l2_interface_pbb_tag_rewrite, \
18416 "<intfc> | sw_if_index <nn> \n" \
18417 "[disable | push | pop | translate_pbb_stag <outer_tag>] \n" \
18418 "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]") \
18419_(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]") \
18420_(flow_classify_set_interface, \
18421 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
18422_(flow_classify_dump, "type [ip4|ip6]") \
18423_(ip_fib_dump, "") \
Neale Ranns5a8123b2017-01-26 01:18:23 -080018424_(ip_mfib_dump, "") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010018425_(ip6_fib_dump, "") \
Neale Ranns5a8123b2017-01-26 01:18:23 -080018426_(ip6_mfib_dump, "") \
Damjan Marion7cd468a2016-12-19 23:05:39 +010018427_(feature_enable_disable, "arc_name <arc_name> " \
18428 "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]") \
18429_(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>" \
18430"[disable]") \
18431_(l2_xconnect_dump, "") \
18432_(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>") \
18433_(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>") \
18434_(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")
18435
Pavel Kotucek738f3f22017-01-09 15:11:03 +010018436#if DPDK > 0
18437#define foreach_vpe_dpdk_api_msg \
18438_(sw_interface_set_dpdk_hqos_pipe, \
18439 "rx <intfc> | sw_if_index <id> subport <subport-id> pipe <pipe-id>\n" \
18440 "profile <profile-id>\n") \
18441_(sw_interface_set_dpdk_hqos_subport, \
18442 "rx <intfc> | sw_if_index <id> subport <subport-id> [rate <n>]\n" \
18443 "[bktsize <n>] [tc0 <n>] [tc1 <n>] [tc2 <n>] [tc3 <n>] [period <n>]\n") \
18444_(sw_interface_set_dpdk_hqos_tctbl, \
18445 "rx <intfc> | sw_if_index <id> entry <n> tc <n> queue <n>\n")
18446#endif
18447
Damjan Marion7cd468a2016-12-19 23:05:39 +010018448/* List of command functions, CLI names map directly to functions */
18449#define foreach_cli_function \
18450_(comment, "usage: comment <ignore-rest-of-line>") \
18451_(dump_interface_table, "usage: dump_interface_table") \
18452_(dump_sub_interface_table, "usage: dump_sub_interface_table") \
18453_(dump_ipv4_table, "usage: dump_ipv4_table") \
18454_(dump_ipv6_table, "usage: dump_ipv6_table") \
18455_(dump_stats_table, "usage: dump_stats_table") \
18456_(dump_macro_table, "usage: dump_macro_table ") \
18457_(dump_node_table, "usage: dump_node_table") \
18458_(dump_msg_api_table, "usage: dump_msg_api_table") \
18459_(get_msg_id, "usage: get_msg_id name_and_crc") \
18460_(echo, "usage: echo <message>") \
18461_(exec, "usage: exec <vpe-debug-CLI-command>") \
18462_(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>") \
18463_(help, "usage: help") \
18464_(q, "usage: quit") \
18465_(quit, "usage: quit") \
18466_(search_node_table, "usage: search_node_table <name>...") \
18467_(set, "usage: set <variable-name> <value>") \
18468_(script, "usage: script <file-name>") \
18469_(unset, "usage: unset <variable-name>")
18470
18471#define _(N,n) \
18472 static void vl_api_##n##_t_handler_uni \
18473 (vl_api_##n##_t * mp) \
18474 { \
18475 vat_main_t * vam = &vat_main; \
18476 if (vam->json_output) { \
18477 vl_api_##n##_t_handler_json(mp); \
18478 } else { \
18479 vl_api_##n##_t_handler(mp); \
18480 } \
18481 }
18482foreach_vpe_api_reply_msg;
18483#undef _
18484
Pavel Kotucek738f3f22017-01-09 15:11:03 +010018485#if DPDK > 0
18486#define _(N,n) \
18487 static void vl_api_##n##_t_handler_uni \
18488 (vl_api_##n##_t * mp) \
18489 { \
18490 vat_main_t * vam = &vat_main; \
18491 if (vam->json_output) { \
18492 vl_api_##n##_t_handler_json(mp); \
18493 } else { \
18494 vl_api_##n##_t_handler(mp); \
18495 } \
18496 }
18497foreach_vpe_dpdk_api_reply_msg;
18498#undef _
18499#endif
18500
Damjan Marion7cd468a2016-12-19 23:05:39 +010018501void
18502vat_api_hookup (vat_main_t * vam)
18503{
18504#define _(N,n) \
18505 vl_msg_api_set_handlers(VL_API_##N, #n, \
18506 vl_api_##n##_t_handler_uni, \
18507 vl_noop_handler, \
18508 vl_api_##n##_t_endian, \
18509 vl_api_##n##_t_print, \
18510 sizeof(vl_api_##n##_t), 1);
18511 foreach_vpe_api_reply_msg;
18512#undef _
18513
Pavel Kotucek738f3f22017-01-09 15:11:03 +010018514#if DPDK > 0
18515#define _(N,n) \
18516 vl_msg_api_set_handlers(VL_API_##N, #n, \
18517 vl_api_##n##_t_handler_uni, \
18518 vl_noop_handler, \
18519 vl_api_##n##_t_endian, \
18520 vl_api_##n##_t_print, \
18521 sizeof(vl_api_##n##_t), 1);
18522 foreach_vpe_dpdk_api_reply_msg;
18523#undef _
18524#endif
18525
Damjan Marion7cd468a2016-12-19 23:05:39 +010018526#if (VPP_API_TEST_BUILTIN==0)
18527 vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
18528#endif
18529
18530 vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
18531
18532 vam->function_by_name = hash_create_string (0, sizeof (uword));
18533
18534 vam->help_by_name = hash_create_string (0, sizeof (uword));
18535
18536 /* API messages we can send */
18537#define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
18538 foreach_vpe_api_msg;
18539#undef _
Pavel Kotucek738f3f22017-01-09 15:11:03 +010018540#if DPDK >0
18541#define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
18542 foreach_vpe_dpdk_api_msg;
18543#undef _
18544#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +010018545
18546 /* Help strings */
18547#define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18548 foreach_vpe_api_msg;
18549#undef _
Pavel Kotucek738f3f22017-01-09 15:11:03 +010018550#if DPDK >0
18551#define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18552 foreach_vpe_dpdk_api_msg;
18553#undef _
18554#endif
Damjan Marion7cd468a2016-12-19 23:05:39 +010018555
18556 /* CLI functions */
18557#define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
18558 foreach_cli_function;
18559#undef _
18560
18561 /* Help strings */
18562#define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18563 foreach_cli_function;
18564#undef _
18565}
18566
18567/*
18568 * fd.io coding-style-patch-verification: ON
18569 *
18570 * Local Variables:
18571 * eval: (c-set-style "gnu")
18572 * End:
18573 */